/[cmucl]/src/lisp/FreeBSD-os.c
ViewVC logotype

Contents of /src/lisp/FreeBSD-os.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (hide annotations)
Tue Aug 27 22:18:30 2002 UTC (11 years, 7 months ago) by moore
Branch: MAIN
CVS Tags: LINKAGE_TABLE
Changes since 1.7: +21 -1 lines
File MIME type: text/plain
On x86 FreeBSD and Linux, change the way foreign symbol addresses are resolved.
They now go through a table -- effectively a new space in the core file.
Function references are resolved lazily, data references are resolved on startup
and when a .so is loaded.  The end result is that cores can be dumped that
contain references to symbols in shared libraries.  Also, the dependence of the core on addresses in the Lisp runtime is broken.

The linkage table feature is controlled by :linkage-table and LINKAGE_TABLE in C
runtime.  Several foreign symbols are now Lisp static symbols, so a cross
compile is required whether or not the new stuff is used.  I've checked in
boot4-cross-foreign-linkage.lisp that builds the compiler for linkage table; do whatever you usually do for the non-linkage table case:)  Seriously, lets start
a discussion on standardizing "cross compilation," not to mention the general
build procedure.
1 ram 1.1 /*
2     * FreeBSD-os.c. Maybe could be just BSD-os.c
3     * From osf1-os.c,v 1.1 94/03/27 15:30:51 hallgren Exp $
4     *
5     * OS-dependent routines. This file (along with os.h) exports an
6     * OS-independent interface to the operating system VM facilities.
7     * Suprisingly, this interface looks a lot like the Mach interface
8     * (but simpler in some places). For some operating systems, a subset
9     * of these functions will have to be emulated.
10     *
11     * This is the OSF1 version. By Sean Hallgren.
12     * Much hacked by Paul Werkowski
13 dtc 1.2 * GENCGC support by Douglas Crosher, 1996, 1997.
14     *
15 moore 1.8 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.8 2002/08/27 22:18:30 moore Exp $
16 ram 1.1 *
17     */
18    
19     #include <stdio.h>
20     #include <sys/param.h>
21     #include <sys/file.h>
22     #include <errno.h>
23     #include "./signal.h"
24     #include "os.h"
25     #include "arch.h"
26     #include "globals.h"
27     #include "interrupt.h"
28     #include "lispregs.h"
29     #include "internals.h"
30    
31 dtc 1.2 #include <sys/types.h>
32     #include <signal.h>
33     /* #include <sys/sysinfo.h> */
34     #include <sys/proc.h>
35 moore 1.8 #include <dlfcn.h>
36 pw 1.3 #include "validate.h"
37 ram 1.1 vm_size_t os_vm_page_size;
38    
39 dtc 1.5 #define DPRINTF(t,a) {if (t) fprintf a;}
40 dtc 1.2
41     #if defined GENCGC
42     #include "gencgc.h"
43     #endif
44    
45 moore 1.7 #if __FreeBSD_version > 400000
46     /* The lisp runtime is dynamically linked, but we need a definition of
47     errno for genesis. */
48     #undef errno
49     int errno;
50     #endif
51 ram 1.1
52 dtc 1.5 void os_init(void)
53 ram 1.1 {
54 dtc 1.5 os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
55 ram 1.1 }
56    
57 dtc 1.5 int sc_reg(struct sigcontext *c, int offset)
58 ram 1.1 {
59     switch(offset)
60     {
61     case 0: return c->sc_eax;
62     case 2: return c->sc_ecx;
63     case 4: return c->sc_edx;
64     case 6: return c->sc_ebx;
65     case 8: return c->sc_esp;
66     case 10: return c->sc_ebp;
67     case 12: return c->sc_esi;
68     case 14: return c->sc_edi;
69     }
70     return 0;
71     }
72 dtc 1.5
73     void os_save_context(void)
74 ram 1.1 {
75 dtc 1.5 /*
76     * Called from interrupt handlers so C stuff knows things set in Lisp.
77 ram 1.1 */
78     }
79 dtc 1.5
80     void os_set_context(void)
81 ram 1.1 {
82     }
83    
84 dtc 1.5 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
85 ram 1.1 {
86 dtc 1.5 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
87    
88     if (addr)
89     flags |= MAP_FIXED;
90     else
91     flags |= MAP_VARIABLE;
92 ram 1.1
93 dtc 1.5 DPRINTF(0, (stderr, "os_validate %x %d => ", addr, len));
94 ram 1.1
95 dtc 1.5 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
96    
97     if (addr == (os_vm_address_t) -1)
98 ram 1.1 {
99     perror("mmap");
100     return NULL;
101     }
102 dtc 1.5
103     DPRINTF(0, (stderr, "%x\n", addr));
104 ram 1.1
105     return addr;
106     }
107    
108 dtc 1.5 void os_invalidate(os_vm_address_t addr, os_vm_size_t len)
109 ram 1.1 {
110 dtc 1.5 DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len));
111    
112     if (munmap(addr, len) == -1)
113 ram 1.1 perror("munmap");
114     }
115    
116 dtc 1.5 os_vm_address_t os_map(int fd, int offset, os_vm_address_t addr,
117     os_vm_size_t len)
118 ram 1.1 {
119 dtc 1.5 addr = mmap(addr, len,
120     OS_VM_PROT_ALL,
121     MAP_PRIVATE | MAP_FILE | MAP_FIXED,
122     fd, (off_t) offset);
123    
124     if (addr == (os_vm_address_t) -1)
125 ram 1.1 perror("mmap");
126 dtc 1.5
127 ram 1.1 return addr;
128     }
129    
130 dtc 1.5 void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
131 ram 1.1 {
132     }
133    
134 dtc 1.5 void os_protect(os_vm_address_t address, os_vm_size_t length,
135     os_vm_prot_t prot)
136 ram 1.1 {
137 dtc 1.5 if (mprotect(address, length, prot) == -1)
138 ram 1.1 perror("mprotect");
139     }
140 dtc 1.5
141 ram 1.1
142 dtc 1.5
143     static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
144 ram 1.1 {
145 dtc 1.5 char* beg = (char*) sbeg;
146     char* end = (char*) sbeg + slen;
147     char* adr = (char*) a;
148 ram 1.1 return (adr >= beg && adr < end);
149     }
150 dtc 1.5
151     boolean valid_addr(os_vm_address_t addr)
152 ram 1.1 {
153     int ret;
154     os_vm_address_t newaddr;
155 dtc 1.5 newaddr = os_trunc_to_page(addr);
156 ram 1.1
157 dtc 1.5 if ( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
158     || in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE )
159 dtc 1.6 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size )
160     || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size )
161 dtc 1.5 || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE )
162     || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE ))
163 ram 1.1 return TRUE;
164     return FALSE;
165     }
166    
167    
168 dtc 1.5 static void sigbus_handler(int signal, int code, struct sigcontext *context,
169     void *fault_addr)
170 ram 1.1 {
171 dtc 1.2 #if defined GENCGC
172     int page_index = find_page_index(fault_addr);
173    
174     #if SIGBUS_VERBOSE
175     fprintf(stderr,"Signal %d, fault_addr=%x, page_index=%d:\n",
176 dtc 1.5 signal, fault_addr, page_index);
177 dtc 1.2 #endif
178    
179     /* Check if the fault is within the dynamic space. */
180     if (page_index != -1) {
181 dtc 1.4 /* Un-protect the page */
182 dtc 1.2
183 dtc 1.5 /* The page should have been marked write protected */
184 dtc 1.4 if (!PAGE_WRITE_PROTECTED(page_index))
185 dtc 1.5 fprintf(stderr, "*** Sigbus in page not marked as write protected\n");
186 dtc 1.4
187     os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
188     page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
189     page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
190 dtc 1.5
191 dtc 1.4 return;
192 dtc 1.2 }
193     #endif
194    
195 dtc 1.5 DPRINTF(0, (stderr, "sigbus:\n"));
196 dtc 1.2 interrupt_handle_now(signal, code, context);
197 ram 1.1 }
198 dtc 1.5
199     static void sigsegv_handler(int signal, int code, struct sigcontext *context)
200 ram 1.1 {
201 dtc 1.5 DPRINTF(0, (stderr, "os_sigsegv\n"));
202 dtc 1.2 interrupt_handle_now(signal, code, context);
203 ram 1.1 }
204    
205 dtc 1.5 void os_install_interrupt_handlers(void)
206 ram 1.1 {
207 dtc 1.5 interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
208     interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
209 moore 1.8 }
210    
211     void *os_dlsym(const char *sym_name, lispobj lib_list)
212     {
213     if (lib_list != NIL) {
214     lispobj lib_list_head;
215    
216     for (lib_list_head = lib_list;
217     lib_list_head != NIL;
218     lib_list_head = (CONS(lib_list_head))->cdr) {
219     struct cons *lib_cons = (CONS(lib_list_head))->car;
220     struct sap *dlhandle = (CONS(lib_cons))->car;
221     void *sym_addr = dlsym((void *)dlhandle->pointer, sym_name);
222    
223     if (sym_addr)
224     return sym_addr;
225     }
226     }
227     return dlsym(RTLD_DEFAULT, sym_name);
228 ram 1.1 }

  ViewVC Help
Powered by ViewVC 1.1.5