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.55 by gbeauche, 2005-03-23T22:00:06Z vs.
Revision 1.56 by gbeauche, 2005-06-12T21:47:46Z

# Line 590 | Line 590 | if (ret != KERN_SUCCESS) { \
590          exit (1); \
591   }
592  
593 + #ifdef __ppc__
594 + #define SIGSEGV_THREAD_STATE_TYPE               ppc_thread_state_t
595 + #define SIGSEGV_THREAD_STATE_FLAVOR             PPC_THREAD_STATE
596 + #define SIGSEGV_THREAD_STATE_COUNT              PPC_THREAD_STATE_COUNT
597 + #define SIGSEGV_FAULT_INSTRUCTION               state->srr0
598 + #define SIGSEGV_SKIP_INSTRUCTION                powerpc_skip_instruction
599 + #define SIGSEGV_REGISTER_FILE                   (unsigned long *)&state->srr0, (unsigned long *)&state->r0
600 + #endif
601 + #ifdef __i386__
602 + #define SIGSEGV_THREAD_STATE_TYPE               struct i386_saved_state
603 + #define SIGSEGV_THREAD_STATE_FLAVOR             i386_SAVED_STATE
604 + #define SIGSEGV_THREAD_STATE_COUNT              i386_SAVED_STATE_COUNT
605 + #define SIGSEGV_FAULT_INSTRUCTION               state->eip
606 + #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
607 + #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)&state->edi) /* EDI is the first GPR we consider */
608 + #endif
609   #define SIGSEGV_FAULT_ADDRESS                   code[1]
594 #define SIGSEGV_FAULT_INSTRUCTION               get_fault_instruction(thread, state)
610   #define SIGSEGV_FAULT_HANDLER_INVOKE(ADDR, IP)  ((code[0] == KERN_PROTECTION_FAILURE) ? sigsegv_fault_handler(ADDR, IP) : SIGSEGV_RETURN_FAILURE)
611 < #define SIGSEGV_FAULT_HANDLER_ARGLIST   mach_port_t thread, exception_data_t code, ppc_thread_state_t *state
611 > #define SIGSEGV_FAULT_HANDLER_ARGLIST   mach_port_t thread, exception_data_t code, SIGSEGV_THREAD_STATE_TYPE *state
612   #define SIGSEGV_FAULT_HANDLER_ARGS              thread, code, &state
598 #define SIGSEGV_SKIP_INSTRUCTION                powerpc_skip_instruction
599 #define SIGSEGV_REGISTER_FILE                   &state->srr0, &state->r0
600
601 // Given a suspended thread, stuff the current instruction and
602 // registers into state.
603 //
604 // It would have been nice to have this be ppc/x86 independant which
605 // could have been done easily with a thread_state_t instead of
606 // ppc_thread_state_t, but because of the way this is called it is
607 // easier to do it this way.
608 #if (defined(ppc) || defined(__ppc__))
609 static inline sigsegv_address_t get_fault_instruction(mach_port_t thread, ppc_thread_state_t *state)
610 {
611        kern_return_t krc;
612        mach_msg_type_number_t count;
613
614        count = MACHINE_THREAD_STATE_COUNT;
615        krc = thread_get_state(thread, MACHINE_THREAD_STATE, (thread_state_t)state, &count);
616        MACH_CHECK_ERROR (thread_get_state, krc);
617
618        return (sigsegv_address_t)state->srr0;
619 }
620 #endif
613  
614   // Since there can only be one exception thread running at any time
615   // this is not a problem.
# Line 773 | Line 765 | enum {
765   #endif
766   };
767   #endif
768 + #if defined(__APPLE__) && defined(__MACH__)
769 + // expected to be the same as FreeBSD
770 + enum {
771 +        X86_REG_EIP = 10,
772 +        X86_REG_EAX = 7,
773 +        X86_REG_ECX = 6,
774 +        X86_REG_EDX = 5,
775 +        X86_REG_EBX = 4,
776 +        X86_REG_ESP = 13,
777 +        X86_REG_EBP = 2,
778 +        X86_REG_ESI = 1,
779 +        X86_REG_EDI = 0
780 + };
781 + #endif
782   #if defined(_WIN32)
783   enum {
784   #if (defined(i386) || defined(__i386__))
# Line 1562 | Line 1568 | static bool arm_skip_instruction(unsigne
1568   // It is called from the signal handler or the exception handler.
1569   static bool handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGLIST_1)
1570   {
1571 + #ifdef HAVE_MACH_EXCEPTIONS
1572 +        // We must match the initial count when writing back the CPU state registers
1573 +        kern_return_t krc;
1574 +        mach_msg_type_number_t count;
1575 +
1576 +        count = SIGSEGV_THREAD_STATE_COUNT;
1577 +        krc = thread_get_state(thread, SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)state, &count);
1578 +        MACH_CHECK_ERROR (thread_get_state, krc);
1579 + #endif
1580 +
1581          sigsegv_address_t fault_address = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS;
1582          sigsegv_address_t fault_instruction = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION;
1583          
# Line 1580 | Line 1596 | static bool handle_badaccess(SIGSEGV_FAU
1596                          // is modified off of the stack, in Mach we
1597                          // need to actually call thread_set_state to
1598                          // have the register values updated.
1583                        kern_return_t krc;
1584
1599                          krc = thread_set_state(thread,
1600 <                                                                   MACHINE_THREAD_STATE, (thread_state_t)state,
1601 <                                                                   MACHINE_THREAD_STATE_COUNT);
1602 <                        MACH_CHECK_ERROR (thread_get_state, krc);
1600 >                                                                   SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)state,
1601 >                                                                   count);
1602 >                        MACH_CHECK_ERROR (thread_set_state, krc);
1603   #endif
1604                          return true;
1605                  }
# Line 1731 | Line 1745 | catch_exception_raise(mach_port_t except
1745                                            exception_data_t code,
1746                                            mach_msg_type_number_t codeCount)
1747   {
1748 <        ppc_thread_state_t state;
1748 >        SIGSEGV_THREAD_STATE_TYPE state;
1749          kern_return_t krc;
1750  
1751          if ((exception == EXC_BAD_ACCESS)  && (codeCount >= 2)) {
# Line 1870 | Line 1884 | static bool sigsegv_do_install_handler(s
1884          // addressing modes) used in PPC instructions, you will need the
1885          // GPR state anyway.
1886          krc = thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, _exceptionPort,
1887 <                                EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
1887 >                                EXCEPTION_DEFAULT, SIGSEGV_THREAD_STATE_FLAVOR);
1888          if (krc != KERN_SUCCESS) {
1889                  mach_error("thread_set_exception_ports", krc);
1890                  return false;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines