1.0.45.22: non-racy RUN-PROGRAM :PTY on OpenBSD
[sbcl.git] / src / runtime / save.c
1 /*
2  * This software is part of the SBCL system. See the README file for
3  * more information.
4  *
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.
10  */
11
12 #ifndef LISP_FEATURE_WIN32
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #endif
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <signal.h>
20 #include <sys/file.h>
21
22 #include "sbcl.h"
23 #include "runtime.h"
24 #include "os.h"
25 #include "core.h"
26 #include "globals.h"
27 #include "save.h"
28 #include "dynbind.h"
29 #include "lispregs.h"
30 #include "validate.h"
31 #include "gc-internal.h"
32 #include "thread.h"
33
34 #include "genesis/static-symbols.h"
35 #include "genesis/symbol.h"
36
37 #if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX)
38 #include "genesis/lutex.h"
39 #endif
40
41 /* write_runtime_options uses a simple serialization scheme that
42  * consists of one word of magic, one word indicating whether options
43  * are actually saved, and one word per struct field. */
44 static void
45 write_runtime_options(FILE *file, struct runtime_options *options)
46 {
47     size_t optarray[RUNTIME_OPTIONS_WORDS];
48
49     memset(&optarray, 0, sizeof(optarray));
50     optarray[0] = RUNTIME_OPTIONS_MAGIC;
51
52     if (options != NULL) {
53         /* optarray[1] is a flag indicating that options are present */
54         optarray[1] = 1;
55         optarray[2] = options->dynamic_space_size;
56         optarray[3] = options->thread_control_stack_size;
57     }
58
59     if (RUNTIME_OPTIONS_WORDS !=
60         fwrite(optarray, sizeof(size_t), RUNTIME_OPTIONS_WORDS, file)) {
61         perror("Error writing runtime options to file");
62     }
63 }
64
65 static void
66 write_lispobj(lispobj obj, FILE *file)
67 {
68     if (1 != fwrite(&obj, sizeof(lispobj), 1, file)) {
69         perror("Error writing to file");
70     }
71 }
72
73 static long
74 write_bytes(FILE *file, char *addr, long bytes, os_vm_offset_t file_offset)
75 {
76     long count, here, data;
77
78     bytes = (bytes+os_vm_page_size-1)&~(os_vm_page_size-1);
79
80 #ifdef LISP_FEATURE_WIN32
81     /* touch every single page in the space to force it to be mapped. */
82     for (count = 0; count < bytes; count += 0x1000) {
83         volatile int temp = addr[count];
84     }
85 #endif
86
87     fflush(file);
88     here = ftell(file);
89     fseek(file, 0, SEEK_END);
90     data = (ftell(file)+os_vm_page_size-1)&~(os_vm_page_size-1);
91     fseek(file, data, SEEK_SET);
92
93     while (bytes > 0) {
94         count = fwrite(addr, 1, bytes, file);
95         if (count > 0) {
96             bytes -= count;
97             addr += count;
98         }
99         else {
100             perror("error writing to save file");
101             bytes = 0;
102         }
103     }
104     fflush(file);
105     fseek(file, here, SEEK_SET);
106     return ((data - file_offset) / os_vm_page_size) - 1;
107 }
108
109 #if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX)
110 /* saving lutexes in the core */
111 static void **lutex_addresses;
112 static long n_lutexes = 0;
113 static long max_lutexes = 0;
114
115 static long
116 default_scan_action(lispobj *obj)
117 {
118     return (sizetab[widetag_of(*obj)])(obj);
119 }
120
121 static long
122 lutex_scan_action(lispobj *obj)
123 {
124     /* note the address of the lutex */
125     if(n_lutexes >= max_lutexes) {
126         max_lutexes *= 2;
127         lutex_addresses = realloc(lutex_addresses, max_lutexes * sizeof(void *));
128         gc_assert(lutex_addresses);
129     }
130
131     lutex_addresses[n_lutexes++] = obj;
132
133     return (*sizetab[widetag_of(*obj)])(obj);
134 }
135
136 typedef long (*scan_table[256])(lispobj *obj);
137
138 static void
139 scan_objects(lispobj *start, long n_words, scan_table table)
140 {
141     lispobj *end = start + n_words;
142     lispobj *object_ptr;
143     long n_words_scanned;
144     for (object_ptr = start;
145          object_ptr < end;
146          object_ptr += n_words_scanned) {
147         lispobj obj = *object_ptr;
148
149         n_words_scanned = (table[widetag_of(obj)])(object_ptr);
150     }
151 }
152
153 static void
154 scan_for_lutexes(lispobj *addr, long n_words)
155 {
156     static int initialized = 0;
157     static scan_table lutex_scan_table;
158
159     if (!initialized) {
160         int i;
161
162         /* allocate a little space to get started */
163         lutex_addresses = malloc(16*sizeof(void *));
164         gc_assert(lutex_addresses);
165         max_lutexes = 16;
166
167         /* initialize the mapping table */
168         for(i = 0; i < ((sizeof lutex_scan_table)/(sizeof lutex_scan_table[0])); ++i) {
169             lutex_scan_table[i] = default_scan_action;
170         }
171
172         lutex_scan_table[LUTEX_WIDETAG] = lutex_scan_action;
173
174         initialized = 1;
175     }
176
177     /* do the scan */
178     scan_objects(addr, n_words, lutex_scan_table);
179 }
180 #endif
181
182 static void
183 output_space(FILE *file, int id, lispobj *addr, lispobj *end, os_vm_offset_t file_offset)
184 {
185     size_t words, bytes, data;
186     static char *names[] = {NULL, "dynamic", "static", "read-only"};
187
188     write_lispobj(id, file);
189     words = end - addr;
190     write_lispobj(words, file);
191
192     bytes = words * sizeof(lispobj);
193
194 #if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX)
195     printf("scanning space for lutexes...\n");
196     scan_for_lutexes((char *)addr, words);
197 #endif
198
199     printf("writing %lu bytes from the %s space at 0x%08lx\n",
200            (unsigned long)bytes, names[id], (unsigned long)addr);
201
202     data = write_bytes(file, (char *)addr, bytes, file_offset);
203
204     write_lispobj(data, file);
205     write_lispobj((long)addr / os_vm_page_size, file);
206     write_lispobj((bytes + os_vm_page_size - 1) / os_vm_page_size, file);
207 }
208
209 FILE *
210 open_core_for_saving(char *filename)
211 {
212     /* Open the output file. We don't actually need the file yet, but
213      * the fopen() might fail for some reason, and we want to detect
214      * that and back out before we do anything irreversible. */
215     unlink(filename);
216     return fopen(filename, "wb");
217 }
218
219 boolean
220 save_to_filehandle(FILE *file, char *filename, lispobj init_function,
221                    boolean make_executable,
222                    boolean save_runtime_options)
223 {
224     struct thread *th;
225     os_vm_offset_t core_start_pos;
226
227     /* Smash the enclosing state. (Once we do this, there's no good
228      * way to go back, which is a sufficient reason that this ends up
229      * being SAVE-LISP-AND-DIE instead of SAVE-LISP-AND-GO-ON). */
230     printf("[undoing binding stack and other enclosing state... ");
231     fflush(stdout);
232     for_each_thread(th) {       /* XXX really? */
233         unbind_to_here((lispobj *)th->binding_stack_start,th);
234         SetSymbolValue(CURRENT_CATCH_BLOCK, 0,th);
235         SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK, 0,th);
236     }
237     printf("done]\n");
238     fflush(stdout);
239
240     /* (Now we can actually start copying ourselves into the output file.) */
241
242     printf("[saving current Lisp image into %s:\n", filename);
243     fflush(stdout);
244
245     core_start_pos = ftell(file);
246     write_lispobj(CORE_MAGIC, file);
247
248     write_lispobj(VERSION_CORE_ENTRY_TYPE_CODE, file);
249     write_lispobj(3, file);
250     write_lispobj(SBCL_CORE_VERSION_INTEGER, file);
251
252     write_lispobj(BUILD_ID_CORE_ENTRY_TYPE_CODE, file);
253     write_lispobj(/* (We're writing the word count of the entry here, and the 2
254           * term is one word for the leading BUILD_ID_CORE_ENTRY_TYPE_CODE
255           * word and one word where we store the count itself.) */
256          2 + strlen((const char *)build_id),
257          file);
258     {
259         unsigned char *p;
260         for (p = (unsigned char *)build_id; *p; ++p)
261             write_lispobj(*p, file);
262     }
263
264     write_lispobj(NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE, file);
265     write_lispobj(/* (word count = 3 spaces described by 5 words each, plus the
266           * entry type code, plus this count itself) */
267          (5*3)+2, file);
268     output_space(file,
269                  READ_ONLY_CORE_SPACE_ID,
270                  (lispobj *)READ_ONLY_SPACE_START,
271                  (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0),
272                  core_start_pos);
273     output_space(file,
274                  STATIC_CORE_SPACE_ID,
275                  (lispobj *)STATIC_SPACE_START,
276                  (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER,0),
277                  core_start_pos);
278 #ifdef LISP_FEATURE_GENCGC
279     /* Flush the current_region, updating the tables. */
280     gc_alloc_update_all_page_tables();
281     update_dynamic_space_free_pointer();
282 #endif
283 #ifdef reg_ALLOC
284 #ifdef LISP_FEATURE_GENCGC
285     output_space(file,
286                  DYNAMIC_CORE_SPACE_ID,
287                  (lispobj *)DYNAMIC_SPACE_START,
288                  dynamic_space_free_pointer,
289                  core_start_pos);
290 #else
291     output_space(file,
292                  DYNAMIC_CORE_SPACE_ID,
293                  (lispobj *)current_dynamic_space,
294                  dynamic_space_free_pointer,
295                  core_start_pos);
296 #endif
297 #else
298     output_space(file,
299                  DYNAMIC_CORE_SPACE_ID,
300                  (lispobj *)DYNAMIC_SPACE_START,
301                  (lispobj *)SymbolValue(ALLOCATION_POINTER,0),
302                  core_start_pos);
303 #endif
304
305     write_lispobj(INITIAL_FUN_CORE_ENTRY_TYPE_CODE, file);
306     write_lispobj(3, file);
307     write_lispobj(init_function, file);
308
309 #ifdef LISP_FEATURE_GENCGC
310     {
311         size_t size = (last_free_page*sizeof(long)+os_vm_page_size-1)
312             &~(os_vm_page_size-1);
313         unsigned long *data = calloc(size, 1);
314         if (data) {
315             unsigned long word;
316             long offset;
317             int i;
318             for (i = 0; i < last_free_page; i++) {
319                 /* Thanks to alignment requirements, the two low bits
320                  * are always zero, so we can use them to store the
321                  * allocation type -- region is always closed, so only
322                  * the two low bits of allocation flags matter. */
323                 word = page_table[i].region_start_offset;
324                 gc_assert((word & 0x03) == 0);
325                 data[i] = word | (0x03 & page_table[i].allocated);
326             }
327             write_lispobj(PAGE_TABLE_CORE_ENTRY_TYPE_CODE, file);
328             write_lispobj(4, file);
329             write_lispobj(size, file);
330             offset = write_bytes(file, (char *)data, size, core_start_pos);
331             write_lispobj(offset, file);
332         }
333     }
334 #endif
335
336 #if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX)
337     if(n_lutexes > 0) {
338         long offset;
339         printf("writing %ld lutexes to the core...\n", n_lutexes);
340         write_lispobj(LUTEX_TABLE_CORE_ENTRY_TYPE_CODE, file);
341         /* word count of the entry */
342         write_lispobj(4, file);
343         /* indicate how many lutexes we saved */
344         write_lispobj(n_lutexes, file);
345         /* save the lutexes */
346         offset = write_bytes(file, (char *) lutex_addresses,
347                              n_lutexes * sizeof(*lutex_addresses),
348                              core_start_pos);
349
350         write_lispobj(offset, file);
351     }
352 #endif
353
354     write_lispobj(END_CORE_ENTRY_TYPE_CODE, file);
355
356     /* Write a trailing header, ignored when parsing the core normally.
357      * This is used to locate the start of the core when the runtime is
358      * prepended to it. */
359     fseek(file, 0, SEEK_END);
360
361     /* If NULL runtime options are passed to write_runtime_options,
362      * command-line processing is performed as normal in the SBCL
363      * executable. Otherwise, the saved runtime options are used and
364      * all command-line arguments are available to Lisp in
365      * SB-EXT:*POSIX-ARGV*. */
366     write_runtime_options(file,
367                           (save_runtime_options ? runtime_options : NULL));
368
369     if (1 != fwrite(&core_start_pos, sizeof(os_vm_offset_t), 1, file)) {
370         perror("Error writing core starting position to file");
371         fclose(file);
372     } else {
373         write_lispobj(CORE_MAGIC, file);
374         fclose(file);
375     }
376
377 #ifndef LISP_FEATURE_WIN32
378     if (make_executable)
379         chmod (filename, 0755);
380 #endif
381
382     printf("done]\n");
383     exit(0);
384 }
385
386 /* Check if the build_id for the current runtime is present in a
387  * buffer. */
388 int
389 check_runtime_build_id(void *buf, size_t size)
390 {
391     size_t idlen;
392     char *pos;
393
394     idlen = strlen(build_id) - 1;
395     while ((pos = memchr(buf, build_id[0], size)) != NULL) {
396         size -= (pos + 1) - (char *)buf;
397         buf = (pos + 1);
398         if (idlen <= size && memcmp(buf, build_id + 1, idlen) == 0)
399             return 1;
400     }
401
402     return 0;
403 }
404
405 /* Slurp the executable portion of the runtime into a malloced buffer
406  * and return it.  Places the size in bytes of the runtime into
407  * 'size_out'.  Returns NULL if the runtime cannot be loaded from
408  * 'runtime_path'. */
409 void *
410 load_runtime(char *runtime_path, size_t *size_out)
411 {
412     void *buf = NULL;
413     FILE *input = NULL;
414     size_t size, count;
415     os_vm_offset_t core_offset;
416
417     core_offset = search_for_embedded_core (runtime_path);
418     if ((input = fopen(runtime_path, "rb")) == NULL) {
419         fprintf(stderr, "Unable to open runtime: %s\n", runtime_path);
420         goto lose;
421     }
422
423     fseek(input, 0, SEEK_END);
424     size = (size_t) ftell(input);
425     fseek(input, 0, SEEK_SET);
426
427     if (core_offset != -1 && size > core_offset)
428         size = core_offset;
429
430     buf = successful_malloc(size);
431     if ((count = fread(buf, 1, size, input)) != size) {
432         fprintf(stderr, "Premature EOF while reading runtime.\n");
433         goto lose;
434     }
435
436     if (!check_runtime_build_id(buf, size)) {
437         fprintf(stderr, "Failed to locate current build_id in runtime: %s\n",
438             runtime_path);
439         goto lose;
440     }
441
442     fclose(input);
443     *size_out = size;
444     return buf;
445
446 lose:
447     if (input != NULL)
448         fclose(input);
449     if (buf != NULL)
450         free(buf);
451     return NULL;
452 }
453
454 boolean
455 save_runtime_to_filehandle(FILE *output, void *runtime, size_t runtime_size)
456 {
457     size_t padding;
458     void *padbytes;
459
460     if (runtime_size != fwrite(runtime, 1, runtime_size, output)) {
461         perror("Error saving runtime");
462         return 0;
463     }
464
465     padding = (os_vm_page_size - (runtime_size % os_vm_page_size)) & ~os_vm_page_size;
466     if (padding > 0) {
467         padbytes = successful_malloc(padding);
468         memset(padbytes, 0, padding);
469         if (padding != fwrite(padbytes, 1, padding, output)) {
470             perror("Error saving runtime");
471             free(padbytes);
472             return 0;
473         }
474         free(padbytes);
475     }
476
477     return 1;
478 }
479
480 FILE *
481 prepare_to_save(char *filename, boolean prepend_runtime, void **runtime_bytes,
482                 size_t *runtime_size)
483 {
484     FILE *file;
485     char *runtime_path;
486
487     if (prepend_runtime) {
488         runtime_path = os_get_runtime_executable_path(0);
489
490         if (runtime_path == NULL && saved_runtime_path == NULL) {
491             fprintf(stderr, "Unable to get default runtime path.\n");
492             return NULL;
493         }
494
495         if (runtime_path == NULL)
496             *runtime_bytes = load_runtime(saved_runtime_path, runtime_size);
497         else {
498             *runtime_bytes = load_runtime(runtime_path, runtime_size);
499             free(runtime_path);
500         }
501
502         if (*runtime_bytes == NULL)
503             return 0;
504     }
505
506     file = open_core_for_saving(filename);
507     if (file == NULL) {
508         free(*runtime_bytes);
509         perror(filename);
510         return NULL;
511     }
512
513     return file;
514 }
515
516 boolean
517 save(char *filename, lispobj init_function, boolean prepend_runtime,
518      boolean save_runtime_options)
519 {
520     FILE *file;
521     void *runtime_bytes = NULL;
522     size_t runtime_size;
523
524     file = prepare_to_save(filename, prepend_runtime, &runtime_bytes, &runtime_size);
525     if (file == NULL)
526         return 1;
527
528     if (prepend_runtime)
529         save_runtime_to_filehandle(file, runtime_bytes, runtime_size);
530
531     return save_to_filehandle(file, filename, init_function, prepend_runtime,
532                               save_runtime_options);
533 }