diff --git a/libcxxabi/include/cxxabi.h b/libcxxabi/include/cxxabi.h index 82a7e74b5538..867ba72940fa 100644 --- a/libcxxabi/include/cxxabi.h +++ b/libcxxabi/include/cxxabi.h @@ -21,6 +21,14 @@ #define _LIBCPPABI_VERSION 1001 #define LIBCXXABI_NORETURN __attribute__((noreturn)) +// FIXME: This is also in unwind.h and libunwind.h, can we consolidate? +#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \ + !defined(__ARM_DWARF_EH__) && !defined(__APPLE__) +#define LIBCXXABI_ARM_EHABI 1 +#else +#define LIBCXXABI_ARM_EHABI 0 +#endif + #ifdef __cplusplus namespace std { @@ -44,7 +52,7 @@ extern LIBCXXABI_NORETURN void __cxa_throw(void * thrown_exception, extern void * __cxa_get_exception_ptr(void * exceptionObject) throw(); extern void * __cxa_begin_catch(void * exceptionObject) throw(); extern void __cxa_end_catch(); -#if __arm__ +#if LIBCXXABI_ARM_EHABI extern bool __cxa_begin_cleanup(void * exceptionObject) throw(); extern void __cxa_end_cleanup(); #endif @@ -172,8 +180,8 @@ extern bool __cxa_uncaught_exception() throw(); } // extern "C" } // namespace __cxxabiv1 -#endif // __cplusplus - namespace abi = __cxxabiv1; +#endif // __cplusplus + #endif // __CXXABI_H diff --git a/libcxxabi/include/libunwind.h b/libcxxabi/include/libunwind.h index eaeab39f9033..7b00f4fec561 100644 --- a/libcxxabi/include/libunwind.h +++ b/libcxxabi/include/libunwind.h @@ -17,6 +17,14 @@ #include #include +// FIXME: This is also in unwind.h and cxxabi.h, can we consolidate? +#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \ + !defined(__ARM_DWARF_EH__) && !defined(__APPLE__) +#define LIBCXXABI_ARM_EHABI 1 +#else +#define LIBCXXABI_ARM_EHABI 0 +#endif + #if __APPLE__ #include #if __arm__ @@ -56,8 +64,13 @@ typedef struct unw_cursor_t unw_cursor_t; typedef struct unw_addr_space *unw_addr_space_t; typedef int unw_regnum_t; +#if LIBCXXABI_ARM_EHABI +typedef uint32_t unw_word_t; +typedef uint64_t unw_fpreg_t; +#else typedef uint64_t unw_word_t; typedef double unw_fpreg_t; +#endif struct unw_proc_info_t { unw_word_t start_ip; /* start address of function */ diff --git a/libcxxabi/include/unwind.h b/libcxxabi/include/unwind.h index 131657da2dd7..f3a09ecd2457 100644 --- a/libcxxabi/include/unwind.h +++ b/libcxxabi/include/unwind.h @@ -23,6 +23,7 @@ #define LIBUNWIND_UNAVAIL #endif +// FIXME: This is also in cxxabi.h and libunwind.h, can we consolidate? #if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \ !defined(__ARM_DWARF_EH__) && !defined(__APPLE__) #define LIBCXXABI_ARM_EHABI 1 @@ -41,7 +42,9 @@ typedef enum { _URC_HANDLER_FOUND = 6, _URC_INSTALL_CONTEXT = 7, _URC_CONTINUE_UNWIND = 8, +#if LIBCXXABI_ARM_EHABI _URC_FAILURE = 9 +#endif } _Unwind_Reason_Code; typedef enum { diff --git a/libcxxabi/src/Unwind/AddressSpace.hpp b/libcxxabi/src/Unwind/AddressSpace.hpp index 283f14e4c43a..2682ec4169b9 100644 --- a/libcxxabi/src/Unwind/AddressSpace.hpp +++ b/libcxxabi/src/Unwind/AddressSpace.hpp @@ -31,11 +31,27 @@ namespace libunwind { #include "dwarf2.h" #include "Registers.hpp" +#if LIBCXXABI_ARM_EHABI +#if __LINUX__ + // Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system. + typedef long unsigned int *_Unwind_Ptr; + extern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr targetAddr, int *length); + _Unwind_Ptr (*dl_unwind_find_exidx)(_Unwind_Ptr targetAddr, int *length) = + __gnu_Unwind_Find_exidx; +#else + #include +#endif +#endif // LIBCXXABI_ARM_EHABI + namespace libunwind { /// Used by findUnwindSections() to return info about needed sections. struct UnwindInfoSections { - uintptr_t dso_base; +#if _LIBUNWIND_SUPPORT_DWARF_UNWIND || _LIBUNWIND_SUPPORT_DWARF_INDEX || \ + _LIBUNWIND_SUPPORT_COMPACT_UNWIND + // No dso_base for ARM EHABI. + uintptr_t dso_base; +#endif #if _LIBUNWIND_SUPPORT_DWARF_UNWIND uintptr_t dwarf_section; uintptr_t dwarf_section_length; @@ -48,6 +64,10 @@ struct UnwindInfoSections { uintptr_t compact_unwind_section; uintptr_t compact_unwind_section_length; #endif +#if LIBCXXABI_ARM_EHABI + uintptr_t arm_section; + uintptr_t arm_section_length; +#endif }; @@ -303,9 +323,15 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; return true; } -#else - // TO DO - +#elif LIBCXXABI_ARM_EHABI + int length = 0; + info.arm_section = (uintptr_t) dl_unwind_find_exidx( + (_Unwind_Ptr) targetAddr, &length); + info.arm_section_length = length; + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n", + info.arm_section, info.arm_section_length); + if (info.arm_section && info.arm_section_length) + return true; #endif return false; diff --git a/libcxxabi/src/Unwind/config.h b/libcxxabi/src/Unwind/config.h index 7d7e6bf0b7cd..638dab245851 100644 --- a/libcxxabi/src/Unwind/config.h +++ b/libcxxabi/src/Unwind/config.h @@ -57,16 +57,24 @@ #endif #else - // #define _LIBUNWIND_BUILD_ZERO_COST_APIS - // #define _LIBUNWIND_BUILD_SJLJ_APIS - // #define _LIBUNWIND_SUPPORT_FRAME_APIS - // #define _LIBUNWIND_EXPORT - // #define _LIBUNWIND_HIDDEN - // #define _LIBUNWIND_LOG() - // #define _LIBUNWIND_ABORT() - // #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND - // #define _LIBUNWIND_SUPPORT_DWARF_UNWIND - // #define _LIBUNWIND_SUPPORT_DWARF_INDEX + // ARM EHABI. + static inline void assert_rtn(const char* func, const char* file, int line, const char* msg) __attribute__ ((noreturn)); + static inline void assert_rtn(const char* func, const char* file, int line, const char* msg) { + fprintf(stderr, "libunwind: %s %s:%d - %s\n", func, file, line, msg); + assert(false); + abort(); + } + #define _LIBUNWIND_BUILD_ZERO_COST_APIS (__i386__ || __x86_64__ || __arm64__ || __arm__) + #define _LIBUNWIND_BUILD_SJLJ_APIS 0 + #define _LIBUNWIND_SUPPORT_FRAME_APIS (__i386__ || __x86_64__) + #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) + #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) + #define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__) + #define _LIBUNWIND_ABORT(msg) assert_rtn(__func__, __FILE__, __LINE__, msg) + + #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0 + #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0 + #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0 #endif