/[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.3 - (hide annotations)
Thu Feb 25 12:41:02 1999 UTC (15 years, 1 month ago) by pw
Branch: MAIN
Changes since 1.2: +2 -2 lines
File MIME type: text/plain
Minor change to #include validate.h instead of x86-validate.h
1 ram 1.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 dtc 1.2 * GENCGC support by Douglas Crosher, 1996, 1997.
14     *
15 pw 1.3 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.3 1999/02/25 12:41:02 pw Exp $
16 ram 1.1 *
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 dtc 1.2 #include <sys/types.h>
32     #include <signal.h>
33     /* #include <sys/sysinfo.h> */
34     #include <sys/proc.h>
35 pw 1.3 #include "validate.h"
36 ram 1.1 vm_size_t os_vm_page_size;
37     #define DPRINTF(t,a) {if(t)fprintf a;}
38    
39     #define HAVE_SIGVEC /* defined - now obsolete */
40     #define HAVE_SIGACTION /* replacement for SIGVEC */
41     /* SIGSTKSZ == 40Kb */
42     #define SIG_STACK_SIZE (SIGSTKSZ/sizeof(double))
43     /* make sure the stack is 8 byte aligned */
44     #if defined USE_SIG_STACK
45     static double estack_buf[SIG_STACK_SIZE];
46     #endif
47 dtc 1.2
48     #if defined GENCGC
49     #include "gencgc.h"
50     #endif
51    
52 ram 1.1
53     void
54     os_init()
55     {
56    
57     #if defined USE_SIG_STACK
58     static struct sigaltstack estack;
59     estack.ss_base = (char*)estack_buf; /* this should be ss_sp */
60     estack.ss_size = SIGSTKSZ;
61     estack.ss_flags = 0;
62     if (sigaltstack(&estack, 0) < 0)
63     perror("sigaltstack");
64     #endif
65     os_vm_page_size=OS_VM_DEFAULT_PAGESIZE;
66     }
67    
68     int
69     sc_reg(struct sigcontext *c, int offset)
70     {
71     switch(offset)
72     {
73     case 0: return c->sc_eax;
74     case 2: return c->sc_ecx;
75     case 4: return c->sc_edx;
76     case 6: return c->sc_ebx;
77     case 8: return c->sc_esp;
78     case 10: return c->sc_ebp;
79     case 12: return c->sc_esi;
80     case 14: return c->sc_edi;
81     }
82     return 0;
83     }
84     void
85     os_save_context()
86     {
87     /* Called from interrupt handlers so C stuff knows things set in Lisp
88     */
89     }
90     void
91     os_set_context()
92     {
93     }
94    
95     os_vm_address_t
96     os_validate(os_vm_address_t addr, os_vm_size_t len)
97     {
98     int flags = MAP_PRIVATE|MAP_ANONYMOUS;
99    
100     if(addr) flags|=MAP_FIXED;
101     else flags|=MAP_VARIABLE;
102    
103     DPRINTF(0,(stderr,"os_validate %x %d => ",addr,len));
104     if((addr=mmap(addr,len,OS_VM_PROT_ALL,flags,-1,0)) == (os_vm_address_t) -1)
105     {
106     perror("mmap");
107     return NULL;
108     }
109     DPRINTF(0,(stderr,"%x\n",addr));
110    
111     return addr;
112     }
113    
114     void
115     os_invalidate(os_vm_address_t addr, os_vm_size_t len)
116     {
117     DPRINTF(0,(stderr,"os_invalidate %x %d\n",addr,len));
118 dtc 1.2 if(munmap(addr,len) == -1) {
119     fprintf(stderr,"munmap(0x%x,%d)==-1\n",addr,len);
120 ram 1.1 perror("munmap");
121 dtc 1.2 }
122 ram 1.1 }
123    
124     os_vm_address_t
125     os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
126     {
127     if((addr=mmap(addr,len,OS_VM_PROT_ALL,MAP_PRIVATE|MAP_FILE|MAP_FIXED,fd,
128     (off_t) offset)) == (os_vm_address_t) -1)
129     perror("mmap");
130    
131     return addr;
132     }
133    
134     void
135     os_flush_icache(os_vm_address_t address, os_vm_size_t length)
136     {
137     }
138    
139     void
140     os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
141     {
142     if(mprotect(address, length, prot) == -1)
143     perror("mprotect");
144     }
145    
146     static boolean
147     in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
148     {
149     char* beg = (char*)sbeg;
150     char* end = (char*)sbeg + slen;
151     char* adr = (char*)a;
152     return (adr >= beg && adr < end);
153     }
154     boolean
155     valid_addr(os_vm_address_t addr)
156     {
157     int ret;
158     os_vm_address_t newaddr;
159     newaddr=os_trunc_to_page(addr);
160    
161     if( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
162     || in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE )
163     || in_range_p(addr, DYNAMIC_0_SPACE_START, DYNAMIC_SPACE_SIZE )
164     || in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE )
165     || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE )
166     || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE ))
167     return TRUE;
168     return FALSE;
169     }
170    
171    
172     static void
173 dtc 1.2 sigbus_handler(int signal, int code, struct sigcontext *context,
174     void *fault_addr)
175 ram 1.1 {
176 dtc 1.2 #if defined GENCGC
177     int page_index = find_page_index(fault_addr);
178    
179     #if SIGBUS_VERBOSE
180     fprintf(stderr,"Signal %d, fault_addr=%x, page_index=%d:\n",
181     signal,fault_addr,page_index);
182     #endif
183    
184     /* Check if the fault is within the dynamic space. */
185     if (page_index != -1) {
186     /* Un-protect the page */
187    
188     /* The page should have been marked write_protected */
189     if (page_table[page_index].write_protected != 1)
190     fprintf(stderr,"*** Sigbus in page not marked as write protected");
191    
192     os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
193     page_table[page_index].write_protected = 0;
194     page_table[page_index].write_protected_cleared = 1;
195    
196     #if SIGBUS_VERBOSE
197     fprintf(stderr,"* page: gen=%d bytes_used=%d first_object_offset=%d dont_move=%d\n",
198     page_table[page_index].gen,
199     page_table[page_index].bytes_used,
200     page_table[page_index].first_object_offset,
201     page_table[page_index].dont_move);
202     fprintf(stderr,"* data: %x %x %x %x\n",
203     *(((long *)fault_addr)-1),
204     *(((long *)fault_addr)-0),
205     *(((long *)fault_addr)+1),
206     *(((long *)fault_addr)+2));
207     {
208     int pi2 = find_page_index(*(((long *)fault_addr)-0));
209    
210     if ( pi2!=-1 )
211     fprintf(stderr,"* pi2: gen=%d bytes_used=%d first_object_offset=%d dont_move=%d\n",
212     page_table[pi2].gen,
213     page_table[pi2].bytes_used,
214     page_table[pi2].first_object_offset,
215     page_table[pi2].dont_move);
216     }
217     #endif
218    
219     return;
220     }
221     #endif
222    
223 ram 1.1 DPRINTF(0,(stderr,"sigbus:\n"));
224 dtc 1.2 interrupt_handle_now(signal, code, context);
225 ram 1.1 }
226     static void
227     sigsegv_handler(int signal, int code, struct sigcontext *context)
228     {
229     DPRINTF(0,(stderr,"os_sigsegv\n"));
230 dtc 1.2 interrupt_handle_now(signal, code, context);
231 ram 1.1 }
232    
233     void
234     os_install_interrupt_handlers(void)
235     {
236     interrupt_install_low_level_handler(SIGSEGV,sigsegv_handler);
237     interrupt_install_low_level_handler(SIGBUS,sigbus_handler);
238     }

  ViewVC Help
Powered by ViewVC 1.1.5