1 // -*- C++ -*- Exception handling routines for catching. 2 // Copyright (C) 2001, 2003, 2004, 2009, 2011 Free Software Foundation, Inc. 3 // 4 // This file is part of GCC. 5 // 6 // GCC is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 // 11 // GCC is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 #include <cstdlib> 26 #include "unwind-cxx.h" 27 28 using namespace __cxxabiv1; 29 30 extern "C" void * 31 __cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) _GLIBCXX_NOTHROW 32 { 33 _Unwind_Exception *exceptionObject 34 = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); 35 36 return __gxx_caught_object(exceptionObject); 37 } 38 39 extern "C" void * 40 __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) _GLIBCXX_NOTHROW 41 { 42 _Unwind_Exception *exceptionObject 43 = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); 44 __cxa_eh_globals *globals = __cxa_get_globals (); 45 __cxa_exception *prev = globals->caughtExceptions; 46 __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); 47 void* objectp; 48 49 // Foreign exceptions can't be stacked here. If the exception stack is 50 // empty, then fine. Otherwise we really have no choice but to terminate. 51 // Note that this use of "header" is a lie. It's fine so long as we only 52 // examine header->unwindHeader though. 53 if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 54 { 55 if (prev != 0) 56 std::terminate (); 57 58 // Remember for end_catch and rethrow. 59 globals->caughtExceptions = header; 60 61 // ??? No sensible value to return; we don't know what the 62 // object is, much less where it is in relation to the header. 63 return 0; 64 } 65 66 int count = header->handlerCount; 67 // Count is less than zero if this exception was rethrown from an 68 // immediately enclosing region. 69 if (count < 0) 70 count = -count + 1; 71 else 72 count += 1; 73 header->handlerCount = count; 74 globals->uncaughtExceptions -= 1; 75 76 if (header != prev) 77 { 78 header->nextException = prev; 79 globals->caughtExceptions = header; 80 } 81 82 objectp = __gxx_caught_object(exceptionObject); 83 #ifdef __ARM_EABI_UNWINDER__ 84 _Unwind_Complete(exceptionObject); 85 #endif 86 return objectp; 87 } 88 89 90 extern "C" void 91 __cxxabiv1::__cxa_end_catch () 92 { 93 __cxa_eh_globals *globals = __cxa_get_globals_fast (); 94 __cxa_exception *header = globals->caughtExceptions; 95 96 // A rethrow of a foreign exception will be removed from the 97 // the exception stack immediately by __cxa_rethrow. 98 if (!header) 99 return; 100 101 // A foreign exception couldn't have been stacked (see above), 102 // so by definition processing must be complete. 103 if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 104 { 105 globals->caughtExceptions = 0; 106 _Unwind_DeleteException (&header->unwindHeader); 107 return; 108 } 109 110 int count = header->handlerCount; 111 if (count < 0) 112 { 113 // This exception was rethrown. Decrement the (inverted) catch 114 // count and remove it from the chain when it reaches zero. 115 if (++count == 0) 116 globals->caughtExceptions = header->nextException; 117 } 118 else if (--count == 0) 119 { 120 // Handling for this exception is complete. Destroy the object. 121 globals->caughtExceptions = header->nextException; 122 _Unwind_DeleteException (&header->unwindHeader); 123 return; 124 } 125 else if (count < 0) 126 // A bug in the exception handling library or compiler. 127 std::terminate (); 128 129 header->handlerCount = count; 130 } 131 132 133 bool 134 std::uncaught_exception() throw() 135 { 136 __cxa_eh_globals *globals = __cxa_get_globals (); 137 return globals->uncaughtExceptions != 0; 138 } 139