@@ -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
185185COMPILER_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