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.31 by gbeauche, 2003-10-13T20:15:41Z vs.
Revision 1.33 by gbeauche, 2003-10-21T23:10:19Z

# Line 221 | Line 221 | static void powerpc_decode_instruction(i
221   #define SIGSEGV_FAULT_HANDLER_ARGLIST_1 siginfo_t *sip, void *scp
222   #define SIGSEGV_FAULT_HANDLER_ARGS              sip, scp
223   #define SIGSEGV_FAULT_ADDRESS                   sip->si_addr
224 < #if defined(__NetBSD__) || defined(__FreeBSD__)
224 > #if defined(__sun__)
225 > #if (defined(sparc) || defined(__sparc__))
226 > #include <sys/ucontext.h>
227 > #define SIGSEGV_CONTEXT_REGS                    (((ucontext_t *)scp)->uc_mcontext.gregs)
228 > #define SIGSEGV_FAULT_INSTRUCTION               SIGSEGV_CONTEXT_REGS[REG_PC]
229 > #endif
230 > #endif
231 > #if defined(__FreeBSD__)
232   #if (defined(i386) || defined(__i386__))
233   #define SIGSEGV_FAULT_INSTRUCTION               (((struct sigcontext *)scp)->sc_eip)
234   #define SIGSEGV_REGISTER_FILE                   ((unsigned int *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */
# Line 290 | Line 297 | static void powerpc_decode_instruction(i
297   #define SIGSEGV_FAULT_HANDLER_ARGS              sig, code, scp
298   #define SIGSEGV_FAULT_ADDRESS                   get_fault_address(scp)
299   #define SIGSEGV_FAULT_INSTRUCTION               scp->sc_pc
293
294 // From Boehm's GC 6.0alpha8
295 static sigsegv_address_t get_fault_address(struct sigcontext *scp)
296 {
297        unsigned int instruction = *((unsigned int *)(scp->sc_pc));
298        unsigned long fault_address = scp->sc_regs[(instruction >> 16) & 0x1f];
299        fault_address += (signed long)(signed short)(instruction & 0xffff);
300        return (sigsegv_address_t)fault_address;
301 }
300   #endif
301   #endif
302  
# Line 336 | Line 334 | static sigsegv_address_t get_fault_addre
334   #define SIGSEGV_ALL_SIGNALS                             FAULT_HANDLER(SIGSEGV)
335   #endif
336  
337 < // NetBSD or FreeBSD
338 < #if defined(__NetBSD__) || defined(__FreeBSD__)
337 > // NetBSD
338 > #if defined(__NetBSD__)
339   #if (defined(m68k) || defined(__m68k__))
340   #include <m68k/frame.h>
341   #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext *scp
# Line 365 | Line 363 | static sigsegv_address_t get_fault_addre
363          }
364          return (sigsegv_address_t)fault_addr;
365   }
366 < #else
367 < #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, void *scp, char *addr
366 > #endif
367 > #if (defined(alpha) || defined(__alpha__))
368 > #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext *scp
369 > #define SIGSEGV_FAULT_HANDLER_ARGS              sig, code, scp
370 > #define SIGSEGV_FAULT_ADDRESS                   get_fault_address(scp)
371 > #define SIGSEGV_ALL_SIGNALS                             FAULT_HANDLER(SIGBUS)
372 > #endif
373 > #if (defined(i386) || defined(__i386__))
374 > #error "FIXME: need to decode instruction and compute EA"
375 > #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext *scp
376 > #define SIGSEGV_FAULT_HANDLER_ARGS              sig, code, scp
377 > #define SIGSEGV_ALL_SIGNALS                             FAULT_HANDLER(SIGSEGV)
378 > #endif
379 > #endif
380 > #if defined(__FreeBSD__)
381 > #define SIGSEGV_ALL_SIGNALS                             FAULT_HANDLER(SIGBUS)
382 > #if (defined(i386) || defined(__i386__))
383 > #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int code, struct sigcontext *scp, char *addr
384   #define SIGSEGV_FAULT_HANDLER_ARGS              sig, code, scp, addr
385   #define SIGSEGV_FAULT_ADDRESS                   addr
386 < #define SIGSEGV_ALL_SIGNALS                             FAULT_HANDLER(SIGBUS)
386 > #define SIGSEGV_FAULT_INSTRUCTION               scp->sc_eip
387 > #define SIGSEGV_REGISTER_FILE                   ((unsigned int *)&scp->sc_edi)
388 > #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
389   #endif
390   #endif
391  
392 + // Extract fault address out of a sigcontext
393 + #if (defined(alpha) || defined(__alpha__))
394 + // From Boehm's GC 6.0alpha8
395 + static sigsegv_address_t get_fault_address(struct sigcontext *scp)
396 + {
397 +        unsigned int instruction = *((unsigned int *)(scp->sc_pc));
398 +        unsigned long fault_address = scp->sc_regs[(instruction >> 16) & 0x1f];
399 +        fault_address += (signed long)(signed short)(instruction & 0xffff);
400 +        return (sigsegv_address_t)fault_address;
401 + }
402 + #endif
403 +
404 +
405   // MacOS X, not sure which version this works in. Under 10.1
406   // vm_protect does not appear to work from a signal handler. Under
407   // 10.2 signal handlers get siginfo type arguments but the si_addr
# Line 1192 | Line 1221 | void sigsegv_set_dump_state(sigsegv_stat
1221   #include <sys/mman.h>
1222   #include "vm_alloc.h"
1223  
1224 + const int REF_INDEX = 123;
1225 + const int REF_VALUE = 45;
1226 +
1227   static int page_size;
1228   static volatile char * page = 0;
1229   static volatile int handler_called = 0;
1230  
1231 + #ifdef __GNUC__
1232 + // Code range where we expect the fault to come from
1233 + static void *b_region, *e_region;
1234 + #endif
1235 +
1236   static sigsegv_return_t sigsegv_test_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
1237   {
1238          handler_called++;
1239 <        if ((fault_address - 123) != page)
1239 >        if ((fault_address - REF_INDEX) != page)
1240                  exit(10);
1241 <        if (vm_protect((char *)((unsigned long)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0)
1241 > #ifdef __GNUC__
1242 >        // Make sure reported fault instruction address falls into
1243 >        // expected code range
1244 >        if (instruction_address != SIGSEGV_INVALID_PC
1245 >                && ((instruction_address <  (sigsegv_address_t)b_region) ||
1246 >                        (instruction_address >= (sigsegv_address_t)e_region)))
1247                  exit(11);
1248 + #endif
1249 +        if (vm_protect((char *)((unsigned long)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0)
1250 +                exit(12);
1251          return SIGSEGV_RETURN_SUCCESS;
1252   }
1253  
1254   #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1210 #ifdef __GNUC__
1211 // Code range where we expect the fault to come from
1212 static void *b_region, *e_region;
1213 #endif
1214
1255   static sigsegv_return_t sigsegv_insn_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
1256   {
1257          if (((unsigned long)fault_address - (unsigned long)page) < page_size) {
# Line 1239 | Line 1279 | int main(void)
1279          if ((page = (char *)vm_acquire(page_size)) == VM_MAP_FAILED)
1280                  return 2;
1281          
1282 +        memset((void *)page, 0, page_size);
1283          if (vm_protect((char *)page, page_size, VM_PAGE_READ) < 0)
1284                  return 3;
1285          
1286          if (!sigsegv_install_handler(sigsegv_test_handler))
1287                  return 4;
1288          
1289 <        page[123] = 45;
1290 <        page[123] = 45;
1291 <        
1289 > #ifdef __GNUC__
1290 >        b_region = &&L_b_region1;
1291 >        e_region = &&L_e_region1;
1292 > #endif
1293 > L_b_region1:
1294 >        page[REF_INDEX] = REF_VALUE;
1295 >        if (page[REF_INDEX] != REF_VALUE)
1296 >          exit(20);
1297 >        page[REF_INDEX] = REF_VALUE;
1298 > L_e_region1:
1299 >
1300          if (handler_called != 1)
1301                  return 5;
1302  
# Line 1273 | Line 1322 | int main(void)
1322          } while (0)
1323          
1324   #ifdef __GNUC__
1325 <        b_region = &&L_b_region;
1326 <        e_region = &&L_e_region;
1325 >        b_region = &&L_b_region2;
1326 >        e_region = &&L_e_region2;
1327   #endif
1328 < L_b_region:
1328 > L_b_region2:
1329          TEST_SKIP_INSTRUCTION(unsigned char);
1330          TEST_SKIP_INSTRUCTION(unsigned short);
1331          TEST_SKIP_INSTRUCTION(unsigned int);
1332 < L_e_region:
1332 > L_e_region2:
1333   #endif
1334  
1335          vm_exit();
1336          return 0;
1337   }
1338   #endif
1339 +
1340 +
1341 +
1342 +
1343 +
1344 +
1345 +
1346 +
1347 +
1348 +
1349 +
1350 +
1351 +
1352 +
1353 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines