summaryrefslogtreecommitdiffstats
path: root/libcxxabi/src
diff options
context:
space:
mode:
authorJonathan Roelofs <jonathan@codesourcery.com>2014-08-21 18:42:36 +0000
committerJonathan Roelofs <jonathan@codesourcery.com>2014-08-21 18:42:36 +0000
commitf0a3281c5f0b0fe40388c6fd55a6e091d2cae5c5 (patch)
treef62dfe1bcdd9d7abf3aa4498d9395b3232b403a0 /libcxxabi/src
parentdf1836f750b3314a38fff2191d8d5a25b5825a15 (diff)
downloadbcm5719-llvm-f0a3281c5f0b0fe40388c6fd55a6e091d2cae5c5.tar.gz
bcm5719-llvm-f0a3281c5f0b0fe40388c6fd55a6e091d2cae5c5.zip
Add baremetal ARM support to libcxxabi/libunwind
http://reviews.llvm.org/D4993 llvm-svn: 216202
Diffstat (limited to 'libcxxabi/src')
-rw-r--r--libcxxabi/src/Unwind/AddressSpace.hpp25
-rw-r--r--libcxxabi/src/config.h7
-rw-r--r--libcxxabi/src/cxa_personality.cpp10
3 files changed, 40 insertions, 2 deletions
diff --git a/libcxxabi/src/Unwind/AddressSpace.hpp b/libcxxabi/src/Unwind/AddressSpace.hpp
index 594b4015f4b..4e94afc8eef 100644
--- a/libcxxabi/src/Unwind/AddressSpace.hpp
+++ b/libcxxabi/src/Unwind/AddressSpace.hpp
@@ -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_exidx(_Unwind_Ptr addr, int *len);
// 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::findUnwindSections(pint_t targetAddr,
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::findOtherFDE(pint_t targetAddr, pint_t &fde) {
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::findFunctionName(pint_t addr, char *buf,
return true;
}
}
+#endif
return false;
}
diff --git a/libcxxabi/src/config.h b/libcxxabi/src/config.h
index 72894471231..174abd2cf32 100644
--- a/libcxxabi/src/config.h
+++ b/libcxxabi/src/config.h
@@ -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
diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp
index c2ee3fdf18a..1c80898cbeb 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -314,8 +314,18 @@ static const void* read_target2_value(const void* ptr)
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*
OpenPOWER on IntegriCloud