[libunwind] r270692 - Introduce a native-only unwinder build.

Asiri Rathnayake via cfe-commits cfe-commits at lists.llvm.org
Wed May 25 05:36:37 PDT 2016


Author: asiri
Date: Wed May 25 07:36:34 2016
New Revision: 270692

URL: http://llvm.org/viewvc/llvm-project?rev=270692&view=rev
Log:
Introduce a native-only unwinder build.

Currently libunwind is built to support cross-unwinding [1] by default, which
requires the buffers unw_context_t and unw_cursor_t to be large enough to hold
the vritual register set (VRS) of any supported architecture. This is not
desirable for some platforms where the stack usage of the unwinder needs
to be kept to a minimum (e.g. bare-metal targets). The current patch introduces
a native-only (-DLIBUNWIND_ENABLE_CROSS_UNWINDING=OFF) unwinder variant that
adopts strict sizes for the buffers unw_context_t and unw_cursor_t depending
on the target architecture.

[1] http://www.nongnu.org/libunwind/man/libunwind(3).html#section_4

Change-Id: I380fff9a56c16a0fc520e3b1d8454a34b4a48373

Modified:
    libunwind/trunk/CMakeLists.txt
    libunwind/trunk/include/__libunwind_config.h
    libunwind/trunk/include/libunwind.h
    libunwind/trunk/src/CompactUnwinder.hpp
    libunwind/trunk/src/Registers.hpp
    libunwind/trunk/src/UnwindCursor.hpp
    libunwind/trunk/src/config.h
    libunwind/trunk/src/libunwind.cpp

