1 ;;;; target-only code that knows how to load compiled code directly
4 ;;;; FIXME: The filename here is confusing because "core" here means
5 ;;;; "main memory", while elsewhere in the system it connotes a
6 ;;;; ".core" file dumping the contents of main memory.
8 ;;;; This software is part of the SBCL system. See the README file for
11 ;;;; This software is derived from the CMU CL system, which was
12 ;;;; written at Carnegie Mellon University and released into the
13 ;;;; public domain. The software is in the public domain and is
14 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
15 ;;;; files for more information.
19 (declaim (ftype (sfunction (#!+immobile-code boolean fixnum fixnum
)
20 code-component
) allocate-code-object
))
21 (defun allocate-code-object (#!+immobile-code immobile-p boxed unboxed
)
25 (cond #!+immobile-code
27 (sb!vm
::allocate-immobile-code boxed unboxed
))
30 (alien-funcall (extern-alien "alloc_code_object"
31 (function unsigned unsigned unsigned
))
33 #!+x86
(setf (sb!vm
::%code-fixups code
)
34 #.
(!coerce-to-specialized
#() '(unsigned-byte 32)))
37 (%primitive allocate-code-object boxed unboxed
))
39 ;; OFFSET is in bytes from the start of the code component's raw bytes
40 (defun new-simple-fun (code fun-index offset nfuns
)
41 (declare (type (unsigned-byte 27) fun-index
)
43 (type (unsigned-byte 14) nfuns
))
44 (unless (zerop (logand offset sb
!vm
:lowtag-mask
))
45 (bug "unaligned function object, offset = #X~X" offset
))
46 (let ((header-data (get-header-data code
)))
48 (let* ((n-header-words (logand header-data sb
!vm
:short-header-max-words
))
49 (index (+ (- sb
!vm
:other-pointer-lowtag
)
50 (ash n-header-words sb
!vm
:word-shift
)
51 (ash (1- fun-index
) 2))))
52 (aver (eql (sap-ref-32 (int-sap (get-lisp-obj-address code
)) index
) 0))
53 (setf (sap-ref-32 (int-sap (get-lisp-obj-address code
)) index
) offset
))
54 ;; Special case for the first simple-fun:
55 ;; The value range of 'offset' and 'nfuns' is the same
56 ;; regardless of word size.
57 ;; It's as if it's a positive 32-bit fixnum (29 significant bits).
58 ;; 16 bits is enough for the offset because it only needs to
59 ;; skip over the unboxed constants.
61 (let ((newval (logior (ash (the (mod #x8000
) offset
) 14) nfuns
)))
62 (aver (eql (sb!vm
::%code-n-entries code
) 0))
63 (setf (sb!vm
::%code-n-entries code
) newval
))
65 (let ((newval (logior (ash (the (mod #x8000
) offset
) 16) nfuns
)))
66 (aver (eql (ldb (byte 32 24) header-data
) 0))
67 (set-header-data code
(dpb newval
(byte 32 24) header-data
)))))
68 (let ((fun (%primitive sb
!c
:compute-fun code offset
)))
69 ;; x86 backends store the address of the entrypoint in 'self'
71 (with-pinned-objects (fun)
72 (setf (%simple-fun-self fun
)
73 (%make-lisp-obj
(+ (get-lisp-obj-address fun
)
74 (ash sb
!vm
:simple-fun-code-offset sb
!vm
:word-shift
)
75 (- sb
!vm
:fun-pointer-lowtag
)))))
76 ;; non-x86 backends store the function itself (what else?) in 'self'
78 (setf (%simple-fun-self fun
) fun
)
81 ;;; Make a function entry, filling in slots from the ENTRY-INFO.
82 (defun make-fun-entry (fun-index entry-info code-obj object nfuns
)
83 (declare (type entry-info entry-info
) (type core-object object
))
84 (let ((res (new-simple-fun code-obj fun-index
85 (label-position (entry-info-offset entry-info
))
87 (setf (%simple-fun-name res
) (entry-info-name entry-info
))
88 (setf (%simple-fun-arglist res
) (entry-info-arguments entry-info
))
89 (setf (%simple-fun-type res
) (entry-info-type entry-info
))
90 (setf (%simple-fun-info res
) (entry-info-info entry-info
))
91 (note-fun entry-info res object
)))
93 ;;; Dump a component to core. We pass in the assembler fixups, code
94 ;;; vector and node info.
95 (defun make-core-component (component segment length fixup-notes object
)
96 (declare (type component component
)
97 (type segment segment
)
100 (type core-object object
))
101 (let ((debug-info (debug-info-for-component component
)))
102 ;; FIXME: use WITHOUT-GCING only for stuff that needs it.
103 ;; Most likely this could be WITH-PINNED-OBJECTS.
104 ;; See also the remark in LOAD-CODE about the order of installing
105 ;; simple-funs and setting the 'nfuns' value.
107 (let* ((2comp (component-info component
))
108 (constants (ir2-component-constants 2comp
))
109 (box-num (- (length constants
) sb
!vm
:code-constants-offset
))
110 (code-obj (allocate-code-object
111 #!+immobile-code
(eq *compile-to-memory-space
* :immobile
)
113 (declare (type index box-num length
))
115 (copy-byte-vector-to-system-area
116 (the (simple-array assembly-unit
1) (segment-contents-as-vector segment
))
117 (code-instructions code-obj
))
119 (do-core-fixups code-obj fixup-notes
)
121 (let* ((entries (ir2-component-entries 2comp
))
122 (nfuns (length entries
))
124 (dolist (entry entries
)
125 (make-fun-entry (decf fun-index
) entry code-obj object nfuns
)))
127 #!-
(or x86
(and x86-64
(not immobile-space
)))
128 (sb!vm
:sanctify-for-execution code-obj
)
130 (push debug-info
(core-object-debug-info object
))
131 (setf (%code-debug-info code-obj
) debug-info
)
133 (do ((index sb
!vm
:code-constants-offset
(1+ index
)))
134 ((>= index
(length constants
)))
135 (let ((const (aref constants index
)))
139 (setf (code-header-ref code-obj index
)
140 (constant-value const
)))
144 (reference-core-fun code-obj index
(cdr const
) object
))
146 (setf (code-header-ref code-obj index
)
147 (find-or-create-fdefn (cdr const
))))
149 (setf (code-header-ref code-obj index
)
150 (%coerce-name-to-fun
(cdr const
))))))))))))
153 ;;; Backpatch all the DEBUG-INFOs dumped so far with the specified
154 ;;; SOURCE-INFO list. We also check that there are no outstanding
155 ;;; forward references to functions.
156 (defun fix-core-source-info (info object
&optional function
)
157 (declare (type core-object object
)
158 (type (or null function
) function
))
159 (aver (zerop (hash-table-count (core-object-patch-table object
))))
160 (let ((source (debug-source-for-info info
:function function
)))
161 (dolist (info (core-object-debug-info object
))
162 (setf (debug-info-source info
) source
)))
163 (setf (core-object-debug-info object
) nil
)