2 * This software is part of the SBCL system. See the README file for
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
26 #include "gc-internal.h"
28 #include "genesis/static-symbols.h"
29 #include "genesis/symbol.h"
32 write_bytes(FILE *file
, char *addr
, long bytes
)
34 long count
, here
, data
;
36 bytes
= (bytes
+os_vm_page_size
-1)&~(os_vm_page_size
-1);
41 data
= (ftell(file
)+os_vm_page_size
-1)&~(os_vm_page_size
-1);
45 count
= fwrite(addr
, 1, bytes
, file
);
51 perror("error writing to save file");
57 return data
/os_vm_page_size
- 1;
61 output_space(FILE *file
, int id
, lispobj
*addr
, lispobj
*end
)
63 int words
, bytes
, data
;
64 static char *names
[] = {NULL
, "dynamic", "static", "read-only"};
70 bytes
= words
* sizeof(lispobj
);
72 printf("writing %d bytes from the %s space at 0x%08lx\n",
73 bytes
, names
[id
], (unsigned long)addr
);
75 data
= write_bytes(file
, (char *)addr
, bytes
);
78 putw((long)addr
/ os_vm_page_size
, file
);
79 putw((bytes
+ os_vm_page_size
- 1) / os_vm_page_size
, file
);
83 save(char *filename
, lispobj init_function
)
87 /* Open the output file. We don't actually need the file yet, but
88 * the fopen() might fail for some reason, and we want to detect
89 * that and back out before we do anything irreversible. */
91 file
= fopen(filename
, "w");
97 /* Smash the enclosing state. (Once we do this, there's no good
98 * way to go back, which is a sufficient reason that this ends up
99 * being SAVE-LISP-AND-DIE instead of SAVE-LISP-AND-GO-ON). */
100 printf("[undoing binding stack and other enclosing state... ");
102 unbind_to_here((lispobj
*)BINDING_STACK_START
);
103 SetSymbolValue(CURRENT_CATCH_BLOCK
, 0);
104 SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK
, 0);
108 /* (Now we can actually start copying ourselves into the output file.) */
110 printf("[saving current Lisp image into %s:\n", filename
);
113 putw(CORE_MAGIC
, file
);
115 putw(VERSION_CORE_ENTRY_TYPE_CODE
, file
);
117 putw(SBCL_CORE_VERSION_INTEGER
, file
);
119 putw(BUILD_ID_CORE_ENTRY_TYPE_CODE
, file
);
120 putw(/* (We're writing the word count of the entry here, and the 2
121 * term is one word for the leading BUILD_ID_CORE_ENTRY_TYPE_CODE
122 * word and one word where we store the count itself.) */
123 2 + strlen(build_id
),
127 for (p
= build_id
; *p
; ++p
)
131 putw(NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE
, file
);
132 putw(/* (word count = 3 spaces described by 5 words each, plus the
133 * entry type code, plus this count itself) */
136 READ_ONLY_CORE_SPACE_ID
,
137 (lispobj
*)READ_ONLY_SPACE_START
,
138 (lispobj
*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER
));
140 STATIC_CORE_SPACE_ID
,
141 (lispobj
*)STATIC_SPACE_START
,
142 (lispobj
*)SymbolValue(STATIC_SPACE_FREE_POINTER
));
145 DYNAMIC_CORE_SPACE_ID
,
146 (lispobj
*)current_dynamic_space
,
147 dynamic_space_free_pointer
);
149 #ifdef LISP_FEATURE_GENCGC
150 /* Flush the current_region, updating the tables. */
151 gc_alloc_update_all_page_tables();
152 update_x86_dynamic_space_free_pointer();
155 DYNAMIC_CORE_SPACE_ID
,
156 (lispobj
*)DYNAMIC_SPACE_START
,
157 (lispobj
*)SymbolValue(ALLOCATION_POINTER
));
160 putw(INITIAL_FUN_CORE_ENTRY_TYPE_CODE
, file
);
162 putw(init_function
, file
);
164 putw(END_CORE_ENTRY_TYPE_CODE
, file
);