Modified: libunwind/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/CMakeLists.txt?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/CMakeLists.txt (original)
+++ libunwind/trunk/CMakeLists.txt Wed May 25 07:36:34 2016
@@ -103,6 +103,7 @@ option(LIBUNWIND_ENABLE_ASSERTIONS "Enab
 option(LIBUNWIND_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
 option(LIBUNWIND_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
 option(LIBUNWIND_ENABLE_SHARED "Build libunwind as a shared library." ON)
+option(LIBUNWIND_ENABLE_CROSS_UNWINDING "Enable cross-platform unwinding support." ON)
 
 set(LIBUNWIND_GCC_TOOLCHAIN "" CACHE STRING "GCC toolchain for cross compiling.")
 set(LIBUNWIND_SYSROOT "" CACHE STRING "Sysroot for cross compiling.")
@@ -202,6 +203,11 @@ else()
   endif ()
 endif ()
 
+# Cross-unwinding
+if (NOT LIBUNWIND_ENABLE_CROSS_UNWINDING)
+  list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_IS_NATIVE_ONLY)
+endif ()
+
 # This is the _ONLY_ place where add_definitions is called.
 if (MSVC)
   add_definitions(-D_CRT_SECURE_NO_WARNINGS)

Modified: libunwind/trunk/include/__libunwind_config.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/__libunwind_config.h?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/include/__libunwind_config.h (original)
+++ libunwind/trunk/include/__libunwind_config.h Wed May 25 07:36:34 2016
@@ -17,4 +17,43 @@
 #define _LIBUNWIND_ARM_EHABI 0
 #endif
 
+#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
+# if defined(__i386__)
+#  define _LIBUNWIND_TARGET_I386 1
+#  define _LIBUNWIND_CONTEXT_SIZE 8
+#  define _LIBUNWIND_CURSOR_SIZE 19
+# elif defined(__x86_64__)
+#  define _LIBUNWIND_TARGET_X86_64 1
+#  define _LIBUNWIND_CONTEXT_SIZE 21
+#  define _LIBUNWIND_CURSOR_SIZE 33
+# elif defined(__ppc__)
+#  define _LIBUNWIND_TARGET_PPC 1
+#  define _LIBUNWIND_CONTEXT_SIZE 117
+#  define _LIBUNWIND_CURSOR_SIZE 128
+# elif defined(__aarch64__)
+#  define _LIBUNWIND_TARGET_AARCH64 1
+#  define _LIBUNWIND_CONTEXT_SIZE 66
+#  define _LIBUNWIND_CURSOR_SIZE 78
+# elif defined(__arm__)
+#  define _LIBUNWIND_TARGET_ARM 1
+#  define _LIBUNWIND_CONTEXT_SIZE 60
+#  define _LIBUNWIND_CURSOR_SIZE 67
+# elif defined(__or1k__)
+#  define _LIBUNWIND_TARGET_OR1K 1
+#  define _LIBUNWIND_CONTEXT_SIZE 16
+#  define _LIBUNWIND_CURSOR_SIZE 28
+# else
+#  error "Unsupported architecture."
+# endif
+#else // !_LIBUNWIND_IS_NATIVE_ONLY
+# define _LIBUNWIND_TARGET_I386 1
+# define _LIBUNWIND_TARGET_X86_64 1
+# define _LIBUNWIND_TARGET_PPC 1
+# define _LIBUNWIND_TARGET_AARCH64 1
+# define _LIBUNWIND_TARGET_ARM 1
+# define _LIBUNWIND_TARGET_OR1K 1
+# define _LIBUNWIND_CONTEXT_SIZE 128
+# define _LIBUNWIND_CURSOR_SIZE 140
+#endif // _LIBUNWIND_IS_NATIVE_ONLY
+
 #endif // ____LIBUNWIND_CONFIG_H__

Modified: libunwind/trunk/include/libunwind.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/libunwind.h?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/include/libunwind.h (original)
+++ libunwind/trunk/include/libunwind.h Wed May 25 07:36:34 2016
@@ -46,12 +46,12 @@ enum {
 };
 
 struct unw_context_t {
-  uint64_t data[128];
+  uint64_t data[_LIBUNWIND_CONTEXT_SIZE];
 };
 typedef struct unw_context_t unw_context_t;
 
 struct unw_cursor_t {
-  uint64_t data[140];
+  uint64_t data[_LIBUNWIND_CURSOR_SIZE];
 };
 typedef struct unw_cursor_t unw_cursor_t;
 

Modified: libunwind/trunk/src/CompactUnwinder.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/CompactUnwinder.hpp?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/src/CompactUnwinder.hpp (original)
+++ libunwind/trunk/src/CompactUnwinder.hpp Wed May 25 07:36:34 2016
@@ -27,6 +27,7 @@
 
 namespace libunwind {
 
+#if defined(_LIBUNWIND_TARGET_I386)
 /// CompactUnwinder_x86 uses a compact unwind info to virtually "step" (aka
 /// unwind) by modifying a Registers_x86 register set
 template <typename A>
@@ -255,8 +256,10 @@ void CompactUnwinder_x86<A>::framelessUn
   // old esp is before return address
   registers.setSP((uint32_t)returnAddressLocation + 4);
 }
+#endif // _LIBUNWIND_TARGET_I386
 
 
+#if defined(_LIBUNWIND_TARGET_X86_64)
 /// CompactUnwinder_x86_64 uses a compact unwind info to virtually "step" (aka
 /// unwind) by modifying a Registers_x86_64 register set
 template <typename A>
@@ -484,9 +487,11 @@ void CompactUnwinder_x86_64<A>::frameles
   // old esp is before return address
   registers.setSP(returnAddressLocation + 8);
 }
+#endif // _LIBUNWIND_TARGET_X86_64
 
 
 
+#if defined(_LIBUNWIND_TARGET_AARCH64)
 /// CompactUnwinder_arm64 uses a compact unwind info to virtually "step" (aka
 /// unwind) by modifying a Registers_arm64 register set
 template <typename A>
@@ -686,6 +691,7 @@ int CompactUnwinder_arm64<A>::stepWithCo
 
   return UNW_STEP_SUCCESS;
 }
+#endif // _LIBUNWIND_TARGET_AARCH64
 
 
 } // namespace libunwind

