/[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.23.4.1 - (show annotations)
Sun Nov 2 13:30:03 2008 UTC (5 years, 5 months ago) by rtoy
Branch: unicode-utf16-extfmt-branch
Changes since 1.23: +2 -18 lines
File MIME type: text/plain
Sync to snapshot 2008-11.  But we didn't sync code/extfmts.lisp or
iso8859-1.lisp and utf-8.lisp.  (I don't think we want those changes,
yet.)
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.23.4.1 2008/11/02 13:30:03 rtoy Exp $
16 *
17 */
18
19 #include "os.h"
20 #include <sys/file.h>
21 #include <machine/npx.h>
22 #include <errno.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 <dlfcn.h>
31 #include "validate.h"
32 #include <stdio.h>
33 #include <unistd.h>
34
35 #if defined GENCGC
36 #include "gencgc.h"
37 #endif
38
39 vm_size_t os_vm_page_size;
40
41
42 void
43 os_init(void)
44 {
45 os_vm_page_size = getpagesize();
46 }
47
48 unsigned long *
49 os_sigcontext_reg(ucontext_t *scp, int index)
50 {
51 switch (index) {
52 case 0:
53 return (unsigned long *) &scp->uc_mcontext.mc_eax;
54 case 2:
55 return (unsigned long *) &scp->uc_mcontext.mc_ecx;
56 case 4:
57 return (unsigned long *) &scp->uc_mcontext.mc_edx;
58 case 6:
59 return (unsigned long *) &scp->uc_mcontext.mc_ebx;
60 case 8:
61 return (unsigned long *) &scp->uc_mcontext.mc_esp;
62 case 10:
63 return (unsigned long *) &scp->uc_mcontext.mc_ebp;
64 case 12:
65 return (unsigned long *) &scp->uc_mcontext.mc_esi;
66 case 14:
67 return (unsigned long *) &scp->uc_mcontext.mc_edi;
68 }
69 return NULL;
70 }
71
72 unsigned long *
73 os_sigcontext_pc(ucontext_t *scp)
74 {
75 return (unsigned long *) &scp->uc_mcontext.mc_eip;
76 }
77
78 unsigned char *
79 os_sigcontext_fpu_reg(ucontext_t *scp, int index)
80 {
81 union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
82 int fpformat = scp->uc_mcontext.mc_fpformat;
83 unsigned char *reg = NULL;
84
85 switch (fpformat) {
86 case _MC_FPFMT_XMM:
87 reg = sv->sv_xmm.sv_fp[index].fp_acc.fp_bytes;
88 break;
89 case _MC_FPFMT_387:
90 reg = sv->sv_87.sv_ac[index].fp_bytes;
91 break;
92 case _MC_FPFMT_NODEV:
93 reg = NULL;
94 break;
95 }
96 return reg;
97 }
98
99 unsigned long
100 os_sigcontext_fpu_modes(ucontext_t *scp)
101 {
102 union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
103 unsigned long modes;
104 int fpformat = scp->uc_mcontext.mc_fpformat;
105 unsigned short cw, sw;
106
107 if (fpformat == _MC_FPFMT_XMM) {
108 cw = sv->sv_xmm.sv_env.en_cw;
109 sw = sv->sv_xmm.sv_env.en_sw;
110 } else if (fpformat == _MC_FPFMT_387) {
111 cw = sv->sv_87.sv_env.en_cw & 0xffff;
112 sw = sv->sv_87.sv_env.en_sw & 0xffff;
113 } else { /* _MC_FPFMT_NODEV */
114 cw = 0;
115 sw = 0x3f;
116 }
117 modes = (sw & 0xff) << 16 | cw;
118 modes ^= 0x3f;
119 return modes;
120 }
121
122 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
123 {
124 int flags = MAP_PRIVATE | MAP_ANON;
125
126 if (addr)
127 flags |= MAP_FIXED;
128
129 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
130
131 if (addr == (os_vm_address_t) - 1) {
132 perror("mmap");
133 return NULL;
134 }
135
136 return addr;
137 }
138
139 void
140 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
141 {
142 if (munmap(addr, len) == -1)
143 perror("munmap");
144 }
145
146 os_vm_address_t
147 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
148 {
149 addr = mmap(addr, len, OS_VM_PROT_ALL,
150 MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
151
152 if (addr == (os_vm_address_t) - 1)
153 perror("mmap");
154
155 return addr;
156 }
157
158 void
159 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
160 {
161 }
162
163 void
164 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
165 {
166 if (mprotect(address, length, prot) == -1)
167 perror("mprotect");
168 }
169
170
171
172 static boolean
173 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
174 {
175 char *beg = (char *) sbeg;
176 char *end = (char *) sbeg + slen;
177 char *adr = (char *) a;
178
179 return adr >= beg && adr < end;
180 }
181
182 boolean valid_addr(os_vm_address_t addr)
183 {
184 os_vm_address_t newaddr;
185
186 newaddr = os_trunc_to_page(addr);
187
188 if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
189 || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
190 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
191 #ifndef GENCGC
192 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
193 #endif
194 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
195 || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
196 return TRUE;
197 return FALSE;
198 }
199
200
201 static void
202 sigbus_handler(int signal, siginfo_t *info, ucontext_t *context)
203 {
204 #ifdef RED_ZONE_HIT
205 if (os_control_stack_overflow(info->si_addr, context))
206 return;
207 #endif
208
209 #if defined GENCGC
210 if (info->si_code == PROTECTION_VIOLATION_CODE) {
211 if (gc_write_barrier(info->si_addr)) {
212 return;
213 }
214 }
215 #endif /* GENCGC */
216
217 interrupt_handle_now(signal, info, context);
218 }
219
220 /*
221 * Restore the exception flags cleared by the kernel. These bits must
222 * be set for Lisp to determine which exception caused the signal. At
223 * present, there is no way to distinguish underflow exceptions from
224 * denormalized operand exceptions. An underflow exception is assumed
225 * if the subcode is FPE_FLTUND.
226 */
227 static void
228 sigfpe_handler(int signal, siginfo_t *info, ucontext_t *context)
229 {
230 union savefpu *sv = (union savefpu *) context->uc_mcontext.mc_fpstate;
231 int fpformat = context->uc_mcontext.mc_fpformat;
232 int code = info->si_code;
233 unsigned char trap = 0;
234
235 switch (code) {
236 case FPE_FLTDIV: /* ZE */
237 trap = 0x04;
238 break;
239 case FPE_FLTOVF: /* OE */
240 trap = 0x08;
241 break;
242 case FPE_FLTUND: /* DE or UE */
243 trap = 0x10;
244 break;
245 case FPE_FLTRES: /* PE */
246 trap = 0x20;
247 break;
248 case FPE_FLTINV: /* IE */
249 trap = 0x01;
250 break;
251 }
252 switch (fpformat) {
253 case _MC_FPFMT_XMM:
254 sv->sv_xmm.sv_env.en_sw |= trap;
255 break;
256 case _MC_FPFMT_387:
257 sv->sv_87.sv_env.en_sw |= trap;
258 break;
259 }
260 interrupt_handle_now(signal, info, context);
261 }
262
263 void
264 os_install_interrupt_handlers(void)
265 {
266 interrupt_install_low_level_handler
267 (PROTECTION_VIOLATION_SIGNAL, sigbus_handler);
268 interrupt_install_low_level_handler(SIGFPE, sigfpe_handler);
269 }
270
271 void *
272 os_dlsym(const char *sym_name, lispobj lib_list)
273 {
274 if (lib_list != NIL) {
275 lispobj lib_list_head;
276
277 for (lib_list_head = lib_list;
278 lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
279 struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
280 struct sap *dlhandle = (struct sap *) PTR(lib_cons->car);
281 void *sym_addr = dlsym((void *) dlhandle->pointer, sym_name);
282
283 if (sym_addr)
284 return sym_addr;
285 }
286 }
287
288 return dlsym(RTLD_DEFAULT, sym_name);
289 }
290
291 void
292 restore_fpu(ucontext_t *scp)
293 {
294 union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
295 int fpformat = scp->uc_mcontext.mc_fpformat;
296 unsigned short cw;
297
298 if (fpformat == _MC_FPFMT_XMM) {
299 cw = sv->sv_xmm.sv_env.en_cw;
300 } else if (fpformat == _MC_FPFMT_387) {
301 cw = sv->sv_87.sv_env.en_cw & 0xffff;
302 } else { /* _MC_FPFMT_NODEV */
303 return;
304 }
305 __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw));
306 }

  ViewVC Help
Powered by ViewVC 1.1.5