[libcxxabi] r211745 - Update libc++abi to use the ARM EHABI unwinder from its libunwind.

Nico Weber nicolasweber at gmx.de
Wed Jun 25 16:52:08 PDT 2014


Author: nico
Date: Wed Jun 25 18:52:07 2014
New Revision: 211745

URL: http://llvm.org/viewvc/llvm-project?rev=211745&view=rev
Log:
Update libc++abi to use the ARM EHABI unwinder from its libunwind.

Modified:
    libcxxabi/trunk/src/cxa_exception.cpp
    libcxxabi/trunk/src/cxa_exception.hpp
    libcxxabi/trunk/src/cxa_personality.cpp

Modified: libcxxabi/trunk/src/cxa_exception.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp?rev=211745&r1=211744&r2=211745&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_exception.cpp (original)
+++ libcxxabi/trunk/src/cxa_exception.cpp Wed Jun 25 18:52:07 2014
@@ -447,8 +447,17 @@ For a foreign exception:
 */
 void __cxa_end_catch()
 {
-    static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),
-                  "sizeof(__cxa_exception) must be equal to sizeof(__cxa_dependent_exception)");
+  static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),
+                "sizeof(__cxa_exception) must be equal to "
+                "sizeof(__cxa_dependent_exception)");
+    static_assert(offsetof(__cxa_exception, referenceCount) ==
+                      offsetof(__cxa_dependent_exception, primaryException),
+                  "the layout of __cxa_exception must match the layout of "
+                  "__cxa_dependent_exception");
+    static_assert(offsetof(__cxa_exception, handlerCount) ==
+                      offsetof(__cxa_dependent_exception, handlerCount),
+                  "the layout of __cxa_exception must match the layout of "
+                  "__cxa_dependent_exception");
     __cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch
     __cxa_exception* exception_header = globals->caughtExceptions;
     // If we've rethrown a foreign exception, then globals->caughtExceptions

Modified: libcxxabi/trunk/src/cxa_exception.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_exception.hpp?rev=211745&r1=211744&r2=211745&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_exception.hpp (original)
+++ libcxxabi/trunk/src/cxa_exception.hpp Wed Jun 25 18:52:07 2014
@@ -67,9 +67,10 @@ struct __cxa_exception {
 };
 
 // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
