[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
This revision was automatically updated to reflect the committed changes. Closed by commit rUNW326250: [libunwind][MIPS]: Add support for unwinding in N32 processes. (authored by jhb, committed by ). Changed prior to commit: https://reviews.llvm.org/D39074?vs=133660&id=136144#toc Repository: rUNW libunwind https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -799,7 +799,8 @@ l.jr r9 l.nop -#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \ +defined(__mips_soft_float) // // void libunwind::Registers_mips_o32::jumpto() @@ -855,7 +856,7 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips64) && defined(__mips_soft_float) // // void libunwind::Registers_mips_newabi::jumpto() Index: src/AddressSpace.hpp === --- src/AddressSpace.hpp +++ src/AddressSpace.hpp @@ -207,6 +207,7 @@ return val; } uintptr_t getP(pint_t addr); + uint64_tgetRegister(pint_t addr); static uint64_t getULEB128(pint_t &addr, pint_t end); static int64_t getSLEB128(pint_t &addr, pint_t end); @@ -228,6 +229,14 @@ #endif } +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if __SIZEOF_POINTER__ == 8 || defined(__mips64) + return get64(addr); +#else + return get32(addr); +#endif +} + /// Read a ULEB128 into a 64-bit word. inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; @@ -600,6 +609,7 @@ uint32_t get32(pint_t addr); uint64_t get64(pint_t addr); pint_tgetP(pint_t addr); + uint64_t getRegister(pint_t addr); uint64_t getULEB128(pint_t &addr, pint_t end); int64_t getSLEB128(pint_t &addr, pint_t end); pint_tgetEncodedP(pint_t &addr, pint_t end, uint8_t encoding, @@ -636,7 +646,12 @@ } template -uint64_t RemoteAddressSpace::getULEB128(pint_t &addr, pint_t end) { +typename P::uint_t OtherAddressSpace::getRegister(pint_t addr) { + return P::getRegister(*(uint64_t *)localCopy(addr)); +} + +template +uint64_t OtherAddressSpace::getULEB128(pint_t &addr, pint_t end) { uintptr_t size = (end - addr); LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); LocalAddressSpace::pint_t sladdr = laddr; Index: src/DwarfInstructions.hpp === --- src/DwarfInstructions.hpp +++ src/DwarfInstructions.hpp @@ -82,10 +82,10 @@ const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: -return addressSpace.getP(cfa + (pint_t)savedReg.value); +return addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser::kRegisterAtExpression: -return addressSpace.getP( +return addressSpace.getRegister( evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa)); Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -116,7 +116,8 @@ xorl %eax, %eax# return UNW_ESUCCESS ret -#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \ +defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) @@ -172,7 +173,7 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips64) && defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -61,9 +61,10 @@ # define REGISTER_KIND Registers_arm #elif defined(__or1k__) # define REGISTER_KIND Registers_or1k -#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \ +defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips64) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! Index: include/__libunwind_config.h ===
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis accepted this revision. sdardis added a comment. This revision is now accepted and ready to land. Herald added a subscriber: christof. LGTM after https://reviews.llvm.org/D43585 lands. Repository: rUNW libunwind https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added a comment. Yes. Something like LIBUNWIND_TEST_CFLAGS mapping to config.test_cflags, which libunwind/test/libunwind/test/config.py then appends when building the tests. Thanks. Repository: rUNW libunwind https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb added a comment. Hmmm, I'm a bit lost on the CFLAGS bit. I couldn't find a reference to LIBOMP_TEST_CFLAGS anywhere in the openmp tree. There is a LIBOMP_CFLAGS that doesn't appear to be test specific. To try to find a way to modify the CFLAGS for tests I looked at how LIBUNWIND_BUILD_32_BITS works. It sets a value (config.enable_32bit) in test/lit.site.cfg.in. This is then used by the utils/libcxx/test/config.py script in the libcxx repository in the configure_default_compile_flags() function to add -m32 to CFLAGS. There isn't an existing config.* knob that can add arbitrary things to CFLAGS though, so I think adding a LIBUNWIND_TEST_CFLAGS would mean changing the config.py to learn about a new 'config.cflags' or the like and then mapping LIBUNWIND_TEST_CFLAGS to that via lit.site.cfg.in? Repository: rUNW libunwind https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added a comment. The only thing this needs now is to get correct testing support. Could you add support for passing down to the configuration script an additional set of cflags like compiler-rt and libomp do (as a separate patch)? If you look at libomp, you'll see LIBOMP_TEST_CFLAGS defined in the cmake build system and threaded through various places so the built tests can have the correct options. Without supporting that we get a mixed set of objects, which isn't correct. Repository: rUNW libunwind https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb updated this revision to Diff 133660. bsdjhb added a comment. - Rebase. - Rework ABI macro checks. Repository: rUNW libunwind https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -61,9 +61,10 @@ # define REGISTER_KIND Registers_arm #elif defined(__or1k__) # define REGISTER_KIND Registers_or1k -#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \ +defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips64) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -116,7 +116,8 @@ xorl %eax, %eax# return UNW_ESUCCESS ret -#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \ +defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) @@ -172,7 +173,7 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips64) && defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -799,7 +799,8 @@ l.jr r9 l.nop -#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \ +defined(__mips_soft_float) // // void libunwind::Registers_mips_o32::jumpto() @@ -855,7 +856,7 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips64) && defined(__mips_soft_float) // // void libunwind::Registers_mips_newabi::jumpto() Index: src/DwarfInstructions.hpp === --- src/DwarfInstructions.hpp +++ src/DwarfInstructions.hpp @@ -82,10 +82,10 @@ const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: -return addressSpace.getP(cfa + (pint_t)savedReg.value); +return addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser::kRegisterAtExpression: -return addressSpace.getP( +return addressSpace.getRegister( evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa)); Index: src/AddressSpace.hpp === --- src/AddressSpace.hpp +++ src/AddressSpace.hpp @@ -207,6 +207,7 @@ return val; } uintptr_t getP(pint_t addr); + uint64_tgetRegister(pint_t addr); static uint64_t getULEB128(pint_t &addr, pint_t end); static int64_t getSLEB128(pint_t &addr, pint_t end); @@ -228,6 +229,14 @@ #endif } +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if __SIZEOF_POINTER__ == 8 || defined(__mips64) + return get64(addr); +#else + return get32(addr); +#endif +} + /// Read a ULEB128 into a 64-bit word. inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; @@ -600,6 +609,7 @@ uint32_t get32(pint_t addr); uint64_t get64(pint_t addr); pint_tgetP(pint_t addr); + uint64_t getRegister(pint_t addr); uint64_t getULEB128(pint_t &addr, pint_t end); int64_t getSLEB128(pint_t &addr, pint_t end); pint_tgetEncodedP(pint_t &addr, pint_t end, uint8_t encoding, @@ -636,7 +646,12 @@ } template -uint64_t RemoteAddressSpace::getULEB128(pint_t &addr, pint_t end) { +typename P::uint_t OtherAddressSpace::getRegister(pint_t addr) { + return P::getRegister(*(uint64_t *)localCopy(addr)); +} + +template +uint64_t OtherAddressSpace::getULEB128(pint_t &addr, pint_t end) { uintptr_t size = (end - addr); LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); LocalAddressSpace::pint_t sladdr = laddr; Index: include/__libunwind_config.h === --- include/__libunwind_config.h +++ include/__libunwind_config.h @@ -71,11 +71,15 @@ # define _LIBUNWIND_CURSOR_SIZE 24 # define _LIBUN
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb marked 7 inline comments as done. bsdjhb added a comment. Nice sleuthing! Repository: rUNW libunwind https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added a comment. Ok, I've found my issue. inttypes.h in libcxx include_next's , which on my debian linux systems has the include chain , , . "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
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb added a comment. @sdardis Can you confirm if the existing N64 bits work fine for you or if the tests crash similarly? https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb added a comment. After fighting with cmake for a bit, I just broke down and cross-compiled the tests by hand and then ran them under a qemu system (rather than using qemu user mode). All of the tests ran fine for me without crashing using GCC 6.3.0 for FreeBSD 12 with N32. Given the save/restore code is identical for N32 and N64 I would have expected N64 to fail previously if it was restoring the wrong register? https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added a comment. I just checked both my qemu copy and on my mips64 machine and it seems to be a a copy / paste error. Reposting here directly from my machines: MIPS64: diff --git a/test/libunwind/test/config.py b/test/libunwind/test/config.py index 2a0c828..a8952c3 100644 --- a/test/libunwind/test/config.py +++ b/test/libunwind/test/config.py @@ -48,6 +48,8 @@ class Configuration(LibcxxConfiguration): # Stack unwinding tests need unwinding tables and these are not # generated by default on all Targets. self.cxx.compile_flags += ['-funwind-tables'] + self.cxx.compile_flags += ['-mabi=n32'] +self.cxx.link_flags += ['-mabi=n32'] if not self.get_lit_bool('enable_threads', True): self.cxx.compile_flags += ['-D_LIBUNWIND_HAS_NO_THREADS'] self.config.available_features.add('libunwind-no-threads') X86_64: diff --git a/test/libunwind/test/config.py b/test/libunwind/test/config.py index 2a0c828..f1953e2 100644 --- a/test/libunwind/test/config.py +++ b/test/libunwind/test/config.py @@ -48,6 +48,8 @@ class Configuration(LibcxxConfiguration): # Stack unwinding tests need unwinding tables and these are not # generated by default on all Targets. self.cxx.compile_flags += ['-funwind-tables'] + self.cxx.compile_flags += ['-mabi=n32'] +self.cxx.link_flags += ['-mabi=n32', '/home/sdardis/mips-mti-linux-gnu/2016.05-06/bin/../lib/gcc/mips-mti-linux-gnu/4.9.2/../../../../mips-mti-linux-gnu/lib/mips-r2-hard/lib32/libgcc_s.so.1'] if not self.get_lit_bool('enable_threads', True): self.cxx.compile_flags += ['-D_LIBUNWIND_HAS_NO_THREADS'] self.config.available_features.add('libunwind-no-threads') I corrected whitespace nit before I posted the comment. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb added a comment. In https://reviews.llvm.org/D39074#974913, @sdardis wrote: > This was libunwind's test suite: > > Compiled test failed unexpectedly! > > Testing Time: 0.53s > > Failing Tests (1): > libunwind :: libunwind_02.pass.cpp > > Expected Passes: 3 > Unexpected Failures: 1 > > > > The hacky patch I used to test n32: > > --- a/test/libunwind/test/config.py > +++ b/test/libunwind/test/config.py > @@ -48,6 +48,8 @@ class Configuration(LibcxxConfiguration): ># Stack unwinding tests need unwinding tables and these are not ># generated by default on all Targets. >self.cxx.compile_flags += ['-funwind-tables'] > +self.cxx.compile_flags += ['-mabi=n33'] > +self.cxx.link_flags += ['-mabi=n32'] >if not self.get_lit_bool('enable_threads', True): >self.cxx.compile_flags += ['-D_LIBUNWIND_HAS_NO_THREADS'] >self.config.available_features.add('libunwind-no-threads') > > Just to be sure, is that '-mabi=n33' in the compile flags a copy and paste typo in the diff or do you have it locally in the real change as well? https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added a comment. Um, I now appear to be getting different results for running under QEMU doing it the proper way. I was previously rebuilding the failing test by hand and running under qemu. I don't believe I changed anything important, I'll have to take a longer look. If you define an Executor for libunwind you can run the testsuite under QEMU, automagically. I have: LIBUNWIND_EXECUTOR PrefixExecutor(['/home/sdardis/bin/qemu-mipsn32.sh'],LocalExecutor()) /home/sdardis/bin/qemu-mips32.sh for is a simple bash script: #!/bin/bash ~/mips-mti-linux-gnu/2016.05-06/bin/qemu-mipsn32 -L /home/snd-local/mips-mti-linux-gnu/2016.05-06/sysroot/mips-r2-hard/ -E LD_LIBRARY_PATH=/home/snd-local/mips-mti-linux-gnu/2016.05-06/mips-mti-linux-gnu/lib/mips-r2-hard/lib32/ "$@" Hope this helps. Thanks for all the work you're putting into this. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added a comment. This was libunwind's test suite: Compiled test failed unexpectedly! Testing Time: 0.53s Failing Tests (1): libunwind :: libunwind_02.pass.cpp Expected Passes: 3 Unexpected Failures: 1 The hacky patch I used to test n32: --- a/test/libunwind/test/config.py +++ b/test/libunwind/test/config.py @@ -48,6 +48,8 @@ class Configuration(LibcxxConfiguration): # Stack unwinding tests need unwinding tables and these are not # generated by default on all Targets. self.cxx.compile_flags += ['-funwind-tables'] +self.cxx.compile_flags += ['-mabi=n33'] +self.cxx.link_flags += ['-mabi=n32'] if not self.get_lit_bool('enable_threads', True): self.cxx.compile_flags += ['-D_LIBUNWIND_HAS_NO_THREADS'] self.config.available_features.add('libunwind-no-threads') https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb added a comment. To be clear, are you getting the failure running libunwind's test suite or your own test? I've managed to get libunwind to cross-compile for me using GCC 6.3.0 on FreeBSD for O32, N32, and N64, but only to build the library, not the tests. I've been running a simple C++ test program (which is using a patched libunwind along with libc++ as it's C++ runtime) for testing. The program uses _Unwind_Backtrace() as well as throws a couple of C++ exceptions with catch handlers that print out the values thrown. If you are able to cross-build the libunwind tests and then run them under qemu I'd appreciate a pointer to get that working as I'd be happier running libunwind's tests than my own. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added a comment. Sorry for the delay in getting back to this, but testing this by building it explicitly for N32 (I built a full N32 compiler + libunwind and modified the test setup py to compile for N322) and I'm getting crashes on the return path in _Unwind_Backtrace. The problem occurs when saving the registers, as saving the (second I believe) last register clobbers the saved return address. I've seen crashes on MIPS64 (eb). Qemu however is aborting at runtime, but I haven't had the time to trace the execution, and I haven't found a way yet to dump the locations of the shared libraries at runtime to determine where the fault lies. This was with GCC 4.9.2 (debian) on MIPS64 and our 2016.05-06 toolchain for qemu. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb updated this revision to Diff 129103. bsdjhb added a comment. - Rebase after N64 -> newabi commit. https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -63,7 +63,8 @@ # define REGISTER_KIND Registers_or1k #elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) # 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) # define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -172,7 +172,8 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -685,7 +685,8 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) // // void libunwind::Registers_mips_newabi::jumpto() Index: src/DwarfInstructions.hpp === --- src/DwarfInstructions.hpp +++ src/DwarfInstructions.hpp @@ -82,10 +82,10 @@ const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: -return addressSpace.getP(cfa + (pint_t)savedReg.value); +return addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser::kRegisterAtExpression: -return addressSpace.getP( +return addressSpace.getRegister( evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa)); Index: src/AddressSpace.hpp === --- src/AddressSpace.hpp +++ src/AddressSpace.hpp @@ -207,6 +207,7 @@ return val; } uintptr_t getP(pint_t addr); + uint64_tgetRegister(pint_t addr); static uint64_t getULEB128(pint_t &addr, pint_t end); static int64_t getSLEB128(pint_t &addr, pint_t end); @@ -228,6 +229,14 @@ #endif } +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if __SIZEOF_POINTER__ == 8 || (defined(__mips__) && defined(_ABIN32)) + return get64(addr); +#else + return get32(addr); +#endif +} + /// Read a ULEB128 into a 64-bit word. inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; @@ -600,6 +609,7 @@ uint32_t get32(pint_t addr); uint64_t get64(pint_t addr); pint_tgetP(pint_t addr); + uint64_t getRegister(pint_t addr); uint64_t getULEB128(pint_t &addr, pint_t end); int64_t getSLEB128(pint_t &addr, pint_t end); pint_tgetEncodedP(pint_t &addr, pint_t end, uint8_t encoding, @@ -636,7 +646,12 @@ } template -uint64_t RemoteAddressSpace::getULEB128(pint_t &addr, pint_t end) { +typename P::uint_t OtherAddressSpace::getRegister(pint_t addr) { + return P::getRegister(*(uint64_t *)localCopy(addr)); +} + +template +uint64_t OtherAddressSpace::getULEB128(pint_t &addr, pint_t end) { uintptr_t size = (end - addr); LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); LocalAddressSpace::pint_t sladdr = laddr; Index: include/__libunwind_config.h === --- include/__libunwind_config.h +++ include/__libunwind_config.h @@ -75,6 +75,10 @@ #define _LIBUNWIND_TARGET_MIPS_O32 1 #define _LIBUNWIND_CONTEXT_SIZE 18 #define _LIBUNWIND_CURSOR_SIZE 24 +# elif defined(_ABIN32) && defined(__mips_soft_float) +#define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +#define _LIBUNWIND_CONTEXT_SIZE 35 +#define _LIBUNWIND_CURSOR_SIZE 42 # elif defined(_ABI64) && defined(__mips_soft_float) #define _LIBUNWIND_TARGET_MIPS_NEWABI 1 #define _LIBUNWIND_CONTEXT_SIZE 35 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb added a comment. Ok, I'm definitely fine with splitting the rename out into a separate patch. Will wait for @sdardis to be sure. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
compnerd added a comment. Looking over this patch again, I think I really would prefer that this was split up into two patches. The first one should be entirely mechanical, replacing `n64` with `newabi`. The second patch would actually make the changes that you are are after. That would really help with focusing what the issue here actually is. I don't see anything technically that is an issue (I admit I didn't verify the sizes, but the assertions should hopefully catch that). Beyond that split up, Id like to get a signoff from @sdardis for the MIPS specific bits, but from the libunwind side, LGTM. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb added a comment. ping @sdardis, @compnerd https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb updated this revision to Diff 126841. bsdjhb marked an inline comment as done. bsdjhb added a comment. - Use __SIZEOF_POINTER__ instead of __LP64__. - Adjust comment for newabi register class. https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/Registers.hpp src/UnwindCursor.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -61,8 +61,9 @@ # define REGISTER_KIND Registers_or1k #elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) -# define REGISTER_KIND Registers_mips_n64 +#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) &&\ +defined(__mips_soft_float) +# define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! #else Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -172,7 +172,8 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -590,15 +590,16 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) // -// void libunwind::Registers_mips_n64::jumpto() +// void libunwind::Registers_mips_newabi::jumpto() // // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_n646jumptoEv) +DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder Index: src/UnwindCursor.hpp === --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -514,8 +514,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - int stepWithCompactEncoding(Registers_mips_n64 &) { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + int stepWithCompactEncoding(Registers_mips_newabi &) { return UNW_EINVAL; } #endif @@ -570,8 +570,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - bool compactSaysUseDwarf(Registers_mips_n64 &, uint32_t *) const { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { return true; } #endif @@ -625,8 +625,8 @@ } #endif -#if defined (_LIBUNWIND_TARGET_MIPS_N64) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_n64 &) const { +#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { return 0; } #endif Index: src/Registers.hpp === --- src/Registers.hpp +++ src/Registers.hpp @@ -2248,13 +2248,13 @@ } #endif // _LIBUNWIND_TARGET_MIPS_O32 -#if defined(_LIBUNWIND_TARGET_MIPS_N64) -/// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS -/// process. -class _LIBUNWIND_HIDDEN Registers_mips_n64 { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a +/// MIPS process using NEWABI (the N32 or N64 ABIs). +class _LIBUNWIND_HIDDEN Registers_mips_newabi { public: - Registers_mips_n64(); - Registers_mips_n64(const void *registers); + Registers_mips_newabi(); + Registers_mips_newabi(const void *registers); boolvalidRegister(int num) const; uint64_tgetRegister(int num) const; @@ -2275,28 +2275,28 @@ void setIP(uint64_t value) { _registers.__pc = value; } private: - struct mips_n64_thread_state_t { + struct mips_newabi_thread_state_t { uint64_t __r[32]; uint64_t __pc; uint64_t __hi; uint64_t __lo; }; - mips_n64_thread_state_t _registers; + mips_newabi_thread_state_t _registers; }; -inline Registers_mips_n64::Registers_mips_n64(const void *registers) { - static_assert((check_fit::does_fit), -"mips_n64 registers do not fit into unw_context_t"); +inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { + static_assert((check_fit::does_fit), +"mips_newabi registers do not fit into unw_context_t"); memcpy
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb marked 2 inline comments as done. bsdjhb added inline comments. Comment at: src/AddressSpace.hpp:201 +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if defined(__LP64__) || (defined(__mips__) && defined(_ABIN32)) + return get64(addr); compnerd wrote: > Can you use `__SIZEOF_POINTER__` rather than `__LP64__` please? The former > accounts for LLP64 environments as well. I wonder if we should adjust the #if condition used to control the types of pint_t and sint_t earlier in this file to also use __SIZEOF_POINTER__ (as a separate change)? https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added inline comments. Comment at: include/__libunwind_config.h:73 +# elif defined(_ABIN32) && defined(__mips_soft_float) +#define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +#define _LIBUNWIND_CONTEXT_SIZE 35 compnerd wrote: > Minor nit: I prefer either `NABI` or `NEW_ABI`. Normally mips documentation/source code either spells out n32/n64 when referring to the 64 bit abis or calls it a variation of NewABI/newabi/NEWABI (all one word). Comment at: src/Registers.hpp:2252-2253 +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a NEWABI +/// MIPS process including both the N32 and N64 ABIs. +class _LIBUNWIND_HIDDEN Registers_mips_newabi { Nit on the wording: Registers_mips_newabi holds the register state of a thread in a NEWABI MIPS process including both the N32 and N64 ABIs. -> Registers_mips_newabi holds the register state of a thread in a MIPS process using NEWABI (the N32 or N64 ABIs). https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
compnerd added inline comments. Comment at: include/__libunwind_config.h:73 +# elif defined(_ABIN32) && defined(__mips_soft_float) +#define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +#define _LIBUNWIND_CONTEXT_SIZE 35 Minor nit: I prefer either `NABI` or `NEW_ABI`. Comment at: src/AddressSpace.hpp:201 +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if defined(__LP64__) || (defined(__mips__) && defined(_ABIN32)) + return get64(addr); Can you use `__SIZEOF_POINTER__` rather than `__LP64__` please? The former accounts for LLP64 environments as well. Comment at: src/UnwindRegistersRestore.S:548 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && defined(__mips_soft_float) sdardis wrote: > This line is overly long, break with '\' after the second &&. clang-format should also fix the width correctly. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb updated this revision to Diff 126620. bsdjhb added a comment. - Rebase after O32/N64 commit. https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/Registers.hpp src/UnwindCursor.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -61,8 +61,9 @@ # define REGISTER_KIND Registers_or1k #elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) -# define REGISTER_KIND Registers_mips_n64 +#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) &&\ +defined(__mips_soft_float) +# define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! #else Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -172,7 +172,8 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -590,15 +590,16 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) // -// void libunwind::Registers_mips_n64::jumpto() +// void libunwind::Registers_mips_newabi::jumpto() // // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_n646jumptoEv) +DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder Index: src/UnwindCursor.hpp === --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -514,8 +514,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - int stepWithCompactEncoding(Registers_mips_n64 &) { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + int stepWithCompactEncoding(Registers_mips_newabi &) { return UNW_EINVAL; } #endif @@ -570,8 +570,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - bool compactSaysUseDwarf(Registers_mips_n64 &, uint32_t *) const { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { return true; } #endif @@ -625,8 +625,8 @@ } #endif -#if defined (_LIBUNWIND_TARGET_MIPS_N64) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_n64 &) const { +#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { return 0; } #endif Index: src/Registers.hpp === --- src/Registers.hpp +++ src/Registers.hpp @@ -2248,13 +2248,13 @@ } #endif // _LIBUNWIND_TARGET_MIPS_O32 -#if defined(_LIBUNWIND_TARGET_MIPS_N64) -/// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS -/// process. -class _LIBUNWIND_HIDDEN Registers_mips_n64 { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a NEWABI +/// MIPS process including both the N32 and N64 ABIs. +class _LIBUNWIND_HIDDEN Registers_mips_newabi { public: - Registers_mips_n64(); - Registers_mips_n64(const void *registers); + Registers_mips_newabi(); + Registers_mips_newabi(const void *registers); boolvalidRegister(int num) const; uint64_tgetRegister(int num) const; @@ -2275,28 +2275,28 @@ void setIP(uint64_t value) { _registers.__pc = value; } private: - struct mips_n64_thread_state_t { + struct mips_newabi_thread_state_t { uint64_t __r[32]; uint64_t __pc; uint64_t __hi; uint64_t __lo; }; - mips_n64_thread_state_t _registers; + mips_newabi_thread_state_t _registers; }; -inline Registers_mips_n64::Registers_mips_n64(const void *registers) { - static_assert((check_fit::does_fit), -"mips_n64 registers do not fit into unw_context_t"); +inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { + static_assert((check_fit::does_fit), +"mips_newabi registers do not fit into unw_context_t"); memcpy(&_registers, static_cast(registers), sizeof(_registers)); } -inline Registers_
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb updated this revision to Diff 120624. bsdjhb added a comment. - Rebase after MAX_REGISTER change. https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/Registers.hpp src/UnwindCursor.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -61,8 +61,9 @@ # define REGISTER_KIND Registers_or1k #elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) -# define REGISTER_KIND Registers_mips_n64 +#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) &&\ +defined(__mips_soft_float) +# define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! #else Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -172,7 +172,8 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -580,15 +580,16 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) // -// void libunwind::Registers_mips_n64::jumpto() +// void libunwind::Registers_mips_newabi::jumpto() // // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_n646jumptoEv) +DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder Index: src/UnwindCursor.hpp === --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -514,8 +514,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - int stepWithCompactEncoding(Registers_mips_n64 &) { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + int stepWithCompactEncoding(Registers_mips_newabi &) { return UNW_EINVAL; } #endif @@ -570,8 +570,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - bool compactSaysUseDwarf(Registers_mips_n64 &, uint32_t *) const { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { return true; } #endif @@ -619,8 +619,8 @@ } #endif -#if defined (_LIBUNWIND_TARGET_MIPS_N64) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_n64 &) const { +#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { return 0; } #endif Index: src/Registers.hpp === --- src/Registers.hpp +++ src/Registers.hpp @@ -2247,13 +2247,13 @@ } #endif // _LIBUNWIND_TARGET_MIPS_O32 -#if defined(_LIBUNWIND_TARGET_MIPS_N64) -/// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS -/// process. -class _LIBUNWIND_HIDDEN Registers_mips_n64 { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a NEWABI +/// MIPS process including both the N32 and N64 ABIs. +class _LIBUNWIND_HIDDEN Registers_mips_newabi { public: - Registers_mips_n64(); - Registers_mips_n64(const void *registers); + Registers_mips_newabi(); + Registers_mips_newabi(const void *registers); boolvalidRegister(int num) const; uint64_tgetRegister(int num) const; @@ -2274,28 +2274,28 @@ void setIP(uint64_t value) { _registers.__pc = value; } private: - struct mips_n64_thread_state_t { + struct mips_newabi_thread_state_t { uint64_t __r[32]; uint64_t __pc; uint64_t __hi; uint64_t __lo; }; - mips_n64_thread_state_t _registers; + mips_newabi_thread_state_t _registers; }; -inline Registers_mips_n64::Registers_mips_n64(const void *registers) { - static_assert((check_fit::does_fit), -"mips_n64 registers do not fit into unw_context_t"); +inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { + static_assert((check_fit::does_fit), +"mips_newabi registers do not fit into unw_context_t"); memcpy(&_registers, static_cast(registers), sizeof(_registers)); } -inline Regis
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb marked 2 inline comments as done. bsdjhb added inline comments. Comment at: include/__libunwind_config.h:62 +# define _LIBUNWIND_CONTEXT_SIZE 35 +# define _LIBUNWIND_CURSOR_SIZE 46 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 66 sdardis wrote: > Shouldn't this 46 be 47? No, the other parts of a cursor besides the register context use ILP32 layout for N32 instead of LP64. In particular, I think N32 has less padding after the two 'bool' members at the end of UnwindCursor<>. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb updated this revision to Diff 120578. bsdjhb marked 3 inline comments as done. bsdjhb added a comment. - Use correct #ifdef for N32. - Rename N64 to newabi. https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/Registers.hpp src/UnwindCursor.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -60,8 +60,9 @@ # define REGISTER_KIND Registers_or1k #elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) -# define REGISTER_KIND Registers_mips_n64 +#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) &&\ +defined(__mips_soft_float) +# define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! #else Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -143,7 +143,8 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -545,15 +545,16 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\ +defined(__mips_soft_float) // -// void libunwind::Registers_mips_n64::jumpto() +// void libunwind::Registers_mips_newabi::jumpto() // // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_n646jumptoEv) +DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder Index: src/UnwindCursor.hpp === --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -520,8 +520,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - int stepWithCompactEncoding(Registers_mips_n64 &) { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + int stepWithCompactEncoding(Registers_mips_newabi &) { return UNW_EINVAL; } #endif @@ -576,8 +576,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - bool compactSaysUseDwarf(Registers_mips_n64 &, uint32_t *) const { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { return true; } #endif @@ -625,8 +625,8 @@ } #endif -#if defined (_LIBUNWIND_TARGET_MIPS_N64) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_n64 &) const { +#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { return 0; } #endif Index: src/Registers.hpp === --- src/Registers.hpp +++ src/Registers.hpp @@ -2187,13 +2187,13 @@ } #endif // _LIBUNWIND_TARGET_MIPS_O32 -#if defined(_LIBUNWIND_TARGET_MIPS_N64) -/// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS -/// process. -class _LIBUNWIND_HIDDEN Registers_mips_n64 { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a NEWABI +/// MIPS process including both the N32 and N64 ABIs. +class _LIBUNWIND_HIDDEN Registers_mips_newabi { public: - Registers_mips_n64(); - Registers_mips_n64(const void *registers); + Registers_mips_newabi(); + Registers_mips_newabi(const void *registers); boolvalidRegister(int num) const; uint64_tgetRegister(int num) const; @@ -2214,28 +2214,28 @@ void setIP(uint64_t value) { _registers.__pc = value; } private: - struct mips_n64_thread_state_t { + struct mips_newabi_thread_state_t { uint64_t __r[32]; uint64_t __pc; uint64_t __hi; uint64_t __lo; }; - mips_n64_thread_state_t _registers; + mips_newabi_thread_state_t _registers; }; -inline Registers_mips_n64::Registers_mips_n64(const void *registers) { - static_assert((check_fit::does_fit), -"mips_n64 registers do not fit into unw_context_t"); +inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { + static_assert((check_fit::does_fit), +"mips_newabi registers do not fit into unw_context_t"); memcpy(&_registers, static_cast(re
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
sdardis added inline comments. Comment at: include/__libunwind_config.h:59-68 +# elif defined(__mips__) && defined(_ABIN32) && defined(__mips_soft_float) +# define _LIBUNWIND_TARGET_MIPS_N64 1 +# define _LIBUNWIND_CONTEXT_SIZE 35 +# define _LIBUNWIND_CURSOR_SIZE 46 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 66 # elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) # define _LIBUNWIND_TARGET_MIPS_N64 1 Change the define of _LIBUNWIND_TARGET_MIPS_N64 to _LIBUNWIND_TARGET_MIPS_NEWABI, then these two elif branches can have the condition (defined(_ABIN32) && defined(_ABI64) and refactored into one elif branch. Comment at: include/__libunwind_config.h:62 +# define _LIBUNWIND_CONTEXT_SIZE 35 +# define _LIBUNWIND_CURSOR_SIZE 46 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 66 Shouldn't this 46 be 47? Comment at: src/AddressSpace.hpp:201 +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if defined(__LP64__) || defined(__mips_n32) + return get64(addr); defined(__mips_n32) -> (defined(__mips__) && defined(_ABIN32)) Comment at: src/UnwindRegistersRestore.S:548 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && defined(__mips_soft_float) This line is overly long, break with '\' after the second &&. Comment at: src/UnwindRegistersSave.S:146 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && defined(__mips_soft_float) This line looks overly long, break before the second &&. Comment at: src/libunwind.cpp:63-66 +#elif defined(__mips__) && defined(_ABIN32) && defined(__mips_soft_float) +# define REGISTER_KIND Registers_mips_n64 #elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_n64 Fold these two branches together and have the condition (defined(_ABIN32) || defined(_ABI64), then follow-up by renaming Registers_mips_n64 to Register_mips_NEWABI. Add a comment to the definition of that class stating that it covers both n32 and n64. https://reviews.llvm.org/D39074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.
bsdjhb created this revision. Herald added subscribers: JDevlieghere, arichardson, aprantl. N32 uses the same register context as N64. However, N32 requires one change to properly fetch addresses from registers stored in memory. Since N32 is an ILP32 platform, getP() only fetches the first 32-bits of a stored register. For a big-endian platform this fetches the upper 32-bits which will be zero. To fix this, add a new getRegister() method to AddressSpace which is responsible for extracting the address stored in a register in memory. This matches getP() for all current ABIs except for N32 where it reads the 64-bit register and returns the low 32-bits as an address. The DwarfInstructions::getSavedRegister() method uses AddressSpace::getRegister() instead of AddressSpace::getP(). Possibly, DwarfInstructions::getSavedRegister()'s return type should be changed from pint_t to uint64_t. https://reviews.llvm.org/D39074 Files: include/__libunwind_config.h src/AddressSpace.hpp src/DwarfInstructions.hpp src/UnwindRegistersRestore.S src/UnwindRegistersSave.S src/libunwind.cpp Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -60,6 +60,8 @@ # define REGISTER_KIND Registers_or1k #elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 +#elif defined(__mips__) && defined(_ABIN32) && defined(__mips_soft_float) +# define REGISTER_KIND Registers_mips_n64 #elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_n64 #elif defined(__mips__) Index: src/UnwindRegistersSave.S === --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -143,7 +143,7 @@ or$2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/UnwindRegistersRestore.S === --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -545,7 +545,7 @@ lw$4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && defined(__mips_soft_float) // // void libunwind::Registers_mips_n64::jumpto() Index: src/DwarfInstructions.hpp === --- src/DwarfInstructions.hpp +++ src/DwarfInstructions.hpp @@ -82,10 +82,10 @@ const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: -return addressSpace.getP(cfa + (pint_t)savedReg.value); +return addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser::kRegisterAtExpression: -return addressSpace.getP( +return addressSpace.getRegister( evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa)); Index: src/AddressSpace.hpp === --- src/AddressSpace.hpp +++ src/AddressSpace.hpp @@ -175,6 +175,7 @@ return val; } uintptr_t getP(pint_t addr); + uint64_tgetRegister(pint_t addr); static uint64_t getULEB128(pint_t &addr, pint_t end); static int64_t getSLEB128(pint_t &addr, pint_t end); @@ -196,6 +197,14 @@ #endif } +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if defined(__LP64__) || defined(__mips_n32) + return get64(addr); +#else + return get32(addr); +#endif +} + /// Read a ULEB128 into a 64-bit word. inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; @@ -511,6 +520,7 @@ uint32_t get32(pint_t addr); uint64_t get64(pint_t addr); pint_tgetP(pint_t addr); + uint64_t getRegister(pint_t addr); uint64_t getULEB128(pint_t &addr, pint_t end); int64_t getSLEB128(pint_t &addr, pint_t end); pint_tgetEncodedP(pint_t &addr, pint_t end, uint8_t encoding, @@ -547,7 +557,12 @@ } template -uint64_t RemoteAddressSpace::getULEB128(pint_t &addr, pint_t end) { +typename P::uint_t OtherAddressSpace::getRegister(pint_t addr) { + return P::getRegister(*(uint64_t *)localCopy(addr)); +} + +template +uint64_t OtherAddressSpace::getULEB128(pint_t &addr, pint_t end) { uintptr_t size = (end - addr); LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); LocalAddressSpace::pint_t sladdr = laddr; Index: include/__libunwind_config.h === --- include/__libunwind_config.h +++ include/__libunwind_config.h @@ -56,6 +56,11 @@ # define _LIBUNWIND_CONTEXT_SIZE