[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
Simon Dardis via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 8 03:53:02 PST 2018
sdardis added a comment.
Ok, I've found my issue. inttypes.h in libcxx include_next's <inttypes.h>, which on my debian linux systems has the include chain <features.h>, <stubs.h>, <sgidefs.h>. <sgidefs.h> "helpfully" provides #defines of the various _ABIXXX macros, which normally the compiler defines depending on the ABI. The include chain for other parts of libunwind differ which means src/UnwindLevel1-gcc-ext.c had a different definition of the stuct unw_context_t, which was the version defined for O32. As GCC and clang laid out the stack differently for each ABI differently the bug was masked. However for N32 at https://reviews.llvm.org/owners/package/3/, the layout was such that the unwind context in the locals area was right below the saved registers for _Unwind_Backtrace which trashed older saved values, then triggered a SIGSEGV on return due to reloading the saved contents of the $lo into $ra in my case.
The fix is fairly simple. Change the ABI #ifdef defined() checks to be:
#ifdef _defined(_ABIO32) && _MIPS_SIM == _ABIO32
for O32 or similar for a single ABI. For N32 and N64 together, it's sufficient to test for the presence of __mips64.
================
Comment at: include/__libunwind_config.h:74
# elif defined(__mips__)
# if defined(_ABIO32) && defined(__mips_soft_float)
# define _LIBUNWIND_TARGET_MIPS_O32 1
----------------
See my comment about the N32 abi check.
================
Comment at: include/__libunwind_config.h:78
# define _LIBUNWIND_CURSOR_SIZE 24
+# elif defined(_ABIN32) && defined(__mips_soft_float)
+# define _LIBUNWIND_TARGET_MIPS_NEWABI 1
----------------
This needs to be:
```
# elif defined(_ABIN32) && _MIPS_SIM == _ABIN32
```
================
Comment at: include/__libunwind_config.h:82
+# define _LIBUNWIND_CURSOR_SIZE 42
# elif defined(_ABI64) && defined(__mips_soft_float)
# define _LIBUNWIND_TARGET_MIPS_NEWABI 1
----------------
Same here.
================
Comment at: src/AddressSpace.hpp:233
+inline uint64_t LocalAddressSpace::getRegister(pint_t addr) {
+#if __SIZEOF_POINTER__ == 8 || (defined(__mips__) && defined(_ABIN32))
+ return get64(addr);
----------------
Change that mips check to defined(__mips64) which covers the target being mips and it being n64 or n32.
================
Comment at: src/UnwindRegistersRestore.S:688
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && \
+ defined(__mips_soft_float)
----------------
Rather checking that the _ABI64 or _ABIN32 are defined, check that __mips64 is defined.
================
Comment at: src/UnwindRegistersSave.S:175
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && \
+ defined(__mips_soft_float)
----------------
See my comment on register restore file.
================
Comment at: src/libunwind.cpp:66
# define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) && \
+ defined(__mips_soft_float)
----------------
Check that __mips64 is defined rather than the specific _ABI macros.
https://reviews.llvm.org/D39074
More information about the cfe-commits
mailing list