/[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.9 - (show annotations)
Wed Aug 28 07:16:38 2002 UTC (11 years, 7 months ago) by moore
Branch: MAIN
CVS Tags: release-18e-base, release-18e-pre2, cold-pcl-base, UNICODE-BASE, release-18e, release-18e-pre1
Branch point for: UNICODE-BRANCH, release-18e-branch, cold-pcl
Changes since 1.8: +3 -3 lines
File MIME type: text/plain
Fix foregin object braindamage noted by Pierre Mai.
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 * GENCGC support by Douglas Crosher, 1996, 1997.
14 *
15 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.9 2002/08/28 07:16:38 moore Exp $
16 *
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 #include <sys/types.h>
32 #include <signal.h>
33 /* #include <sys/sysinfo.h> */
34 #include <sys/proc.h>
35 #include <dlfcn.h>
36 #include "validate.h"
37 vm_size_t os_vm_page_size;
38
39 #define DPRINTF(t,a) {if (t) fprintf a;}
40
41 #if defined GENCGC
42 #include "gencgc.h"
43 #endif
44
45 #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
52 void os_init(void)
53 {
54 os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
55 }
56
57 int sc_reg(struct sigcontext *c, int offset)
58 {
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
73 void os_save_context(void)
74 {
75 /*
76 * Called from interrupt handlers so C stuff knows things set in Lisp.
77 */
78 }
79
80 void os_set_context(void)
81 {
82 }
83
84 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
85 {
86 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
87
88 if (addr)
89 flags |= MAP_FIXED;
90 else
91 flags |= MAP_VARIABLE;
92
93 DPRINTF(0, (stderr, "os_validate %x %d => ", addr, len));
94
95 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
96
97 if (addr == (os_vm_address_t) -1)
98 {
99 perror("mmap");
100 return NULL;
101 }
102
103 DPRINTF(0, (stderr, "%x\n", addr));
104
105 return addr;
106 }
107
108 void os_invalidate(os_vm_address_t addr, os_vm_size_t len)
109 {
110 DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len));
111
112 if (munmap(addr, len) == -1)
113 perror("munmap");
114 }
115
116 os_vm_address_t os_map(int fd, int offset, os_vm_address_t addr,
117 os_vm_size_t len)
118 {
119 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 perror("mmap");
126
127 return addr;
128 }
129
130 void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
131 {
132 }
133
134 void os_protect(os_vm_address_t address, os_vm_size_t length,
135 os_vm_prot_t prot)
136 {
137 if (mprotect(address, length, prot) == -1)
138 perror("mprotect");
139 }
140
141
142
143 static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
144 {
145 char* beg = (char*) sbeg;
146 char* end = (char*) sbeg + slen;
147 char* adr = (char*) a;
148 return (adr >= beg && adr < end);
149 }
150
151 boolean valid_addr(os_vm_address_t addr)
152 {
153 int ret;
154 os_vm_address_t newaddr;
155 newaddr = os_trunc_to_page(addr);
156
157 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 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size )
160 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size )
161 || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE )
162 || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE ))
163 return TRUE;
164 return FALSE;
165 }
166
167
168 static void sigbus_handler(int signal, int code, struct sigcontext *context,
169 void *fault_addr)
170 {
171 #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 signal, fault_addr, page_index);
177 #endif
178
179 /* Check if the fault is within the dynamic space. */
180 if (page_index != -1) {
181 /* Un-protect the page */
182
183 /* The page should have been marked write protected */
184 if (!PAGE_WRITE_PROTECTED(page_index))
185 fprintf(stderr, "*** Sigbus in page not marked as write protected\n");
186
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
191 return;
192 }
193 #endif
194
195 DPRINTF(0, (stderr, "sigbus:\n"));
196 interrupt_handle_now(signal, code, context);
197 }
198
199 static void sigsegv_handler(int signal, int code, struct sigcontext *context)
200 {
201 DPRINTF(0, (stderr, "os_sigsegv\n"));
202 interrupt_handle_now(signal, code, context);
203 }
204
205 void os_install_interrupt_handlers(void)
206 {
207 interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
208 interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
209 }
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(CONS(lib_list_head)->car);
220 struct sap *dlhandle = (struct sap *)PTR(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 }

  ViewVC Help
Powered by ViewVC 1.1.5