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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits