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.71 by gbeauche, 2008-01-01T09:40:33Z vs.
Revision 1.74 by gbeauche, 2008-01-06T16:19:27Z

# Line 70 | Line 70 | static bool sigsegv_do_install_handler(i
70   enum transfer_type_t {
71          SIGSEGV_TRANSFER_UNKNOWN        = 0,
72          SIGSEGV_TRANSFER_LOAD           = 1,
73 <        SIGSEGV_TRANSFER_STORE          = 2,
73 >        SIGSEGV_TRANSFER_STORE          = 2
74   };
75  
76   // Transfer size
# Line 79 | Line 79 | enum transfer_size_t {
79          SIZE_BYTE,
80          SIZE_WORD, // 2 bytes
81          SIZE_LONG, // 4 bytes
82 <        SIZE_QUAD, // 8 bytes
82 >        SIZE_QUAD  // 8 bytes
83   };
84  
85   #if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__))
# Line 605 | Line 605 | if (ret != KERN_SUCCESS) { \
605   #define SIGSEGV_EXCEPTION_STATE_TYPE    ppc_exception_state_t
606   #define SIGSEGV_EXCEPTION_STATE_FLAVOR  PPC_EXCEPTION_STATE
607   #define SIGSEGV_EXCEPTION_STATE_COUNT   PPC_EXCEPTION_STATE_COUNT
608 < #define SIGSEGV_FAULT_ADDRESS                   sip->exc_state.dar
608 > #define SIGSEGV_FAULT_ADDRESS                   SIP->exc_state.dar
609   #define SIGSEGV_THREAD_STATE_TYPE               ppc_thread_state_t
610   #define SIGSEGV_THREAD_STATE_FLAVOR             PPC_THREAD_STATE
611   #define SIGSEGV_THREAD_STATE_COUNT              PPC_THREAD_STATE_COUNT
612 < #define SIGSEGV_FAULT_INSTRUCTION               sip->thr_state.srr0
612 > #define SIGSEGV_FAULT_INSTRUCTION               SIP->thr_state.srr0
613   #define SIGSEGV_SKIP_INSTRUCTION                powerpc_skip_instruction
614 < #define SIGSEGV_REGISTER_FILE                   (unsigned long *)&sip->thr_state.srr0, (unsigned long *)&sip->thr_state.r0
614 > #define SIGSEGV_REGISTER_FILE                   (unsigned long *)&SIP->thr_state.srr0, (unsigned long *)&SIP->thr_state.r0
615   #endif
616   #ifdef __ppc64__
617   #define SIGSEGV_EXCEPTION_STATE_TYPE    ppc_exception_state64_t
618   #define SIGSEGV_EXCEPTION_STATE_FLAVOR  PPC_EXCEPTION_STATE64
619   #define SIGSEGV_EXCEPTION_STATE_COUNT   PPC_EXCEPTION_STATE64_COUNT
620 < #define SIGSEGV_FAULT_ADDRESS                   sip->exc_state.dar
620 > #define SIGSEGV_FAULT_ADDRESS                   SIP->exc_state.dar
621   #define SIGSEGV_THREAD_STATE_TYPE               ppc_thread_state64_t
622   #define SIGSEGV_THREAD_STATE_FLAVOR             PPC_THREAD_STATE64
623   #define SIGSEGV_THREAD_STATE_COUNT              PPC_THREAD_STATE64_COUNT
624 < #define SIGSEGV_FAULT_INSTRUCTION               sip->thr_state.srr0
624 > #define SIGSEGV_FAULT_INSTRUCTION               SIP->thr_state.srr0
625   #define SIGSEGV_SKIP_INSTRUCTION                powerpc_skip_instruction
626 < #define SIGSEGV_REGISTER_FILE                   (unsigned long *)&sip->thr_state.srr0, (unsigned long *)&sip->thr_state.r0
626 > #define SIGSEGV_REGISTER_FILE                   (unsigned long *)&SIP->thr_state.srr0, (unsigned long *)&SIP->thr_state.r0
627   #endif
628   #ifdef __i386__
629   #define SIGSEGV_EXCEPTION_STATE_TYPE    struct i386_exception_state
630   #define SIGSEGV_EXCEPTION_STATE_FLAVOR  i386_EXCEPTION_STATE
631   #define SIGSEGV_EXCEPTION_STATE_COUNT   i386_EXCEPTION_STATE_COUNT
632 < #define SIGSEGV_FAULT_ADDRESS                   sip->exc_state.faultvaddr
632 > #define SIGSEGV_FAULT_ADDRESS                   SIP->exc_state.faultvaddr
633   #define SIGSEGV_THREAD_STATE_TYPE               struct i386_thread_state
634   #define SIGSEGV_THREAD_STATE_FLAVOR             i386_THREAD_STATE
635   #define SIGSEGV_THREAD_STATE_COUNT              i386_THREAD_STATE_COUNT
636 < #define SIGSEGV_FAULT_INSTRUCTION               sip->thr_state.eip
636 > #define SIGSEGV_FAULT_INSTRUCTION               SIP->thr_state.eip
637   #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
638 < #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)&sip->thr_state.eax) /* EAX is the first GPR we consider */
638 > #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)&SIP->thr_state.eax) /* EAX is the first GPR we consider */
639   #endif
640   #ifdef __x86_64__
641   #define SIGSEGV_EXCEPTION_STATE_TYPE    struct x86_exception_state64
642   #define SIGSEGV_EXCEPTION_STATE_FLAVOR  x86_EXCEPTION_STATE64
643   #define SIGSEGV_EXCEPTION_STATE_COUNT   x86_EXCEPTION_STATE64_COUNT
644 < #define SIGSEGV_FAULT_ADDRESS                   sip->exc_state.faultvaddr
644 > #define SIGSEGV_FAULT_ADDRESS                   SIP->exc_state.faultvaddr
645   #define SIGSEGV_THREAD_STATE_TYPE               struct x86_thread_state64
646   #define SIGSEGV_THREAD_STATE_FLAVOR             x86_THREAD_STATE64
647   #define SIGSEGV_THREAD_STATE_COUNT              x86_THREAD_STATE64_COUNT
648 < #define SIGSEGV_FAULT_INSTRUCTION               sip->thr_state.rip
648 > #define SIGSEGV_FAULT_INSTRUCTION               SIP->thr_state.rip
649   #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
650 < #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)&sip->thr_state.rax) /* RAX is the first GPR we consider */
650 > #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)&SIP->thr_state.rax) /* RAX is the first GPR we consider */
651   #endif
652   #define SIGSEGV_FAULT_ADDRESS_FAST              code[1]
653   #define SIGSEGV_FAULT_INSTRUCTION_FAST  SIGSEGV_INVALID_ADDRESS
# Line 1677 | Line 1677 | struct sigsegv_info_t {
1677   };
1678  
1679   #ifdef HAVE_MACH_EXCEPTIONS
1680 < static void mach_get_exception_state(sigsegv_info_t *sip)
1680 > static void mach_get_exception_state(sigsegv_info_t *SIP)
1681   {
1682 <        sip->exc_state_count = SIGSEGV_EXCEPTION_STATE_COUNT;
1683 <        kern_return_t krc = thread_get_state(sip->thread,
1682 >        SIP->exc_state_count = SIGSEGV_EXCEPTION_STATE_COUNT;
1683 >        kern_return_t krc = thread_get_state(SIP->thread,
1684                                                                                   SIGSEGV_EXCEPTION_STATE_FLAVOR,
1685 <                                                                                 (natural_t *)&sip->exc_state,
1686 <                                                                                 &sip->exc_state_count);
1685 >                                                                                 (natural_t *)&SIP->exc_state,
1686 >                                                                                 &SIP->exc_state_count);
1687          MACH_CHECK_ERROR(thread_get_state, krc);
1688 <        sip->has_exc_state = true;
1688 >        SIP->has_exc_state = true;
1689   }
1690  
1691 < static void mach_get_thread_state(sigsegv_info_t *sip)
1691 > static void mach_get_thread_state(sigsegv_info_t *SIP)
1692   {
1693 <        sip->thr_state_count = SIGSEGV_THREAD_STATE_COUNT;
1694 <        kern_return_t krc = thread_get_state(sip->thread,
1693 >        SIP->thr_state_count = SIGSEGV_THREAD_STATE_COUNT;
1694 >        kern_return_t krc = thread_get_state(SIP->thread,
1695                                                                                   SIGSEGV_THREAD_STATE_FLAVOR,
1696 <                                                                                 (natural_t *)&sip->thr_state,
1697 <                                                                                 &sip->thr_state_count);
1696 >                                                                                 (natural_t *)&SIP->thr_state,
1697 >                                                                                 &SIP->thr_state_count);
1698          MACH_CHECK_ERROR(thread_get_state, krc);
1699 <        sip->has_thr_state = true;
1699 >        SIP->has_thr_state = true;
1700   }
1701  
1702 < static void mach_set_thread_state(sigsegv_info_t *sip)
1702 > static void mach_set_thread_state(sigsegv_info_t *SIP)
1703   {
1704 <        kern_return_t krc = thread_set_state(sip->thread,
1704 >        kern_return_t krc = thread_set_state(SIP->thread,
1705                                                                                   SIGSEGV_THREAD_STATE_FLAVOR,
1706 <                                                                                 (natural_t *)&sip->thr_state,
1707 <                                                                                 sip->thr_state_count);
1706 >                                                                                 (natural_t *)&SIP->thr_state,
1707 >                                                                                 SIP->thr_state_count);
1708          MACH_CHECK_ERROR(thread_set_state, krc);
1709   }
1710   #endif
1711  
1712   // Return the address of the invalid memory reference
1713 < sigsegv_address_t sigsegv_get_fault_address(sigsegv_info_t *sip)
1713 > sigsegv_address_t sigsegv_get_fault_address(sigsegv_info_t *SIP)
1714   {
1715   #ifdef HAVE_MACH_EXCEPTIONS
1716          static int use_fast_path = -1;
1717 <        if (use_fast_path != 1 && !sip->has_exc_state) {
1718 <                mach_get_exception_state(sip);
1717 >        if (use_fast_path != 1 && !SIP->has_exc_state) {
1718 >                mach_get_exception_state(SIP);
1719  
1720                  sigsegv_address_t addr = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS;
1721                  if (use_fast_path < 0)
1722 <                        use_fast_path = addr == sip->addr;
1723 <                sip->addr = addr;
1722 >                        use_fast_path = addr == SIP->addr;
1723 >                SIP->addr = addr;
1724          }
1725   #endif
1726 <        return sip->addr;
1726 >        return SIP->addr;
1727   }
1728  
1729   // Return the address of the instruction that caused the fault, or
1730   // SIGSEGV_INVALID_ADDRESS if we could not retrieve this information
1731 < sigsegv_address_t sigsegv_get_fault_instruction_address(sigsegv_info_t *sip)
1731 > sigsegv_address_t sigsegv_get_fault_instruction_address(sigsegv_info_t *SIP)
1732   {
1733   #ifdef HAVE_MACH_EXCEPTIONS
1734 <        if (!sip->has_thr_state) {
1735 <                mach_get_thread_state(sip);
1734 >        if (!SIP->has_thr_state) {
1735 >                mach_get_thread_state(SIP);
1736  
1737 <                sip->pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION;
1737 >                SIP->pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION;
1738          }
1739   #endif
1740 <        return sip->pc;
1740 >        return SIP->pc;
1741   }
1742  
1743   // This function handles the badaccess to memory.
1744   // It is called from the signal handler or the exception handler.
1745   static bool handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGLIST_1)
1746   {
1747 <        sigsegv_info_t si;
1748 <        si.addr = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS_FAST;
1749 <        si.pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION_FAST;
1747 >        sigsegv_info_t SI;
1748 >        SI.addr = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS_FAST;
1749 >        SI.pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION_FAST;
1750   #ifdef HAVE_MACH_EXCEPTIONS
1751 <        si.thread = thread;
1752 <        si.has_exc_state = false;
1753 <        si.has_thr_state = false;
1751 >        SI.thread = thread;
1752 >        SI.has_exc_state = false;
1753 >        SI.has_thr_state = false;
1754   #endif
1755 <        sigsegv_info_t * const sip = &si;
1755 >        sigsegv_info_t * const SIP = &SI;
1756  
1757          // Call user's handler and reinstall the global handler, if required
1758 <        switch (SIGSEGV_FAULT_HANDLER_INVOKE(sip)) {
1758 >        switch (SIGSEGV_FAULT_HANDLER_INVOKE(SIP)) {
1759          case SIGSEGV_RETURN_SUCCESS:
1760                  return true;
1761  
# Line 1764 | Line 1764 | static bool handle_badaccess(SIGSEGV_FAU
1764                  // Call the instruction skipper with the register file
1765                  // available
1766   #ifdef HAVE_MACH_EXCEPTIONS
1767 <                if (!sip->has_thr_state)
1768 <                        mach_get_thread_state(sip);
1767 >                if (!SIP->has_thr_state)
1768 >                        mach_get_thread_state(SIP);
1769   #endif
1770                  if (SIGSEGV_SKIP_INSTRUCTION(SIGSEGV_REGISTER_FILE)) {
1771   #ifdef HAVE_MACH_EXCEPTIONS
# Line 1773 | Line 1773 | static bool handle_badaccess(SIGSEGV_FAU
1773                          // is modified off of the stack, in Mach we
1774                          // need to actually call thread_set_state to
1775                          // have the register values updated.
1776 <                        mach_set_thread_state(sip);
1776 >                        mach_set_thread_state(SIP);
1777   #endif
1778                          return true;
1779                  }
# Line 1782 | Line 1782 | static bool handle_badaccess(SIGSEGV_FAU
1782          case SIGSEGV_RETURN_FAILURE:
1783                  // We can't do anything with the fault_address, dump state?
1784                  if (sigsegv_state_dumper != 0)
1785 <                        sigsegv_state_dumper(sip);
1785 >                        sigsegv_state_dumper(SIP);
1786                  break;
1787          }
1788  
# Line 2389 | Line 2389 | int main(void)
2389          
2390          if (!sigsegv_install_handler(sigsegv_test_handler))
2391                  return 4;
2392 <        
2392 >
2393   #ifdef __GNUC__
2394          b_region = &&L_b_region1;
2395          e_region = &&L_e_region1;
2396   #endif
2397 < L_b_region1:
2398 <        page[REF_INDEX] = REF_VALUE;
2399 <        if (page[REF_INDEX] != REF_VALUE)
2400 <          exit(20);
2401 <        page[REF_INDEX] = REF_VALUE;
2402 <        BARRIER();
2403 < L_e_region1:
2397 >        /* This is a really awful hack but otherwise gcc is smart enough
2398 >         * (or bug'ous enough?) to optimize the labels and place them
2399 >         * e.g. at the "main" entry point, which is wrong.
2400 >         */
2401 >        volatile int label_hack = 1;
2402 >        switch (label_hack) {
2403 >        case 1:
2404 >        L_b_region1:
2405 >                page[REF_INDEX] = REF_VALUE;
2406 >                if (page[REF_INDEX] != REF_VALUE)
2407 >                        exit(20);
2408 >                page[REF_INDEX] = REF_VALUE;
2409 >                BARRIER();
2410 >                // fall-through
2411 >        case 2:
2412 >        L_e_region1:
2413 >                BARRIER();
2414 >                break;
2415 >        }
2416  
2417          if (handler_called != 1)
2418                  return 5;
# Line 2431 | Line 2443 | int main(void)
2443          b_region = &&L_b_region2;
2444          e_region = &&L_e_region2;
2445   #endif
2446 < L_b_region2:
2447 <        TEST_SKIP_INSTRUCTION(unsigned char);
2448 <        TEST_SKIP_INSTRUCTION(unsigned short);
2449 <        TEST_SKIP_INSTRUCTION(unsigned int);
2450 <        TEST_SKIP_INSTRUCTION(unsigned long);
2451 <        TEST_SKIP_INSTRUCTION(signed char);
2452 <        TEST_SKIP_INSTRUCTION(signed short);
2453 <        TEST_SKIP_INSTRUCTION(signed int);
2454 <        TEST_SKIP_INSTRUCTION(signed long);
2455 <        BARRIER();
2456 < L_e_region2:
2457 <
2446 >        switch (label_hack) {
2447 >        case 1:
2448 >        L_b_region2:
2449 >                TEST_SKIP_INSTRUCTION(unsigned char);
2450 >                TEST_SKIP_INSTRUCTION(unsigned short);
2451 >                TEST_SKIP_INSTRUCTION(unsigned int);
2452 >                TEST_SKIP_INSTRUCTION(unsigned long);
2453 >                TEST_SKIP_INSTRUCTION(signed char);
2454 >                TEST_SKIP_INSTRUCTION(signed short);
2455 >                TEST_SKIP_INSTRUCTION(signed int);
2456 >                TEST_SKIP_INSTRUCTION(signed long);
2457 >                BARRIER();
2458 >                // fall-through
2459 >        case 2:
2460 >        L_e_region2:
2461 >                BARRIER();
2462 >                break;
2463 >        }
2464          if (!arch_insn_skipper_tests())
2465                  return 20;
2466   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines