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.65 by gbeauche, 2007-06-05T13:15:57Z vs.
Revision 1.74 by gbeauche, 2008-01-06T16:19:27Z

# Line 10 | Line 10
10   *    tjw@omnigroup.com Sun, 4 Jun 2000
11   *    www.omnigroup.com/mailman/archive/macosx-dev/2000-June/002030.html
12   *
13 < *  Basilisk II (C) 1997-2005 Christian Bauer
13 > *  Basilisk II (C) 1997-2008 Christian Bauer
14   *
15   *  This program is free software; you can redistribute it and/or modify
16   *  it under the terms of the GNU General Public License as published by
# 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__))
85 > #if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__))
86   // Addressing mode
87   enum addressing_mode_t {
88          MODE_UNKNOWN,
# Line 602 | Line 602 | if (ret != KERN_SUCCESS) { \
602   }
603  
604   #ifdef __ppc__
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
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               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 *)&state->srr0, (unsigned long *)&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
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
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
627   #endif
628   #ifdef __i386__
629 < #ifdef i386_SAVED_STATE
630 < #define SIGSEGV_THREAD_STATE_TYPE               struct i386_saved_state
631 < #define SIGSEGV_THREAD_STATE_FLAVOR             i386_SAVED_STATE
632 < #define SIGSEGV_THREAD_STATE_COUNT              i386_SAVED_STATE_COUNT
617 < #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)&state->edi) /* EDI is the first GPR we consider */
618 < #else
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
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_REGISTER_FILE                   ((unsigned long *)&state->eax) /* EAX is the first GPR we consider */
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 */
639   #endif
640 < #define SIGSEGV_FAULT_INSTRUCTION               state->eip
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
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
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 */
651   #endif
652 < #define SIGSEGV_FAULT_ADDRESS                   code[1]
653 < #define SIGSEGV_FAULT_HANDLER_INVOKE(ADDR, IP)  ((code[0] == KERN_PROTECTION_FAILURE || code[0] == KERN_INVALID_ADDRESS) ? sigsegv_fault_handler(ADDR, IP) : SIGSEGV_RETURN_FAILURE)
654 < #define SIGSEGV_FAULT_HANDLER_ARGLIST   mach_port_t thread, exception_data_t code, SIGSEGV_THREAD_STATE_TYPE *state
655 < #define SIGSEGV_FAULT_HANDLER_ARGS              thread, code, &state
652 > #define SIGSEGV_FAULT_ADDRESS_FAST              code[1]
653 > #define SIGSEGV_FAULT_INSTRUCTION_FAST  SIGSEGV_INVALID_ADDRESS
654 > #define SIGSEGV_FAULT_HANDLER_ARGLIST   mach_port_t thread, exception_data_t code
655 > #define SIGSEGV_FAULT_HANDLER_ARGS              thread, code
656  
657   // Since there can only be one exception thread running at any time
658   // this is not a problem.
# Line 785 | Line 810 | enum {
810   #endif
811   #if defined(__APPLE__) && defined(__MACH__)
812   enum {
813 + #if (defined(i386) || defined(__i386__))
814   #ifdef i386_SAVED_STATE
815          // same as FreeBSD (in Open Darwin 8.0.1)
816          X86_REG_EIP = 10,
# Line 801 | Line 827 | enum {
827          X86_REG_EIP = 10,
828          X86_REG_EAX = 0,
829          X86_REG_ECX = 2,
830 <        X86_REG_EDX = 4,
830 >        X86_REG_EDX = 3,
831          X86_REG_EBX = 1,
832          X86_REG_ESP = 7,
833          X86_REG_EBP = 6,
834          X86_REG_ESI = 5,
835          X86_REG_EDI = 4
836   #endif
837 + #endif
838 + #if defined(__x86_64__)
839 +        X86_REG_R8  = 8,
840 +        X86_REG_R9  = 9,
841 +        X86_REG_R10 = 10,
842 +        X86_REG_R11 = 11,
843 +        X86_REG_R12 = 12,
844 +        X86_REG_R13 = 13,
845 +        X86_REG_R14 = 14,
846 +        X86_REG_R15 = 15,
847 +        X86_REG_EDI = 4,
848 +        X86_REG_ESI = 5,
849 +        X86_REG_EBP = 6,
850 +        X86_REG_EBX = 1,
851 +        X86_REG_EDX = 3,
852 +        X86_REG_EAX = 0,
853 +        X86_REG_ECX = 2,
854 +        X86_REG_ESP = 7,
855 +        X86_REG_EIP = 16
856 + #endif
857   };
858   #endif
859   #if defined(_WIN32)
# Line 1115 | Line 1161 | static bool ix86_skip_instruction(unsign
1161   #endif
1162  
1163   // Decode and skip PPC instruction
1164 < #if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__))
1164 > #if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__))
1165   static bool powerpc_skip_instruction(unsigned long * nip_p, unsigned long * regs)
1166   {
1167          instruction_t instr;
# Line 1590 | Line 1636 | static bool arm_skip_instruction(unsigne
1636  
1637  
1638   // Fallbacks
1639 + #ifndef SIGSEGV_FAULT_ADDRESS_FAST
1640 + #define SIGSEGV_FAULT_ADDRESS_FAST              SIGSEGV_FAULT_ADDRESS
1641 + #endif
1642 + #ifndef SIGSEGV_FAULT_INSTRUCTION_FAST
1643 + #define SIGSEGV_FAULT_INSTRUCTION_FAST  SIGSEGV_FAULT_INSTRUCTION
1644 + #endif
1645   #ifndef SIGSEGV_FAULT_INSTRUCTION
1646 < #define SIGSEGV_FAULT_INSTRUCTION               SIGSEGV_INVALID_PC
1646 > #define SIGSEGV_FAULT_INSTRUCTION               SIGSEGV_INVALID_ADDRESS
1647   #endif
1648   #ifndef SIGSEGV_FAULT_HANDLER_ARGLIST_1
1649   #define SIGSEGV_FAULT_HANDLER_ARGLIST_1 SIGSEGV_FAULT_HANDLER_ARGLIST
1650   #endif
1651   #ifndef SIGSEGV_FAULT_HANDLER_INVOKE
1652 < #define SIGSEGV_FAULT_HANDLER_INVOKE(ADDR, IP)  sigsegv_fault_handler(ADDR, IP)
1652 > #define SIGSEGV_FAULT_HANDLER_INVOKE(P) sigsegv_fault_handler(P)
1653   #endif
1654  
1655   // SIGSEGV recovery supported ?
# Line 1610 | Line 1662 | static bool arm_skip_instruction(unsigne
1662   *  SIGSEGV global handler
1663   */
1664  
1665 + struct sigsegv_info_t {
1666 +        sigsegv_address_t addr;
1667 +        sigsegv_address_t pc;
1668 + #ifdef HAVE_MACH_EXCEPTIONS
1669 +        mach_port_t thread;
1670 +        bool has_exc_state;
1671 +        SIGSEGV_EXCEPTION_STATE_TYPE exc_state;
1672 +        mach_msg_type_number_t exc_state_count;
1673 +        bool has_thr_state;
1674 +        SIGSEGV_THREAD_STATE_TYPE thr_state;
1675 +        mach_msg_type_number_t thr_state_count;
1676 + #endif
1677 + };
1678 +
1679 + #ifdef HAVE_MACH_EXCEPTIONS
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,
1684 +                                                                                 SIGSEGV_EXCEPTION_STATE_FLAVOR,
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;
1689 + }
1690 +
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,
1695 +                                                                                 SIGSEGV_THREAD_STATE_FLAVOR,
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;
1700 + }
1701 +
1702 + static void mach_set_thread_state(sigsegv_info_t *SIP)
1703 + {
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);
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)
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);
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;
1724 +        }
1725 + #endif
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)
1732 + {
1733 + #ifdef HAVE_MACH_EXCEPTIONS
1734 +        if (!SIP->has_thr_state) {
1735 +                mach_get_thread_state(SIP);
1736 +
1737 +                SIP->pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION;
1738 +        }
1739 + #endif
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;
1750   #ifdef HAVE_MACH_EXCEPTIONS
1751 <        // We must match the initial count when writing back the CPU state registers
1752 <        kern_return_t krc;
1753 <        mach_msg_type_number_t count;
1621 <
1622 <        count = SIGSEGV_THREAD_STATE_COUNT;
1623 <        krc = thread_get_state(thread, SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)state, &count);
1624 <        MACH_CHECK_ERROR (thread_get_state, krc);
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;
1756  
1627        sigsegv_address_t fault_address = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS;
1628        sigsegv_address_t fault_instruction = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION;
1629        
1757          // Call user's handler and reinstall the global handler, if required
1758 <        switch (SIGSEGV_FAULT_HANDLER_INVOKE(fault_address, fault_instruction)) {
1758 >        switch (SIGSEGV_FAULT_HANDLER_INVOKE(SIP)) {
1759          case SIGSEGV_RETURN_SUCCESS:
1760                  return true;
1761  
# Line 1636 | Line 1763 | static bool handle_badaccess(SIGSEGV_FAU
1763          case SIGSEGV_RETURN_SKIP_INSTRUCTION:
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);
1769 + #endif
1770                  if (SIGSEGV_SKIP_INSTRUCTION(SIGSEGV_REGISTER_FILE)) {
1771   #ifdef HAVE_MACH_EXCEPTIONS
1772                          // Unlike UNIX signals where the thread state
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 <                        krc = thread_set_state(thread,
1646 <                                                                   SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)state,
1647 <                                                                   count);
1648 <                        MACH_CHECK_ERROR (thread_set_state, krc);
1776 >                        mach_set_thread_state(SIP);
1777   #endif
1778                          return true;
1779                  }
# Line 1654 | 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(fault_address, fault_instruction);
1785 >                        sigsegv_state_dumper(SIP);
1786                  break;
1787          }
1788  
# Line 1795 | Line 1923 | catch_exception_raise(mach_port_t except
1923                                            mach_port_t task,
1924                                            exception_type_t exception,
1925                                            exception_data_t code,
1926 <                                          mach_msg_type_number_t codeCount)
1926 >                                          mach_msg_type_number_t code_count)
1927   {
1800        SIGSEGV_THREAD_STATE_TYPE state;
1928          kern_return_t krc;
1929  
1930 <        if ((exception == EXC_BAD_ACCESS)  && (codeCount >= 2)) {
1931 <                if (handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGS))
1932 <                        return KERN_SUCCESS;
1930 >        if (exception == EXC_BAD_ACCESS) {
1931 >                switch (code[0]) {
1932 >                case KERN_PROTECTION_FAILURE:
1933 >                case KERN_INVALID_ADDRESS:
1934 >                        if (handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGS))
1935 >                                return KERN_SUCCESS;
1936 >                        break;
1937 >                }
1938          }
1939  
1940          // In Mach we do not need to remove the exception handler.
1941          // If we forward the exception, eventually some exception handler
1942          // will take care of this exception.
1943 <        krc = forward_exception(thread, task, exception, code, codeCount, &ports);
1943 >        krc = forward_exception(thread, task, exception, code, code_count, &ports);
1944  
1945          return krc;
1946   }
# Line 2132 | Line 2264 | static volatile int handler_called = 0;
2264   static void *b_region, *e_region;
2265   #endif
2266  
2267 < static sigsegv_return_t sigsegv_test_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
2267 > static sigsegv_return_t sigsegv_test_handler(sigsegv_info_t *sip)
2268   {
2269 +        const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip);
2270 +        const sigsegv_address_t instruction_address = sigsegv_get_fault_instruction_address(sip);
2271   #if DEBUG
2272          printf("sigsegv_test_handler(%p, %p)\n", fault_address, instruction_address);
2273          printf("expected fault at %p\n", page + REF_INDEX);
# Line 2147 | Line 2281 | static sigsegv_return_t sigsegv_test_han
2281   #ifdef __GNUC__
2282          // Make sure reported fault instruction address falls into
2283          // expected code range
2284 <        if (instruction_address != SIGSEGV_INVALID_PC
2284 >        if (instruction_address != SIGSEGV_INVALID_ADDRESS
2285                  && ((instruction_address <  (sigsegv_address_t)b_region) ||
2286                          (instruction_address >= (sigsegv_address_t)e_region)))
2287                  exit(11);
# Line 2158 | Line 2292 | static sigsegv_return_t sigsegv_test_han
2292   }
2293  
2294   #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
2295 < static sigsegv_return_t sigsegv_insn_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
2295 > static sigsegv_return_t sigsegv_insn_handler(sigsegv_info_t *sip)
2296   {
2297 +        const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip);
2298 +        const sigsegv_address_t instruction_address = sigsegv_get_fault_instruction_address(sip);
2299   #if DEBUG
2300          printf("sigsegv_insn_handler(%p, %p)\n", fault_address, instruction_address);
2301   #endif
# Line 2167 | Line 2303 | static sigsegv_return_t sigsegv_insn_han
2303   #ifdef __GNUC__
2304                  // Make sure reported fault instruction address falls into
2305                  // expected code range
2306 <                if (instruction_address != SIGSEGV_INVALID_PC
2306 >                if (instruction_address != SIGSEGV_INVALID_ADDRESS
2307                          && ((instruction_address <  (sigsegv_address_t)b_region) ||
2308                                  (instruction_address >= (sigsegv_address_t)e_region)))
2309                          return SIGSEGV_RETURN_FAILURE;
# Line 2253 | 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 2295 | 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