/[cmucl]/src/lisp/FreeBSD-os.c
ViewVC logotype

Diff of /src/lisp/FreeBSD-os.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by ram, Tue Jan 21 00:28:13 1997 UTC revision 1.1.2.2 by pw, Tue May 23 16:38:11 2000 UTC
# Line 10  Line 10 
10   *   *
11   * This is the OSF1 version.  By Sean Hallgren.   * This is the OSF1 version.  By Sean Hallgren.
12   * Much hacked by Paul Werkowski   * Much hacked by Paul Werkowski
13     * GENCGC support by Douglas Crosher, 1996, 1997.
14     *
15     * $Header$
16   *   *
17   */   */
18    
19  #include <stdio.h>  #include <stdio.h>
 #include <unistd.h>  
 #include <sys/types.h>  
 #include <sys/param.h>  
 #include <signal.h>  
 #include <sys/user.h>  
 #include <sys/ptrace.h>  
 #include <sys/wait.h>  
20  #include <sys/param.h>  #include <sys/param.h>
21  #include <sys/file.h>  #include <sys/file.h>
 #include <sys/proc.h>  
22  #include <errno.h>  #include <errno.h>
23  #include "./signal.h"  #include "./signal.h"
24  #include "os.h"  #include "os.h"
# Line 33  Line 28 
28  #include "lispregs.h"  #include "lispregs.h"
29  #include "internals.h"  #include "internals.h"
30    
31  #include "x86-validate.h"  #include <sys/types.h>
32    #include <signal.h>
33    /* #include <sys/sysinfo.h> */
34    #include <sys/proc.h>
35    #include "validate.h"
36  vm_size_t os_vm_page_size;  vm_size_t os_vm_page_size;
 #define DPRINTF(t,a) {if(t)fprintf a;}  
37    
38  #define HAVE_SIGVEC             /* defined  - now obsolete */  #define DPRINTF(t,a) {if (t) fprintf a;}
39  #define HAVE_SIGACTION          /* replacement for SIGVEC          */  
40  /* SIGSTKSZ == 40Kb */  #if defined GENCGC
41  #define SIG_STACK_SIZE (SIGSTKSZ/sizeof(double))  #include "gencgc.h"
 /* make sure the stack is 8 byte aligned */  
 #if defined USE_SIG_STACK  
 static double estack_buf[SIG_STACK_SIZE];  
42  #endif  #endif
43    
44    
45  void  void os_init(void)
 os_init()  
46  {  {
47      os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
 #if defined USE_SIG_STACK  
   static struct sigaltstack estack;  
   estack.ss_base = (char*)estack_buf; /* this should be ss_sp */  
   estack.ss_size = SIGSTKSZ;  
   estack.ss_flags = 0;  
   if (sigaltstack(&estack, 0) < 0)  
     perror("sigaltstack");  
 #endif  
   os_vm_page_size=OS_VM_DEFAULT_PAGESIZE;  
48  }  }
49    
50  int  int sc_reg(struct sigcontext *c, int offset)
 sc_reg(struct sigcontext *c, int offset)  
51  {  {
52    switch(offset)    switch(offset)
53      {      {
# Line 77  sc_reg(struct sigcontext *c, int offset) Line 62  sc_reg(struct sigcontext *c, int offset)
62      }      }
63    return 0;    return 0;
64  }  }
65  void  
66  os_save_context()  void os_save_context(void)
67  {  {
68    /* Called from interrupt handlers so C stuff knows things set in Lisp    /*
69       * Called from interrupt handlers so C stuff knows things set in Lisp.
70     */     */
71  }  }
72  void  
73  os_set_context()  void os_set_context(void)
74  {  {
75  }  }
76    
77  os_vm_address_t  os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
 os_validate(os_vm_address_t addr, os_vm_size_t len)  
78  {  {
79    int flags = MAP_PRIVATE|MAP_ANONYMOUS;    int flags = MAP_PRIVATE | MAP_ANONYMOUS;
80    
81      if (addr)
82        flags |= MAP_FIXED;
83      else
84        flags |= MAP_VARIABLE;
85    
86    if(addr) flags|=MAP_FIXED;    DPRINTF(0, (stderr, "os_validate %x %d => ", addr, len));
   else flags|=MAP_VARIABLE;  
87    
88    DPRINTF(0,(stderr,"os_validate %x %d => ",addr,len));    addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
89    if((addr=mmap(addr,len,OS_VM_PROT_ALL,flags,-1,0)) == (os_vm_address_t) -1)  
90      if (addr == (os_vm_address_t) -1)
91      {      {
92        perror("mmap");        perror("mmap");
93        return NULL;        return NULL;
94      }      }
95    DPRINTF(0,(stderr,"%x\n",addr));  
96      DPRINTF(0, (stderr, "%x\n", addr));
97    
98    return addr;    return addr;
99  }  }
100    
101  void  void os_invalidate(os_vm_address_t addr, os_vm_size_t len)
 os_invalidate(os_vm_address_t addr, os_vm_size_t len)  
