[PATCH] libcxxabi/unwind: Add support for ARM EHABI in AddressSpace.hpp

Dana Jansens danakj at google.com
Tue Jun 3 18:27:39 PDT 2014


Here's an updated patch that uses LIBCXX_API_EHABI. Since this is in
AddressSpace.hpp which is part of the "libunwind" layer, I've duplicated
the #define for this from the unwind.h which is part of the "_Unwind" layer
to avoid including the unwind.h header which doesn't belong in
AddressSpace.hpp.


On Wed, Jun 4, 2014 at 2:29 AM, Dana Jansens <danakj at google.com> wrote:

> On Wed, Jun 4, 2014 at 2:09 AM, Nick Kledzik <kledzik at apple.com> wrote:
>
>>
>> On Jun 3, 2014, at 4:58 PM, Dana Jansens <danakj at google.com> wrote:
>>
>>
>>> The setjump-longjump is similar to this.  It does not use the lower
>>> level libunwind APIs and it has its own phase1/phase2 unwinding code
>>> separate from the Itanium style.  So, it makes sense to me for the ARM
>>> EHABI  implementation to be in its own Unwind-ehabi.c file and do not use
>>> libunwind under it.  This was part of why I thought of EHABI as being a
>>> different unwinder than the zero-cost unwinder in terms of
>>> _LIBUNWIND_BUILD_blah.
>>>
>>
>> We discussed making a change like that, but we're more concerned with
>> upstreaming first right now, rather than keeping this all on a private
>> repo. Since the way we developed this was sharing code with the itanium
>> implementation as much as possible, are you okay with upstreaming it in
>> this fashion and then looking at moving it away in the future?
>>
>>
>> Can you be more specific about what you mean by “in this fashion” and
>> “moving it away in the future”.
>>
>
> Sure! What we have in our repo[1] is an implementation of ARM EHABI on top
> of the Itanium APIs. Initially we felt that made a lot of sense, though
> more recently we've started thinking about doing something different to fit
> the ARM EHABI requirements better. So, currently we are sharing code in
> unwind_level1, and AddressSpace and so on, as much as possible. This also
> helps keep our diffs smaller, I think.
>
> In the future (maybe 6 months out) we could consider moving the
> implementation away from sharing code with itanium with #ifdefs, and moving
> to something more separate like SJLJ. But this isn't something we can
> realistically commit to doing right now, so it would make upstreaming a lot
> more difficult.
>
> What we have is a functioning implementation that passes the tests, so I
> think it's not unreasonable. Concretely, this means using #if
> LIBCXX_ARM_EHABI throughout each of the three cxxabi, Unwind, and libunwind
> layers.
>
> [1]
> https://github.com/awong-dev/ndk/compare/upstream-llvm-ndkpatched...master#commit_comments_bucket
>
>
>>
>> -Nick
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140604/2c18d583/attachment.html>
-------------- next part --------------
commit 0e3bc35b917eee440e838e3d7841617342f39aaf
Author: Dana Jansens <danakj at chromium.org>
Date:   Mon Jun 2 08:39:12 2014 -0400

    unwind: Add support for ARM EHABI in LocalAddressSpace.
    
    When building on non-apple, define _LIBUNWIND_SUPPORT_ARM_EHABI_UNWIND.
    Then use this define to make LocalAddressSpace::findUnwindSections()
    find the exidx section, and store that in the UnwindInfoSections.
    
    Since ARM EHABI does not need a dso_base variable in the
    UnwindInfoSections, move it into each of the other platform blocks
    to avoid it when implementing ARM EHABI.
    
    Change-Id: I525e5a0b917a036511eb59a0631af7fb663d6b66

diff --git a/libcxxabi/include/libunwind.h b/libcxxabi/include/libunwind.h
index eaeab39..4c1415e 100644
--- a/libcxxabi/include/libunwind.h
+++ b/libcxxabi/include/libunwind.h
@@ -17,6 +17,14 @@
 #include <stdint.h>
 #include <stddef.h>
 
+// FIXME: This is also in unwind.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__
diff --git a/libcxxabi/include/unwind.h b/libcxxabi/include/unwind.h
index 131657d..03f5f4c 100644
--- a/libcxxabi/include/unwind.h
+++ b/libcxxabi/include/unwind.h
@@ -23,6 +23,7 @@
 #define LIBUNWIND_UNAVAIL
 #endif
 
+// FIXME: This is also in libunwind.h, can we consolidate?
 #if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
     !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
 #define LIBCXXABI_ARM_EHABI 1
diff --git a/libcxxabi/src/Unwind/AddressSpace.hpp b/libcxxabi/src/Unwind/AddressSpace.hpp
index 283f14e..332bc51 100644
--- a/libcxxabi/src/Unwind/AddressSpace.hpp
+++ b/libcxxabi/src/Unwind/AddressSpace.hpp
@@ -31,23 +31,42 @@ 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
+  uintptr_t       dso_base;
   uintptr_t       dwarf_section;
   uintptr_t       dwarf_section_length;
 #endif
 #if _LIBUNWIND_SUPPORT_DWARF_INDEX
+  uintptr_t       dso_base;
   uintptr_t       dwarf_index_section;
   uintptr_t       dwarf_index_section_length;
 #endif
 #if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
+  uintptr_t       dso_base;
   uintptr_t       compact_unwind_section;
   uintptr_t       compact_unwind_section_length;
 #endif
+#if LIBCXXABI_ARM_EHABI
+  // No dso_base for ARM EHABI.
+  uintptr_t       arm_section;
+  uintptr_t       arm_section_length;
+#endif
 };
 
 
@@ -303,9 +322,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 7d7e6bf..638dab2 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
 
 


More information about the cfe-commits mailing list