/[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.2.1 - (show annotations)
Sat Mar 23 18:50:59 2002 UTC (12 years ago) by pw
Branch: RELENG_18
CVS Tags: RELEASE_18d
Changes since 1.1: +1 -1 lines
File MIME type: text/plain
Mega commit to bring RELENG_18 branch in sync with HEAD in preparation
for release tagging 18d.
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.2.1 2002/03/23 18:50:59 pw 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 os_init(void)
47 {
48 os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
49 }
50
51 int sc_reg(struct sigcontext *c, int offset)
52 {
53 switch(offset)
54 {
55 case 0: return c->sc_eax;
56 case 2: return c->sc_ecx;
57 case 4: return c->sc_edx;
58 case 6: return c->sc_ebx;
59 case 8: return c->sc_esp;
60 case 10: return c->sc_ebp;
61 case 12: return c->sc_esi;
62 case 14: return c->sc_edi;
63 }
64 return 0;
65 }
66
67 void os_save_context(void)
68 {
69 /*
70 * Called from interrupt handlers so C stuff knows things set in Lisp.
71 */
72 }
73
74 void os_set_context(void)
75 {
76 }
77
78 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
79 {
80 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
81
82 if (addr)
83 flags |= MAP_FIXED;
84 else
85 flags |= MAP_VARIABLE;
86
87 DPRINTF(0, (stderr, "os_validate %x %d => ", addr, len));
88
89 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
90
91 if (addr == (os_vm_address_t) -1)
92 {
93 perror("mmap");
94 return NULL;
95 }
96
97 DPRINTF(0, (stderr, "%x\n", addr));
98
99 return addr;
100 }
101
102 void os_invalidate(os_vm_address_t addr, os_vm_size_t len)
103 {
104 DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len));
105
106 if (munmap(addr, len) == -1)
107 perror("munmap");
108 }
109
110 os_vm_address_t os_map(int fd, int offset, os_vm_address_t addr,
111 os_vm_size_t len)
112 {
113 addr = mmap(addr, len,
114 OS_VM_PROT_ALL,
115 MAP_PRIVATE | MAP_FILE | MAP_FIXED,
116 fd, (off_t) offset);
117
118 if (addr == (os_vm_address_t) -1)
119 perror("mmap");
120
121 return addr;
122 }
123
124 void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
125 {
126 }
127
128 void os_protect(os_vm_address_t address, os_vm_size_t length,
129 os_vm_prot_t prot)
130 {
131 if (mprotect(address, length, prot) == -1)
132 perror("mprotect");
133 }
134
135
136
137 static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
138 {
139 char* beg = (char*) sbeg;
140 char* end = (char*) sbeg + slen;
141 char* adr = (char*) a;
142 return (adr >= beg && adr < end);
143 }
144
145 boolean valid_addr(os_vm_address_t addr)
146 {
147 int ret;
148 os_vm_address_t newaddr;
149 newaddr = os_trunc_to_page(addr);
150
151 if ( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
152 || in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE )
153 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size )
154 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size )
155 || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE )
156 || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE ))
157 return TRUE;
158 return FALSE;
159 }
160
161
162 static void sigsegv_handler(HANDLER_ARGS)
163 {
164 #if defined GENCGC
165 caddr_t fault_addr = code->si_addr;
166 int page_index = find_page_index((void*)fault_addr);
167
168 #if SIGSEGV_VERBOSE
169 fprintf(stderr,"Signal %d, fault_addr=%x, page_index=%d:\n",
170 signal, fault_addr, page_index);
171 #endif
172
173 /* Check if the fault is within the dynamic space. */
174 if (page_index != -1) {
175 /* Un-protect the page */
176
177 /* The page should have been marked write protected */
178 if (!PAGE_WRITE_PROTECTED(page_index))
179 fprintf(stderr, "*** Sigsegv in page not marked as write protected\n");
180
181 os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
182 page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
183 page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
184
185 return;
186 }
187 #endif
188
189 SAVE_CONTEXT();
190
191 DPRINTF(0, (stderr, "sigsegv:\n"));
192 interrupt_handle_now(signal, code, context);
193 }
194
195 static void sigbus_handler(HANDLER_ARGS)
196 {
197 SAVE_CONTEXT();
198
199 DPRINTF(0, (stderr, "sigbus:\n"));
200 interrupt_handle_now(signal, code, context);
201 }
202
203 void os_install_interrupt_handlers(void)
204 {
205 interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
206 interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
207 }

  ViewVC Help
Powered by ViewVC 1.1.5