/[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.10.6.1 - (hide annotations)
Wed Sep 3 11:32:06 2003 UTC (10 years, 7 months ago) by gerd
Branch: lisp-executable
Changes since 1.10: +1 -2 lines
File MIME type: text/plain
Fred Gilham's Lisp executable support for CMUCL.
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 gerd 1.10.6.1 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.10.6.1 2003/09/03 11:32:06 gerd 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 dtc 1.2
38     #if defined GENCGC
39     #include "gencgc.h"
40     #endif
41    
42 moore 1.7 #if __FreeBSD_version > 400000
43     /* The lisp runtime is dynamically linked, but we need a definition of
44     errno for genesis. */
45     #undef errno
46     int errno;
47     #endif
48 gerd 1.10
49     vm_size_t os_vm_page_size;
50    
51 ram 1.1
52 gerd 1.10 void
53     os_init (void)
54 ram 1.1 {
55 gerd 1.10 os_vm_page_size = getpagesize ();
56 ram 1.1 }
57    
58 gerd 1.10 int
59     sc_reg (struct sigcontext *c, int offset)
60 ram 1.1 {
61     switch(offset)
62     {
63     case 0: return c->sc_eax;
64     case 2: return c->sc_ecx;
65     case 4: return c->sc_edx;
66     case 6: return c->sc_ebx;
67     case 8: return c->sc_esp;
68     case 10: return c->sc_ebp;
69     case 12: return c->sc_esi;
70     case 14: return c->sc_edi;
71     }
72 gerd 1.10
73 ram 1.1 return 0;
74     }
75 dtc 1.5
76 gerd 1.10 void
77     os_save_context (void)
78 ram 1.1 {
79 gerd 1.10 /* Called from interrupt handlers so C stuff knows things set in
80     Lisp. */
81 ram 1.1 }
82 dtc 1.5
83 gerd 1.10 void
84     os_set_context (void)
85 ram 1.1 {
86     }
87    
88 gerd 1.10 os_vm_address_t
89     os_validate (os_vm_address_t addr, os_vm_size_t len)
90 ram 1.1 {
91 dtc 1.5 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
92    
93     if (addr)
94     flags |= MAP_FIXED;
95     else
96     flags |= MAP_VARIABLE;
97 ram 1.1
98 gerd 1.10 addr = mmap (addr, len, OS_VM_PROT_ALL, flags, -1, 0);
99 dtc 1.5
100     if (addr == (os_vm_address_t) -1)
101 ram 1.1 {
102 gerd 1.10 perror ("mmap");
103 ram 1.1 return NULL;
104     }
105 dtc 1.5
106 ram 1.1 return addr;
107     }
108    
109 gerd 1.10 void
110     os_invalidate (os_vm_address_t addr, os_vm_size_t len)
111 ram 1.1 {
112 gerd 1.10 if (munmap (addr, len) == -1)
113     perror ("munmap");
114 ram 1.1 }
115    
116 gerd 1.10 os_vm_address_t
117     os_map (int fd, int offset, os_vm_address_t addr,
118     os_vm_size_t len)
119 ram 1.1 {
120 gerd 1.10 addr = mmap (addr, len, OS_VM_PROT_ALL,
121     MAP_PRIVATE | MAP_FILE | MAP_FIXED,
122     fd, (off_t) offset);
123 dtc 1.5
124     if (addr == (os_vm_address_t) -1)
125 gerd 1.10 perror ("mmap");
126 dtc 1.5
127 ram 1.1 return addr;
128     }
129    
130 gerd 1.10 void
131     os_flush_icache (os_vm_address_t address, os_vm_size_t length)
132 ram 1.1 {
133     }
134    
135 gerd 1.10 void
136     os_protect (os_vm_address_t address, os_vm_size_t length,
137     os_vm_prot_t prot)
138 ram 1.1 {
139 gerd 1.10 if (mprotect (address, length, prot) == -1)
140     perror ("mprotect");
141 ram 1.1 }
142 dtc 1.5
143 ram 1.1
144 dtc 1.5
145 gerd 1.10 static boolean
146     in_range_p (os_vm_address_t a, lispobj sbeg, size_t slen)
147 ram 1.1 {
148 gerd 1.10 char *beg = (char *) sbeg;
149     char *end = (char *) sbeg + slen;
150     char *adr = (char *) a;
151     return adr >= beg && adr < end;
152 ram 1.1 }
153 dtc 1.5
154 gerd 1.10 boolean
155     valid_addr (os_vm_address_t addr)
156 ram 1.1 {
157     os_vm_address_t newaddr;
158 gerd 1.10 newaddr = os_trunc_to_page (addr);
159 ram 1.1
160 gerd 1.10 if (in_range_p (addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
161     || in_range_p (addr, STATIC_SPACE_START , STATIC_SPACE_SIZE)
162     || in_range_p (addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
163     #ifndef GENCGC
164     || in_range_p (addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
165     #endif
166     || in_range_p (addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
167     || in_range_p (addr, BINDING_STACK_START, BINDING_STACK_SIZE))
168 ram 1.1 return TRUE;
169     return FALSE;
170     }
171    
172    
173 gerd 1.10 static void
174     sigbus_handler (int signal, int code, struct sigcontext *context,
175     void *fault_addr)
176     {
177     int page_index;
178    
179     #ifdef RED_ZONE_HIT
180     if (os_control_stack_overflow (fault_addr, context))
181     return;
182     #endif
183    
184 dtc 1.2 #if defined GENCGC
185 gerd 1.10 page_index = find_page_index(fault_addr);
186 dtc 1.2
187 gerd 1.10 /* Check if the fault is within the dynamic space. */
188     if (page_index != -1)
189     {
190     /* Un-protect the page */
191 dtc 1.2
192 gerd 1.10 /* The page should have been marked write protected */
193     if (!PAGE_WRITE_PROTECTED (page_index))
194     fprintf (stderr, "*** Sigbus in page not marked as write protected\n");
195 dtc 1.2
196 gerd 1.10 os_protect (page_address (page_index), 4096, OS_VM_PROT_ALL);
197     page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
198     page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
199 dtc 1.5
200 gerd 1.10 return;
201 dtc 1.2 }
202 gerd 1.10 #endif /* GENCGC */
203 dtc 1.2
204 gerd 1.10 interrupt_handle_now (signal, code, context);
205 ram 1.1 }
206 dtc 1.5
207 gerd 1.10 static void
208     sigsegv_handler (int signal, int code, struct sigcontext *context)
209 ram 1.1 {
210 gerd 1.10 interrupt_handle_now (signal, code, context);
211 ram 1.1 }
212    
213 gerd 1.10 void
214     os_install_interrupt_handlers (void)
215 ram 1.1 {
216 gerd 1.10 interrupt_install_low_level_handler
217     (SIGSEGV, (void (*) (HANDLER_ARGS)) sigsegv_handler);
218     interrupt_install_low_level_handler
219     (SIGBUS, (void (*) (HANDLER_ARGS)) sigbus_handler);
220 moore 1.8 }
221    
222 gerd 1.10 void *
223     os_dlsym (const char *sym_name, lispobj lib_list)
224 moore 1.8 {
225 gerd 1.10 if (lib_list != NIL)
226     {
227     lispobj lib_list_head;
228 moore 1.8
229 gerd 1.10 for (lib_list_head = lib_list;
230     lib_list_head != NIL;
231     lib_list_head = CONS (lib_list_head)->cdr)
232     {
233     struct cons *lib_cons = CONS (CONS (lib_list_head)->car);
234     struct sap *dlhandle = (struct sap *) PTR (lib_cons->car);
235     void *sym_addr = dlsym ((void *) dlhandle->pointer, sym_name);
236 moore 1.8
237 gerd 1.10 if (sym_addr)
238     return sym_addr;
239 moore 1.8 }
240     }
241 gerd 1.10
242     return dlsym (RTLD_DEFAULT, sym_name);
243 ram 1.1 }

  ViewVC Help
Powered by ViewVC 1.1.5