/[cmucl]/src/lisp/OpenBSD-os.c
ViewVC logotype

Contents of /src/lisp/OpenBSD-os.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.20.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.1: +122 -102 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 * OpenBSD-os.c.
3 * From FreeBSD-os.c 1.6 2000/10/24 13:32:30 dtc 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 * Frobbed for OpenBSD by Pierre R. Mai, 2001.
15 *
16 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/OpenBSD-os.c,v 1.1.20.1 2005/12/19 01:10:11 rtoy Exp $
17 *
18 */
19
20 #include <stdio.h>
21 #include <sys/param.h>
22 #include <sys/file.h>
23 #include <errno.h>
24 #include "./signal.h"
25 #include "os.h"
26 #include "arch.h"
27 #include "globals.h"
28 #include "interrupt.h"
29 #include "lispregs.h"
30 #include "internals.h"
31
32 #include <sys/types.h>
33 #include <signal.h>
34 /* #include <sys/sysinfo.h> */
35 #include <sys/proc.h>
36 #include "validate.h"
37 vm_size_t os_vm_page_size;
38
39 #define DPRINTF(t,a) {if (t) fprintf a;}
40
41 #if defined GENCGC
42 #include "gencgc.h"
43 #endif
44
45
46 void
47 os_init(void)
48 {
49 os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
50 }
51
52 int
53 sc_reg(struct sigcontext *c, int offset)
54 {
55 switch (offset) {
56 case 0:
57 return c->sc_eax;
58 case 2:
59 return c->sc_ecx;
60 case 4:
61 return c->sc_edx;
62 case 6:
63 return c->sc_ebx;
64 case 8:
65 return c->sc_esp;
66 case 10:
67 return c->sc_ebp;
68 case 12:
69 return c->sc_esi;
70 case 14:
71 return c->sc_edi;
72 }
73 return 0;
74 }
75
76 void
77 os_save_context(void)
78 {
79 /*
80 * Called from interrupt handlers so C stuff knows things set in Lisp.
81 */
82 }
83
84 void
85 os_set_context(void)
86 {
87 }
88
89 os_vm_address_t
90 os_validate(os_vm_address_t addr, os_vm_size_t len)
91 {
92 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
93
94 if (addr)
95 flags |= MAP_FIXED;
96 else
97 flags |= MAP_VARIABLE;
98
99 DPRINTF(0, (stderr, "os_validate %x %d => ", addr, len));
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 DPRINTF(0, (stderr, "%x\n", addr));
109
110 return addr;
111 }
112
113 void
114 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
115 {
116 DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len));
117
118 if (munmap(addr, len) == -1)
119 perror("munmap");
120 }
121
122 os_vm_address_t
123 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
124 {
125 addr = mmap(addr, len,
126 OS_VM_PROT_ALL,
127 MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
128
129 if (addr == (os_vm_address_t) - 1)
130 perror("mmap");
131
132 return addr;
133 }
134
135 void
136 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
137 {
138 }
139
140 void
141 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
142 {
143 if (mprotect(address, length, prot) == -1)
144 perror("mprotect");
145 }
146
147
148
149 static boolean
150 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
151 {
152 char *beg = (char *) sbeg;
153 char *end = (char *) sbeg + slen;
154 char *adr = (char *) a;
155
156 return (adr >= beg && adr < end);
157 }
158
159 boolean
160 valid_addr(os_vm_address_t addr)
161 {
162 int ret;
163 os_vm_address_t newaddr;
164
165 newaddr = os_trunc_to_page(addr);
166
167 if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
168 || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
169 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
170 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
171 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
172 || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
173 return TRUE;
174 return FALSE;
175 }
176
177
178 static void
179 sigsegv_handler(HANDLER_ARGS)
180 {
181 #if defined GENCGC
182 caddr_t fault_addr = code->si_addr;
183 int page_index = find_page_index((void *) fault_addr);
184
185 #if SIGSEGV_VERBOSE
186 fprintf(stderr, "Signal %d, fault_addr=%x, page_index=%d:\n",
187 signal, fault_addr, page_index);
188 #endif
189
190 /* Check if the fault is within the dynamic space. */
191 if (page_index != -1) {
192 /* Un-protect the page */
193
194 /* The page should have been marked write protected */
195 if (!PAGE_WRITE_PROTECTED(page_index))
196 fprintf(stderr,
197 "*** Sigsegv in page not marked as write protected\n");
198
199 os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
200 page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
201 page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
202
203 return;
204 }
205 #endif
206
207 SAVE_CONTEXT();
208
209 DPRINTF(0, (stderr, "sigsegv:\n"));
210 interrupt_handle_now(signal, code, context);
211 }
212
213 static void
214 sigbus_handler(HANDLER_ARGS)
215 {
216 SAVE_CONTEXT();
217
218 DPRINTF(0, (stderr, "sigbus:\n"));
219 interrupt_handle_now(signal, code, context);
220 }
221
222 void
223 os_install_interrupt_handlers(void)
224 {
225 interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
226 interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
227 }

  ViewVC Help
Powered by ViewVC 1.1.5