1 // -*- C++ -*- Exception handling routines for throwing. 2 // Copyright (C) 2001-2013 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 <bits/c++config.h> 26 #include "unwind-cxx.h" 27 28 using namespace __cxxabiv1; 29 30 31 static void 32 __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) 33 { 34 // This cleanup is set only for primaries. 35 __cxa_refcounted_exception *header 36 = __get_refcounted_exception_header_from_ue (exc); 37 38 // We only want to be called through _Unwind_DeleteException. 39 // _Unwind_DeleteException in the HP-UX IA64 libunwind library 40 // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT 41 // like the GCC _Unwind_DeleteException function does. 42 if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) 43 __terminate (header->exc.terminateHandler); 44 45 #if ATOMIC_INT_LOCK_FREE > 1 46 if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) 47 { 48 #endif 49 if (header->exc.exceptionDestructor) 50 header->exc.exceptionDestructor (header + 1); 51 52 __cxa_free_exception (header + 1); 53 #if ATOMIC_INT_LOCK_FREE > 1 54 } 55 #endif 56 } 57 58 59 extern "C" void 60 __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, 61 void (_GLIBCXX_CDTOR_CALLABI *dest) (void *)) 62 { 63 PROBE2 (throw, obj, tinfo); 64 65 __cxa_eh_globals *globals = __cxa_get_globals (); 66 globals->uncaughtExceptions += 1; 67 68 // Definitely a primary. 69 __cxa_refcounted_exception *header 70 = __get_refcounted_exception_header_from_obj (obj); 71 header->referenceCount = 1; 72 header->exc.exceptionType = tinfo; 73 header->exc.exceptionDestructor = dest; 74 header->exc.unexpectedHandler = __unexpected_handler; 75 header->exc.terminateHandler = __terminate_handler; 76 __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class); 77 header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup; 78 79 #ifdef _GLIBCXX_SJLJ_EXCEPTIONS 80 _Unwind_SjLj_RaiseException (&header->exc.unwindHeader); 81 #else 82 _Unwind_RaiseException (&header->exc.unwindHeader); 83 #endif 84 85 // Some sort of unwinding error. Note that terminate is a handler. 86 __cxa_begin_catch (&header->exc.unwindHeader); 87 std::terminate (); 88 } 89 90 extern "C" void 91 __cxxabiv1::__cxa_rethrow () 92 { 93 __cxa_eh_globals *globals = __cxa_get_globals (); 94 __cxa_exception *header = globals->caughtExceptions; 95 96 globals->uncaughtExceptions += 1; 97 98 // Watch for luser rethrowing with no active exception. 99 if (header) 100 { 101 // Tell __cxa_end_catch this is a rethrow. 102 if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 103 globals->caughtExceptions = 0; 104 else 105 { 106 header->handlerCount = -header->handlerCount; 107 // Only notify probe for C++ exceptions. 108 PROBE2 (rethrow, __get_object_from_ambiguous_exception(header), 109 header->exceptionType); 110 } 111 112 #ifdef _GLIBCXX_SJLJ_EXCEPTIONS 113 _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); 114 #else 115 #if defined(_LIBUNWIND_STD_ABI) 116 _Unwind_RaiseException (&header->unwindHeader); 117 #else 118 _Unwind_Resume_or_Rethrow (&header->unwindHeader); 119 #endif 120 #endif 121 122 // Some sort of unwinding error. Note that terminate is a handler. 123 __cxa_begin_catch (&header->unwindHeader); 124 } 125 std::terminate (); 126 } 127