2 * A saved SBCL system is a .core file; the code here helps us accept
3 * such a file as input.
7 * This software is part of the SBCL system. See the README file for
10 * This software is derived from the CMU CL system, which was
11 * written at Carnegie Mellon University and released into the
12 * public domain. The software is in the public domain and is
13 * provided with absolutely no warranty. See the COPYING and CREDITS
14 * files for more information.
20 #include <sys/types.h>
38 unsigned char build_id
[] =
39 #include "../../output/build-id.tmp"
43 process_directory(int fd
, u32
*ptr
, int count
)
45 struct ndir_entry
*entry
;
47 FSHOW((stderr
, "/process_directory(..), count=%d\n", count
));
49 for (entry
= (struct ndir_entry
*) ptr
; --count
>= 0; ++entry
) {
51 long id
= entry
->identifier
;
52 long offset
= os_vm_page_size
* (1 + entry
->data_page
);
53 os_vm_address_t addr
=
54 (os_vm_address_t
) (os_vm_page_size
* entry
->address
);
55 lispobj
*free_pointer
= (lispobj
*) addr
+ entry
->nwords
;
56 long len
= os_vm_page_size
* entry
->page_count
;
59 os_vm_address_t real_addr
;
60 FSHOW((stderr
, "/mapping %ld(0x%lx) bytes at 0x%lx\n",
61 (long)len
, (long)len
, addr
));
62 real_addr
= os_map(fd
, offset
, addr
, len
);
63 if (real_addr
!= addr
) {
64 lose("file mapped in wrong place! "
65 "(0x%08x != 0x%08lx)",
71 FSHOW((stderr
, "/space id = %d, free pointer = 0x%08x\n",
72 id
, (long)free_pointer
));
75 case DYNAMIC_CORE_SPACE_ID
:
76 #ifdef LISP_FEATURE_GENCGC
77 if (addr
!= (os_vm_address_t
)DYNAMIC_SPACE_START
) {
78 fprintf(stderr
, "in core: 0x%lx; in runtime: 0x%lx \n",
79 (long)addr
, (long)DYNAMIC_SPACE_START
);
80 lose("core/runtime address mismatch: DYNAMIC_SPACE_START");
83 if ((addr
!= (os_vm_address_t
)DYNAMIC_0_SPACE_START
) &&
84 (addr
!= (os_vm_address_t
)DYNAMIC_1_SPACE_START
)) {
85 fprintf(stderr
, "in core: 0x%lx; in runtime: 0x%lx or 0x%lx\n",
87 (long)DYNAMIC_0_SPACE_START
,
88 (long)DYNAMIC_1_SPACE_START
);
89 lose("warning: core/runtime address mismatch: DYNAMIC_SPACE_START");
92 /* FIXME: Should the conditional here be reg_ALLOC instead of
95 #if defined(LISP_FEATURE_X86)
96 SetSymbolValue(ALLOCATION_POINTER
, (lispobj
)free_pointer
,0);
98 dynamic_space_free_pointer
= free_pointer
;
100 /* For stop-and-copy GC, this will be whatever the GC was
101 * using at the time. With GENCGC, this will always be
102 * space 0. (We checked above that for GENCGC,
103 * addr==DYNAMIC_SPACE_START.) */
104 current_dynamic_space
= (lispobj
*)addr
;
106 case STATIC_CORE_SPACE_ID
:
107 if (addr
!= (os_vm_address_t
)STATIC_SPACE_START
) {
108 fprintf(stderr
, "in core: 0x%lx - in runtime: 0x%lx\n",
109 (long)addr
, (long)STATIC_SPACE_START
);
110 lose("core/runtime address mismatch: STATIC_SPACE_START");
113 case READ_ONLY_CORE_SPACE_ID
:
114 if (addr
!= (os_vm_address_t
)READ_ONLY_SPACE_START
) {
115 fprintf(stderr
, "in core: 0x%lx - in runtime: 0x%lx\n",
116 (long)addr
, (long)READ_ONLY_SPACE_START
);
117 lose("core/runtime address mismatch: READ_ONLY_SPACE_START");
121 lose("unknown space ID %ld addr 0x%p", id
);
127 load_core_file(char *file
)
129 u32
*header
, val
, len
, *ptr
, remaining_len
;
130 int fd
= open(file
, O_RDONLY
), count
;
132 lispobj initial_function
= NIL
;
133 FSHOW((stderr
, "/entering load_core_file(%s)\n", file
));
135 fprintf(stderr
, "could not open file \"%s\"\n", file
);
140 header
= calloc(os_vm_page_size
/ sizeof(u32
), sizeof(u32
));
142 count
= read(fd
, header
, os_vm_page_size
);
143 if (count
< os_vm_page_size
) {
144 lose("premature end of core file");
146 SHOW("successfully read first page of core");
151 if (val
!= CORE_MAGIC
) {
152 lose("invalid magic number in core: 0x%lx should have been 0x%x.",
156 SHOW("found CORE_MAGIC");
158 while (val
!= END_CORE_ENTRY_TYPE_CODE
) {
161 remaining_len
= len
- 2; /* (-2 to cancel the two ++ operations) */
162 FSHOW((stderr
, "/val=0x%ld, remaining_len=0x%ld\n",
163 (long)val
, (long)remaining_len
));
167 case END_CORE_ENTRY_TYPE_CODE
:
168 SHOW("END_CORE_ENTRY_TYPE_CODE case");
171 case VERSION_CORE_ENTRY_TYPE_CODE
:
172 SHOW("VERSION_CORE_ENTRY_TYPE_CODE case");
173 if (*ptr
!= SBCL_CORE_VERSION_INTEGER
) {
174 lose("core file version (%d) != runtime library version (%d)",
176 SBCL_CORE_VERSION_INTEGER
);
180 case BUILD_ID_CORE_ENTRY_TYPE_CODE
:
181 SHOW("BUILD_ID_CORE_ENTRY_TYPE_CODE case");
185 FSHOW((stderr
, "build_id[]=\"%s\"\n", build_id
));
186 FSHOW((stderr
, "remaining_len = %d\n", remaining_len
));
187 if (remaining_len
!= strlen(build_id
))
188 goto losing_build_id
;
189 for (i
= 0; i
< remaining_len
; ++i
) {
190 FSHOW((stderr
, "ptr[%d] = char = %d, expected=%d\n",
191 i
, ptr
[i
], build_id
[i
]));
192 if (ptr
[i
] != build_id
[i
])
193 goto losing_build_id
;
197 /* .core files are not binary-compatible between
198 * builds because we can't easily detect whether the
199 * sources were patched between the time the
200 * dumping-the-.core runtime was built and the time
201 * that the loading-the-.core runtime was built.
203 * (We could easily detect whether version.lisp-expr
204 * was changed, but people experimenting with patches
205 * don't necessarily update version.lisp-expr.) */
207 lose("can't load .core for different runtime, sorry");
210 case NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE
:
211 SHOW("NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE case");
212 process_directory(fd
,
215 remaining_len
/ (sizeof(struct ndir_entry
) /
218 remaining_len
/ (sizeof(struct ndir_entry
) /
224 case INITIAL_FUN_CORE_ENTRY_TYPE_CODE
:
225 SHOW("INITIAL_FUN_CORE_ENTRY_TYPE_CODE case");
226 initial_function
= (lispobj
)*ptr
;
230 lose("unknown core file entry: %ld", (long)val
);
233 ptr
+= remaining_len
;
234 FSHOW((stderr
, "/new ptr=%x\n", ptr
));
236 SHOW("about to free(header)");
238 SHOW("returning from load_core_file(..)");
239 return initial_function
;