diff options
author | Paul Brook <paul@codesourcery.com> | 2004-12-17 17:56:59 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2004-12-17 17:56:59 +0000 |
commit | 9ae793df4972d8c7e1a0cac03889e4cbd09d2a23 (patch) | |
tree | 45f0b201e6dbf7d774860dcb8373f86365e7c702 | |
parent | 4215937f2ae78c90bb7481911cb0163d70fa3b68 (diff) |
2004-12-17 Paul Brook <paul@codesourcery.com>
* libsupc++/eh_arm.cc (__cxa_begin_cleanup): Add exception to list.
(cxa_end_cleanup): Call __gnu_end_cleanup.
(__gnu_end_cleanup): New function.
* libsupc++/unwind-cxx.h (struct __cxa_exception): Add field for
propagating exception stack.
(struct __cxa_exception): Add propagatingExceptions.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/csl-arm-2004-q3-branch@92327 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | ChangeLog.csl-arm | 10 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/eh_arm.cc | 65 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/unwind-cxx.h | 13 |
3 files changed, 81 insertions, 7 deletions
diff --git a/ChangeLog.csl-arm b/ChangeLog.csl-arm index a883e71e566..357019c0114 100644 --- a/ChangeLog.csl-arm +++ b/ChangeLog.csl-arm @@ -1,3 +1,13 @@ +2004-12-17 Paul Brook <paul@codesourcery.com> + + * libstdc++/libsupc++/eh_arm.cc (__cxa_begin_cleanup): Add exception + to list. + (cxa_end_cleanup): Call __gnu_end_cleanup. + (__gnu_end_cleanup): New function. + * libstdc++/libsupc++/unwind-cxx.h (struct __cxa_exception): Add + field for propagating exception stack. + (struct __cxa_exception): Add propagatingExceptions. + 2004-11-16 Paul Brook <paul@codesourcery.com> * libstdc++/libsupc++/eh_arm.cc: Include cxxabi.h. diff --git a/libstdc++-v3/libsupc++/eh_arm.cc b/libstdc++-v3/libsupc++/eh_arm.cc index ecc86085dd0..1680ac7ae56 100644 --- a/libstdc++-v3/libsupc++/eh_arm.cc +++ b/libstdc++-v3/libsupc++/eh_arm.cc @@ -83,16 +83,69 @@ __cxa_type_match(_Unwind_Exception* ue_header, return ctm_failed; } -extern "C" void -__cxa_begin_cleanup(_Unwind_Exception* ue_header __attribute__((unused))) +extern "C" bool +__cxa_begin_cleanup(_Unwind_Exception* ue_header) { + __cxa_eh_globals *globals = __cxa_get_globals(); + __cxa_exception *header = __get_exception_header_from_ue(ue_header); + + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) + { + // 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; + } + return true; +} + +/* Do the work for __cxa_end_cleanup. Returns the currently propagating + exception object. */ +extern "C" _Unwind_Exception * +__gnu_end_cleanup(void) +{ + __cxa_exception *header; + __cxa_eh_globals *globals = __cxa_get_globals(); + + header = globals->propagatingExceptions; + + // Check something hasn't gone horribly wrong. + if (!header) + std::terminate(); + + header->propagationCount--; + if (header->propagationCount == 0) + { + // Remove exception from chain. + globals->propagatingExceptions = header->nextPropagatingException; + header->nextPropagatingException = NULL; + } + return &header->unwindHeader; } -/* This needs to tailcall _Unwind_Resume without clobbering any registers, - or altering the stack. */ +/* This needs to run the C++ semantics routine, then tailcall + _Unwind_Resume without clobbering any registers or altering the stack. */ extern "C" void __attribute__((naked)) -__cxa_end_cleanup (_Unwind_Exception* ue_header) +__cxa_end_cleanup(void) { - _Unwind_Resume (ue_header); + /* We only need to save r1-r3. Push r4 to preserve stack alignment. */ +#ifdef __thumb__ + asm volatile ("push\t{r1, r2, r3, r4}\n" + "bl\t__gnu_end_cleanup\n" + "pop\t{r1, r2, r3, r4}\n" + "bl\t_Unwind_Resume\n" + ::: "memory"); +#else + asm volatile ("stmfd\tsp!, {r1, r2, r3, r4}\n" + "bl\t__gnu_end_cleanup\n" + "ldmfd\tsp!, {r1, r2, r3, r4}\n" + "bl\t_Unwind_Resume\n" + ::: "memory"); +#endif } #endif diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h index 373447a9ff5..f3db100f79f 100644 --- a/libstdc++-v3/libsupc++/unwind-cxx.h +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -67,6 +67,14 @@ struct __cxa_exception // value is a signal that this object has been rethrown. int handlerCount; +#ifdef __ARM_EABI_UNWINDER__ + // Stack of exceptions in cleanups. + __cxa_exception *nextPropagatingException; + + // The nuber of active cleanup handlers for this exception. + int propagationCount; +#endif + // Cache parsed handler data from the personality routine Phase 1 // for Phase 2 and __cxa_call_unexpected. int handlerSwitchValue; @@ -84,6 +92,9 @@ struct __cxa_eh_globals { __cxa_exception *caughtExceptions; unsigned int uncaughtExceptions; +#ifdef __ARM_EABI_UNWINDER__ + __cxa_exception *propagatingExceptions; +#endif }; @@ -133,7 +144,7 @@ typedef enum { extern "C" bool __cxa_type_match(_Unwind_Exception*, const std::type_info*, bool, void**); extern "C" void __cxa_begin_cleanup (_Unwind_Exception*); -extern "C" void __cxa_end_cleanup (_Unwind_Exception*); +extern "C" void __cxa_end_cleanup (void); #endif // Invokes given handler, dying appropriately if the user handler was |