libunwind: Fix unw_step() for ARM EHABI.
This commit fixes the unw_step() for ARM EHABI. However, this commit
also changes the implementation details for ARM EHABI.
The first change is that the personality function should call
__gnu_unwind_frame() for default (or de facto) frame unwinding based on
the ARM-defined unwind opcode. The function __gnu_unwind_frame() will
in turn calls unw_step() which actually unwinds the frame.
The second change is that the implementation _Unwind_Backtrace() should
no longer calls unw_step() to unwind the frame; since according to ARM
EHABI, the personality function should unwind the frame for us.
Special thanks to Anton for helpful suggestion on the initial version of
this patch.
llvm-svn: 238560
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 7fab97f364d2e2f0beb7fffa3e42885db72982d5
diff --git a/src/UnwindCursor.hpp b/src/UnwindCursor.hpp
index b4d413f..7703af9 100644
--- a/src/UnwindCursor.hpp
+++ b/src/UnwindCursor.hpp
@@ -440,6 +440,20 @@
#if LIBCXXABI_ARM_EHABI
bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections §s);
+
+ int stepWithEHABI() {
+ size_t len = 0;
+ size_t off = 0;
+ // FIXME: Calling decode_eht_entry() here is violating the libunwind
+ // abstraction layer.
+ const uint32_t *ehtp =
+ decode_eht_entry(reinterpret_cast<const uint32_t *>(_info.unwind_info),
+ &off, &len);
+ if (_Unwind_VRS_Interpret((_Unwind_Context *)this, ehtp, off, len) !=
+ _URC_CONTINUE_UNWIND)
+ return UNW_STEP_END;
+ return UNW_STEP_SUCCESS;
+ }
#endif
#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
@@ -731,7 +745,7 @@
// isSingleWordEHT -- whether the entry is in the index.
unw_word_t personalityRoutine = 0xbadf00d;
bool scope32 = false;
- uintptr_t lsda = 0xbadf00d;
+ uintptr_t lsda;
// If the high bit in the exception handling table entry is set, the entry is
// in compact form (section 6.3 EHABI).
@@ -744,16 +758,19 @@
personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0;
extraWords = 0;
scope32 = false;
+ lsda = isSingleWordEHT ? 0 : (exceptionTableAddr + 4);
break;
case 1:
personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr1;
extraWords = (exceptionTableData & 0x00ff0000) >> 16;
scope32 = false;
+ lsda = exceptionTableAddr + (extraWords + 1) * 4;
break;
case 2:
personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr2;
extraWords = (exceptionTableData & 0x00ff0000) >> 16;
scope32 = true;
+ lsda = exceptionTableAddr + (extraWords + 1) * 4;
break;
default:
_LIBUNWIND_ABORT("unknown personality routine");
@@ -1281,7 +1298,7 @@
#elif _LIBUNWIND_SUPPORT_DWARF_UNWIND
result = this->stepWithDwarfFDE();
#elif LIBCXXABI_ARM_EHABI
- result = UNW_STEP_SUCCESS;
+ result = this->stepWithEHABI();
#else
#error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \
_LIBUNWIND_SUPPORT_DWARF_UNWIND or \