diff options
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/eh_arm.cc | 43 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/eh_personality.cc | 14 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/eh_throw.cc | 2 |
4 files changed, 48 insertions, 21 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0fa5039..f84cefd 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2005-11-16 Nathan Sidwell <nathan@codesourcery.com> + + * libsupc++/eh_arm.cc (__cxa_begin_cleanup): Remember a + foreign exception too. + (__gnu_end_cleanup): Recover a foreign exception too. + * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Cope + with forced unwinding. + * libsupc++/eh_throw.cc (__cxxabiv1::__cxa_rethrow): Use + _Unwind_Resume_or_Rethrow for ARM EABI. + 2005-11-14 Geoffrey Keating <geoffk@apple.com> * acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Don't check for diff --git a/libstdc++-v3/libsupc++/eh_arm.cc b/libstdc++-v3/libsupc++/eh_arm.cc index d87d82a..269b2ec 100644 --- a/libstdc++-v3/libsupc++/eh_arm.cc +++ b/libstdc++-v3/libsupc++/eh_arm.cc @@ -89,20 +89,31 @@ __cxa_begin_cleanup(_Unwind_Exception* ue_header) { __cxa_eh_globals *globals = __cxa_get_globals(); __cxa_exception *header = __get_exception_header_from_ue(ue_header); + bool native = __is_gxx_exception_class(header->unwindHeader.exception_class); - if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) + + if (native) { - // TODO: cleanups with foreign exceptions. - return false; + header->propagationCount++; + // Add it to the chain if this is the first time we've seen this + // exception. + if (header->propagationCount == 1) + { + header->nextPropagatingException = globals->propagatingExceptions; + globals->propagatingExceptions = header; + } } - header->propagationCount++; - // Add it to the chain if this is the first time we've seen this exception. - if (header->propagationCount == 1) + else { - header->nextPropagatingException = globals->propagatingExceptions; + // Remember the exception object, so end_cleanup can return it. + // These cannot be stacked, so we must abort if we already have + // a propagating exception. + if (globals->propagatingExceptions) + std::terminate (); globals->propagatingExceptions = header; } - return true; + + return !native; } // Do the work for __cxa_end_cleanup. Returns the currently propagating @@ -119,13 +130,19 @@ __gnu_end_cleanup(void) if (!header) std::terminate(); - header->propagationCount--; - if (header->propagationCount == 0) + if (__is_gxx_exception_class(header->unwindHeader.exception_class)) { - // Remove exception from chain. - globals->propagatingExceptions = header->nextPropagatingException; - header->nextPropagatingException = NULL; + header->propagationCount--; + if (header->propagationCount == 0) + { + // Remove exception from chain. + globals->propagatingExceptions = header->nextPropagatingException; + header->nextPropagatingException = NULL; + } } + else + globals->propagatingExceptions = NULL; + return &header->unwindHeader; } diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index 6205851..f07864f 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -369,7 +369,7 @@ PERSONALITY_FUNCTION (int version, #ifdef __ARM_EABI_UNWINDER__ _Unwind_Action actions; - switch (state) + switch (state & _US_ACTION_MASK) { case _US_VIRTUAL_UNWIND_FRAME: actions = _UA_SEARCH_PHASE; @@ -377,7 +377,8 @@ PERSONALITY_FUNCTION (int version, case _US_UNWIND_FRAME_STARTING: actions = _UA_CLEANUP_PHASE; - if (ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) + if (!(state & _US_FORCE_UNWIND) + && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) actions |= _UA_HANDLER_FRAME; break; @@ -388,6 +389,7 @@ PERSONALITY_FUNCTION (int version, default: abort(); } + actions |= state & _US_FORCE_UNWIND; // We don't know which runtime we're working with, so can't check this. // However the ABI routines hide this from us, and we don't actually need @@ -523,13 +525,13 @@ PERSONALITY_FUNCTION (int version, // exception class, there's no exception type. // ??? What to do about GNU Java and GNU Ada exceptions. -#ifdef __ARM_EABI_UNWINDER__ - throw_type = ue_header; -#else if ((actions & _UA_FORCE_UNWIND) || foreign_exception) throw_type = 0; else +#ifdef __ARM_EABI_UNWINDER__ + throw_type = ue_header; +#else throw_type = xh->exceptionType; #endif @@ -613,7 +615,6 @@ PERSONALITY_FUNCTION (int version, install_context: -#ifndef __ARM_EABI_UNWINDER__ // We can't use any of the cxa routines with foreign exceptions, // because they all expect ue_header to be a struct __cxa_exception. // So in that case, call terminate or unexpected directly. @@ -631,7 +632,6 @@ PERSONALITY_FUNCTION (int version, } } else -#endif { if (found_type == found_terminate) __cxa_call_terminate(ue_header); diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index 8b04f39..9f26be0 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -97,7 +97,7 @@ __cxxabiv1::__cxa_rethrow () #ifdef _GLIBCXX_SJLJ_EXCEPTIONS _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); #else -#if defined(_LIBUNWIND_STD_ABI) || defined (__ARM_EABI_UNWINDER__) +#if defined(_LIBUNWIND_STD_ABI) _Unwind_RaiseException (&header->unwindHeader); #else _Unwind_Resume_or_Rethrow (&header->unwindHeader); |