102  {  {
103    DPRINTF(0,(stderr,"os_invalidate %x %d\n",addr,len));    DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len));
104    if(munmap(addr,len) == -1)  
105      if (munmap(addr, len) == -1)
106      perror("munmap");      perror("munmap");
107  }  }
108    
109  os_vm_address_t  os_vm_address_t os_map(int fd, int offset, os_vm_address_t addr,
110  os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)                         os_vm_size_t len)
111  {  {
112    if((addr=mmap(addr,len,OS_VM_PROT_ALL,MAP_PRIVATE|MAP_FILE|MAP_FIXED,fd,    addr = mmap(addr, len,
113                  (off_t) offset)) == (os_vm_address_t) -1)                OS_VM_PROT_ALL,
114                  MAP_PRIVATE | MAP_FILE | MAP_FIXED,
115                  fd, (off_t) offset);
116    
117      if (addr == (os_vm_address_t) -1)
118      perror("mmap");      perror("mmap");
119    
120    return addr;    return addr;
121  }  }
122    
123  void  void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
 os_flush_icache(os_vm_address_t address, os_vm_size_t length)  
124  {  {
125  }  }
126    
127  void  void os_protect(os_vm_address_t address, os_vm_size_t length,
128  os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)                  os_vm_prot_t prot)
129  {  {
130    if(mprotect(address, length, prot) == -1)    if (mprotect(address, length, prot) == -1)
131      perror("mprotect");      perror("mprotect");
132  }  }
133    
134    
135  static boolean  
136  in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)  static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
137  {  {
138    char* beg = (char*)sbeg;    char* beg = (char*) sbeg;
139    char* end = (char*)sbeg + slen;    char* end = (char*) sbeg + slen;
140    char* adr = (char*)a;    char* adr = (char*) a;
141    return (adr >= beg && adr < end);    return (adr >= beg && adr < end);
142  }  }
143  boolean  
144  valid_addr(os_vm_address_t addr)  boolean valid_addr(os_vm_address_t addr)
145  {  {
146    int ret;    int ret;
147    os_vm_address_t newaddr;    os_vm_address_t newaddr;
148    newaddr=os_trunc_to_page(addr);    newaddr = os_trunc_to_page(addr);
149    
150    if(   in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)    if (   in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
151       || in_range_p(addr, STATIC_SPACE_START   , STATIC_SPACE_SIZE   )        || in_range_p(addr, STATIC_SPACE_START   , STATIC_SPACE_SIZE   )
152       || in_range_p(addr, DYNAMIC_0_SPACE_START, DYNAMIC_SPACE_SIZE  )        || in_range_p(addr, DYNAMIC_0_SPACE_START, DYNAMIC_SPACE_SIZE  )
153       || in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE  )        || in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE  )
154       || in_range_p(addr, CONTROL_STACK_START  , CONTROL_STACK_SIZE  )        || in_range_p(addr, CONTROL_STACK_START  , CONTROL_STACK_SIZE  )
155       || in_range_p(addr, BINDING_STACK_START  , BINDING_STACK_SIZE  ))        || in_range_p(addr, BINDING_STACK_START  , BINDING_STACK_SIZE  ))
156      return TRUE;      return TRUE;
157    return FALSE;    return FALSE;
158  }  }
159    
160    
161  static void  static void sigbus_handler(int signal, int code, struct sigcontext *context,
162  sigbus_handler(int signal, int code, struct sigcontext *context)                             void *fault_addr)
163  {  {
164    DPRINTF(0,(stderr,"sigbus:\n"));  #if defined GENCGC
165  #if defined NOTYET    int  page_index = find_page_index(fault_addr);
166    if(!interrupt_maybe_gc(signal, code, context))  
167    #if SIGBUS_VERBOSE
168      fprintf(stderr,"Signal %d, fault_addr=%x, page_index=%d:\n",
169              signal, fault_addr, page_index);
170  #endif  #endif
171      interrupt_handle_now(signal, code, context);  
172  }    /* Check if the fault is within the dynamic space. */
173  static void    if (page_index != -1) {
174  sigsegv_handler(int signal, int code, struct sigcontext *context)      /* Un-protect the page */
175  {  
176    DPRINTF(0,(stderr,"os_sigsegv\n"));      /* The page should have been marked write protected */
177  #if defined NOTYET      if (!PAGE_WRITE_PROTECTED(page_index))
178    if(!interrupt_maybe_gc(signal, code, context))        fprintf(stderr, "*** Sigbus in page not marked as write protected\n");
179    
180        os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
181        page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
182        page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
183    
184        return;
185        }
186  #endif  #endif
187      interrupt_handle_now(signal, code, context);  
188      DPRINTF(0, (stderr, "sigbus:\n"));
189      interrupt_handle_now(signal, code, context);
190  }  }
191    
192  void  static void sigsegv_handler(int signal, int code, struct sigcontext *context)
 os_install_interrupt_handlers(void)  
