[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