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 |
< |
sip->exc_state_count = SIGSEGV_EXCEPTION_STATE_COUNT; |
1686 |
< |
kern_return_t krc = thread_get_state(sip->thread, |
1687 |
< |
SIGSEGV_EXCEPTION_STATE_FLAVOR, |
1688 |
< |
(natural_t *)&sip->exc_state, |
1689 |
< |
&sip->exc_state_count); |
1690 |
< |
MACH_CHECK_ERROR(thread_get_state, krc); |
1691 |
< |
sip->has_exc_state = true; |
1718 |
> |
mach_get_exception_state(sip); |
1719 |
|
|
1720 |
|
sigsegv_address_t addr = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS; |
1721 |
|
if (use_fast_path < 0) |
1732 |
|
{ |
1733 |
|
#ifdef HAVE_MACH_EXCEPTIONS |
1734 |
|
if (!sip->has_thr_state) { |
1735 |
< |
sip->thr_state_count = SIGSEGV_THREAD_STATE_COUNT; |
1709 |
< |
kern_return_t krc = thread_get_state(sip->thread, |
1710 |
< |
SIGSEGV_THREAD_STATE_FLAVOR, |
1711 |
< |
(natural_t *)&sip->thr_state, |
1712 |
< |
&sip->thr_state_count); |
1713 |
< |
MACH_CHECK_ERROR(thread_get_state, krc); |
1714 |
< |
sip->has_thr_state = true; |
1735 |
> |
mach_get_thread_state(sip); |
1736 |
|
|
1737 |
|
sip->pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION; |
1738 |
|
} |
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 |
< |
kern_return_t krc = thread_set_state(sip->thread, |
1752 |
< |
SIGSEGV_THREAD_STATE_FLAVOR, |
1753 |
< |
(natural_t *)&sip->thr_state, |
1754 |
< |
sip->thr_state_count); |
1755 |
< |
MACH_CHECK_ERROR(thread_set_state, krc); |
1776 |
> |
mach_set_thread_state(sip); |
1777 |
|
#endif |
1778 |
|
return true; |
1779 |
|
} |