Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.

Commit 83e5e5f

Browse files
committed
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. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@263010 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c05591f commit 83e5e5f

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

lib/builtins/gcc_personality_v0.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,26 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)
131131
return result;
132132
}
133133

134+
#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
135+
!defined(__ARM_DWARF_EH__)
136+
#define USING_ARM_EHABI 1
137+
_Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *,
138+
struct _Unwind_Context *);
139+
#endif
140+
141+
static inline _Unwind_Reason_Code
142+
continueUnwind(struct _Unwind_Exception *exceptionObject,
143+
struct _Unwind_Context *context) {
144+
#if USING_ARM_EHABI
145+
/*
146+
* On ARM EHABI the personality routine is responsible for actually
147+
* unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
148+
*/
149+
if (__gnu_unwind_frame(exceptionObject, context) != _URC_OK)
150+
return _URC_FAILURE;
151+
#endif
152+
return _URC_CONTINUE_UNWIND;
153+
}
134154

135155
/*
136156
* The C compiler makes references to __gcc_personality_v0 in
@@ -147,6 +167,11 @@ COMPILER_RT_ABI _Unwind_Reason_Code
147167
__gcc_personality_sj0(int version, _Unwind_Action actions,
148168
uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
149169
struct _Unwind_Context *context)
170+
#elif USING_ARM_EHABI
171+
/* The ARM EHABI personality routine has a different signature. */
172+
COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
173+
_Unwind_State state, struct _Unwind_Exception *exceptionObject,
174+
struct _Unwind_Context *context)
150175
#else
151176
COMPILER_RT_ABI _Unwind_Reason_Code
152177
__gcc_personality_v0(int version, _Unwind_Action actions,
@@ -156,13 +181,19 @@ __gcc_personality_v0(int version, _Unwind_Action actions,
156181
{
157182
/* Since C does not have catch clauses, there is nothing to do during */
158183
/* phase 1 (the search phase). */
159-
if ( actions & _UA_SEARCH_PHASE )
160-
return _URC_CONTINUE_UNWIND;
161-
184+
#if USING_ARM_EHABI
185+
/* After resuming from a cleanup we should also continue on to the next
186+
* frame straight away. */
187+
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
188+
#else
189+
if ( actions & _UA_SEARCH_PHASE )
190+
#endif
191+
return continueUnwind(exceptionObject, context);
192+
162193
/* There is nothing to do if there is no LSDA for this frame. */
163194
const uint8_t* lsda = (uint8_t*)_Unwind_GetLanguageSpecificData(context);
164195
if ( lsda == (uint8_t*) 0 )
165-
return _URC_CONTINUE_UNWIND;
196+
return continueUnwind(exceptionObject, context);
166197

167198
uintptr_t pc = _Unwind_GetIP(context)-1;
168199
uintptr_t funcStart = _Unwind_GetRegionStart(context);
@@ -205,6 +236,6 @@ __gcc_personality_v0(int version, _Unwind_Action actions,
205236
}
206237

207238
/* No landing pad found, continue unwinding. */
208-
return _URC_CONTINUE_UNWIND;
239+
return continueUnwind(exceptionObject, context);
209240
}
210241

0 commit comments

Comments
 (0)