Changeset View
Changeset View
Standalone View
Standalone View
src/UnwindLevel1.c
Show First 20 Lines • Show All 486 Lines • ▼ Show 20 Lines | |||||
/// Called by personality handler during phase 2 to get instruction pointer. | /// Called by personality handler during phase 2 to get instruction pointer. | ||||
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { | _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { | ||||
unw_cursor_t *cursor = (unw_cursor_t *)context; | unw_cursor_t *cursor = (unw_cursor_t *)context; | ||||
unw_word_t result; | unw_word_t result; | ||||
unw_get_reg(cursor, UNW_REG_IP, &result); | unw_get_reg(cursor, UNW_REG_IP, &result); | ||||
_LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR, | _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR, | ||||
(void *)context, result); | (void *)context, result); | ||||
return (uintptr_t)result; | return (uintptr_t)__builtin_extract_return_addr((void*)result); | ||||
mstorsjo: How widely is this builtin available, e.g. on older versions of clang or in gcc? | |||||
dcedermanAuthorUnsubmitted Looks like it has been available since 1997 for GCC and 2009 for Clang. But looking into it I think it would be better to follow the same approach as aarch64 and modify the return address in stepWithDwarf instead, without using the builtin. That would also allow for better handling of functions that returns structs. dcederman: Looks like it has been available since 1997 for GCC and 2009 for Clang. But looking into it I… | |||||
} | } | ||||
/// Called by personality handler during phase 2 to alter instruction pointer, | /// Called by personality handler during phase 2 to alter instruction pointer, | ||||
/// such as setting where the landing pad is, so _Unwind_Resume() will | /// such as setting where the landing pad is, so _Unwind_Resume() will | ||||
/// start executing in the landing pad. | /// start executing in the landing pad. | ||||
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, | _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, | ||||
uintptr_t value) { | uintptr_t value) { | ||||
_LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIxPTR ")", | _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIxPTR ")", | ||||
(void *)context, value); | (void *)context, value); | ||||
unw_cursor_t *cursor = (unw_cursor_t *)context; | unw_cursor_t *cursor = (unw_cursor_t *)context; | ||||
unw_set_reg(cursor, UNW_REG_IP, value); | unw_set_reg(cursor, UNW_REG_IP, value); | ||||
} | } | ||||
#endif // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) | #endif // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) |
How widely is this builtin available, e.g. on older versions of clang or in gcc?