Modified: libunwind/trunk/src/Registers.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/Registers.hpp?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/src/Registers.hpp (original)
+++ libunwind/trunk/src/Registers.hpp Wed May 25 07:36:34 2016
@@ -25,6 +25,7 @@ namespace libunwind {
 struct v128 { uint32_t vec[4]; };
 
 
+#if defined(_LIBUNWIND_TARGET_I386)
 /// Registers_x86 holds the register state of a thread in a 32-bit intel
 /// process.
 class _LIBUNWIND_HIDDEN Registers_x86 {
@@ -86,8 +87,8 @@ private:
 };
 
 inline Registers_x86::Registers_x86(const void *registers) {
-  static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
-                    "x86 registers do not fit into unw_context_t");
+  static_assert(check_fit<Registers_x86, unw_context_t>::does_fit,
+                "x86 registers do not fit into unw_context_t");
   memcpy(&_registers, registers, sizeof(_registers));
 }
 
@@ -211,8 +212,10 @@ inline v128 Registers_x86::getVectorRegi
 inline void Registers_x86::setVectorRegister(int, v128) {
   _LIBUNWIND_ABORT("no x86 vector registers");
 }
+#endif // _LIBUNWIND_TARGET_I386
 
 
+#if defined(_LIBUNWIND_TARGET_X86_64)
 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
 /// process.
 class _LIBUNWIND_HIDDEN Registers_x86_64 {
@@ -278,8 +281,8 @@ private:
 };
 
 inline Registers_x86_64::Registers_x86_64(const void *registers) {
-  static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
-                    "x86_64 registers do not fit into unw_context_t");
+  static_assert(check_fit<Registers_x86_64, unw_context_t>::does_fit,
+                "x86_64 registers do not fit into unw_context_t");
   memcpy(&_registers, registers, sizeof(_registers));
 }
 
@@ -459,8 +462,10 @@ inline v128 Registers_x86_64::getVectorR
 inline void Registers_x86_64::setVectorRegister(int, v128) {
   _LIBUNWIND_ABORT("no x86_64 vector registers");
 }
+#endif // _LIBUNWIND_TARGET_X86_64
 
 
+#if defined(_LIBUNWIND_TARGET_PPC)
 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
 /// process.
 class _LIBUNWIND_HIDDEN Registers_ppc {
@@ -543,8 +548,8 @@ private:
 };
 
 inline Registers_ppc::Registers_ppc(const void *registers) {
-  static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
-                    "ppc registers do not fit into unw_context_t");
+  static_assert(check_fit<Registers_ppc, unw_context_t>::does_fit,
+                "ppc registers do not fit into unw_context_t");
   memcpy(&_registers, static_cast<const uint8_t *>(registers),
          sizeof(_registers));
   static_assert(sizeof(ppc_thread_state_t) == 160,
@@ -1023,8 +1028,10 @@ inline const char *Registers_ppc::getReg
   }
 
 }
+#endif // _LIBUNWIND_TARGET_PPC
 
 
+#if defined(_LIBUNWIND_TARGET_AARCH64)
 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
 /// process.
 class _LIBUNWIND_HIDDEN Registers_arm64 {
@@ -1071,8 +1078,8 @@ private:
 };
 
 inline Registers_arm64::Registers_arm64(const void *registers) {
-  static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
-                    "arm64 registers do not fit into unw_context_t");
+  static_assert(check_fit<Registers_arm64, unw_context_t>::does_fit,
+                "arm64 registers do not fit into unw_context_t");
   memcpy(&_registers, registers, sizeof(_registers));
   static_assert(sizeof(GPRs) == 0x110,
                 "expected VFP registers to be at offset 272");
@@ -1289,7 +1296,9 @@ inline v128 Registers_arm64::getVectorRe
 inline void Registers_arm64::setVectorRegister(int, v128) {
   _LIBUNWIND_ABORT("no arm64 vector register support yet");
 }
+#endif // _LIBUNWIND_TARGET_AARCH64
 
