/[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 - (hide annotations)
Sun Mar 23 21:23:41 2003 UTC (11 years ago) by gerd
Branch: MAIN
CVS Tags: release-19b-pre1, release-19b-pre2, snapshot-2003-10, snapshot-2004-10, snapshot-2004-08, snapshot-2004-09, remove_negative_zero_not_zero, snapshot-2004-05, snapshot-2004-06, snapshot-2004-07, dynamic-extent-base, mod-arith-base, sparc_gencgc_merge, snapshot-2004-12, snapshot-2004-11, amd64-merge-start, prm-before-macosx-merge-tag, snapshot-2003-11, snapshot-2005-07, release-19a-base, sparc_gencgc, snapshot-2003-12, release-19a-pre1, release-19a-pre3, release-19a-pre2, release-19a, snapshot-2005-03, release-19b-base, snapshot-2004-04, snapshot-2005-01, snapshot-2005-06, snapshot-2005-05, snapshot-2005-04, ppc_gencgc_snap_2005-05-14, snapshot-2005-02, snapshot-2005-09, snapshot-2005-08, lisp-executable-base
Branch point for: release-19b-branch, mod-arith-branch, sparc_gencgc_branch, dynamic-extent, ppc_gencgc_branch, lisp-executable, release-19a-branch
Changes since 1.9: +105 -89 lines
File MIME type: text/plain
	Optional control stack checking.  This is controlled by the
	feature :stack-checking because it's not implemented for other
	systems/architectures yet.  It is currently known to work on
	FreeBSD 4.8-RC/x86 and Debian 2.2.20/x86.

	* bootfiles/18e/boot3.lisp: New boot file, well, only a
	description of the boot procedure since no boot file is needed.

	* lisp/x86-validate.h (SIGNAL_STACK_START, SIGNAL_STACK_SIZE)
	[__FreeBSD__, __linux__]: New defines.
	(CONTROL_STACK_SIZE) {__FreeBSD__, __linux__]:
	Adjust for signal stack.

	* lisp/validate.c (validate) [RED_ZONE_HIT]: Call
	os_guard_control_stack.  Some cleanup.

	* lisp/os.h (BOTH_ZONES, YELLOW_ZONE, RED_ZONE): New enums.
	Add function prototypes.

	* lisp/interrupt.c (interrupt_install_low_level_handler)
	[RED_ZONE_HIT]: Deliver protection violations on a dedicated
	signal stack.

	* lisp/os-common.c (os_stack_grows_down_1, os_stack_grows_down):
	New functions.
	(guard_zones, control_stack_zone, os_guard_control_stack)
	(os_control_stack_overflow) [RED_ZONE_HIT]: New functions.
	(os_control_stack_overflow) [!RED_ZONE_HIT]: Dummy function.

	* lisp/Linux-os.c (sigsegv_handler) [RED_ZONE_HIT]: Handle control
	stack overflows.

	* lisp/FreeBSD-os.c: General cleansing.
	(sigbus_handler) [RED_ZONE_HIT]: Handle control stack overflows.

	* lisp/FreeBSD-os.h (PROTECTION_VIOLATION_SIGNAL): New define.

	* lisp/Linux-os.h (PROTECTION_VIOLATION_SIGNAL): New define.

	* compiler/x86/system.lisp (lisp::%scrub-control-stack): Change
	defknown from sys:scrub-control-stack.
	(%scrub-control-stack): Rename VOP.

	* code/lispinit.lisp (os-guard-control-stack) [#+stack-checking]:
	Define alien os_guard_control_stack.
	(%scrub-control-stack) [#+x86]: New function.
	(scrub-control-stack) [#+x86]: Call %scrub-control-stack,
	call os-guard-control-stack if #+stack-checking.

	* code/interr.lisp (yellow-zone-hit,
	red-zone-hit) [#+stack-checking]: New functions.

	* code/error.lisp (stack-overflow) [#+stack-checking]: New
	condition.

	* compiler/generic/new-genesis.lisp (finish-symbols)
	[#+stack-checking]: Add symbols for control stack checking.

	* compiler/x86/parms.lisp (static-symbols): Likewise.
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 gerd 1.10 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.10 2003/03/23 21:23:41 gerd 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 moore 1.8 #include <dlfcn.h>
36 pw 1.3 #include "validate.h"
37 dtc 1.2
38     #if defined GENCGC
39     #include "gencgc.h"
40     #endif
41    
42 moore 1.7 #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 gerd 1.10
49     vm_size_t os_vm_page_size;
50    
51 ram 1.1
52 gerd 1.10 void
53     os_init (void)
54 ram 1.1 {
55 gerd 1.10 os_vm_page_size = getpagesize ();
56 ram 1.1 }
57    
58 gerd 1.10 int
59     sc_reg (struct sigcontext *c, int offset)
60 ram 1.1 {
61     switch(offset)
62     {
63     case 0: return c->sc_eax;
64     case 2: return c->sc_ecx;
65     case 4: return c->sc_edx;
66     case 6: return c->sc_ebx;
67     case 8: return c->sc_esp;
68     case 10: return c->sc_ebp;
69     case 12: return c->sc_esi;
70     case 14: return c->sc_edi;
71     }
72 gerd 1.10
73 ram 1.1 return 0;
74     }
75 dtc 1.5
76 gerd 1.10 void
77     os_save_context (void)
78 ram 1.1 {
79 gerd 1.10 /* Called from interrupt handlers so C stuff knows things set in
80     Lisp. */
81 ram 1.1 }
82 dtc 1.5
83 gerd 1.10 void
84     os_set_context (void)
85 ram 1.1 {
86     }
87    
88 gerd 1.10 os_vm_address_t
89     os_validate (os_vm_address_t addr, os_vm_size_t len)
90 ram 1.1 {
91 dtc 1.5 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
92    
93     if (addr)
94     flags |= MAP_FIXED;
95     else
96     flags |= MAP_VARIABLE;
97 ram 1.1
98 gerd 1.10 addr = mmap (addr, len, OS_VM_PROT_ALL, flags, -1, 0);
99 dtc 1.5
100     if (addr == (os_vm_address_t) -1)
101 ram 1.1 {
102 gerd 1.10 perror ("mmap");
103 ram 1.1 return NULL;
104     }
105 dtc 1.5
106 ram 1.1 return addr;
107     }
108    
109 gerd 1.10 void
110     os_invalidate (os_vm_address_t addr, os_vm_size_t len)
111 ram 1.1 {
112 gerd 1.10 if (munmap (addr, len) == -1)
113     perror ("munmap");
114 ram 1.1 }
115    
116 gerd 1.10 os_vm_address_t
117     os_map (int fd, int offset, os_vm_address_t addr,
118     os_vm_size_t len)
119 ram 1.1 {
120 gerd 1.10 addr = mmap (addr, len, OS_VM_PROT_ALL,
121     MAP_PRIVATE | MAP_FILE | MAP_FIXED,
122     fd, (off_t) offset);
123 dtc 1.5
124     if (addr == (os_vm_address_t) -1)
125 gerd 1.10 perror ("mmap");
126 dtc 1.5
127 ram 1.1 return addr;
128     }
129    
130 gerd 1.10 void
131     os_flush_icache (os_vm_address_t address, os_vm_size_t length)
132 ram 1.1 {
133     }
134    
135 gerd 1.10 void
136     os_protect (os_vm_address_t address, os_vm_size_t length,
137     os_vm_prot_t prot)
138 ram 1.1 {
139 gerd 1.10 if (mprotect (address, length, prot) == -1)
140     perror ("mprotect");
141 ram 1.1 }
142 dtc 1.5
143 ram 1.1
144 dtc 1.5
145 gerd 1.10 static boolean
146     in_range_p (os_vm_address_t a, lispobj sbeg, size_t slen)
147 ram 1.1 {
148 gerd 1.10 char *beg = (char *) sbeg;
149     char *end = (char *) sbeg + slen;
150     char *adr = (char *) a;
151     return adr >= beg && adr < end;
152 ram 1.1 }
153 dtc 1.5
154 gerd 1.10 boolean
155     valid_addr (os_vm_address_t addr)
156 ram 1.1 {
157     int ret;
158     os_vm_address_t newaddr;
159 gerd 1.10 newaddr = os_trunc_to_page (addr);
160 ram 1.1
161 gerd 1.10 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     #ifndef GENCGC
165     || in_range_p (addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
166     #endif
167     || in_range_p (addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
168     || in_range_p (addr, BINDING_STACK_START, BINDING_STACK_SIZE))
169 ram 1.1 return TRUE;
170     return FALSE;
171     }
172    
173    
174 gerd 1.10 static void
175     sigbus_handler (int signal, int code, struct sigcontext *context,
176     void *fault_addr)
177     {
178     int page_index;
179    
180     #ifdef RED_ZONE_HIT
181     if (os_control_stack_overflow (fault_addr, context))
182     return;
183     #endif
184    
185 dtc 1.2 #if defined GENCGC
186 gerd 1.10 page_index = find_page_index(fault_addr);
187 dtc 1.2
188 gerd 1.10 /* Check if the fault is within the dynamic space. */
189     if (page_index != -1)
190     {
191     /* Un-protect the page */
192 dtc 1.2
193 gerd 1.10 /* The page should have been marked write protected */
194     if (!PAGE_WRITE_PROTECTED (page_index))
195     fprintf (stderr, "*** Sigbus in page not marked as write protected\n");
196 dtc 1.2
197 gerd 1.10 os_protect (page_address (page_index), 4096, OS_VM_PROT_ALL);
198     page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
199     page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
200 dtc 1.5
201 gerd 1.10 return;
202 dtc 1.2 }
203 gerd 1.10 #endif /* GENCGC */
204 dtc 1.2
205 gerd 1.10 interrupt_handle_now (signal, code, context);
206 ram 1.1 }
207 dtc 1.5
208 gerd 1.10 static void
209     sigsegv_handler (int signal, int code, struct sigcontext *context)
210 ram 1.1 {
211 gerd 1.10 interrupt_handle_now (signal, code, context);
212 ram 1.1 }
213    
214 gerd 1.10 void
215     os_install_interrupt_handlers (void)
216 ram 1.1 {
217 gerd 1.10 interrupt_install_low_level_handler
218     (SIGSEGV, (void (*) (HANDLER_ARGS)) sigsegv_handler);
219     interrupt_install_low_level_handler
220     (SIGBUS, (void (*) (HANDLER_ARGS)) sigbus_handler);
221 moore 1.8 }
222    
223 gerd 1.10 void *
224     os_dlsym (const char *sym_name, lispobj lib_list)
225 moore 1.8 {
226 gerd 1.10 if (lib_list != NIL)
227     {
228     lispobj lib_list_head;
229 moore 1.8
230 gerd 1.10 for (lib_list_head = lib_list;
231     lib_list_head != NIL;
232     lib_list_head = CONS (lib_list_head)->cdr)
233     {
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 moore 1.8
238 gerd 1.10 if (sym_addr)
239     return sym_addr;
240 moore 1.8 }
241     }
242 gerd 1.10
243     return dlsym (RTLD_DEFAULT, sym_name);
244 ram 1.1 }

  ViewVC Help
Powered by ViewVC 1.1.5