ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/sigsegv.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/sigsegv.cpp (file contents):
Revision 1.3 by gbeauche, 2001-06-05T12:16:34Z vs.
Revision 1.4 by gbeauche, 2001-06-26T22:35:41Z

# Line 70 | Line 70 | static bool sigsegv_do_install_handler(i
70   #endif
71   #if (defined(sparc) || defined(__sparc__))
72   #include <asm/sigcontext.h>
73 < #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext* scp, char* addr
73 > #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext *scp, char* addr
74   #define SIGSEGV_FAULT_ADDRESS                   addr
75   #endif
76   #if (defined(powerpc) || defined(__powerpc__))
77   #include <asm/sigcontext.h>
78 < #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, struct sigcontext* scp
78 > #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, struct sigcontext *scp
79   #define SIGSEGV_FAULT_ADDRESS                   scp->regs->dar
80   #define SIGSEGV_FAULT_INSTRUCTION               scp->regs->nip
81   #endif
82 + #if (defined(alpha) || defined(__alpha__))
83 + #include <asm/sigcontext.h>
84 + #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext *scp
85 + #define SIGSEGV_FAULT_ADDRESS                   get_fault_address(scp)
86 + #define SIGSEGV_FAULT_INSTRUCTION               scp->sc_pc
87 +
88 + // From Boehm's GC 6.0alpha8
89 + static sigsegv_address_t get_fault_address(struct sigcontext *scp)
90 + {
91 +        unsigned int instruction = *((unsigned int *)(scp->sc_pc));
92 +        unsigned long fault_address = scp->sc_regs[(instruction >> 16) & 0x1f];
93 +        fault_address += (signed long)(signed short)(instruction & 0xffff);
94 +        return (sigsegv_address_t)fault_address;
95 + }
96 + #endif
97   #endif
98  
99   // Irix 5 or 6 on MIPS
# Line 132 | Line 147 | static bool sigsegv_do_install_handler(i
147   #define SIGSEGV_ALL_SIGNALS                             FAULT_HANDLER(SIGBUS)
148   #endif
149   #endif
150 +
151 + // MacOS X
152 + #if defined(__APPLE__) && defined(__MACH__)
153 + #if (defined(ppc) || defined(__ppc__))
154 + #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext *scp
155 + #define SIGSEGV_FAULT_ADDRESS                   get_fault_address(scp)
156 + #define SIGSEGV_FAULT_INSTRUCTION               scp->sc_ir
157 + #define SIGSEGV_ALL_SIGNALS                             FAULT_HANDLER(SIGBUS)
158 +
159 + // From Boehm's GC 6.0alpha8
160 + #define EXTRACT_OP1(iw)     (((iw) & 0xFC000000) >> 26)
161 + #define EXTRACT_OP2(iw)     (((iw) & 0x000007FE) >> 1)
162 + #define EXTRACT_REGA(iw)    (((iw) & 0x001F0000) >> 16)
163 + #define EXTRACT_REGB(iw)    (((iw) & 0x03E00000) >> 21)
164 + #define EXTRACT_REGC(iw)    (((iw) & 0x0000F800) >> 11)
165 + #define EXTRACT_DISP(iw)    ((short *) &(iw))[1]
166 +
167 + static sigsegv_address_t get_fault_address(struct sigcontext *scp)
168 + {
169 +        unsigned int   instr = *((unsigned int *) scp->sc_ir);
170 +        unsigned int * regs = &((unsigned int *) scp->sc_regs)[2];
171 +        int            disp = 0, tmp;
172 +        unsigned int   baseA = 0, baseB = 0;
173 +        unsigned int   addr, alignmask = 0xFFFFFFFF;
174 +
175 +        switch(EXTRACT_OP1(instr)) {
176 +        case 38:   /* stb */
177 +        case 39:   /* stbu */
178 +        case 54:   /* stfd */
179 +        case 55:   /* stfdu */
180 +        case 52:   /* stfs */
181 +        case 53:   /* stfsu */
182 +        case 44:   /* sth */
183 +        case 45:   /* sthu */
184 +        case 47:   /* stmw */
185 +        case 36:   /* stw */
186 +        case 37:   /* stwu */
187 +                tmp = EXTRACT_REGA(instr);
188 +                if(tmp > 0)
189 +                        baseA = regs[tmp];
190 +                disp = EXTRACT_DISP(instr);
191 +                break;
192 +        case 31:
193 +                switch(EXTRACT_OP2(instr)) {
194 +                case 86:    /* dcbf */
195 +                case 54:    /* dcbst */
196 +                case 1014:  /* dcbz */
197 +                case 247:   /* stbux */
198 +                case 215:   /* stbx */
199 +                case 759:   /* stfdux */
200 +                case 727:   /* stfdx */
201 +                case 983:   /* stfiwx */
202 +                case 695:   /* stfsux */
203 +                case 663:   /* stfsx */
204 +                case 918:   /* sthbrx */
205 +                case 439:   /* sthux */
206 +                case 407:   /* sthx */
207 +                case 661:   /* stswx */
208 +                case 662:   /* stwbrx */
209 +                case 150:   /* stwcx. */
210 +                case 183:   /* stwux */
211 +                case 151:   /* stwx */
212 +                case 135:   /* stvebx */
213 +                case 167:   /* stvehx */
214 +                case 199:   /* stvewx */
215 +                case 231:   /* stvx */
216 +                case 487:   /* stvxl */
217 +                        tmp = EXTRACT_REGA(instr);
218 +                        if(tmp > 0)
219 +                                baseA = regs[tmp];
220 +                        baseB = regs[EXTRACT_REGC(instr)];
221 +                        /* determine Altivec alignment mask */
222 +                        switch(EXTRACT_OP2(instr)) {
223 +                        case 167:   /* stvehx */
224 +                                alignmask = 0xFFFFFFFE;
225 +                                break;
226 +                        case 199:   /* stvewx */
227 +                                alignmask = 0xFFFFFFFC;
228 +                                break;
229 +                        case 231:   /* stvx */
230 +                                alignmask = 0xFFFFFFF0;
231 +                                break;
232 +                        case 487:  /* stvxl */
233 +                                alignmask = 0xFFFFFFF0;
234 +                                break;
235 +                        }
236 +                        break;
237 +                case 725:   /* stswi */
238 +                        tmp = EXTRACT_REGA(instr);
239 +                        if(tmp > 0)
240 +                                baseA = regs[tmp];
241 +                        break;
242 +                default:   /* ignore instruction */
243 +                        return 0;
244 +                        break;
245 +                }
246 +                break;
247 +        default:   /* ignore instruction */
248 +                return 0;
249 +                break;
250 +        }
251 +        
252 +        addr = (baseA + baseB) + disp;
253 +        addr &= alignmask;
254 +        return (sigsegv_address_t)addr;
255 + }
256 + #endif
257 + #endif
258   #endif
259  
260   // Fallbacks
# Line 243 | Line 366 | void sigsegv_deinstall_handler(void)
366   *  Test program used for configure/test
367   */
368  
369 < #ifdef CONFIGURE_TEST
369 > #ifdef CONFIGURE_TEST_SIGSEGV_RECOVERY
370   #include <stdio.h>
371   #include <stdlib.h>
249 #include <unistd.h>
372   #include <fcntl.h>
373   #include <sys/mman.h>
374 + #include "vm_alloc.h"
375  
376   static int page_size;
377   static volatile char * page = 0;
# Line 259 | Line 382 | static bool sigsegv_test_handler(sigsegv
382          handler_called++;
383          if ((fault_address - 123) != page)
384                  exit(1);
385 <        if (mprotect((char *)((unsigned long)fault_address & -page_size), page_size, PROT_READ | PROT_WRITE) != 0)
385 >        if (vm_protect((char *)((unsigned long)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0)
386                  exit(1);
387          return true;
388   }
389  
390   int main(void)
391   {
392 <        int zero_fd = open("/dev/zero", O_RDWR);
270 <        if (zero_fd < 0)
392 >        if (vm_init() < 0)
393                  return 1;
394  
395          page_size = getpagesize();
396 <        page = (char *)mmap(0, page_size, PROT_READ, MAP_PRIVATE, zero_fd, 0);
397 <        if (page == MAP_FAILED)
396 >        if ((page = (char *)vm_acquire(page_size)) == VM_MAP_FAILED)
397 >                return 1;
398 >        
399 >        if (vm_protect((char *)page, page_size, VM_PAGE_READ) < 0)
400                  return 1;
401          
402          if (!sigsegv_install_handler(sigsegv_test_handler))
# Line 284 | Line 408 | int main(void)
408          if (handler_called != 1)
409                  return 1;
410  
411 +        vm_exit();
412          return 0;
413   }
414   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines