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