Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 667450 | Differences between
and this patch

Collapse All | Expand All

(-)a/src/cxa_default_handlers.cpp (-5 / +2 lines)
Lines 37-49 static void demangling_terminate_handler() Link Here
37
        {
37
        {
38
            _Unwind_Exception* unwind_exception =
38
            _Unwind_Exception* unwind_exception =
39
                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
39
                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
40
            bool native_exception =
40
	    if(__isOurExceptionClass(unwind_exception))
41
                (unwind_exception->exception_class   & get_vendor_and_language) == 
42
                                 (kOurExceptionClass & get_vendor_and_language);
43
            if (native_exception)
44
            {
41
            {
45
                void* thrown_object =
42
                void* thrown_object =
46
                    unwind_exception->exception_class == kOurDependentExceptionClass ?
43
		    __getExceptionClass(unwind_exception) == kOurDependentExceptionClass ?
47
                        ((__cxa_dependent_exception*)exception_header)->primaryException :
44
                        ((__cxa_dependent_exception*)exception_header)->primaryException :
48
                        exception_header + 1;
45
                        exception_header + 1;
49
                const __shim_type_info* thrown_type =
46
                const __shim_type_info* thrown_type =
(-)a/src/cxa_exception.cpp (-15 / +29 lines)
Lines 79-100 size_t cxa_exception_size_from_exception_thrown_size(size_t size) { Link Here
79
                                   alignof(__cxa_exception));
79
                                   alignof(__cxa_exception));
80
}
80
}
81
81
82
static void setExceptionClass(_Unwind_Exception* unwind_exception) {
82
void __setExceptionClass(_Unwind_Exception* unwind_exception, uint64_t newValue) {
83
    unwind_exception->exception_class = kOurExceptionClass;
83
    ::memcpy(&unwind_exception->exception_class, &newValue, sizeof(newValue));
84
}
85
86
static void setOurExceptionClass(_Unwind_Exception* unwind_exception) {
87
    __setExceptionClass(unwind_exception, kOurExceptionClass);
84
}
88
}
85
89
86
static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) {
90
static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) {
87
    unwind_exception->exception_class = kOurDependentExceptionClass;
91
    __setExceptionClass(unwind_exception, kOurDependentExceptionClass);
88
}
92
}
89
93
90
//  Is it one of ours?
94
//  Is it one of ours?
91
static bool isOurExceptionClass(const _Unwind_Exception* unwind_exception) {
95
uint64_t __getExceptionClass(const _Unwind_Exception* unwind_exception) {
92
    return (unwind_exception->exception_class & get_vendor_and_language) == 
96
//  On x86 and some ARM unwinders, unwind_exception->exception_class is
93
           (kOurExceptionClass                & get_vendor_and_language);
97
//      a uint64_t.  On other ARM unwinders, it is a char[8]
98
//  See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
99
//  So we just copy it into a uint64_t to be sure.
100
    uint64_t exClass;
101
    ::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass));
102
    return exClass;
