Start landing support for ARM EHABI unwinding.
authorNico Weber <nicolasweber@gmx.de>
Wed, 25 Jun 2014 22:49:13 +0000 (22:49 +0000)
committerNico Weber <nicolasweber@gmx.de>
Wed, 25 Jun 2014 22:49:13 +0000 (22:49 +0000)
The new code will be behind a LIBCXXABI_ARM_EHABI define (so that platforms
that don't want it can continue using e.g. SJLJ). This commit mostly just
adds the LIBCXXABI_ARM_EHABI define.

llvm-svn: 211739

libcxxabi/include/cxxabi.h
libcxxabi/include/libunwind.h
libcxxabi/include/unwind.h
libcxxabi/src/Unwind/AddressSpace.hpp
libcxxabi/src/Unwind/config.h

index 82a7e74..867ba72 100644 (file)
 #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 
index eaeab39..7b00f4f 100644 (file)
 #include <stdint.h>
 #include <stddef.h>
 
+// 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 <Availability.h>
     #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 */
index 131657d..f3a09ec 100644 (file)
@@ -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 {
index 283f14e..2682ec4 100644 (file)
@@ -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 <link.h>
+#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;
index 7d7e6bf..638dab2 100644 (file)
   #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