[libunwind] Handle G in personality string
Tested with the following program:
```
static volatile int* x = nullptr;
void throws() __attribute__((noinline)) {
if (getpid() == 0)
return;
throw "error";
}
void maybe_throws() __attribute__((noinline)) {
volatile int y = 1;
x = &y;
throws();
y = 2;
}
int main(int argc, char** argv) {
int y;
try {
maybe_throws();
} catch (const char* e) {
//printf("Caught\n");
}
y = *x;
printf("%d\n", y); // should be MTE failure.
return 0;
}
```
Built using `clang++ -c -O2 -target aarch64-linux -fexceptions -march=armv8-a+memtag -fsanitize=memtag-heap,memtag-stack`
Currently only Android implements runtime support for MTE stack tagging.
Without this change, we crash on `__cxa_get_globals` when trying to catch
the exception (because the stack frame __cxa_get_globals frame will fail due
to tags left behind on the stack). With this change, we crash on the `y = *x;`
as expected, because the stack frame has been untagged, but the pointer hasn't.
Reviewed By: #libunwind, compnerd, MaskRay
Differential Revision: https://reviews.llvm.org/D128998
NOKEYCHECK=True
GitOrigin-RevId: a3153381af48b2e704750255a704748a13c4c4de
diff --git a/src/UnwindCursor.hpp b/src/UnwindCursor.hpp
index 27eca08..f118497 100644
--- a/src/UnwindCursor.hpp
+++ b/src/UnwindCursor.hpp
@@ -442,7 +442,7 @@
virtual void setFloatReg(int, unw_fpreg_t) {
_LIBUNWIND_ABORT("setFloatReg not implemented");
}
- virtual int step() { _LIBUNWIND_ABORT("step not implemented"); }
+ virtual int step(bool = false) { _LIBUNWIND_ABORT("step not implemented"); }
virtual void getInfo(unw_proc_info_t *) {
_LIBUNWIND_ABORT("getInfo not implemented");
}
@@ -494,7 +494,7 @@
virtual bool validFloatReg(int);
virtual unw_fpreg_t getFloatReg(int);
virtual void setFloatReg(int, unw_fpreg_t);
- virtual int step();
+ virtual int step(bool = false);
virtual void getInfo(unw_proc_info_t *);
virtual void jumpto();
virtual bool isSignalFrame();
@@ -925,7 +925,7 @@
virtual bool validFloatReg(int);
virtual unw_fpreg_t getFloatReg(int);
virtual void setFloatReg(int, unw_fpreg_t);
- virtual int step();
+ virtual int step(bool stage2 = false);
virtual void getInfo(unw_proc_info_t *);
virtual void jumpto();
virtual bool isSignalFrame();
@@ -999,22 +999,21 @@
pint_t pc, uintptr_t dso_base);
bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s,
uint32_t fdeSectionOffsetHint=0);
- int stepWithDwarfFDE() {
- return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace,
- (pint_t)this->getReg(UNW_REG_IP),
- (pint_t)_info.unwind_info,
- _registers, _isSignalFrame);
+ int stepWithDwarfFDE(bool stage2) {
+ return DwarfInstructions<A, R>::stepWithDwarf(
+ _addressSpace, (pint_t)this->getReg(UNW_REG_IP),
+ (pint_t)_info.unwind_info, _registers, _isSignalFrame, stage2);
}
#endif
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
bool getInfoFromCompactEncodingSection(pint_t pc,
const UnwindInfoSections §s);
- int stepWithCompactEncoding() {
- #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
+ int stepWithCompactEncoding(bool stage2 = false) {
+#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
if ( compactSaysUseDwarf() )
- return stepWithDwarfFDE();
- #endif
+ return stepWithDwarfFDE(stage2);
+#endif
R dummy;
return stepWithCompactEncoding(dummy);
}
@@ -2796,8 +2795,8 @@
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
// defined(_LIBUNWIND_TARGET_S390X)
-template <typename A, typename R>
-int UnwindCursor<A, R>::step() {
+template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
+ (void)stage2;
// Bottom of stack is defined is when unwind info cannot be found.
if (_unwindInfoMissing)
return UNW_STEP_END;
@@ -2811,13 +2810,13 @@
#endif
{
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
- result = this->stepWithCompactEncoding();
+ result = this->stepWithCompactEncoding(stage2);
#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
result = this->stepWithSEHData();
#elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
result = this->stepWithTBTableData();
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
- result = this->stepWithDwarfFDE();
+ result = this->stepWithDwarfFDE(stage2);
#elif defined(_LIBUNWIND_ARM_EHABI)
result = this->stepWithEHABI();
#else