+#if defined(_LIBUNWIND_TARGET_ARM)
 /// Registers_arm holds the register state of a thread in a 32-bit arm
 /// process.
 ///
@@ -1395,8 +1404,8 @@ inline Registers_arm::Registers_arm(cons
     _saved_vfp_d16_d31(false),
     _saved_iwmmx(false),
     _saved_iwmmx_control(false) {
-  static_assert(sizeof(Registers_arm) < sizeof(unw_context_t),
-                    "arm registers do not fit into unw_context_t");
+  static_assert(check_fit<Registers_arm, unw_context_t>::does_fit,
+                "arm registers do not fit into unw_context_t");
   // See unw_getcontext() note about data.
   memcpy(&_registers, registers, sizeof(_registers));
   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
@@ -1711,6 +1720,10 @@ inline v128 Registers_arm::getVectorRegi
 inline void Registers_arm::setVectorRegister(int, v128) {
   _LIBUNWIND_ABORT("ARM vector support not implemented");
 }
+#endif // _LIBUNWIND_TARGET_ARM
+
+
+#if defined(_LIBUNWIND_TARGET_OR1K)
 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
 /// process.
 class _LIBUNWIND_HIDDEN Registers_or1k {
@@ -1745,8 +1758,8 @@ private:
 };
 
 inline Registers_or1k::Registers_or1k(const void *registers) {
-  static_assert(sizeof(Registers_or1k) < sizeof(unw_context_t),
-                    "or1k registers do not fit into unw_context_t");
+  static_assert(check_fit<Registers_or1k, unw_context_t>::does_fit,
+                "or1k registers do not fit into unw_context_t");
   memcpy(&_registers, static_cast<const uint8_t *>(registers),
          sizeof(_registers));
 }
@@ -1893,6 +1906,7 @@ inline const char *Registers_or1k::getRe
   }
 
 }
+#endif // _LIBUNWIND_TARGET_OR1K
 } // namespace libunwind
 
 #endif // __REGISTERS_HPP__

Modified: libunwind/trunk/src/UnwindCursor.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindCursor.hpp?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindCursor.hpp (original)
+++ libunwind/trunk/src/UnwindCursor.hpp Wed May 25 07:36:34 2016
@@ -481,30 +481,39 @@ private:
     return stepWithCompactEncoding(dummy);
   }
 
+#if defined(_LIBUNWIND_TARGET_X86_64)
   int stepWithCompactEncoding(Registers_x86_64 &) {
     return CompactUnwinder_x86_64<A>::stepWithCompactEncoding(
         _info.format, _info.start_ip, _addressSpace, _registers);
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_I386)
   int stepWithCompactEncoding(Registers_x86 &) {
     return CompactUnwinder_x86<A>::stepWithCompactEncoding(
         _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers);
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_PPC)
   int stepWithCompactEncoding(Registers_ppc &) {
     return UNW_EINVAL;
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_AARCH64)
   int stepWithCompactEncoding(Registers_arm64 &) {
     return CompactUnwinder_arm64<A>::stepWithCompactEncoding(
         _info.format, _info.start_ip, _addressSpace, _registers);
   }
+#endif
 
   bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
     R dummy;
     return compactSaysUseDwarf(dummy, offset);
   }
 
+#if defined(_LIBUNWIND_TARGET_X86_64)
   bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const {
     if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) {
       if (offset)
@@ -513,7 +522,9 @@ private:
     }
     return false;
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_I386)
   bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const {
     if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) {
       if (offset)
@@ -522,11 +533,15 @@ private:
     }
     return false;
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_PPC)
   bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const {
     return true;
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_AARCH64)
   bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
     if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
       if (offset)
@@ -535,6 +550,7 @@ private:
     }
     return false;
   }
+#endif
 #endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
 
 #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
@@ -543,25 +559,35 @@ private:
     return dwarfEncoding(dummy);
   }
 
+#if defined(_LIBUNWIND_TARGET_X86_64)
   compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const {
     return UNWIND_X86_64_MODE_DWARF;
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_I386)
   compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const {
     return UNWIND_X86_MODE_DWARF;
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_PPC)
   compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const {
     return 0;
   }
