optarray[3] = options->thread_control_stack_size;
}
- fwrite(optarray, sizeof(size_t), RUNTIME_OPTIONS_WORDS, file);
+ if (RUNTIME_OPTIONS_WORDS !=
+ fwrite(optarray, sizeof(size_t), RUNTIME_OPTIONS_WORDS, file)) {
+ perror("Error writing runtime options to file");
+ }
}
static void
write_lispobj(lispobj obj, FILE *file)
{
- fwrite(&obj, sizeof(lispobj), 1, file);
+ if (1 != fwrite(&obj, sizeof(lispobj), 1, file)) {
+ perror("Error writing to file");
+ }
}
static long
&~(os_vm_page_size-1);
unsigned long *data = calloc(size, 1);
if (data) {
+ unsigned long word;
long offset;
int i;
for (i = 0; i < last_free_page; i++) {
- data[i] = page_table[i].region_start_offset;
+ /* Thanks to alignment requirements, the two low bits
+ * are always zero, so we can use them to store the
+ * allocation type -- region is always closed, so only
+ * the two low bits of allocation flags matter. */
+ word = page_table[i].region_start_offset;
+ gc_assert((word & 0x03) == 0);
+ data[i] = word | (0x03 & page_table[i].allocated);
}
write_lispobj(PAGE_TABLE_CORE_ENTRY_TYPE_CODE, file);
write_lispobj(4, file);
write_lispobj(size, file);
- offset = write_bytes(file, (char *) data, size, core_start_pos);
+ offset = write_bytes(file, (char *)data, size, core_start_pos);
write_lispobj(offset, file);
}
}
write_runtime_options(file,
(save_runtime_options ? runtime_options : NULL));
- fwrite(&core_start_pos, sizeof(os_vm_offset_t), 1, file);
- write_lispobj(CORE_MAGIC, file);
- fclose(file);
+ if (1 != fwrite(&core_start_pos, sizeof(os_vm_offset_t), 1, file)) {
+ perror("Error writing core starting position to file");
+ fclose(file);
+ } else {
+ write_lispobj(CORE_MAGIC, file);
+ fclose(file);
+ }
#ifndef LISP_FEATURE_WIN32
if (make_executable)
exit(0);
}
+/* Check if the build_id for the current runtime is present in a
+ * buffer. */
+int
+check_runtime_build_id(void *buf, size_t size)
+{
+ size_t idlen;
+ char *pos;
+
+ idlen = strlen(build_id) - 1;
+ while ((pos = memchr(buf, build_id[0], size)) != NULL) {
+ size -= (pos + 1) - (char *)buf;
+ buf = (pos + 1);
+ if (idlen <= size && memcmp(buf, build_id + 1, idlen) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
/* Slurp the executable portion of the runtime into a malloced buffer
* and return it. Places the size in bytes of the runtime into
* 'size_out'. Returns NULL if the runtime cannot be loaded from
goto lose;
}
+ if (!check_runtime_build_id(buf, size)) {
+ fprintf(stderr, "Failed to locate current build_id in runtime: %s\n",
+ runtime_path);
+ goto lose;
+ }
+
fclose(input);
*size_out = size;
return buf;
size_t padding;
void *padbytes;
- fwrite(runtime, 1, runtime_size, output);
+ if (runtime_size != fwrite(runtime, 1, runtime_size, output)) {
+ perror("Error saving runtime");
+ return 0;
+ }
padding = (os_vm_page_size - (runtime_size % os_vm_page_size)) & ~os_vm_page_size;
if (padding > 0) {
padbytes = successful_malloc(padding);
memset(padbytes, 0, padding);
- fwrite(padbytes, 1, padding, output);
+ if (padding != fwrite(padbytes, 1, padding, output)) {
+ perror("Error saving runtime");
+ free(padbytes);
+ return 0;
+ }
free(padbytes);
}
char *runtime_path;
if (prepend_runtime) {
- runtime_path = os_get_runtime_executable_path();
+ runtime_path = os_get_runtime_executable_path(0);
- if (runtime_path == NULL) {
+ if (runtime_path == NULL && saved_runtime_path == NULL) {
fprintf(stderr, "Unable to get default runtime path.\n");
return NULL;
}
- *runtime_bytes = load_runtime(runtime_path, runtime_size);
- free(runtime_path);
+ if (runtime_path == NULL)
+ *runtime_bytes = load_runtime(saved_runtime_path, runtime_size);
+ else {
+ *runtime_bytes = load_runtime(runtime_path, runtime_size);
+ free(runtime_path);
+ }
if (*runtime_bytes == NULL)
return 0;