forked from OSchip/llvm-project
Add ARM EHABI support to gcc_personality_v0.
Until now the only exception APIs supported by gcc_personality_v0 are DWARF EH and SJLJ. This adds support for ARM EHABI as well. This is achieved by a) changing the function signature on ARM EHABI, b) unwinding the stack before returning _URC_CONTINUE_UNWIND. See "Exception Handling ABI for the ARM Architecture" for details (http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf). Patch by Timon Van Overveldt. llvm-svn: 263010
This commit is contained in:
parent
ecf1b4c24d
commit
5b7b9e946c
|
@ -131,6 +131,26 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)
|
|||
return result;
|
||||
}
|
||||
|
||||
#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
|
||||
!defined(__ARM_DWARF_EH__)
|
||||
#define USING_ARM_EHABI 1
|
||||
_Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *,
|
||||
struct _Unwind_Context *);
|
||||
#endif
|
||||
|
||||
static inline _Unwind_Reason_Code
|
||||
continueUnwind(struct _Unwind_Exception *exceptionObject,
|
||||
struct _Unwind_Context *context) {
|
||||
#if USING_ARM_EHABI
|
||||
/*
|
||||
* On ARM EHABI the personality routine is responsible for actually
|
||||
* unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
|
||||
*/
|
||||
if (__gnu_unwind_frame(exceptionObject, context) != _URC_OK)
|
||||
return _URC_FAILURE;
|
||||
#endif
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
}
|
||||
|
||||
/*
|
||||
* The C compiler makes references to __gcc_personality_v0 in
|
||||
|
@ -147,6 +167,11 @@ COMPILER_RT_ABI _Unwind_Reason_Code
|
|||
__gcc_personality_sj0(int version, _Unwind_Action actions,
|
||||
uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
|
||||
struct _Unwind_Context *context)
|
||||
#elif USING_ARM_EHABI
|
||||
/* The ARM EHABI personality routine has a different signature. */
|
||||
COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
|
||||
_Unwind_State state, struct _Unwind_Exception *exceptionObject,
|
||||
struct _Unwind_Context *context)
|
||||
#else
|
||||
COMPILER_RT_ABI _Unwind_Reason_Code
|
||||
__gcc_personality_v0(int version, _Unwind_Action actions,
|
||||
|
@ -156,13 +181,19 @@ __gcc_personality_v0(int version, _Unwind_Action actions,
|
|||
{
|
||||
/* Since C does not have catch clauses, there is nothing to do during */
|
||||
/* phase 1 (the search phase). */
|
||||
if ( actions & _UA_SEARCH_PHASE )
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
|
||||
#if USING_ARM_EHABI
|
||||
/* After resuming from a cleanup we should also continue on to the next
|
||||
* frame straight away. */
|
||||
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
|
||||
#else
|
||||
if ( actions & _UA_SEARCH_PHASE )
|
||||
#endif
|
||||
return continueUnwind(exceptionObject, context);
|
||||
|
||||
/* There is nothing to do if there is no LSDA for this frame. */
|
||||
const uint8_t* lsda = (uint8_t*)_Unwind_GetLanguageSpecificData(context);
|
||||
if ( lsda == (uint8_t*) 0 )
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
return continueUnwind(exceptionObject, context);
|
||||
|
||||
uintptr_t pc = _Unwind_GetIP(context)-1;
|
||||
uintptr_t funcStart = _Unwind_GetRegionStart(context);
|
||||
|
@ -205,6 +236,6 @@ __gcc_personality_v0(int version, _Unwind_Action actions,
|
|||
}
|
||||
|
||||
/* No landing pad found, continue unwinding. */
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
return continueUnwind(exceptionObject, context);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue