/[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.1 - (show annotations)
Tue Jan 21 00:28:13 1997 UTC (17 years, 3 months ago) by ram
Branch: MAIN
CVS Tags: RELEASE_18a
Branch point for: RELENG_18
File MIME type: text/plain
source kit 1.03.7
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 *
14 */
15
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/param.h>
20 #include <signal.h>
21 #include <sys/user.h>
22 #include <sys/ptrace.h>
23 #include <sys/wait.h>
24 #include <sys/param.h>
25 #include <sys/file.h>
26 #include <sys/proc.h>
27 #include <errno.h>
28 #include "./signal.h"
29 #include "os.h"
30 #include "arch.h"
31 #include "globals.h"
32 #include "interrupt.h"
33 #include "lispregs.h"
34 #include "internals.h"
35
36 #include "x86-validate.h"
37 vm_size_t os_vm_page_size;
38 #define DPRINTF(t,a) {if(t)fprintf a;}
39
40 #define HAVE_SIGVEC /* defined - now obsolete */
41 #define HAVE_SIGACTION /* replacement for SIGVEC */
42 /* SIGSTKSZ == 40Kb */
43 #define SIG_STACK_SIZE (SIGSTKSZ/sizeof(double))
44 /* make sure the stack is 8 byte aligned */
45 #if defined USE_SIG_STACK
46 static double estack_buf[SIG_STACK_SIZE];
47 #endif
48
49 void
50 os_init()
51 {
52
53 #if defined USE_SIG_STACK
54 static struct sigaltstack estack;
55 estack.ss_base = (char*)estack_buf; /* this should be ss_sp */
56 estack.ss_size = SIGSTKSZ;
57 estack.ss_flags = 0;
58 if (sigaltstack(&estack, 0) < 0)
59 perror("sigaltstack");
60 #endif
61 os_vm_page_size=OS_VM_DEFAULT_PAGESIZE;
62 }
63
64 int
65 sc_reg(struct sigcontext *c, int offset)
66 {
67 switch(offset)
68 {
69 case 0: return c->sc_eax;
70 case 2: return c->sc_ecx;
71 case 4: return c->sc_edx;
72 case 6: return c->sc_ebx;
73 case 8: return c->sc_esp;
74 case 10: return c->sc_ebp;
75 case 12: return c->sc_esi;
76 case 14: return c->sc_edi;
77 }
78 return 0;
79 }
80 void
81 os_save_context()
82 {
83 /* Called from interrupt handlers so C stuff knows things set in Lisp
84 */
85 }
86 void
87 os_set_context()
88 {
89 }
90
91 os_vm_address_t
92 os_validate(os_vm_address_t addr, os_vm_size_t len)
93 {
94 int flags = MAP_PRIVATE|MAP_ANONYMOUS;
95
96 if(addr) flags|=MAP_FIXED;
97 else flags|=MAP_VARIABLE;
98
99 DPRINTF(0,(stderr,"os_validate %x %d => ",addr,len));
100 if((addr=mmap(addr,len,OS_VM_PROT_ALL,flags,-1,0)) == (os_vm_address_t) -1)
101 {
102 perror("mmap");
103 return NULL;
104 }
105 DPRINTF(0,(stderr,"%x\n",addr));
106
107 return addr;
108 }
109
110 void
111 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
112 {
113 DPRINTF(0,(stderr,"os_invalidate %x %d\n",addr,len));
114 if(munmap(addr,len) == -1)
115 perror("munmap");
116 }
117
118 os_vm_address_t
119 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
120 {
121 if((addr=mmap(addr,len,OS_VM_PROT_ALL,MAP_PRIVATE|MAP_FILE|MAP_FIXED,fd,
122 (off_t) offset)) == (os_vm_address_t) -1)
123 perror("mmap");
124
125 return addr;
126 }
127
128 void
129 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
130 {
131 }
132
133 void
134 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
135 {
136 if(mprotect(address, length, prot) == -1)
137 perror("mprotect");
138 }
139
140 static boolean
141 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
142 {
143 char* beg = (char*)sbeg;
144 char* end = (char*)sbeg + slen;
145 char* adr = (char*)a;
146 return (adr >= beg && adr < end);
147 }
148 boolean
149 valid_addr(os_vm_address_t addr)
150 {
151 int ret;
152 os_vm_address_t newaddr;
153 newaddr=os_trunc_to_page(addr);
154
155 if( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
156 || in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE )
157 || in_range_p(addr, DYNAMIC_0_SPACE_START, DYNAMIC_SPACE_SIZE )
158 || in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE )
159 || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE )
160 || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE ))
161 return TRUE;
162 return FALSE;
163 }
164
165
166 static void
167 sigbus_handler(int signal, int code, struct sigcontext *context)
168 {
169 DPRINTF(0,(stderr,"sigbus:\n"));
170 #if defined NOTYET
171 if(!interrupt_maybe_gc(signal, code, context))
172 #endif
173 interrupt_handle_now(signal, code, context);
174 }
175 static void
176 sigsegv_handler(int signal, int code, struct sigcontext *context)
177 {
178 DPRINTF(0,(stderr,"os_sigsegv\n"));
179 #if defined NOTYET
180 if(!interrupt_maybe_gc(signal, code, context))
181 #endif
182 interrupt_handle_now(signal, code, context);
183 }
184
185 void
186 os_install_interrupt_handlers(void)
187 {
188 interrupt_install_low_level_handler(SIGSEGV,sigsegv_handler);
189 interrupt_install_low_level_handler(SIGBUS,sigbus_handler);
190 }
191
192
193 /* All this is needed to get the floating-point status register
194 * that was stuffed in process context on a SIGFPE. We need it
195 * to determine what kind of condition occured. This code also
196 * sets up the possibility of defining some local structs to
197 * make up for lack of sigcontext registers and have a low level
198 * SIGFPE handler dummy something up.
199 */
200 #ifdef not_now_maybe_not_ever
201 struct user u;
202 unsigned int
203 BSD_get_fp_modes()
204 {
205 /* All this is highly dependent on FreeBSD internals. Watch Out! */
206 /* offset to where NPX state is saved in a process */
207 unsigned int fpoff = (char*)&u.u_pcb.pcb_savefpu - (char*)&u;
208 unsigned int fplen = sizeof u.u_pcb.pcb_savefpu / sizeof(int);
209 /* offset to the last exception status word */
210 unsigned int swoff = (char*)&u.u_pcb.pcb_savefpu.sv_ex_sw - (char*)&u;
211 pid_t pid;
212 /* fork to capture NPX state in another process */
213 pid = fork();
214 if(pid)
215 {
216 u_long ex_sw, ex_cw;
217 int status;
218 printf("p: wait1\n"); fflush(stdout);
219 wait4(pid, &status, WUNTRACED, NULL);
220 printf("P: wait over\n"); fflush(stdout);
221 ex_sw = ptrace(PT_READ_U, pid, (caddr_t)swoff, 0);
222 if(ex_sw == -1)
223 perror("ptrace");
224 {
225 /* Might as well get the rest of the saved state. */
226 int i, *ip = (int*)&u.u_pcb.pcb_savefpu;
227 unsigned int*uaddr = (unsigned int*)fpoff;
228 for(i=0; i<fplen; i++, uaddr++)
229 *ip++ = ptrace(PT_READ_U, pid, (caddr_t)uaddr, 0);
230 ex_cw = u.u_pcb.pcb_savefpu.sv_env.en_cw & 0xffff;
231 }
232 printf("sw %x cw %x\n",ex_sw,ex_cw); fflush(stdout);
233 printf("p: Kill\n"); fflush(stdout);
234 ptrace(PT_CONTINUE, pid, NULL, 0);
235 printf("p: wait2\n"); fflush(stdout);
236 wait4(pid, &status, 0, NULL);
237 printf("p: wait over\n"); fflush(stdout);
238 ex_sw &= 0xffff;
239 ex_cw &= 0xffff;
240 ex_cw ^= 0x3f;
241 return (ex_sw << 16) | ex_cw ;
242 }
243 else
244 {
245 /* As child, notify OS to allow ptrace calls */
246 int status = ptrace(PT_TRACE_ME, getpid(), NULL, 0);
247 if(status == -1)
248 perror("kid");
249 printf("c:\n"); fflush(stdout);
250 /* Go idle so parent can poke at process contents. */
251 raise(SIGSTOP);
252 printf("c: stopped?\n");
253 while(0)
254 { sigsuspend(0); printf("c:\n"); fflush(stdout); }
255 exit(1);
256 }
257 }
258 #endif
259

  ViewVC Help
Powered by ViewVC 1.1.5