diff options
author | Jonathan Roelofs <jonathan@codesourcery.com> | 2014-08-21 18:42:36 +0000 |
---|---|---|
committer | Jonathan Roelofs <jonathan@codesourcery.com> | 2014-08-21 18:42:36 +0000 |
commit | f0a3281c5f0b0fe40388c6fd55a6e091d2cae5c5 (patch) | |
tree | f62dfe1bcdd9d7abf3aa4498d9395b3232b403a0 /libcxxabi/src | |
parent | df1836f750b3314a38fff2191d8d5a25b5825a15 (diff) | |
download | bcm5719-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.hpp | 25 | ||||
-rw-r--r-- | libcxxabi/src/config.h | 7 | ||||
-rw-r--r-- | libcxxabi/src/cxa_personality.cpp | 10 |
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* |