103
}
104
105
bool __isOurExceptionClass(const _Unwind_Exception* unwind_exception) {
106
    return (__getExceptionClass(unwind_exception) & get_vendor_and_language) ==
107
           (kOurExceptionClass                    & get_vendor_and_language);
94
}
108
}
95
109
96
static bool isDependentException(_Unwind_Exception* unwind_exception) {
110
static bool isDependentException(_Unwind_Exception* unwind_exception) {
97
    return (unwind_exception->exception_class & 0xFF) == 0x01;
111
    return (__getExceptionClass(unwind_exception) & 0xFF) == 0x01;
98
}
112
}
99
113
100
//  This does not need to be atomic
114
//  This does not need to be atomic
Lines 249-255 __cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *)) { Link Here
249
    exception_header->terminateHandler  = std::get_terminate();
263
    exception_header->terminateHandler  = std::get_terminate();
250
    exception_header->exceptionType = tinfo;
264
    exception_header->exceptionType = tinfo;
251
    exception_header->exceptionDestructor = dest;
265
    exception_header->exceptionDestructor = dest;
252
    setExceptionClass(&exception_header->unwindHeader);
266
    setOurExceptionClass(&exception_header->unwindHeader);
253
    exception_header->referenceCount = 1;  // This is a newly allocated exception, no need for thread safety.
267
    exception_header->referenceCount = 1;  // This is a newly allocated exception, no need for thread safety.
254
    globals->uncaughtExceptions += 1;   // Not atomically, since globals are thread-local
268
    globals->uncaughtExceptions += 1;   // Not atomically, since globals are thread-local
255
269
Lines 300-306 bool __cxa_begin_cleanup(void *unwind_arg) throw() { Link Here
300
    __cxa_exception* exception_header =
314
    __cxa_exception* exception_header =
301
        cxa_exception_from_exception_unwind_exception(unwind_exception);
315
        cxa_exception_from_exception_unwind_exception(unwind_exception);
302
316
303
    if (isOurExceptionClass(unwind_exception))
317
    if (__isOurExceptionClass(unwind_exception))
304
    {
318
    {
305
        if (0 == exception_header->propagationCount)
319
        if (0 == exception_header->propagationCount)
306
        {
320
        {
Lines 343-349 __cxa_end_cleanup_impl() Link Here
343
        std::terminate();
357
        std::terminate();
344
    }
358
    }
345
359
346
    if (isOurExceptionClass(&exception_header->unwindHeader))
360
    if (__isOurExceptionClass(&exception_header->unwindHeader))
347
    {
361
    {
348
        --exception_header->propagationCount;
362
        --exception_header->propagationCount;
349
        if (0 == exception_header->propagationCount)
363
        if (0 == exception_header->propagationCount)
Lines 408-414 void* Link Here
408
__cxa_begin_catch(void* unwind_arg) throw()
422
__cxa_begin_catch(void* unwind_arg) throw()
409
{
423
{
410
    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
424
    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
411
    bool native_exception = isOurExceptionClass(unwind_exception);
425
    bool native_exception = __isOurExceptionClass(unwind_exception);
412
    __cxa_eh_globals* globals = __cxa_get_globals();
426
    __cxa_eh_globals* globals = __cxa_get_globals();
413
    // exception_header is a hackish offset from a foreign exception, but it
427
    // exception_header is a hackish offset from a foreign exception, but it
414
    //   works as long as we're careful not to try to access any __cxa_exception
428
    //   works as long as we're careful not to try to access any __cxa_exception
Lines 485-491 void __cxa_end_catch() { Link Here
485
    //    nothing more to be done.  Do nothing!
499
    //    nothing more to be done.  Do nothing!
486
    if (NULL != exception_header)
500
    if (NULL != exception_header)
487
    {
501
    {
488
        bool native_exception = isOurExceptionClass(&exception_header->unwindHeader);
502
        bool native_exception = __isOurExceptionClass(&exception_header->unwindHeader);
489
        if (native_exception)
503
        if (native_exception)
490
        {
504
        {
491
            // This is a native exception
505
            // This is a native exception
Lines 550-556 std::type_info *__cxa_current_exception_type() { Link Here
550
    __cxa_exception *exception_header = globals->caughtExceptions;
564
    __cxa_exception *exception_header = globals->caughtExceptions;
551
    if (NULL == exception_header)
565
    if (NULL == exception_header)
552
        return NULL;        //  No current exception
566
        return NULL;        //  No current exception
553
    if (!isOurExceptionClass(&exception_header->unwindHeader))
567
    if (!__isOurExceptionClass(&exception_header->unwindHeader))
554
        return NULL;
568
        return NULL;
555
    return exception_header->exceptionType;
569
    return exception_header->exceptionType;
556
}
570
}
Lines 572-578 void __cxa_rethrow() { Link Here
572
    __cxa_exception* exception_header = globals->caughtExceptions;
586
    __cxa_exception* exception_header = globals->caughtExceptions;
573
    if (NULL == exception_header)
587
    if (NULL == exception_header)
574
        std::terminate();      // throw; called outside of a exception handler
588
        std::terminate();      // throw; called outside of a exception handler
575
    bool native_exception = isOurExceptionClass(&exception_header->unwindHeader);
589
    bool native_exception = __isOurExceptionClass(&exception_header->unwindHeader);
576
    if (native_exception)
590
    if (native_exception)
577
    {
591
    {
578
        //  Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch)
592
        //  Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch)
Lines 661-667 void *__cxa_current_primary_exception() throw() { Link Here
661
    __cxa_exception* exception_header = globals->caughtExceptions;
675
    __cxa_exception* exception_header = globals->caughtExceptions;
662
    if (NULL == exception_header)
676
    if (NULL == exception_header)
663
        return NULL;        //  No current exception
677
        return NULL;        //  No current exception
664
    if (!isOurExceptionClass(&exception_header->unwindHeader))
678
    if (!__isOurExceptionClass(&exception_header->unwindHeader))
665
        return NULL;        // Can't capture a foreign exception (no way to refcount it)
679
        return NULL;        // Can't capture a foreign exception (no way to refcount it)
666
    if (isDependentException(&exception_header->unwindHeader)) {
680
    if (isDependentException(&exception_header->unwindHeader)) {
667
        __cxa_dependent_exception* dep_exception_header =
681
        __cxa_dependent_exception* dep_exception_header =
(-)a/src/cxa_exception.hpp (+11 lines)
Lines 24-29 static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC Link Here
24
static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
24
static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
25
static const uint64_t get_vendor_and_language     = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
25
static const uint64_t get_vendor_and_language     = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
26
26
27
uint64_t __getExceptionClass  (const _Unwind_Exception*);
28
void     __setExceptionClass  (      _Unwind_Exception*, uint64_t);
29
bool     __isOurExceptionClass(const _Unwind_Exception*);
30
	
31
#if defined(__arm__) && defined(__GNUC__)
32
// missing values from _Unwind_Reason_Code enum
33
#define _URC_FATAL_PHASE2_ERROR ((_Unwind_Reason_Code)2)
34
#define _URC_FATAL_PHASE1_ERROR ((_Unwind_Reason_Code)3)
35
#define _URC_NORMAL_STOP ((_Unwind_Reason_Code)4)
36
#endif
37
27
struct _LIBCXXABI_HIDDEN __cxa_exception {
38
struct _LIBCXXABI_HIDDEN __cxa_exception {
28
#if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI)
39
#if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI)
29
    // This is a new field to support C++ 0x exception_ptr.
40
    // This is a new field to support C++ 0x exception_ptr.
(-)a/src/cxa_handlers.cpp (-4 / +1 lines)
Lines 84-93 terminate() _NOEXCEPT Link Here
84
        {
84
        {
85
            _Unwind_Exception* unwind_exception =
85
            _Unwind_Exception* unwind_exception =
86
                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
86
                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
87
            bool native_exception =
87
            if (__isOurExceptionClass(unwind_exception))
88
                (unwind_exception->exception_class & get_vendor_and_language) ==
89
                               (kOurExceptionClass & get_vendor_and_language);
90
            if (native_exception)
91
                __terminate(exception_header->terminateHandler);
88
                __terminate(exception_header->terminateHandler);
92
        }
89
        }
93
    }
90
    }
(-)a/src/cxa_personality.cpp (-13 / +7 lines)
Lines 502-508 get_thrown_object_ptr(_Unwind_Exception* unwind_exception) Link Here
502
    // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1
502
    // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1
503
    //    Regardless, this library is prohibited from touching a foreign exception
503
    //    Regardless, this library is prohibited from touching a foreign exception
504
    void* adjustedPtr = unwind_exception + 1;
504
    void* adjustedPtr = unwind_exception + 1;
505
    if (unwind_exception->exception_class == kOurDependentExceptionClass)
505
    if (__getExceptionClass(unwind_exception) == kOurDependentExceptionClass)
506
        adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException;
506
        adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException;
507
    return adjustedPtr;
507
    return adjustedPtr;
508
}
508
}
Lines 960-967 __gxx_personality_v0 Link Here
960
    if (version != 1 || unwind_exception == 0 || context == 0)
960
    if (version != 1 || unwind_exception == 0 || context == 0)
961
        return _URC_FATAL_PHASE1_ERROR;
961
        return _URC_FATAL_PHASE1_ERROR;
962
962
963
    bool native_exception = (exceptionClass     & get_vendor_and_language) ==
963
    bool native_exception = __isOurExceptionClass(unwind_exception);
964
                            (kOurExceptionClass & get_vendor_and_language);
965
    scan_results results;
964
    scan_results results;
966
    if (actions & _UA_SEARCH_PHASE)
965
    if (actions & _UA_SEARCH_PHASE)
967
    {
966
    {
Lines 1098-1105 __gxx_personality_v0(_Unwind_State state, Link Here
1098
    if (unwind_exception == 0 || context == 0)
1097
    if (unwind_exception == 0 || context == 0)
1099
        return _URC_FATAL_PHASE1_ERROR;
1098
        return _URC_FATAL_PHASE1_ERROR;
1100
1099
1101
    bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) ==
1100
    bool native_exception = __isOurExceptionClass(unwind_exception);
1102
                            (kOurExceptionClass & get_vendor_and_language);
1103
1101
1104
#if !defined(LIBCXXABI_USE_LLVM_UNWINDER)
1102
#if !defined(LIBCXXABI_USE_LLVM_UNWINDER)
1105
    // Copy the address of _Unwind_Control_Block to r12 so that
1103
    // Copy the address of _Unwind_Control_Block to r12 so that
Lines 1110-1116 __gxx_personality_v0(_Unwind_State state, Link Here
1110
1108
1111
    // Check the undocumented force unwinding behavior
1109
    // Check the undocumented force unwinding behavior
1112
    bool is_force_unwinding = state & _US_FORCE_UNWIND;
1110
    bool is_force_unwinding = state & _US_FORCE_UNWIND;
1113
    state &= ~_US_FORCE_UNWIND;
1111
    state = (_Unwind_State)(state & ~_US_FORCE_UNWIND);
1114
1112
1115
    scan_results results;
1113
    scan_results results;
1116
    switch (state) {
1114
    switch (state) {
Lines 1203-1211 __cxa_call_unexpected(void* arg) Link Here
1203
    if (unwind_exception == 0)
1201
    if (unwind_exception == 0)
1204
        call_terminate(false, unwind_exception);
1202
        call_terminate(false, unwind_exception);
1205
    __cxa_begin_catch(unwind_exception);
1203
    __cxa_begin_catch(unwind_exception);
1206
    bool native_old_exception =
1204
    bool native_old_exception = __isOurExceptionClass(unwind_exception);
1207
        (unwind_exception->exception_class & get_vendor_and_language) ==
1208
        (kOurExceptionClass                & get_vendor_and_language);
1209
    std::unexpected_handler u_handler;
1205
    std::unexpected_handler u_handler;
1210
    std::terminate_handler t_handler;
1206
    std::terminate_handler t_handler;
1211
    __cxa_exception* old_exception_header = 0;
1207
    __cxa_exception* old_exception_header = 0;
Lines 1267-1282 __cxa_call_unexpected(void* arg) Link Here
1267
            if (new_exception_header == 0)
1263
            if (new_exception_header == 0)
1268
                // This shouldn't be able to happen!
1264
                // This shouldn't be able to happen!
1269
                std::__terminate(t_handler);
1265
                std::__terminate(t_handler);
1270
            bool native_new_exception =
1266
            bool native_new_exception = __isOurExceptionClass(&new_exception_header->unwindHeader);
1271
                (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) ==
1272
                                                (kOurExceptionClass & get_vendor_and_language);
1273
            void* adjustedPtr;
1267
            void* adjustedPtr;
1274
            if (native_new_exception && (new_exception_header != old_exception_header))
1268
            if (native_new_exception && (new_exception_header != old_exception_header))
1275
            {
1269
            {
1276
                const __shim_type_info* excpType =
1270
                const __shim_type_info* excpType =
1277
                    static_cast<const __shim_type_info*>(new_exception_header->exceptionType);
1271
                    static_cast<const __shim_type_info*>(new_exception_header->exceptionType);
1278
                adjustedPtr =
1272
                adjustedPtr =
1279
                    new_exception_header->unwindHeader.exception_class == kOurDependentExceptionClass ?
1273
                    __getExceptionClass(&new_exception_header->unwindHeader) == kOurDependentExceptionClass ?
1280
                        ((__cxa_dependent_exception*)new_exception_header)->primaryException :
1274
                        ((__cxa_dependent_exception*)new_exception_header)->primaryException :
1281
                        new_exception_header + 1;
1275
                        new_exception_header + 1;
1282
                if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
1276
                if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,

Return to bug 667450