@@ -79,22 +79,37 @@ size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
79
79
alignof (__cxa_exception));
80
80
}
81
81
82
- static void setExceptionClass (_Unwind_Exception* unwind_exception) {
83
- unwind_exception->exception_class = kOurExceptionClass ;
82
+ void __setExceptionClass (_Unwind_Exception* unwind_exception, uint64_t newValue) {
83
+ ::memcpy (&unwind_exception->exception_class, &newValue, sizeof (newValue));
84
+ }
85
+
86
+
87
+ static void setOurExceptionClass (_Unwind_Exception* unwind_exception) {
88
+ __setExceptionClass (unwind_exception, kOurExceptionClass );
84
89
}
85
90
86
91
static void setDependentExceptionClass (_Unwind_Exception* unwind_exception) {
87
- unwind_exception-> exception_class = kOurDependentExceptionClass ;
92
+ __setExceptionClass ( unwind_exception, kOurDependentExceptionClass ) ;
88
93
}
89
94
90
95
// Is it one of ours?
91
- static bool isOurExceptionClass (const _Unwind_Exception* unwind_exception) {
92
- return (unwind_exception->exception_class & get_vendor_and_language) ==
93
- (kOurExceptionClass & get_vendor_and_language);
96
+ uint64_t __getExceptionClass (const _Unwind_Exception* unwind_exception) {
97
+ // On x86 and some ARM unwinders, unwind_exception->exception_class is
98
+ // a uint64_t. On other ARM unwinders, it is a char[8]
99
+ // See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
100
+ // So we just copy it into a uint64_t to be sure.
101
+ uint64_t exClass;
102
+ ::memcpy (&exClass, &unwind_exception->exception_class, sizeof (exClass));
103
+ return exClass;
104
+ }
105
+
106
+ bool __isOurExceptionClass (const _Unwind_Exception* unwind_exception) {
107
+ return (__getExceptionClass (unwind_exception) & get_vendor_and_language) ==
108
+ (kOurExceptionClass & get_vendor_and_language);
94
109
}
95
110
96
111
static bool isDependentException (_Unwind_Exception* unwind_exception) {
97
- return (unwind_exception-> exception_class & 0xFF ) == 0x01 ;
112
+ return (__getExceptionClass ( unwind_exception) & 0xFF ) == 0x01 ;
98
113
}
99
114
100
115
// This does not need to be atomic
@@ -249,7 +264,7 @@ __cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *)) {
249
264
exception_header->terminateHandler = std::get_terminate ();
250
265
exception_header->exceptionType = tinfo;
251
266
exception_header->exceptionDestructor = dest;
252
- setExceptionClass (&exception_header->unwindHeader );
267
+ setOurExceptionClass (&exception_header->unwindHeader );
253
268
exception_header->referenceCount = 1 ; // This is a newly allocated exception, no need for thread safety.
254
269
globals->uncaughtExceptions += 1 ; // Not atomically, since globals are thread-local
255
270
@@ -300,7 +315,7 @@ bool __cxa_begin_cleanup(void *unwind_arg) throw() {
300
315
__cxa_exception* exception_header =
301
316
cxa_exception_from_exception_unwind_exception (unwind_exception);
302
317
303
- if (isOurExceptionClass (unwind_exception))
318
+ if (__isOurExceptionClass (unwind_exception))
304
319
{
305
320
if (0 == exception_header->propagationCount )
306
321
{
@@ -343,7 +358,7 @@ __cxa_end_cleanup_impl()
343
358
std::terminate ();
344
359
}
345
360
346
- if (isOurExceptionClass (&exception_header->unwindHeader ))
361
+ if (__isOurExceptionClass (&exception_header->unwindHeader ))
347
362
{
348
363
--exception_header->propagationCount ;
349
364
if (0 == exception_header->propagationCount )
@@ -408,7 +423,7 @@ void*
408
423
__cxa_begin_catch (void * unwind_arg) throw()
409
424
{
410
425
_Unwind_Exception* unwind_exception = static_cast <_Unwind_Exception*>(unwind_arg);
411
- bool native_exception = isOurExceptionClass (unwind_exception);
426
+ bool native_exception = __isOurExceptionClass (unwind_exception);
412
427
__cxa_eh_globals* globals = __cxa_get_globals ();
413
428
// exception_header is a hackish offset from a foreign exception, but it
414
429
// works as long as we're careful not to try to access any __cxa_exception
@@ -485,7 +500,7 @@ void __cxa_end_catch() {
485
500
// nothing more to be done. Do nothing!
486
501
if (NULL != exception_header)
487
502
{
488
- bool native_exception = isOurExceptionClass (&exception_header->unwindHeader );
503
+ bool native_exception = __isOurExceptionClass (&exception_header->unwindHeader );
489
504
if (native_exception)
490
505
{
491
506
// This is a native exception
@@ -550,7 +565,7 @@ std::type_info *__cxa_current_exception_type() {
550
565
__cxa_exception *exception_header = globals->caughtExceptions ;
551
566
if (NULL == exception_header)
552
567
return NULL ; // No current exception
553
- if (!isOurExceptionClass (&exception_header->unwindHeader ))
568
+ if (!__isOurExceptionClass (&exception_header->unwindHeader ))
554
569
return NULL ;
555
570
return exception_header->exceptionType ;
556
571
}
@@ -572,7 +587,7 @@ void __cxa_rethrow() {
572
587
__cxa_exception* exception_header = globals->caughtExceptions ;
573
588
if (NULL == exception_header)
574
589
std::terminate (); // throw; called outside of a exception handler
575
- bool native_exception = isOurExceptionClass (&exception_header->unwindHeader );
590
+ bool native_exception = __isOurExceptionClass (&exception_header->unwindHeader );
576
591
if (native_exception)
577
592
{
578
593
// Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch)
@@ -661,7 +676,7 @@ void *__cxa_current_primary_exception() throw() {
661
676
__cxa_exception* exception_header = globals->caughtExceptions ;
662
677
if (NULL == exception_header)
663
678
return NULL ; // No current exception
664
- if (!isOurExceptionClass (&exception_header->unwindHeader ))
679
+ if (!__isOurExceptionClass (&exception_header->unwindHeader ))
665
680
return NULL ; // Can't capture a foreign exception (no way to refcount it)
666
681
if (isDependentException (&exception_header->unwindHeader )) {
667
682
__cxa_dependent_exception* dep_exception_header =
0 commit comments