From 088977679e11584f89a3a5d35939460311955591 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sat, 30 Mar 2019 20:01:19 +0000 Subject: [PATCH] DWARF EH cleanups. Update the C++ ABI for the C++11 ABI and fix the missing ARM-specific bits. Work around a bug in ARM. --- eh_personality.c | 13 ++++++++----- objcxx_eh.cc | 10 ++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/eh_personality.c b/eh_personality.c index 7f2f1f13..c6e992b4 100644 --- a/eh_personality.c +++ b/eh_personality.c @@ -89,7 +89,7 @@ static void saveLandingPad(struct _Unwind_Context *context, int selector, dw_eh_ptr_t landingPad) { -#ifdef __arm__ +#ifdef __arm__ && !defined(__ARM_DWARF_EH__) // On ARM, we store the saved exception in the generic part of the structure ucb->barrier_cache.sp = _Unwind_GetGR(context, 13); ucb->barrier_cache.bitpattern[1] = (uint32_t)selector; @@ -116,7 +116,7 @@ static int loadLandingPad(struct _Unwind_Context *context, unsigned long *selector, dw_eh_ptr_t *landingPad) { -#ifdef __arm__ +#ifdef __arm__ && !defined(__ARM_DWARF_EH__) *selector = ucb->barrier_cache.bitpattern[1]; *landingPad = (dw_eh_ptr_t)ucb->barrier_cache.bitpattern[3]; return 1; @@ -134,7 +134,7 @@ static int loadLandingPad(struct _Unwind_Context *context, static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex, struct _Unwind_Context *context) { -#ifdef __arm__ +#ifdef __arm__ && !defined(__ARM_DWARF_EH__) if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; } #endif return _URC_CONTINUE_UNWIND; @@ -418,14 +418,17 @@ static inline _Unwind_Reason_Code internal_objc_personality(int version, handler_type handler = check_action_record(context, foreignException, &lsda, action.action_record, thrown_class, &selector); DEBUG_LOG("handler! %d %d\n", (int)handler, (int)selector); + // On ARM, we occasionally get called to install a handler without + // phase 1 running (no idea why, I suspect a bug in the generic + // unwinder), so skip this check. +#ifdef __arm__ && !defined(__ARM_DWARF_EH__) // If this is not a cleanup, ignore it and keep unwinding. - //if (check_action_record(context, foreignException, &lsda, - //action.action_record, thrown_class, &selector) != handler_cleanup) if ((handler != handler_cleanup) && !objcxxException) { DEBUG_LOG("Ignoring handler! %d\n",handler); return continueUnwinding(exceptionObject, context); } +#endif DEBUG_LOG("Installing cleanup...\n"); // If there is a cleanup, we need to return the exception structure // (not the object) to the calling frame. The exception object diff --git a/objcxx_eh.cc b/objcxx_eh.cc index edb48f3b..11c0d513 100644 --- a/objcxx_eh.cc +++ b/objcxx_eh.cc @@ -76,17 +76,27 @@ static BOOL isKindOfClass(Class thrown, Class type) */ struct __cxa_exception { +#if __LP64__ + uintptr_t referenceCount; +#endif std::type_info *exceptionType; void (*exceptionDestructor) (void *); unexpected_handler unexpectedHandler; terminate_handler terminateHandler; __cxa_exception *nextException; int handlerCount; +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + _Unwind_Exception *nextCleanup; + int cleanupCount; +#endif int handlerSwitchValue; const char *actionRecord; const char *languageSpecificData; void *catchTemp; void *adjustedPtr; +#if !__LP64__ + uintptr_t referenceCount; +#endif _Unwind_Exception unwindHeader; };