[libunwind] r326250 - [libunwind][MIPS]: Add support for unwinding in N32 processes.

John Baldwin via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 27 13:24:03 PST 2018


Author: jhb
Date: Tue Feb 27 13:24:02 2018
New Revision: 326250

URL: http://llvm.org/viewvc/llvm-project?rev=326250&view=rev
Log:
[libunwind][MIPS]: Add support for unwinding in N32 processes.

Summary:
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().

Reviewers: sdardis, compnerd

Reviewed By: sdardis

Differential Revision: https://reviews.llvm.org/D39074

Modified:
    libunwind/trunk/include/__libunwind_config.h
    libunwind/trunk/src/AddressSpace.hpp
    libunwind/trunk/src/DwarfInstructions.hpp
    libunwind/trunk/src/UnwindRegistersRestore.S
    libunwind/trunk/src/UnwindRegistersSave.S
    libunwind/trunk/src/libunwind.cpp

Modified: libunwind/trunk/include/__libunwind_config.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/__libunwind_config.h?rev=326250&r1=326249&r2=326250&view=diff
==============================================================================
--- libunwind/trunk/include/__libunwind_config.h (original)
+++ libunwind/trunk/include/__libunwind_config.h Tue Feb 27 13:24:02 2018
@@ -71,11 +71,15 @@
 #  define _LIBUNWIND_CURSOR_SIZE 24
 #  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K
 # elif defined(__mips__)
-#  if defined(_ABIO32) && defined(__mips_soft_float)
+#  if defined(_ABIO32) && _MIPS_SIM == _ABIO32 && defined(__mips_soft_float)
 #    define _LIBUNWIND_TARGET_MIPS_O32 1
 #    define _LIBUNWIND_CONTEXT_SIZE 18
 #    define _LIBUNWIND_CURSOR_SIZE 24
-#  elif defined(_ABI64) && defined(__mips_soft_float)
+#  elif defined(_ABIN32) && _MIPS_SIM == _ABIN32 && defined(__mips_soft_float)
+#    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
+#    define _LIBUNWIND_CONTEXT_SIZE 35
+#    define _LIBUNWIND_CURSOR_SIZE 42
+#  elif defined(_ABI64) && _MIPS_SIM == _ABI64 && defined(__mips_soft_float)
 #    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
 #    define _LIBUNWIND_CONTEXT_SIZE 35
 #    define _LIBUNWIND_CURSOR_SIZE 47

Modified: libunwind/trunk/src/AddressSpace.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=326250&r1=326249&r2=326250&view=diff
==============================================================================
--- libunwind/trunk/src/AddressSpace.hpp (original)
+++ libunwind/trunk/src/AddressSpace.hpp Tue Feb 27 13:24:02 2018
@@ -207,6 +207,7 @@ public:
     return val;
   }
   uintptr_t       getP(pint_t addr);
+  uint64_t        getRegister(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 @@ inline uintptr_t LocalAddressSpace::getP
 #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 @@ public:
   uint32_t  get32(pint_t addr);
   uint64_t  get64(pint_t addr);
   pint_t    getP(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_t    getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
@@ -636,7 +646,12 @@ typename P::uint_t RemoteAddressSpace<P>
 }
 
 template <typename P>
-uint64_t RemoteAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) {
+typename P::uint_t OtherAddressSpace<P>::getRegister(pint_t addr) {
+  return P::getRegister(*(uint64_t *)localCopy(addr));
+}
+
+template <typename P>
+uint64_t OtherAddressSpace<P>::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;

Modified: libunwind/trunk/src/DwarfInstructions.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfInstructions.hpp?rev=326250&r1=326249&r2=326250&view=diff
==============================================================================
--- libunwind/trunk/src/DwarfInstructions.hpp (original)
+++ libunwind/trunk/src/DwarfInstructions.hpp Tue Feb 27 13:24:02 2018
@@ -82,10 +82,10 @@ typename A::pint_t DwarfInstructions<A,
     const RegisterLocation &savedReg) {
   switch (savedReg.location) {
   case CFI_Parser<A>::kRegisterInCFA:
-    return addressSpace.getP(cfa + (pint_t)savedReg.value);
+    return addressSpace.getRegister(cfa + (pint_t)savedReg.value);
 
   case CFI_Parser<A>::kRegisterAtExpression:
-    return addressSpace.getP(
+    return addressSpace.getRegister(
         evaluateExpression((pint_t)savedReg.value, addressSpace,
                             registers, cfa));
 

Modified: libunwind/trunk/src/UnwindRegistersRestore.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersRestore.S?rev=326250&r1=326249&r2=326250&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersRestore.S (original)
+++ libunwind/trunk/src/UnwindRegistersRestore.S Tue Feb 27 13:24:02 2018
@@ -799,7 +799,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li
   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 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li
   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()

Modified: libunwind/trunk/src/UnwindRegistersSave.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersSave.S?rev=326250&r1=326249&r2=326250&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersSave.S (original)
+++ libunwind/trunk/src/UnwindRegistersSave.S Tue Feb 27 13:24:02 2018
@@ -116,7 +116,8 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext
   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 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext
   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)

Modified: libunwind/trunk/src/libunwind.cpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/libunwind.cpp?rev=326250&r1=326249&r2=326250&view=diff
==============================================================================
--- libunwind/trunk/src/libunwind.cpp (original)
+++ libunwind/trunk/src/libunwind.cpp Tue Feb 27 13:24:02 2018
@@ -61,9 +61,10 @@ _LIBUNWIND_EXPORT int unw_init_local(unw
 # 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!




More information about the cfe-commits mailing list