/[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.10.12.1 - (show annotations)
Mon Dec 19 01:10:11 2005 UTC (8 years, 4 months ago) by rtoy
Branch: ppc_gencgc_branch
CVS Tags: ppc_gencgc_snap_2006-01-06, ppc_gencgc_snap_2005-12-17
Changes since 1.10: +115 -115 lines
File MIME type: text/plain
Merge code from main branch of 2005-12-17 to ppc gencgc branch.  Still
doesn't work of course.
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.10.12.1 2005/12/19 01:10:11 rtoy 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
38 #if defined GENCGC
39 #include "gencgc.h"
40 #endif
41
42 #if __FreeBSD_version > 400000
43 /* The lisp runtime is dynamically linked, but we need a definition of
44 errno for genesis. */
45 #undef errno
46 int errno;
47 #endif
48
49 vm_size_t os_vm_page_size;
50
51
52 void
53 os_init(void)
54 {
55 os_vm_page_size = getpagesize();
56 }
57
58 int
59 sc_reg(struct sigcontext *c, int offset)
60 {
61 switch (offset) {
62 case 0:
63 return c->sc_eax;
64 case 2:
65 return c->sc_ecx;
66 case 4:
67 return c->sc_edx;
68 case 6:
69 return c->sc_ebx;
70 case 8:
71 return c->sc_esp;
72 case 10:
73 return c->sc_ebp;
74 case 12:
75 return c->sc_esi;
76 case 14:
77 return c->sc_edi;
78 }
79
80 return 0;
81 }
82
83 void
84 os_save_context(void)
85 {
86 /* Called from interrupt handlers so C stuff knows things set in
87 Lisp. */
88 }
89
90 void
91 os_set_context(void)
92 {
93 }
94
95 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
96 {
97 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
98
99 if (addr)
100 flags |= MAP_FIXED;
101 else
102 flags |= MAP_VARIABLE;
103
104 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
105
106 if (addr == (os_vm_address_t) - 1) {
107 perror("mmap");
108 return NULL;
109 }
110
111 return addr;
112 }
113
114 void
115 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
116 {
117 if (munmap(addr, len) == -1)
118 perror("munmap");
119 }
120
121 os_vm_address_t
122 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
123 {
124 addr = mmap(addr, len, OS_VM_PROT_ALL,
125 MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
126
127 if (addr == (os_vm_address_t) - 1)
128 perror("mmap");
129
130 return addr;
131 }
132
133 void
134 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
135 {
136 }
137
138 void
139 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
140 {
141 if (mprotect(address, length, prot) == -1)
142 perror("mprotect");
143 }
144
145
146
147 static boolean
148 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
149 {
150 char *beg = (char *) sbeg;
151 char *end = (char *) sbeg + slen;
152 char *adr = (char *) a;
153
154 return adr >= beg && adr < end;
155 }
156
157 boolean valid_addr(os_vm_address_t addr)
158 {
159 int ret;
160 os_vm_address_t newaddr;
161
162 newaddr = os_trunc_to_page(addr);
163
164 if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
165 || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
166 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
167 #ifndef GENCGC
168 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
169 #endif
170 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
171 || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
172 return TRUE;
173 return FALSE;
174 }
175
176
177 static void
178 sigbus_handler(int signal, int code, struct sigcontext *context,
179 void *fault_addr)
180 {
181 int page_index;
182
183 #ifdef RED_ZONE_HIT
184 if (os_control_stack_overflow(fault_addr, context))
185 return;
186 #endif
187
188 #if defined GENCGC
189 page_index = find_page_index(fault_addr);
190
191 /* Check if the fault is within the dynamic space. */
192 if (page_index != -1) {
193 /* Un-protect the page */
194
195 /* The page should have been marked write protected */
196 if (!PAGE_WRITE_PROTECTED(page_index))
197 fprintf(stderr,
198 "*** Sigbus in page not marked as write protected\n");
199
200 os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
201 page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
202 page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
203
204 return;
205 }
206 #endif /* GENCGC */
207
208 interrupt_handle_now(signal, code, context);
209 }
210
211 static void
212 sigsegv_handler(int signal, int code, struct sigcontext *context)
213 {
214 interrupt_handle_now(signal, code, context);
215 }
216
217 void
218 os_install_interrupt_handlers(void)
219 {
220 interrupt_install_low_level_handler
221 (SIGSEGV, (void (*)(HANDLER_ARGS)) sigsegv_handler);
222 interrupt_install_low_level_handler
223 (SIGBUS, (void (*)(HANDLER_ARGS)) sigbus_handler);
224 }
225
226 void *
227 os_dlsym(const char *sym_name, lispobj lib_list)
228 {
229 if (lib_list != NIL) {
230 lispobj lib_list_head;
231
232 for (lib_list_head = lib_list;
233 lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
234 struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
235 struct sap *dlhandle = (struct sap *) PTR(lib_cons->car);
236 void *sym_addr = dlsym((void *) dlhandle->pointer, sym_name);
237
238 if (sym_addr)
239 return sym_addr;
240 }
241 }
242
243 return dlsym(RTLD_DEFAULT, sym_name);
244 }

  ViewVC Help
Powered by ViewVC 1.1.5