-    
+// The layout of this structure MUST match the layout of __cxa_exception, with
+// primaryException instead of referenceCount.
 struct __cxa_dependent_exception {
-#if __LP64__
+#if __LP64__ || LIBCXXABI_ARM_EHABI
     void* primaryException;
 #endif
     
@@ -93,7 +94,7 @@ struct __cxa_dependent_exception {
     void *adjustedPtr;
 #endif
     
-#if !__LP64__
+#if !__LP64__ && !LIBCXXABI_ARM_EHABI
     void* primaryException;
 #endif
 

Modified: libcxxabi/trunk/src/cxa_personality.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_personality.cpp?rev=211745&r1=211744&r2=211745&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_personality.cpp (original)
+++ libcxxabi/trunk/src/cxa_personality.cpp Wed Jun 25 18:52:07 2014
@@ -12,6 +12,7 @@
 //  
 //===----------------------------------------------------------------------===//
 
+#include "config.h"
 #include "unwind.h"
 #include "cxa_exception.hpp"
 #include "cxa_handlers.hpp"
@@ -313,7 +314,8 @@ static const void* read_target2_value(co
     uintptr_t offset = *reinterpret_cast<const uintptr_t*>(ptr);
     if (!offset)
         return 0;
-    return *reinterpret_cast<const void**>(reinterpret_cast<uintptr_t>(ptr) + offset);
+    return *reinterpret_cast<const void **>(reinterpret_cast<uintptr_t>(ptr) +
+                                            offset);
 }
 
 static const __shim_type_info*
@@ -331,9 +333,10 @@ get_shim_type_info(uint64_t ttypeIndex,
     (void)ttypeEncoding;
 
     const uint8_t* ttypePtr = classInfo - ttypeIndex * sizeof(uintptr_t);
-    return reinterpret_cast<const __shim_type_info*>(read_target2_value(ttypePtr));
+    return reinterpret_cast<const __shim_type_info *>(
+        read_target2_value(ttypePtr));
 }
-#else
+#else // !LIBCXXABI_ARM_EHABI
 static
 const __shim_type_info*
 get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,
@@ -369,7 +372,7 @@ get_shim_type_info(uint64_t ttypeIndex,
     classInfo -= ttypeIndex;
     return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding);
 }
-#endif
+#endif // !LIBCXXABI_ARM_EHABI
 
 /*
     This is checking a thrown exception type, excpType, against a possibly empty
@@ -493,15 +496,10 @@ void
 set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
               const scan_results& results)
 {
-#if __arm__
-    _Unwind_SetGR(context, 0, reinterpret_cast<uintptr_t>(unwind_exception));
-    _Unwind_SetGR(context, 1, static_cast<uintptr_t>(results.ttypeIndex));
-#else
     _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
                                  reinterpret_cast<uintptr_t>(unwind_exception));
     _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
                                     static_cast<uintptr_t>(results.ttypeIndex));
-#endif
     _Unwind_SetIP(context, results.landingPad);
 }
 
@@ -526,11 +524,10 @@ set_registers(_Unwind_Exception* unwind_
         _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME
 */
 
-static
-void
-scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception,
-            _Unwind_Exception* unwind_exception, _Unwind_Context* context)
-{
+static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
+                        bool native_exception,
+                        _Unwind_Exception *unwind_exception,
+                        _Unwind_Context *context, const uint8_t *lsda) {
     // Initialize results to found nothing but an error
     results.ttypeIndex = 0;
     results.actionRecord = 0;
@@ -569,7 +566,6 @@ scan_eh_tab(scan_results& results, _Unwi
         return;
     }
     // Start scan by getting exception table address
-    const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
     if (lsda == 0)
     {
         // There is no exception table
@@ -929,7 +925,9 @@ __gxx_personality_v0
     {
         // Phase 1 search:  All we're looking for in phase 1 is a handler that
         //   halts unwinding
-        scan_eh_tab(results, actions, native_exception, unwind_exception, context);
+        scan_eh_tab(
+            results, actions, native_exception, unwind_exception, context,
+            (const uint8_t *)_Unwind_GetLanguageSpecificData(context));
         if (results.reason == _URC_HANDLER_FOUND)
         {
             // Found one.  Can we cache the results somewhere to optimize phase 2?
@@ -970,7 +968,10 @@ __gxx_personality_v0
             else
             {
                 // No, do the scan again to reload the results.
-                scan_eh_tab(results, actions, native_exception, unwind_exception, context);
+                scan_eh_tab(
+                    results, actions, native_exception,
+                    unwind_exception, context,
+                    (const uint8_t*)_Unwind_GetLanguageSpecificData(context));
                 // Phase 1 told us we would find a handler.  Now in Phase 2 we
                 //   didn't find a handler.  The eh table should not be changing!
                 if (results.reason != _URC_HANDLER_FOUND)
@@ -983,7 +984,9 @@ __gxx_personality_v0
         // Either we didn't do a phase 1 search (due to forced unwinding), or
         //   phase 1 reported no catching-handlers.
         // Search for a (non-catching) cleanup
-        scan_eh_tab(results, actions, native_exception, unwind_exception, context);
+        scan_eh_tab(
+            results, actions, native_exception, unwind_exception, context,
+            (const uint8_t*)_Unwind_GetLanguageSpecificData(context));
         if (results.reason == _URC_HANDLER_FOUND)
         {
             // Found a non-catching handler.  Jump to it:
@@ -1000,16 +1003,16 @@ __gxx_personality_v0
 }
 #else
 
-extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*);
-
 // Helper function to unwind one frame.
 // ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the
 // personality routine should update the virtual register set (VRS) according to the
 // corresponding frame unwinding instructions (ARM EHABI 9.3.)
-static _Unwind_Reason_Code continue_unwind(_Unwind_Exception* unwind_exception,
-                                           _Unwind_Context* context)
+static _Unwind_Reason_Code continue_unwind(_Unwind_Context* context,
+                                           uint32_t* unwind_opcodes,
+                                           size_t opcode_words)
 {
-    if (__gnu_unwind_frame(unwind_exception, context) != _URC_OK)
+    if (_Unwind_VRS_Interpret(context, unwind_opcodes, 1, opcode_words * 4) !=
+        _URC_CONTINUE_UNWIND)
         return _URC_FAILURE;
     return _URC_CONTINUE_UNWIND;
 }
@@ -1049,15 +1052,48 @@ __gxx_personality_v0(_Unwind_State state
     bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) ==
                             (kOurExceptionClass & get_vendor_and_language);
 
-    // Copy the address of _Unwind_Control_Block to r12 so that _Unwind_GetLanguageSpecificData()
-    // and _Unwind_GetRegionStart() can return correct address.
+#if LIBCXXABI_ARM_EHABI
+    // ARM EHABI # 6.2, # 9.2
+    //
+    //  +---- ehtp
+    //  v
+    // +--------------------------------------+
+    // | +--------+--------+--------+-------+ |
+    // | |0| prel31 to __gxx_personality_v0 | |
+    // | +--------+--------+--------+-------+ |
+    // | |      N |      unwind opcodes     | |  <-- UnwindData
+    // | +--------+--------+--------+-------+ |
+    // | | Word 2        unwind opcodes     | |
+    // | +--------+--------+--------+-------+ |
+    // | ...                                  |
+    // | +--------+--------+--------+-------+ |
+    // | | Word N        unwind opcodes     | |
+    // | +--------+--------+--------+-------+ |
+    // | | LSDA                             | |  <-- lsda
+    // | | ...                              | |
+    // | +--------+--------+--------+-------+ |
+    // +--------------------------------------+
+
+    uint32_t *UnwindData = unwind_exception->pr_cache.ehtp + 1;
+    uint32_t FirstDataWord = *UnwindData;
+    size_t N = ((FirstDataWord >> 24) & 0xff);
+    size_t NDataWords = N + 1;
+#endif
+
+    const uint8_t *lsda =
+        (const uint8_t *)_Unwind_GetLanguageSpecificData(context);
+
+    // Copy the address of _Unwind_Control_Block to r12 so that
+    // _Unwind_GetLanguageSpecificData() and _Unwind_GetRegionStart() can
+    // return correct address.
     _Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception));
 
     scan_results results;
     switch (state) {
     case _US_VIRTUAL_UNWIND_FRAME:
         // Phase 1 search:  All we're looking for in phase 1 is a handler that halts unwinding
-        scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context);
+        scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception,
+                    unwind_exception, context, lsda);
         if (results.reason == _URC_HANDLER_FOUND)
         {
             unwind_exception->barrier_cache.sp = _Unwind_GetGR(context, REG_SP);
@@ -1067,7 +1103,7 @@ __gxx_personality_v0(_Unwind_State state
         }
         // Did not find the catch handler
         if (results.reason == _URC_CONTINUE_UNWIND)
-            return continue_unwind(unwind_exception, context);
+            return continue_unwind(context, UnwindData, NDataWords);
         return results.reason;
 
     case _US_UNWIND_FRAME_STARTING:
@@ -1085,7 +1121,7 @@ __gxx_personality_v0(_Unwind_State state
             {
                 // Search for the catching handler again for the foreign exception.
                 scan_eh_tab(results, static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME),
-                            native_exception, unwind_exception, context);
+                            native_exception, unwind_exception, context, lsda);
                 if (results.reason != _URC_HANDLER_FOUND)  // phase1 search should guarantee to find one
                     call_terminate(native_exception, unwind_exception);
             }
@@ -1095,8 +1131,11 @@ __gxx_personality_v0(_Unwind_State state
             return _URC_INSTALL_CONTEXT;
         }
 
+        // Either we didn't do a phase 1 search (due to forced unwinding), or
+        //  phase 1 reported no catching-handlers.
         // Search for a (non-catching) cleanup
-        scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context);
+        scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception,
+                    unwind_exception, context, lsda);
         if (results.reason == _URC_HANDLER_FOUND)
         {
             // Found a non-catching handler
@@ -1113,11 +1152,11 @@ __gxx_personality_v0(_Unwind_State state
 
         // Did not find any handler
         if (results.reason == _URC_CONTINUE_UNWIND)
-            return continue_unwind(unwind_exception, context);
+            return continue_unwind(context, UnwindData, NDataWords);
         return results.reason;
 
     case _US_UNWIND_FRAME_RESUME:
-        return continue_unwind(unwind_exception, context);
+        return continue_unwind(context, UnwindData, NDataWords);
     }
 
     // We were called improperly: neither a phase 1 or phase 2 search





More information about the cfe-commits mailing list