︙ | | | ︙ | |
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# define CALL_PERSONALITY(func) func(state, ex, ctx)
#endif
#define GNUCOBJC_EXCEPTION_CLASS UINT64_C(0x474E55434F424A43) /* GNUCOBJC */
#define GNUCCXX0_EXCEPTION_CLASS UINT64_C(0x474E5543432B2B00) /* GNUCC++\0 */
#define CLNGCXX0_EXCEPTION_CLASS UINT64_C(0x434C4E47432B2B00) /* CLNGC++\0 */
#define NUM_EMERGENCY_EXCEPTIONS 4
#define _UA_SEARCH_PHASE 0x01
#define _UA_CLEANUP_PHASE 0x02
#define _UA_HANDLER_FRAME 0x04
#define _UA_FORCE_UNWIND 0x08
#define DW_EH_PE_absptr 0x00
#define DW_EH_PE_uleb128 0x01
#define DW_EH_PE_udata2 0x02
#define DW_EH_PE_udata4 0x03
#define DW_EH_PE_udata8 0x04
#define DW_EH_PE_signed 0x08
#define DW_EH_PE_sleb128 (DW_EH_PE_signed | DW_EH_PE_uleb128)
#define DW_EH_PE_sdata2 (DW_EH_PE_signed | DW_EH_PE_udata2)
#define DW_EH_PE_sdata4 (DW_EH_PE_signed | DW_EH_PE_udata4)
#define DW_EH_PE_sdata8 (DW_EH_PE_signed | DW_EH_PE_udata8)
#define DW_EH_PE_pcrel 0x10
#define DW_EH_PE_textrel 0x20
#define DW_EH_PE_datarel 0x30
#define DW_EH_PE_funcrel 0x40
#define DW_EH_PE_aligned 0x50
#define DW_EH_PE_indirect 0x80
#define DW_EH_PE_omit 0xFF
#define CLEANUP_FOUND 0x01
#define HANDLER_FOUND 0x02
struct _Unwind_Context;
typedef enum {
_URC_OK = 0,
_URC_FATAL_PHASE1_ERROR = 3,
_URC_END_OF_STACK = 5,
|
|
>
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
>
|
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# define CALL_PERSONALITY(func) func(state, ex, ctx)
#endif
#define GNUCOBJC_EXCEPTION_CLASS UINT64_C(0x474E55434F424A43) /* GNUCOBJC */
#define GNUCCXX0_EXCEPTION_CLASS UINT64_C(0x474E5543432B2B00) /* GNUCC++\0 */
#define CLNGCXX0_EXCEPTION_CLASS UINT64_C(0x434C4E47432B2B00) /* CLNGC++\0 */
#define numEmergencyExceptions 4
enum {
_UA_SEARCH_PHASE = 0x01,
_UA_CLEANUP_PHASE = 0x02,
_UA_HANDLER_FRAME = 0x04,
_UA_FORCE_UNWIND = 0x08
};
enum {
DW_EH_PE_absptr = 0x00,
DW_EH_PE_uleb128 = 0x01,
DW_EH_PE_udata2 = 0x02,
DW_EH_PE_udata4 = 0x03,
DW_EH_PE_udata8 = 0x04,
DW_EH_PE_signed = 0x08,
DW_EH_PE_sleb128 = (DW_EH_PE_signed | DW_EH_PE_uleb128),
DW_EH_PE_sdata2 = (DW_EH_PE_signed | DW_EH_PE_udata2),
DW_EH_PE_sdata4 = (DW_EH_PE_signed | DW_EH_PE_udata4),
DW_EH_PE_sdata8 = (DW_EH_PE_signed | DW_EH_PE_udata8),
DW_EH_PE_pcrel = 0x10,
DW_EH_PE_textrel = 0x20,
DW_EH_PE_datarel = 0x30,
DW_EH_PE_funcrel = 0x40,
DW_EH_PE_aligned = 0x50,
DW_EH_PE_indirect = 0x80,
DW_EH_PE_omit = 0xFF
};
enum {
CLEANUP_FOUND = 0x01,
HANDLER_FOUND = 0x02
};
struct _Unwind_Context;
typedef enum {
_URC_OK = 0,
_URC_FATAL_PHASE1_ERROR = 3,
_URC_END_OF_STACK = 5,
|
︙ | | | ︙ | |
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
id object;
#ifndef HAVE_ARM_EHABI_EXCEPTIONS
uintptr_t landingpad;
intptr_t filter;
#endif
};
struct lsda {
uintptr_t regionStart, landingpadsStart;
uint8_t typesTableEnc;
const uint8_t *typesTable;
uintptr_t typesTableBase;
uint8_t callsitesEnc;
const uint8_t *callsites, *actionTable;
};
|
|
|
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
id object;
#ifndef HAVE_ARM_EHABI_EXCEPTIONS
uintptr_t landingpad;
intptr_t filter;
#endif
};
struct LSDA {
uintptr_t regionStart, landingpadsStart;
uint8_t typesTableEnc;
const uint8_t *typesTable;
uintptr_t typesTableBase;
uint8_t callsitesEnc;
const uint8_t *callsites, *actionTable;
};
|
︙ | | | ︙ | |
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
#ifdef HAVE_SEH_EXCEPTIONS
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *,
PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code (*)(int, int, uint64_t,
struct _Unwind_Exception *, struct _Unwind_Context *));
#endif
static objc_uncaught_exception_handler_t uncaughtExceptionHandler;
static struct objc_exception emergencyExceptions[NUM_EMERGENCY_EXCEPTIONS];
#ifdef OF_HAVE_THREADS
static OFSpinlock emergencyExceptionsSpinlock;
OF_CONSTRUCTOR()
{
if (OFSpinlockNew(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot create spinlock!");
|
|
|
|
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
#ifdef HAVE_SEH_EXCEPTIONS
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *,
PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code (*)(int, int, uint64_t,
struct _Unwind_Exception *, struct _Unwind_Context *));
#endif
static objc_uncaught_exception_handler uncaughtExceptionHandler;
static struct objc_exception emergencyExceptions[numEmergencyExceptions];
#ifdef OF_HAVE_THREADS
static OFSpinlock emergencyExceptionsSpinlock;
OF_CONSTRUCTOR()
{
if (OFSpinlockNew(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot create spinlock!");
|
︙ | | | ︙ | |
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
value = *(uintptr_t *)(uintptr_t)value;
return value;
}
#endif
static void
readLSDA(struct _Unwind_Context *ctx, const uint8_t *ptr, struct lsda *LSDA)
{
uint8_t landingpadsStartEnc;
uintptr_t callsitesSize;
LSDA->regionStart = _Unwind_GetRegionStart(ctx);
LSDA->landingpadsStart = LSDA->regionStart;
LSDA->typesTable = NULL;
|
|
|
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
|
value = *(uintptr_t *)(uintptr_t)value;
return value;
}
#endif
static void
readLSDA(struct _Unwind_Context *ctx, const uint8_t *ptr, struct LSDA *LSDA)
{
uint8_t landingpadsStartEnc;
uintptr_t callsitesSize;
LSDA->regionStart = _Unwind_GetRegionStart(ctx);
LSDA->landingpadsStart = LSDA->regionStart;
LSDA->typesTable = NULL;
|
︙ | | | ︙ | |
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
|
callsitesSize = (uintptr_t)readULEB128(&ptr);
LSDA->callsites = ptr;
LSDA->actionTable = LSDA->callsites + callsitesSize;
}
static bool
findCallsite(struct _Unwind_Context *ctx, struct lsda *LSDA,
uintptr_t *landingpad, const uint8_t **actionRecords)
{
uintptr_t IP = _Unwind_GetIP(ctx);
const uint8_t *ptr = LSDA->callsites;
*landingpad = 0;
*actionRecords = NULL;
|
|
|
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
|
callsitesSize = (uintptr_t)readULEB128(&ptr);
LSDA->callsites = ptr;
LSDA->actionTable = LSDA->callsites + callsitesSize;
}
static bool
findCallsite(struct _Unwind_Context *ctx, struct LSDA *LSDA,
uintptr_t *landingpad, const uint8_t **actionRecords)
{
uintptr_t IP = _Unwind_GetIP(ctx);
const uint8_t *ptr = LSDA->callsites;
*landingpad = 0;
*actionRecords = NULL;
|
︙ | | | ︙ | |
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
|
if (iter == class)
return true;
return false;
}
static uint8_t
findActionRecord(const uint8_t *actionRecords, struct lsda *LSDA, int actions,
bool foreign, struct objc_exception *e, intptr_t *filterPtr)
{
const uint8_t *ptr;
intptr_t filter, displacement;
do {
ptr = actionRecords;
|
|
|
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
|
if (iter == class)
return true;
return false;
}
static uint8_t
findActionRecord(const uint8_t *actionRecords, struct LSDA *LSDA, int actions,
bool foreign, struct objc_exception *e, intptr_t *filterPtr)
{
const uint8_t *ptr;
intptr_t filter, displacement;
do {
ptr = actionRecords;
|
︙ | | | ︙ | |
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
|
}
_Unwind_SetGR(ctx, 12, (uintptr_t)ex);
#endif
struct objc_exception *e = (struct objc_exception *)ex;
bool foreign = (exClass != GNUCOBJC_EXCEPTION_CLASS);
const uint8_t *LSDAAddr, *actionRecords;
struct lsda LSDA;
uintptr_t landingpad = 0;
uint8_t found = 0;
intptr_t filter = 0;
if (foreign) {
switch (exClass) {
#ifdef CXX_PERSONALITY
|
|
|
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
|
}
_Unwind_SetGR(ctx, 12, (uintptr_t)ex);
#endif
struct objc_exception *e = (struct objc_exception *)ex;
bool foreign = (exClass != GNUCOBJC_EXCEPTION_CLASS);
const uint8_t *LSDAAddr, *actionRecords;
struct LSDA LSDA;
uintptr_t landingpad = 0;
uint8_t found = 0;
intptr_t filter = 0;
if (foreign) {
switch (exClass) {
#ifdef CXX_PERSONALITY
|
︙ | | | ︙ | |
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
|
if (e == NULL) {
#ifdef OF_HAVE_THREADS
if (OFSpinlockLock(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot lock spinlock!");
#endif
for (uint_fast8_t i = 0; i < NUM_EMERGENCY_EXCEPTIONS; i++) {
if (emergencyExceptions[i].exception.class == 0) {
e = &emergencyExceptions[i];
e->exception.class = GNUCOBJC_EXCEPTION_CLASS;
emergency = true;
break;
}
|
|
|
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
|
if (e == NULL) {
#ifdef OF_HAVE_THREADS
if (OFSpinlockLock(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot lock spinlock!");
#endif
for (uint_fast8_t i = 0; i < numEmergencyExceptions; i++) {
if (emergencyExceptions[i].exception.class == 0) {
e = &emergencyExceptions[i];
e->exception.class = GNUCOBJC_EXCEPTION_CLASS;
emergency = true;
break;
}
|
︙ | | | ︙ | |
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
|
if (uncaughtExceptionHandler != NULL)
uncaughtExceptionHandler(object);
OBJC_ERROR("_Unwind_RaiseException() returned!");
}
objc_uncaught_exception_handler_t
objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler_t handler)
{
objc_uncaught_exception_handler_t old = uncaughtExceptionHandler;
uncaughtExceptionHandler = handler;
return old;
}
#ifdef HAVE_SEH_EXCEPTIONS
typedef EXCEPTION_DISPOSITION (*seh_personality_fn)(PEXCEPTION_RECORD, void *,
|
|
|
|
|
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
|
if (uncaughtExceptionHandler != NULL)
uncaughtExceptionHandler(object);
OBJC_ERROR("_Unwind_RaiseException() returned!");
}
objc_uncaught_exception_handler
objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler handler)
{
objc_uncaught_exception_handler old = uncaughtExceptionHandler;
uncaughtExceptionHandler = handler;
return old;
}
#ifdef HAVE_SEH_EXCEPTIONS
typedef EXCEPTION_DISPOSITION (*seh_personality_fn)(PEXCEPTION_RECORD, void *,
|
︙ | | | ︙ | |