[libcxxabi] r216202 - Add baremetal ARM support to libcxxabi/libunwind

Jonathan Roelofs jonathan at codesourcery.com
Thu Aug 21 11:42:37 PDT 2014


Author: jroelofs
Date: Thu Aug 21 13:42:36 2014
New Revision: 216202

URL: http://llvm.org/viewvc/llvm-project?rev=216202&view=rev
Log:
Add baremetal ARM support to libcxxabi/libunwind

http://reviews.llvm.org/D4993

Modified:
    libcxxabi/trunk/src/Unwind/AddressSpace.hpp
    libcxxabi/trunk/src/config.h
    libcxxabi/trunk/src/cxa_personality.cpp

Modified: libcxxabi/trunk/src/Unwind/AddressSpace.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/Unwind/AddressSpace.hpp?rev=216202&r1=216201&r2=216202&view=diff
==============================================================================
--- libcxxabi/trunk/src/Unwind/AddressSpace.hpp (original)
+++ libcxxabi/trunk/src/Unwind/AddressSpace.hpp Thu Aug 21 13:42:36 2014
@@ -17,7 +17,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#if !_LIBUNWIND_IS_BAREMETAL
 #include <dlfcn.h>
+#endif
 
 #if __APPLE__
 #include <mach-o/getsect.h>
@@ -40,9 +43,19 @@ extern "C" _Unwind_Ptr __gnu_Unwind_Find
 // Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system.
 #define dl_unwind_find_exidx __gnu_Unwind_Find_exidx
 
-#else
+#elif !_LIBUNWIND_IS_BAREMETAL
 #include <link.h>
-#endif
+#else // _LIBUNWIND_IS_BAREMETAL
+// When statically linked on bare-metal, the symbols for the EH table are looked
+// up without going through the dynamic loader.
+struct EHTEntry {
+  uint32_t functionOffset;
+  uint32_t unwindOpcodes;
+};
+extern EHTEntry __exidx_start;
+extern EHTEntry __exidx_end;
+#endif // !_LIBUNWIND_IS_BAREMETAL
+
 #endif  // LIBCXXABI_ARM_EHABI
 
 namespace libunwind {
@@ -326,10 +339,16 @@ inline bool LocalAddressSpace::findUnwin
     return true;
   }
 #elif LIBCXXABI_ARM_EHABI
+ #if _LIBUNWIND_IS_BAREMETAL
+  // Bare metal is statically linked, so no need to ask the dynamic loader
+  info.arm_section =        (uintptr_t)(&__exidx_start);
+  info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start);
+ #else
   int length = 0;
   info.arm_section = (uintptr_t) dl_unwind_find_exidx(
       (_Unwind_Ptr) targetAddr, &length);
   info.arm_section_length = (uintptr_t)length;
+ #endif
   _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n",
                              info.arm_section, info.arm_section_length);
   if (info.arm_section && info.arm_section_length)
@@ -354,6 +373,7 @@ inline bool LocalAddressSpace::findOther
 inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
                                                 size_t bufLen,
                                                 unw_word_t *offset) {
+#if !_LIBUNWIND_IS_BAREMETAL
   Dl_info dyldInfo;
   if (dladdr((void *)addr, &dyldInfo)) {
     if (dyldInfo.dli_sname != NULL) {
@@ -362,6 +382,7 @@ inline bool LocalAddressSpace::findFunct
       return true;
     }
   }
+#endif
   return false;
 }
 

Modified: libcxxabi/trunk/src/config.h
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/config.h?rev=216202&r1=216201&r2=216202&view=diff
==============================================================================
--- libcxxabi/trunk/src/config.h (original)
+++ libcxxabi/trunk/src/config.h Thu Aug 21 13:42:36 2014
@@ -22,4 +22,11 @@
 #  define LIBCXXABI_SINGLE_THREADED 1
 #endif
 
+// Set this in the CXXFLAGS when you need it, because otherwise we'd have to
+// #if !defined(__linux__) && !defined(__APPLE__) && ...
+// and so-on for *every* platform.
+#ifndef LIBCXXABI_BAREMETAL
+#  define LIBCXXABI_BAREMETAL 0
+#endif
+
 #endif // LIBCXXABI_CONFIG_H

Modified: libcxxabi/trunk/src/cxa_personality.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_personality.cpp?rev=216202&r1=216201&r2=216202&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_personality.cpp (original)
+++ libcxxabi/trunk/src/cxa_personality.cpp Thu Aug 21 13:42:36 2014
@@ -314,8 +314,18 @@ static const void* read_target2_value(co
     uintptr_t offset = *reinterpret_cast<const uintptr_t*>(ptr);
     if (!offset)
         return 0;
+    // "ARM EABI provides a TARGET2 relocation to describe these typeinfo
+    // pointers. The reason being it allows their precise semantics to be
+    // deferred to the linker. For bare-metal they turn into absolute
+    // relocations. For linux they turn into GOT-REL relocations."
+    // https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html
+#if LIBCXXABI_BAREMETAL
+    return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(ptr) +
+                                         offset);
+#else
     return *reinterpret_cast<const void **>(reinterpret_cast<uintptr_t>(ptr) +
                                             offset);
+#endif
 }
 
 static const __shim_type_info*





More information about the cfe-commits mailing list