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

Commit df1e1ca

Browse files
committed
Support for SJ/LJ unwinding (arm)
1 parent ea92339 commit df1e1ca

File tree

1 file changed

+52
-20
lines changed

1 file changed

+52
-20
lines changed

lib/builtins/gcc_personality_v0.c

+52-20
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)
180180
* on each frame as the stack is unwound during a C++ exception
181181
* throw through a C function compiled with -fexceptions.
182182
*/
183-
#if __arm__
183+
#if defined(__USING_SJLJ_EXCEPTIONS__)
184184
// the setjump-longjump based exceptions personality routine has a different name
185185
COMPILER_RT_ABI _Unwind_Reason_Code
186186
__gcc_personality_sj0(int version, _Unwind_Action actions,
@@ -216,34 +216,66 @@ __gcc_personality_v0(int version, _Unwind_Action actions,
216216
if (ttypeEncoding != DW_EH_PE_omit) {
217217
readULEB128(&lsda);
218218
}
219-
/* Walk call-site table looking for range that includes current PC. */
219+
220+
uintptr_t resumeIp = 0;
220221
uint8_t callSiteEncoding = *lsda++;
221222
uint32_t callSiteTableLength = readULEB128(&lsda);
222-
const uint8_t* callSiteTableStart = lsda;
223-
const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
224-
const uint8_t* p=callSiteTableStart;
225-
while (p < callSiteTableEnd) {
226-
uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
227-
uintptr_t length = readEncodedPointer(&p, callSiteEncoding);
228-
uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding);
229-
readULEB128(&p); /* action value not used for C code */
223+
const uint8_t* callSite = lsda;
224+
225+
#if defined(__USING_SJLJ_EXCEPTIONS__)
226+
(void)callSiteEncoding;
227+
(void)callSiteTableLength;
228+
/* The given "IP" is an index into the call-site table, with two
229+
exceptions -- -1 means no-action, and 0 means terminate. But
230+
since we're using uleb128 values, we've not got random access
231+
to the array. */
232+
if ((int) pc <= 0)
233+
return _URC_CONTINUE_UNWIND;
234+
else {
235+
uintptr_t csLp;
236+
do {
237+
csLp = readULEB128(&callSite);
238+
readULEB128(&callSite); // skip cs action
239+
}
240+
while (--pc);
241+
242+
/* Can never have null landing pad for sjlj -- that would have
243+
been indicated by a -1 call site index. */
244+
resumeIp = csLp + 1;
245+
}
246+
#else
247+
/* Walk call-site table looking for range that includes current PC. */
248+
uintptr_t funcStart = _Unwind_GetRegionStart(context);
249+
uintptr_t pcOffset = pc - funcStart;
250+
const uint8_t* callSiteTableEnd = callSite + callSiteTableLength;
251+
252+
while (callSite < callSiteTableEnd) {
253+
uintptr_t start = readEncodedPointer(&callSite, callSiteEncoding);
254+
uintptr_t length = readEncodedPointer(&callSite, callSiteEncoding);
255+
uintptr_t landingPad = readEncodedPointer(&callSite, callSiteEncoding);
256+
readULEB128(&callSite); /* action value not used for C code */
230257
if ( landingPad == 0 )
231258
continue; /* no landing pad for this entry */
232259
if ( (start <= pcOffset) && (pcOffset < (start+length)) ) {
233260
/* Found landing pad for the PC.
234-
* Set Instruction Pointer to so we re-enter function
261+
* Set Instruction Pointer to so we re-enter function
235262
* at landing pad. The landing pad is created by the compiler
236263
* to take two parameters in registers.
237-
*/
238-
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
239-
(uintptr_t)exceptionObject);
240-
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
241-
_Unwind_SetIP(context, funcStart+landingPad);
242-
return _URC_INSTALL_CONTEXT;
264+
*/
265+
resumeIp = funcStart + landingPad;
266+
break;
243267
}
244268
}
245-
246-
/* No landing pad found, continue unwinding. */
247-
return _URC_CONTINUE_UNWIND;
269+
#endif // SJ/LJ
270+
271+
if (resumeIp == 0)
272+
return _URC_CONTINUE_UNWIND;
273+
else
274+
{
275+
_Unwind_SetGR(context, __builtin_eh_return_data_regno (0), (uintptr_t)exceptionObject);
276+
_Unwind_SetGR(context, __builtin_eh_return_data_regno (1), 0);
277+
_Unwind_SetIP(context, resumeIp);
278+
return _URC_INSTALL_CONTEXT;
279+
}
248280
}
249281

0 commit comments

Comments
 (0)