193  {  {
194    interrupt_install_low_level_handler(SIGSEGV,sigsegv_handler);    DPRINTF(0, (stderr, "os_sigsegv\n"));
195    interrupt_install_low_level_handler(SIGBUS,sigbus_handler);    interrupt_handle_now(signal, code, context);
196  }  }
197    
198    void os_install_interrupt_handlers(void)
199  /* All this is needed to get the floating-point status register  {
200   * that was stuffed in process context on a SIGFPE. We need it    interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
201   * to determine what kind of condition occured. This code also    interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
  * sets up the possibility of defining some local structs to  
  * make up for lack of sigcontext registers and have a low level  
  * SIGFPE handler dummy something up.  
  */  
 #ifdef not_now_maybe_not_ever  
 struct user u;  
 unsigned int  
 BSD_get_fp_modes()  
 {  
   /* All this is highly dependent on FreeBSD internals. Watch Out! */  
   /* offset to where NPX state is saved in a process */  
   unsigned int fpoff = (char*)&u.u_pcb.pcb_savefpu - (char*)&u;  
   unsigned int fplen = sizeof u.u_pcb.pcb_savefpu / sizeof(int);  
   /* offset to the last exception status word */  
   unsigned int swoff = (char*)&u.u_pcb.pcb_savefpu.sv_ex_sw - (char*)&u;  
   pid_t pid;  
   /* fork to capture NPX state in another process */  
   pid =  fork();  
   if(pid)  
     {  
       u_long ex_sw, ex_cw;  
       int status;  
       printf("p: wait1\n"); fflush(stdout);  
       wait4(pid, &status, WUNTRACED, NULL);  
       printf("P: wait over\n"); fflush(stdout);  
       ex_sw = ptrace(PT_READ_U, pid, (caddr_t)swoff, 0);  
       if(ex_sw == -1)  
         perror("ptrace");  
       {  
         /* Might as well get the rest  of the saved state. */  
         int i, *ip = (int*)&u.u_pcb.pcb_savefpu;  
         unsigned int*uaddr = (unsigned int*)fpoff;  
         for(i=0; i<fplen; i++, uaddr++)  
           *ip++ = ptrace(PT_READ_U, pid, (caddr_t)uaddr, 0);  
         ex_cw = u.u_pcb.pcb_savefpu.sv_env.en_cw & 0xffff;  
       }  
       printf("sw %x cw %x\n",ex_sw,ex_cw); fflush(stdout);  
       printf("p: Kill\n"); fflush(stdout);  
       ptrace(PT_CONTINUE, pid, NULL, 0);  
       printf("p: wait2\n"); fflush(stdout);  
       wait4(pid, &status, 0, NULL);  
       printf("p: wait over\n"); fflush(stdout);  
       ex_sw &= 0xffff;  
       ex_cw &= 0xffff;  
       ex_cw ^= 0x3f;  
       return (ex_sw << 16) | ex_cw ;  
     }  
   else  
     {  
       /* As child, notify OS to allow ptrace calls */  
       int status = ptrace(PT_TRACE_ME, getpid(), NULL, 0);  
       if(status == -1)  
         perror("kid");  
       printf("c:\n"); fflush(stdout);  
       /* Go idle so parent can poke at process contents. */  
       raise(SIGSTOP);  
       printf("c: stopped?\n");  
       while(0)  
         { sigsuspend(0); printf("c:\n"); fflush(stdout); }  
       exit(1);  
     }  
202  }  }
 #endif  
   

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.2

  ViewVC Help
Powered by ViewVC 1.1.5