@@ -48,6 +48,68 @@ typedef enum
48
48
handler_class
49
49
} handler_type ;
50
50
51
+ /**
52
+ * Saves the result of the landing pad that we have found. For ARM, this is
53
+ * stored in the generic unwind structure, while on other platforms it is
54
+ * stored in the Objective-C exception.
55
+ */
56
+ static void saveLandingPad (struct _Unwind_Context * context ,
57
+ struct _Unwind_Exception * ucb ,
58
+ struct objc_exception * ex ,
59
+ int selector ,
60
+ dw_eh_ptr_t landingPad )
61
+ {
62
+ #ifdef __arm__
63
+ // On ARM, we store the saved exception in the generic part of the structure
64
+ ucb -> barrier_cache .sp = _Unwind_GetGR (context , 13 );
65
+ ucb -> barrier_cache .bitpattern [1 ] = (uint32_t )selector ;
66
+ ucb -> barrier_cache .bitpattern [3 ] = (uint32_t )landingPad ;
67
+ #else
68
+ // Cache the results for the phase 2 unwind, if we found a handler
69
+ // and this is not a foreign exception. We can't cache foreign exceptions
70
+ // because we don't know their structure (although we could cache C++
71
+ // exceptions...)
72
+ if (ex )
73
+ {
74
+ ex -> handlerSwitchValue = selector ;
75
+ ex -> landingPad = landingPad ;
76
+ }
77
+ #endif
78
+ }
79
+
80
+ /**
81
+ * Loads the saved landing pad. Returns 1 on success, 0 on failure.
82
+ */
83
+ static int loadLandingPad (struct _Unwind_Context * context ,
84
+ struct _Unwind_Exception * ucb ,
85
+ struct objc_exception * ex ,
86
+ unsigned long * selector ,
87
+ dw_eh_ptr_t * landingPad )
88
+ {
89
+ #ifdef __arm__
90
+ * selector = ucb -> barrier_cache .bitpattern [1 ];
91
+ * landingPad = (dw_eh_ptr_t )ucb -> barrier_cache .bitpattern [3 ];
92
+ return 1 ;
93
+ #else
94
+ if (ex )
95
+ {
96
+ * selector = ex -> handlerSwitchValue ;
97
+ * landingPad = ex -> landingPad ;
98
+ return 0 ;
99
+ }
100
+ return 0 ;
101
+ #endif
102
+ }
103
+
104
+ static inline _Unwind_Reason_Code continueUnwinding (struct _Unwind_Exception * ex ,
105
+ struct _Unwind_Context * context )
106
+ {
107
+ #ifdef __arm__
108
+ if (__gnu_unwind_frame (ex , context ) != _URC_OK ) { return _URC_FAILURE ; }
109
+ #endif
110
+ return _URC_CONTINUE_UNWIND ;
111
+ }
112
+
51
113
static void cleanup (_Unwind_Reason_Code reason , struct _Unwind_Exception * e )
52
114
{
53
115
/*
@@ -92,6 +154,7 @@ void objc_exception_throw(id object)
92
154
{
93
155
_objc_unexpected_exception (object );
94
156
}
157
+ fprintf (stderr , "Throw returned %d\n" ,(int ) err );
95
158
abort ();
96
159
}
97
160
@@ -199,15 +262,33 @@ static handler_type check_action_record(struct _Unwind_Context *context,
199
262
return handler_none ;
200
263
}
201
264
265
+ _Unwind_Reason_Code
266
+ __gnu_objc_personality_v01 (_Unwind_State state ,
267
+ struct _Unwind_Exception * ue_header ,
268
+ struct _Unwind_Context * context )
269
+ {
270
+ fprintf (stderr , "LSDA: %p\n" , (void * )_Unwind_GetLanguageSpecificData (context ));
271
+ unsigned char * lsda_addr = (void * )_Unwind_GetLanguageSpecificData (context );
272
+ fprintf (stderr , "Encoding: %x\n" , (int )* lsda_addr );
273
+ return 0 ;
274
+
275
+ }
276
+ typedef uint32_t _uw ;
277
+
202
278
/**
203
279
* The Objective-C exception personality function.
204
280
*/
205
- _Unwind_Reason_Code __gnu_objc_personality_v0 (int version ,
206
- _Unwind_Action actions ,
207
- uint64_t exceptionClass ,
208
- struct _Unwind_Exception * exceptionObject ,
209
- struct _Unwind_Context * context )
210
- {
281
+ BEGIN_PERSONALITY_FUNCTION (__gnu_objc_personality_v0 )
282
+ fprintf (stderr , "Personality function called\n" );
283
+
284
+ _uw * ptr = (_uw * ) exceptionObject -> pr_cache .ehtp ;
285
+ /* Skip the personality routine address. */
286
+ ptr ++ ;
287
+ /* Skip the unwind opcodes. */
288
+ ptr += (((* ptr ) >> 24 ) & 0xff ) + 1 ;
289
+ fprintf (stderr , "Maybe this is the LSDA? 0x%x\n" , ptr );
290
+
291
+
211
292
// This personality function is for version 1 of the ABI. If you use it
212
293
// with a future version of the ABI, it won't know what to do, so it
213
294
// reports a fatal error and give up before it breaks anything.
@@ -216,8 +297,9 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
216
297
return _URC_FATAL_PHASE1_ERROR ;
217
298
}
218
299
struct objc_exception * ex = 0 ;
219
-
220
- //char *cls = (char*)&exceptionClass;
300
+ #ifndef fprintf
301
+ char * cls = (char * )& exceptionClass ;
302
+ #endif
221
303
fprintf (stderr , "Class: %c%c%c%c%c%c%c%c\n" , cls [7 ], cls [6 ], cls [5 ], cls [4 ], cls [3 ], cls [2 ], cls [1 ], cls [0 ]);
222
304
223
305
// Check if this is a foreign exception. If it is a C++ exception, then we
@@ -266,6 +348,7 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
266
348
fprintf (stderr , "Foreign class: %p\n" , thrown_class );
267
349
}
268
350
unsigned char * lsda_addr = (void * )_Unwind_GetLanguageSpecificData (context );
351
+ fprintf (stderr , "LSDA: %p\n" , lsda_addr );
269
352
270
353
// No LSDA implies no landing pads - try the next frame
271
354
if (0 == lsda_addr ) { return _URC_CONTINUE_UNWIND ; }
@@ -276,6 +359,7 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
276
359
277
360
if (actions & _UA_SEARCH_PHASE )
278
361
{
362
+ fprintf (stderr , "Search phase...\n" );
279
363
struct dwarf_eh_lsda lsda = parse_lsda (context , lsda_addr );
280
364
action = dwarf_eh_find_callsite (context , & lsda );
281
365
handler_type handler = check_action_record (context , foreignException ,
@@ -286,13 +370,7 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
286
370
((handler == handler_catchall_id ) && !foreignException ) ||
287
371
(handler == handler_catchall ))
288
372
{
289
- // Cache the results for the phase 2 unwind, if we found a handler
290
- // and this is not a foreign exception.
291
- if (ex )
292
- {
293
- ex -> handlerSwitchValue = selector ;
294
- ex -> landingPad = action .landing_pad ;
295
- }
373
+ saveLandingPad (context , exceptionObject , ex , selector , action .landing_pad );
296
374
fprintf (stderr , "Found handler! %d\n" , handler );
297
375
return _URC_HANDLER_FOUND ;
298
376
}
@@ -353,8 +431,7 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
353
431
else
354
432
{
355
433
// Restore the saved info if we saved some last time.
356
- action .landing_pad = ex -> landingPad ;
357
- selector = ex -> handlerSwitchValue ;
434
+ loadLandingPad (context , exceptionObject , ex , & selector , & action .landing_pad );
358
435
object = ex -> object ;
359
436
free (ex );
360
437
}
@@ -367,12 +444,9 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
367
444
return _URC_INSTALL_CONTEXT ;
368
445
}
369
446
370
- _Unwind_Reason_Code __gnustep_objcxx_personality_v0 (int version ,
371
- _Unwind_Action actions ,
372
- uint64_t exceptionClass ,
373
- struct _Unwind_Exception * exceptionObject ,
374
- struct _Unwind_Context * context )
375
- {
447
+ // FIXME!
448
+ #ifndef __arm__
449
+ BEGIN_PERSONALITY_FUNCTION (__gnustep_objcxx_personality_v0 )
376
450
if (exceptionClass == objc_exception_class )
377
451
{
378
452
struct objc_exception * ex = (struct objc_exception * )
@@ -391,7 +465,6 @@ _Unwind_Reason_Code __gnustep_objcxx_personality_v0(int version,
391
465
exceptionObject = ex -> cxx_exception ;
392
466
exceptionClass = cxx_exception_class ;
393
467
}
394
- return __gxx_personality_v0 (version , actions , exceptionClass ,
395
- exceptionObject , context );
468
+ return CALL_PERSONALITY_FUNCTION (__gxx_personality_v0 );
396
469
}
397
-
470
+ #endif
0 commit comments