| Commit | Line | Data |
|---|---|---|
| eeab7066 RT |
1 | /* |
| 2 | ||
| 3 | This code was written as part of the CMU Common Lisp project at | |
| 4 | Carnegie Mellon University, and has been placed in the public domain. | |
| 5 | ||
| 6 | */ | |
| 7 | ||
| 62957726 | 8 | #include <stdio.h> |
| 9 | #include <sys/types.h> | |
| 10 | #include <sys/file.h> | |
| 11 | ||
| cdac17ab | 12 | #include <fcntl.h> |
| 13 | #include <stdlib.h> | |
| 555746e0 | 14 | #include <unistd.h> |
| cdac17ab | 15 | |
| 62957726 | 16 | #include "os.h" |
| 17 | #include "lisp.h" | |
| 18 | #include "globals.h" | |
| 19 | #include "core.h" | |
| 5eb10b17 | 20 | #include "internals.h" |
| 62957726 | 21 | |
| 22 | extern int version; | |
| 23 | ||
| 9a8c1c2f | 24 | static void |
| 25 | process_directory(int fd, long *ptr, int count) | |
| 62957726 | 26 | { |
| 5eb10b17 | 27 | long id, offset, len; |
| 28 | lispobj *free_pointer; | |
| 29 | os_vm_address_t addr; | |
| 30 | struct ndir_entry *entry; | |
| 31 | ||
| 32 | entry = (struct ndir_entry *) ptr; | |
| 33 | ||
| 34 | while (count-- > 0) { | |
| 35 | id = entry->identifier; | |
| 36 | offset = CORE_PAGESIZE * (1 + entry->data_page); | |
| 37 | addr = (os_vm_address_t) (CORE_PAGESIZE * entry->address); | |
| 38 | free_pointer = (lispobj *) addr + entry->nwords; | |
| 39 | len = CORE_PAGESIZE * entry->page_count; | |
| 40 | ||
| 41 | if (len != 0) { | |
| 42 | os_vm_address_t real_addr; | |
| 9a8c1c2f | 43 | |
| 62957726 | 44 | #ifdef PRINTNOISE |
| 5ced0fdf | 45 | printf("Mapping %ld bytes at 0x%lx.\n", len, addr); |
| 62957726 | 46 | #endif |
| 9a8c1c2f | 47 | real_addr = os_map(fd, offset, addr, len); |
| 48 | if (real_addr != addr) | |
| 49 | fprintf(stderr, | |
| 50 | "process_directory: file mapped in wrong place! (0x%p != 0x%p)\n", | |
| 51 | (void *) real_addr, (void *) addr); | |
| 5eb10b17 | 52 | } |
| 7257ea0b | 53 | #if 0 |
| 5eb10b17 | 54 | printf("Space ID = %d, free pointer = 0x%08x.\n", id, free_pointer); |
| 62957726 | 55 | #endif |
| 56 | ||
| 5eb10b17 | 57 | switch (id) { |
| 58 | case DYNAMIC_SPACE_ID: | |
| 9a8c1c2f | 59 | if (addr != (os_vm_address_t) dynamic_0_space |
| 60 | && addr != (os_vm_address_t) dynamic_1_space) | |
| 61 | printf("Strange ... dynamic space lossage.\n"); | |
| 62 | current_dynamic_space = (lispobj *) addr; | |
| b671ff8f | 63 | #if defined(ibmrt) || defined(i386) || defined(__x86_64) |
| 9a8c1c2f | 64 | SetSymbolValue(ALLOCATION_POINTER, (lispobj) free_pointer); |
| 62957726 | 65 | #else |
| 9a8c1c2f | 66 | current_dynamic_space_free_pointer = free_pointer; |
| 62957726 | 67 | #endif |
| 9a8c1c2f | 68 | break; |
| 5eb10b17 | 69 | case STATIC_SPACE_ID: |
| 9a8c1c2f | 70 | static_space = (lispobj *) addr; |
| 44a8f0c7 | 71 | if (len >= static_space_size) { |
| 57ca5217 | 72 | fprintf(stderr, "Error: Static space size (%ld) exceeds allocated space (%ld)!\n", |
| 44a8f0c7 RT |
73 | len, static_space_size); |
| 74 | exit(1); | |
| 75 | } | |
| 9a8c1c2f | 76 | break; |
| 5eb10b17 | 77 | case READ_ONLY_SPACE_ID: |
| 9a8c1c2f | 78 | /* Don't care about read only space */ |
| 44a8f0c7 | 79 | if (len >= read_only_space_size) { |
| 57ca5217 | 80 | fprintf(stderr, "Error: Read only space size (%ld) exceeds allocated space (%lu)!\n", |
| 44a8f0c7 RT |
81 | len, read_only_space_size); |
| 82 | exit(1); | |
| 83 | } | |
| 9a8c1c2f | 84 | break; |
| 5eb10b17 | 85 | default: |
| 9a8c1c2f | 86 | printf("Strange space ID: %ld; ignored.\n", id); |
| 87 | break; | |
| 62957726 | 88 | } |
| 5eb10b17 | 89 | entry++; |
| 90 | } | |
| 62957726 | 91 | } |
| 92 | ||
| 9a8c1c2f | 93 | lispobj |
| d4bc586c | 94 | load_core_file(const char *file, fpu_mode_t* fpu_type) |
| 62957726 | 95 | { |
| 96 | int fd = open(file, O_RDONLY), count; | |
| 9a8c1c2f | 97 | |
| b671ff8f | 98 | #if !(defined(alpha) || defined(__x86_64)) |
| 62957726 | 99 | long header[CORE_PAGESIZE / sizeof(long)], val, len, *ptr; |
| 6f4a04e5 | 100 | #else |
| 101 | u32 header[CORE_PAGESIZE / sizeof(u32)], val, len, *ptr; | |
| 102 | #endif | |
| 5eb10b17 | 103 | lispobj initial_function = NIL; |
| 62957726 | 104 | |
| 105 | if (fd < 0) { | |
| 5eb10b17 | 106 | fprintf(stderr, "Could not open file \"%s\".\n", file); |
| 107 | perror("open"); | |
| 108 | exit(1); | |
| 62957726 | 109 | } |
| 110 | ||
| 111 | count = read(fd, header, CORE_PAGESIZE); | |
| 112 | if (count < 0) { | |
| 5eb10b17 | 113 | perror("read"); |
| 114 | exit(1); | |
| 62957726 | 115 | } |
| 116 | if (count < CORE_PAGESIZE) { | |
| 5eb10b17 | 117 | fprintf(stderr, "Premature EOF.\n"); |
| 118 | exit(1); | |
| 9a8c1c2f | 119 | } |
| 62957726 | 120 | |
| 121 | ptr = header; | |
| 122 | val = *ptr++; | |
| 123 | ||
| 124 | if (val != CORE_MAGIC) { | |
| 5ced0fdf | 125 | fprintf(stderr, "Invalid magic number: 0x%lx should have been 0x%x.\n", |
| 9a8c1c2f | 126 | val, CORE_MAGIC); |
| 5eb10b17 | 127 | exit(1); |
| 62957726 | 128 | } |
| 129 | ||
| 130 | while (val != CORE_END) { | |
| 5eb10b17 | 131 | val = *ptr++; |
| 132 | len = *ptr++; | |
| 133 | ||
| 134 | switch (val) { | |
| 135 | case CORE_END: | |
| 9a8c1c2f | 136 | break; |
| 5eb10b17 | 137 | |
| 138 | case CORE_VERSION: | |
| 9a8c1c2f | 139 | if (*ptr != version) { |
| 140 | fprintf(stderr, | |
| 141 | "WARNING: startup-code version (%d) different from core version (%ld).\nYou may lose big.\n", | |
| 142 | version, *ptr); | |
| 143 | } | |
| cb786538 | 144 | if (len == 4) { |
| e2056ec6 | 145 | *fpu_type = (fpu_mode_t) ptr[1]; |
| cb786538 | 146 | } else { |
| e2056ec6 | 147 | *fpu_type = AUTO; |
| cb786538 | 148 | } |
| 9a8c1c2f | 149 | break; |
| 5eb10b17 | 150 | |
| 151 | case CORE_VALIDATE: | |
| 9a8c1c2f | 152 | fprintf(stderr, "Validation no longer supported; ignored.\n"); |
| 153 | break; | |
| 5eb10b17 | 154 | |
| 155 | case CORE_NDIRECTORY: | |
| 9a8c1c2f | 156 | process_directory(fd, ptr, |
| b671ff8f | 157 | #if !(defined(alpha) || defined(__x86_64)) |
| 9a8c1c2f | 158 | (len - 2) / (sizeof(struct ndir_entry) / sizeof(long))); |
| 6f4a04e5 | 159 | #else |
| 9a8c1c2f | 160 | (len - 2) / (sizeof(struct ndir_entry) / sizeof(u32))); |
| 6f4a04e5 | 161 | #endif |
| 9a8c1c2f | 162 | break; |
| 5eb10b17 | 163 | |
| 164 | case CORE_INITIAL_FUNCTION: | |
| 9a8c1c2f | 165 | initial_function = (lispobj) * ptr; |
| 166 | break; | |
| 5eb10b17 | 167 | |
| 168 | case CORE_MACHINE_STATE: | |
| 9a8c1c2f | 169 | fprintf(stderr, "Obsolete core file.\n"); |
| 170 | exit(1); | |
| 171 | break; | |
| 5eb10b17 | 172 | |
| 173 | default: | |
| 9a8c1c2f | 174 | printf("Unknown core file entry: %ld; skipping.\n", val); |
| 175 | break; | |
| 5eb10b17 | 176 | } |
| 177 | ||
| 178 | ptr += len - 2; | |
| 62957726 | 179 | } |
| 180 | ||
| 5eb10b17 | 181 | return initial_function; |
| 62957726 | 182 | } |