1// -*- C++ -*- Exception handling routines for catching. 2// Copyright (C) 2001, 2003, 2004 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 2, 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// You should have received a copy of the GNU General Public License 17// along with GCC; see the file COPYING. If not, write to 18// the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19// Boston, MA 02110-1301, USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30#include <cstdlib> 31#include "unwind-cxx.h" 32 33using namespace __cxxabiv1; 34 35extern "C" void * 36__cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) throw() 37{ 38 _Unwind_Exception *exceptionObject 39 = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); 40 41 return __gxx_caught_object(exceptionObject); 42} 43 44extern "C" void * 45__cxxabiv1::__cxa_begin_catch (void *exc_obj_in) throw() 46{ 47 _Unwind_Exception *exceptionObject 48 = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); 49 __cxa_eh_globals *globals = __cxa_get_globals (); 50 __cxa_exception *prev = globals->caughtExceptions; 51 __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); 52 void* objectp; 53 54 // Foreign exceptions can't be stacked here. If the exception stack is 55 // empty, then fine. Otherwise we really have no choice but to terminate. 56 // Note that this use of "header" is a lie. It's fine so long as we only 57 // examine header->unwindHeader though. 58 if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 59 { 60 if (prev != 0) 61 std::terminate (); 62 63 // Remember for end_catch and rethrow. 64 globals->caughtExceptions = header; 65 66 // ??? No sensible value to return; we don't know what the 67 // object is, much less where it is in relation to the header. 68 return 0; 69 } 70 71 int count = header->handlerCount; 72 // Count is less than zero if this exception was rethrown from an 73 // immediately enclosing region. 74 if (count < 0) 75 count = -count + 1; 76 else 77 count += 1; 78 header->handlerCount = count; 79 globals->uncaughtExceptions -= 1; 80 81 if (header != prev) 82 { 83 header->nextException = prev; 84 globals->caughtExceptions = header; 85 } 86 87 objectp = __gxx_caught_object(exceptionObject); 88#ifdef __ARM_EABI_UNWINDER__ 89 _Unwind_Complete(exceptionObject); 90#endif 91 return objectp; 92} 93 94 95extern "C" void 96__cxxabiv1::__cxa_end_catch () 97{ 98 __cxa_eh_globals *globals = __cxa_get_globals_fast (); 99 __cxa_exception *header = globals->caughtExceptions; 100 101 // A rethrow of a foreign exception will be removed from the 102 // the exception stack immediately by __cxa_rethrow. 103 if (!header) 104 return; 105 106 // A foreign exception couldn't have been stacked (see above), 107 // so by definition processing must be complete. 108 if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 109 { 110 globals->caughtExceptions = 0; 111 _Unwind_DeleteException (&header->unwindHeader); 112 return; 113 } 114 115 int count = header->handlerCount; 116 if (count < 0) 117 { 118 // This exception was rethrown. Decrement the (inverted) catch 119 // count and remove it from the chain when it reaches zero. 120 if (++count == 0) 121 globals->caughtExceptions = header->nextException; 122 } 123 else if (--count == 0) 124 { 125 // Handling for this exception is complete. Destroy the object. 126 globals->caughtExceptions = header->nextException; 127 _Unwind_DeleteException (&header->unwindHeader); 128 return; 129 } 130 else if (count < 0) 131 // A bug in the exception handling library or compiler. 132 std::terminate (); 133 134 header->handlerCount = count; 135} 136 137 138bool 139std::uncaught_exception() throw() 140{ 141 __cxa_eh_globals *globals = __cxa_get_globals (); 142 return globals->uncaughtExceptions != 0; 143} 144