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 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 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 *)&state.srr0, (unsigned long *)&state.r0 |
615 |
|
#endif |
616 |
|
#ifdef __i386__ |
617 |
|
#ifdef i386_SAVED_STATE |
618 |
|
#define SIGSEGV_THREAD_STATE_TYPE struct i386_saved_state |
619 |
|
#define SIGSEGV_THREAD_STATE_FLAVOR i386_SAVED_STATE |
620 |
|
#define SIGSEGV_THREAD_STATE_COUNT i386_SAVED_STATE_COUNT |
621 |
< |
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state->edi) /* EDI is the first GPR we consider */ |
621 |
> |
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state.edi) /* EDI is the first GPR we consider */ |
622 |
|
#else |
623 |
+ |
#define SIGSEGV_EXCEPTION_STATE_TYPE struct i386_exception_state |
624 |
+ |
#define SIGSEGV_EXCEPTION_STATE_FLAVOR i386_EXCEPTION_STATE |
625 |
+ |
#define SIGSEGV_EXCEPTION_STATE_COUNT i386_EXCEPTION_STATE_COUNT |
626 |
+ |
#define SIGSEGV_FAULT_ADDRESS exc_state->faultvaddr |
627 |
|
#define SIGSEGV_THREAD_STATE_TYPE struct i386_thread_state |
628 |
|
#define SIGSEGV_THREAD_STATE_FLAVOR i386_THREAD_STATE |
629 |
|
#define SIGSEGV_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT |
630 |
< |
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state->eax) /* EAX is the first GPR we consider */ |
630 |
> |
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state.eax) /* EAX is the first GPR we consider */ |
631 |
|
#endif |
632 |
< |
#define SIGSEGV_FAULT_INSTRUCTION state->eip |
632 |
> |
#define SIGSEGV_FAULT_INSTRUCTION state.eip |
633 |
|
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction |
634 |
|
#endif |
635 |
+ |
#ifdef __x86_64__ |
636 |
+ |
#define SIGSEGV_EXCEPTION_STATE_TYPE struct x86_exception_state64 |
637 |
+ |
#define SIGSEGV_EXCEPTION_STATE_FLAVOR x86_EXCEPTION_STATE64 |
638 |
+ |
#define SIGSEGV_EXCEPTION_STATE_COUNT x86_EXCEPTION_STATE64_COUNT |
639 |
+ |
#define SIGSEGV_FAULT_ADDRESS exc_state->faultvaddr |
640 |
+ |
#define SIGSEGV_THREAD_STATE_TYPE struct x86_thread_state64 |
641 |
+ |
#define SIGSEGV_THREAD_STATE_FLAVOR x86_THREAD_STATE64 |
642 |
+ |
#define SIGSEGV_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT |
643 |
+ |
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state.rax) /* RAX is the first GPR we consider */ |
644 |
+ |
#define SIGSEGV_FAULT_INSTRUCTION state.rip |
645 |
+ |
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction |
646 |
+ |
#endif |
647 |
+ |
#ifdef SIGSEGV_EXCEPTION_STATE_TYPE |
648 |
+ |
#define SIGSEGV_FAULT_HANDLER_ARGLIST mach_port_t thread, SIGSEGV_EXCEPTION_STATE_TYPE *exc_state |
649 |
+ |
#define SIGSEGV_FAULT_HANDLER_ARGS thread, &exc_state |
650 |
+ |
#else |
651 |
|
#define SIGSEGV_FAULT_ADDRESS code[1] |
652 |
< |
#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) |
653 |
< |
#define SIGSEGV_FAULT_HANDLER_ARGLIST mach_port_t thread, exception_data_t code, SIGSEGV_THREAD_STATE_TYPE *state |
654 |
< |
#define SIGSEGV_FAULT_HANDLER_ARGS thread, code, &state |
652 |
> |
#define SIGSEGV_FAULT_HANDLER_ARGLIST mach_port_t thread, exception_data_t code |
653 |
> |
#define SIGSEGV_FAULT_HANDLER_ARGS thread, code |
654 |
> |
#endif |
655 |
|
|
656 |
|
// Since there can only be one exception thread running at any time |
657 |
|
// this is not a problem. |
809 |
|
#endif |
810 |
|
#if defined(__APPLE__) && defined(__MACH__) |
811 |
|
enum { |
812 |
+ |
#if (defined(i386) || defined(__i386__)) |
813 |
|
#ifdef i386_SAVED_STATE |
814 |
|
// same as FreeBSD (in Open Darwin 8.0.1) |
815 |
|
X86_REG_EIP = 10, |
826 |
|
X86_REG_EIP = 10, |
827 |
|
X86_REG_EAX = 0, |
828 |
|
X86_REG_ECX = 2, |
829 |
< |
X86_REG_EDX = 4, |
829 |
> |
X86_REG_EDX = 3, |
830 |
|
X86_REG_EBX = 1, |
831 |
|
X86_REG_ESP = 7, |
832 |
|
X86_REG_EBP = 6, |
833 |
|
X86_REG_ESI = 5, |
834 |
|
X86_REG_EDI = 4 |
835 |
|
#endif |
836 |
+ |
#endif |
837 |
+ |
#if defined(__x86_64__) |
838 |
+ |
X86_REG_R8 = 8, |
839 |
+ |
X86_REG_R9 = 9, |
840 |
+ |
X86_REG_R10 = 10, |
841 |
+ |
X86_REG_R11 = 11, |
842 |
+ |
X86_REG_R12 = 12, |
843 |
+ |
X86_REG_R13 = 13, |
844 |
+ |
X86_REG_R14 = 14, |
845 |
+ |
X86_REG_R15 = 15, |
846 |
+ |
X86_REG_EDI = 4, |
847 |
+ |
X86_REG_ESI = 5, |
848 |
+ |
X86_REG_EBP = 6, |
849 |
+ |
X86_REG_EBX = 1, |
850 |
+ |
X86_REG_EDX = 3, |
851 |
+ |
X86_REG_EAX = 0, |
852 |
+ |
X86_REG_ECX = 2, |
853 |
+ |
X86_REG_ESP = 7, |
854 |
+ |
X86_REG_EIP = 16 |
855 |
+ |
#endif |
856 |
|
}; |
857 |
|
#endif |
858 |
|
#if defined(_WIN32) |
1663 |
|
// We must match the initial count when writing back the CPU state registers |
1664 |
|
kern_return_t krc; |
1665 |
|
mach_msg_type_number_t count; |
1666 |
+ |
SIGSEGV_THREAD_STATE_TYPE state; |
1667 |
|
|
1668 |
|
count = SIGSEGV_THREAD_STATE_COUNT; |
1669 |
< |
krc = thread_get_state(thread, SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)state, &count); |
1669 |
> |
krc = thread_get_state(thread, SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)&state, &count); |
1670 |
|
MACH_CHECK_ERROR (thread_get_state, krc); |
1671 |
|
#endif |
1672 |
|
|
1689 |
|
// need to actually call thread_set_state to |
1690 |
|
// have the register values updated. |
1691 |
|
krc = thread_set_state(thread, |
1692 |
< |
SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)state, |
1692 |
> |
SIGSEGV_THREAD_STATE_FLAVOR, (thread_state_t)&state, |
1693 |
|
count); |
1694 |
|
MACH_CHECK_ERROR (thread_set_state, krc); |
1695 |
|
#endif |
1841 |
|
mach_port_t task, |
1842 |
|
exception_type_t exception, |
1843 |
|
exception_data_t code, |
1844 |
< |
mach_msg_type_number_t codeCount) |
1844 |
> |
mach_msg_type_number_t code_count) |
1845 |
|
{ |
1800 |
– |
SIGSEGV_THREAD_STATE_TYPE state; |
1846 |
|
kern_return_t krc; |
1847 |
|
|
1848 |
< |
if ((exception == EXC_BAD_ACCESS) && (codeCount >= 2)) { |
1849 |
< |
if (handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGS)) |
1850 |
< |
return KERN_SUCCESS; |
1848 |
> |
if (exception == EXC_BAD_ACCESS) { |
1849 |
> |
switch (code[0]) { |
1850 |
> |
case KERN_PROTECTION_FAILURE: |
1851 |
> |
case KERN_INVALID_ADDRESS: |
1852 |
> |
{ |
1853 |
> |
#ifdef SIGSEGV_EXCEPTION_STATE_TYPE |
1854 |
> |
SIGSEGV_EXCEPTION_STATE_TYPE exc_state; |
1855 |
> |
mach_msg_type_number_t exc_state_count; |
1856 |
> |
exc_state_count = SIGSEGV_EXCEPTION_STATE_COUNT; |
1857 |
> |
krc = thread_get_state(thread, SIGSEGV_EXCEPTION_STATE_FLAVOR, (natural_t *)&exc_state, &exc_state_count); |
1858 |
> |
MACH_CHECK_ERROR (thread_get_state, krc); |
1859 |
> |
#endif |
1860 |
> |
|
1861 |
> |
if (handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGS)) |
1862 |
> |
return KERN_SUCCESS; |
1863 |
> |
break; |
1864 |
> |
} |
1865 |
> |
} |
1866 |
|
} |
1867 |
|
|
1868 |
|
// In Mach we do not need to remove the exception handler. |
1869 |
|
// If we forward the exception, eventually some exception handler |
1870 |
|
// will take care of this exception. |
1871 |
< |
krc = forward_exception(thread, task, exception, code, codeCount, &ports); |
1871 |
> |
krc = forward_exception(thread, task, exception, code, code_count, &ports); |
1872 |
|
|
1873 |
|
return krc; |
1874 |
|
} |