/[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.14 - (show annotations)
Sun Jun 10 06:39:46 2007 UTC (6 years, 10 months ago) by cshapiro
Branch: MAIN
Changes since 1.13: +1 -2 lines
File MIME type: text/plain
Remove an unused local variable.
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.14 2007/06/10 06:39:46 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(struct sigcontext *c, int offset)
57 {
58 switch (offset) {
59 case 0:
60 return &c->sc_eax;
61 case 2:
62 return &c->sc_ecx;
63 case 4:
64 return &c->sc_edx;
65 case 6:
66 return &c->sc_ebx;
67 case 8:
68 return &c->sc_esp;
69 case 10:
70 return &c->sc_ebp;
71 case 12:
72 return &c->sc_esi;
73 case 14:
74 return &c->sc_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_ANONYMOUS;
95
96 if (addr)
97 flags |= MAP_FIXED;
98 else
99 flags |= MAP_VARIABLE;
100
101 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
102
103 if (addr == (os_vm_address_t) - 1) {
104 perror("mmap");
105 return NULL;
106 }
107
108 return addr;
109 }
110
111 void
112 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
113 {
114 if (munmap(addr, len) == -1)
115 perror("munmap");
116 }
117
118 os_vm_address_t
119 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
120 {
121 addr = mmap(addr, len, OS_VM_PROT_ALL,
122 MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
123
124 if (addr == (os_vm_address_t) - 1)
125 perror("mmap");
126
127 return addr;
128 }
129
130 void
131 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
132 {
133 }
134
135 void
136 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
137 {
138 if (mprotect(address, length, prot) == -1)
139 perror("mprotect");
140 }
141
142
143
144 static boolean
145 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
146 {
147 char *beg = (char *) sbeg;
148 char *end = (char *) sbeg + slen;
149 char *adr = (char *) a;
150
151 return adr >= beg && adr < end;
152 }
153
154 boolean valid_addr(os_vm_address_t addr)
155 {
156 os_vm_address_t newaddr;
157
158 newaddr = os_trunc_to_page(addr);
159
160 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 return TRUE;
169 return FALSE;
170 }
171
172
173 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 #if defined GENCGC
185 page_index = find_page_index(fault_addr);
186
187 /* Check if the fault is within the dynamic space. */
188 if (page_index != -1) {
189 /* Un-protect the page */
190
191 /* The page should have been marked write protected */
192 if (!PAGE_WRITE_PROTECTED(page_index))
193 fprintf(stderr,
194 "*** Sigbus in page not marked as write protected\n");
195
196 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
200 return;
201 }
202 #endif /* GENCGC */
203
204 interrupt_handle_now(signal, code, context);
205 }
206
207 static void
208 sigsegv_handler(int signal, int code, struct sigcontext *context)
209 {
210 interrupt_handle_now(signal, code, context);
211 }
212
213 void
214 os_install_interrupt_handlers(void)
215 {
216 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 }
221
222 void *
223 os_dlsym(const char *sym_name, lispobj lib_list)
224 {
225 if (lib_list != NIL) {
226 lispobj lib_list_head;
227
228 for (lib_list_head = lib_list;
229 lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
230 struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
231 struct sap *dlhandle = (struct sap *) PTR(lib_cons->car);
232 void *sym_addr = dlsym((void *) dlhandle->pointer, sym_name);
233
234 if (sym_addr)
235 return sym_addr;
236 }
237 }
238
239 return dlsym(RTLD_DEFAULT, sym_name);
240 }

  ViewVC Help
Powered by ViewVC 1.1.5