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

Commit 59c23b7

Browse files
loganchienalexcrichton
authored andcommitted
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 This is a cherry-pick of upstream commit 83e5e5f.
1 parent 17817a2 commit 59c23b7

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

lib/builtins/gcc_personality_v0.c

Lines changed: 37 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

@@ -227,7 +258,8 @@ __gcc_personality_v0(int version, _Unwind_Action actions,
227258
#endif // SJ/LJ
228259

229260
if (resumeIp == 0) {
230-
return _URC_CONTINUE_UNWIND;
261+
/* No landing pad found, continue unwinding. */
262+
return continueUnwind(exceptionObject, context);
231263
} else {
232264
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
233265
(uintptr_t)exceptionObject);

0 commit comments

Comments
 (0)