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

  ViewVC Help
Powered by ViewVC 1.1.5