197403Sobrien// -*- C++ -*- Exception handling routines for throwing. 2117397Skan// Copyright (C) 2001, 2003 Free Software Foundation, Inc. 397403Sobrien// 4132720Skan// This file is part of GCC. 597403Sobrien// 6132720Skan// GCC is free software; you can redistribute it and/or modify 797403Sobrien// it under the terms of the GNU General Public License as published by 897403Sobrien// the Free Software Foundation; either version 2, or (at your option) 997403Sobrien// any later version. 1097403Sobrien// 11132720Skan// GCC is distributed in the hope that it will be useful, 1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1497403Sobrien// GNU General Public License for more details. 1597403Sobrien// 1697403Sobrien// You should have received a copy of the GNU General Public License 17132720Skan// along with GCC; see the file COPYING. If not, write to 18169691Skan// the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19169691Skan// Boston, MA 02110-1301, USA. 2097403Sobrien 2197403Sobrien// As a special exception, you may use this file as part of a free software 2297403Sobrien// library without restriction. Specifically, if other files instantiate 2397403Sobrien// templates or use macros or inline functions from this file, or you compile 2497403Sobrien// this file and link it with other files to produce an executable, this 2597403Sobrien// file does not by itself cause the resulting executable to be covered by 2697403Sobrien// the GNU General Public License. This exception does not however 2797403Sobrien// invalidate any other reasons why the executable file might be covered by 2897403Sobrien// the GNU General Public License. 2997403Sobrien 3097403Sobrien#include <bits/c++config.h> 3197403Sobrien#include "unwind-cxx.h" 3297403Sobrien 3397403Sobrienusing namespace __cxxabiv1; 3497403Sobrien 3597403Sobrien 3697403Sobrienstatic void 3797403Sobrien__gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) 3897403Sobrien{ 3997403Sobrien __cxa_exception *header = __get_exception_header_from_ue (exc); 4097403Sobrien 4197403Sobrien // If we haven't been caught by a foreign handler, then this is 4297403Sobrien // some sort of unwind error. In that case just die immediately. 43117397Skan // _Unwind_DeleteException in the HP-UX IA64 libunwind library 44117397Skan // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT 45117397Skan // like the GCC _Unwind_DeleteException function does. 46117397Skan if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) 4797403Sobrien __terminate (header->terminateHandler); 4897403Sobrien 4997403Sobrien if (header->exceptionDestructor) 5097403Sobrien header->exceptionDestructor (header + 1); 5197403Sobrien 5297403Sobrien __cxa_free_exception (header + 1); 5397403Sobrien} 5497403Sobrien 5597403Sobrien 5697403Sobrienextern "C" void 57169691Skan__cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, 58169691Skan void (*dest) (void *)) 5997403Sobrien{ 6097403Sobrien __cxa_exception *header = __get_exception_header_from_obj (obj); 6197403Sobrien header->exceptionType = tinfo; 6297403Sobrien header->exceptionDestructor = dest; 6397403Sobrien header->unexpectedHandler = __unexpected_handler; 6497403Sobrien header->terminateHandler = __terminate_handler; 65169691Skan __GXX_INIT_EXCEPTION_CLASS(header->unwindHeader.exception_class); 6697403Sobrien header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; 6797403Sobrien 68132720Skan#ifdef _GLIBCXX_SJLJ_EXCEPTIONS 6997403Sobrien _Unwind_SjLj_RaiseException (&header->unwindHeader); 7097403Sobrien#else 7197403Sobrien _Unwind_RaiseException (&header->unwindHeader); 7297403Sobrien#endif 7397403Sobrien 7497403Sobrien // Some sort of unwinding error. Note that terminate is a handler. 7597403Sobrien __cxa_begin_catch (&header->unwindHeader); 7697403Sobrien std::terminate (); 7797403Sobrien} 7897403Sobrien 7997403Sobrienextern "C" void 80169691Skan__cxxabiv1::__cxa_rethrow () 8197403Sobrien{ 8297403Sobrien __cxa_eh_globals *globals = __cxa_get_globals (); 8397403Sobrien __cxa_exception *header = globals->caughtExceptions; 8497403Sobrien 85169691Skan globals->uncaughtExceptions += 1; 86169691Skan 8797403Sobrien // Watch for luser rethrowing with no active exception. 8897403Sobrien if (header) 8997403Sobrien { 9097403Sobrien // Tell __cxa_end_catch this is a rethrow. 91169691Skan if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 92117397Skan globals->caughtExceptions = 0; 93117397Skan else 94117397Skan header->handlerCount = -header->handlerCount; 9597403Sobrien 96132720Skan#ifdef _GLIBCXX_SJLJ_EXCEPTIONS 97117397Skan _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); 9897403Sobrien#else 99169691Skan#if defined(_LIBUNWIND_STD_ABI) 10097403Sobrien _Unwind_RaiseException (&header->unwindHeader); 101117397Skan#else 102117397Skan _Unwind_Resume_or_Rethrow (&header->unwindHeader); 10397403Sobrien#endif 104117397Skan#endif 10597403Sobrien 10697403Sobrien // Some sort of unwinding error. Note that terminate is a handler. 10797403Sobrien __cxa_begin_catch (&header->unwindHeader); 10897403Sobrien } 10997403Sobrien std::terminate (); 11097403Sobrien} 111