+#endif
 
+#if defined(_LIBUNWIND_TARGET_AARCH64)
   compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
     return UNWIND_ARM64_MODE_DWARF;
   }
+#endif
 
+#if defined (_LIBUNWIND_TARGET_OR1K)
   compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
     return 0;
   }
+#endif
 #endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
 
 
@@ -577,7 +603,7 @@ template <typename A, typename R>
 UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
     : _addressSpace(as), _registers(context), _unwindInfoMissing(false),
       _isSignalFrame(false) {
-  static_assert(sizeof(UnwindCursor<A, R>) < sizeof(unw_cursor_t),
+  static_assert(check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit,
                 "UnwindCursor<> does not fit in unw_cursor_t");
   memset(&_info, 0, sizeof(_info));
 }

Modified: libunwind/trunk/src/config.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/config.h?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/src/config.h (original)
+++ libunwind/trunk/src/config.h Wed May 25 07:36:34 2016
@@ -119,5 +119,25 @@
   #define _LIBUNWIND_TRACING_UNWINDING logUnwinding()
 #endif
 
+#ifdef __cplusplus
+// Used to fit UnwindCursor and Registers_xxx types against unw_context_t /
+// unw_cursor_t sized memory blocks.
+#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
+# define COMP_OP ==
+#else
+# define COMP_OP <
+#endif
+template <typename _Type, typename _Mem>
+struct check_fit {
+  template <typename T>
+  struct blk_count {
+    static const uint32_t count =
+      (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
+  };
+  static const bool does_fit =
+    (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count);
+};
+#undef COMP_OP
+#endif // __cplusplus
 
 #endif // LIBUNWIND_CONFIG_H

Modified: libunwind/trunk/src/libunwind.cpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/libunwind.cpp?rev=270692&r1=270691&r2=270692&view=diff
==============================================================================
--- libunwind/trunk/src/libunwind.cpp (original)
+++ libunwind/trunk/src/libunwind.cpp Wed May 25 07:36:34 2016
@@ -45,30 +45,27 @@ _LIBUNWIND_EXPORT int unw_init_local(unw
   _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)\n",
                        static_cast<void *>(cursor),
                        static_cast<void *>(context));
-  // Use "placement new" to allocate UnwindCursor in the cursor buffer.
 #if defined(__i386__)
-  new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86>(
-                                 context, LocalAddressSpace::sThisAddressSpace);
+# define REGISTER_KIND Registers_x86
 #elif defined(__x86_64__)
-  new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86_64>(
-                                 context, LocalAddressSpace::sThisAddressSpace);
+# define REGISTER_KIND Registers_x86_64
 #elif defined(__ppc__)
-  new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_ppc>(
-                                 context, LocalAddressSpace::sThisAddressSpace);
-#elif defined(__arm64__) || defined(__aarch64__)
-  new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm64>(
-                                 context, LocalAddressSpace::sThisAddressSpace);
+# define REGISTER_KIND Registers_ppc
+#elif defined(__aarch64__)
+# define REGISTER_KIND Registers_arm64
 #elif _LIBUNWIND_ARM_EHABI
-  new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm>(
-                                 context, LocalAddressSpace::sThisAddressSpace);
+# define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
-  new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_or1k>(
-                                 context, LocalAddressSpace::sThisAddressSpace);
+# define REGISTER_KIND Registers_or1k
 #elif defined(__mips__)
-#warning The MIPS architecture is not supported.
+# warning The MIPS architecture is not supported.
 #else
-#error Architecture not supported
+# error Architecture not supported
 #endif
+  // Use "placement new" to allocate UnwindCursor in the cursor buffer.
+  new ((void *)cursor) UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
+                                 context, LocalAddressSpace::sThisAddressSpace);
+#undef REGISTER_KIND
   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
   co->setInfoBasedOnIPRegister();
 




More information about the cfe-commits mailing list