[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