/[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.16 - (show annotations)
Sun Jul 15 09:24:57 2007 UTC (6 years, 9 months ago) by cshapiro
Branch: MAIN
Changes since 1.15: +31 -30 lines
File MIME type: text/plain
Use POSIX signals on FreeBSD.
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.16 2007/07/15 09:24:57 cshapiro Exp $
16 *
17 */
18
19 #include "os.h"
20 #include <sys/file.h>
21 #include <errno.h>
22 #include "./signal.h"
23 #include "arch.h"
24 #include "globals.h"
25 #include "interrupt.h"
26 #include "lispregs.h"
27 #include "internals.h"
28
29 #include <signal.h>
30 /* #include <sys/sysinfo.h> */
31 #include <sys/proc.h>
32 #include <dlfcn.h>
33 #include "validate.h"
34
35 #if defined GENCGC
36 #include "gencgc.h"
37 #endif
38
39 #if __FreeBSD_version > 400000
40 /* The lisp runtime is dynamically linked, but we need a definition of
41 errno for genesis. */
42 #undef errno
43 int errno;
44 #endif
45
46 vm_size_t os_vm_page_size;
47
48
49 void
50 os_init(void)
51 {
52 os_vm_page_size = getpagesize();
53 }
54
55 int *
56 sc_reg(ucontext_t *context, int offset)
57 {
58 switch (offset) {
59 case 0:
60 return &context->uc_mcontext.mc_eax;
61 case 2:
62 return &context->uc_mcontext.mc_ecx;
63 case 4:
64 return &context->uc_mcontext.mc_edx;
65 case 6:
66 return &context->uc_mcontext.mc_ebx;
67 case 8:
68 return &context->uc_mcontext.mc_esp;
69 case 10:
70 return &context->uc_mcontext.mc_ebp;
71 case 12:
72 return &context->uc_mcontext.mc_esi;
73 case 14:
74 return &context->uc_mcontext.mc_edi;
75 }
76
77 return (int *) 0;
78 }
79
80 void
81 os_save_context(void)
82 {
83 /* Called from interrupt handlers so C stuff knows things set in
84 Lisp. */
85 }
86
87 void
88 os_set_context(void)
89 {
90 }
91
92 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
93 {
94 int flags = MAP_PRIVATE | MAP_ANON;
95
96 if (addr)
97 flags |= MAP_FIXED;
98
99 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
100
101 if (addr == (os_vm_address_t) - 1) {
102 perror("mmap");
103 return NULL;
104 }
105
106 return addr;
107 }
108
109 void
110 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
111 {
112 if (munmap(addr, len) == -1)
113 perror("munmap");
114 }
115
116 os_vm_address_t
117 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
118 {
119 addr = mmap(addr, len, OS_VM_PROT_ALL,
120 MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
121
122 if (addr == (os_vm_address_t) - 1)
123 perror("mmap");
124
125 return addr;
126 }
127
128 void
129 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
130 {
131 }
132
133 void
134 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
135 {
136 if (mprotect(address, length, prot) == -1)
137 perror("mprotect");
138 }
139
140
141
142 static boolean
143 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
149 return adr >= beg && adr < end;
150 }
151
152 boolean valid_addr(os_vm_address_t addr)
153 {
154 os_vm_address_t newaddr;
155
156 newaddr = os_trunc_to_page(addr);
157
158 if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
159 || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
160 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
161 #ifndef GENCGC
162 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
163 #endif
164 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
165 || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
166 return TRUE;
167 return FALSE;
168 }
169
170
171 static void
172 sigbus_handler(int signal, siginfo_t *info, ucontext_t *context)
173 {
174 int page_index;
175
176 #ifdef RED_ZONE_HIT
177 if (os_control_stack_overflow(info->si_addr, context))
178 return;
179 #endif
180
181 #if defined GENCGC
182 if (info->si_code == BUS_PAGE_FAULT) {
183 page_index = find_page_index(info->si_addr);
184
185 /* Check if the fault is within the dynamic space. */
186 if (page_index != -1) {
187 /* Un-protect the page */
188
189 /* The page should have been marked write protected */
190 if (!PAGE_WRITE_PROTECTED(page_index))
191 fprintf(stderr,
192 "*** Sigbus in page not marked as write protected\n");
193
194 os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
195 page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
196 page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
197
198 return;
199 }
200 }
201 #endif /* GENCGC */
202
203 interrupt_handle_now(signal, info, context);
204 }
205
206 static void
207 sigsegv_handler(int signal, siginfo_t *info, ucontext_t *context)
208 {
209 interrupt_handle_now(signal, info, context);
210 }
211
212 void
213 os_install_interrupt_handlers(void)
214 {
215 interrupt_install_low_level_handler
216 (SIGSEGV, (void (*)(HANDLER_ARGS)) sigsegv_handler);
217 interrupt_install_low_level_handler
218 (SIGBUS, (void (*)(HANDLER_ARGS)) sigbus_handler);
219 }
220
221 void *
222 os_dlsym(const char *sym_name, lispobj lib_list)
223 {
224 if (lib_list != NIL) {
225 lispobj lib_list_head;
226
227 for (lib_list_head = lib_list;
228 lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
229 struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
230 struct sap *dlhandle = (struct sap *) PTR(lib_cons->car);
231 void *sym_addr = dlsym((void *) dlhandle->pointer, sym_name);
232
233 if (sym_addr)
234 return sym_addr;
235 }
236 }
237
238 return dlsym(RTLD_DEFAULT, sym_name);
239 }

  ViewVC Help
Powered by ViewVC 1.1.5