/[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 - (hide annotations)
Sat Mar 23 18:50:59 2002 UTC (12 years, 1 month 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 pmai 1.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 pw 1.1.2.1 * $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 pmai 1.1 *
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