1169691Skan// -*- C++ -*- Helpers for calling unextected and terminate 2169691Skan// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. 3169691Skan// 4169691Skan// This file is part of GCC. 5169691Skan// 6169691Skan// GCC is free software; you can redistribute it and/or modify 7169691Skan// it under the terms of the GNU General Public License as published by 8169691Skan// the Free Software Foundation; either version 2, or (at your option) 9169691Skan// any later version. 10169691Skan// 11169691Skan// GCC is distributed in the hope that it will be useful, 12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169691Skan// GNU General Public License for more details. 15169691Skan// 16169691Skan// You should have received a copy of the GNU General Public License 17169691Skan// 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. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free software 22169691Skan// library without restriction. Specifically, if other files instantiate 23169691Skan// templates or use macros or inline functions from this file, or you compile 24169691Skan// this file and link it with other files to produce an executable, this 25169691Skan// file does not by itself cause the resulting executable to be covered by 26169691Skan// the GNU General Public License. This exception does not however 27169691Skan// invalidate any other reasons why the executable file might be covered by 28169691Skan// the GNU General Public License. 29169691Skan 30169691Skan#include <bits/c++config.h> 31169691Skan#include <cstdlib> 32169691Skan#include <exception_defines.h> 33169691Skan#include "unwind-cxx.h" 34169691Skan 35169691Skanusing namespace __cxxabiv1; 36169691Skan 37169691Skan#include "unwind-pe.h" 38169691Skan 39169691Skan 40169691Skan// Helper routine for when the exception handling code needs to call 41169691Skan// terminate. 42169691Skan 43169691Skanextern "C" void 44169691Skan__cxa_call_terminate(_Unwind_Exception* ue_header) 45169691Skan{ 46169691Skan 47169691Skan if (ue_header) 48169691Skan { 49169691Skan // terminate is classed as a catch handler. 50169691Skan __cxa_begin_catch(ue_header); 51169691Skan 52169691Skan // Call the terminate handler that was in effect when we threw this 53169691Skan // exception. */ 54169691Skan if (__is_gxx_exception_class(ue_header->exception_class)) 55169691Skan { 56169691Skan __cxa_exception* xh; 57169691Skan 58169691Skan xh = __get_exception_header_from_ue(ue_header); 59169691Skan __terminate(xh->terminateHandler); 60169691Skan } 61169691Skan } 62169691Skan /* Call the global routine if we don't have anything better. */ 63169691Skan std::terminate(); 64169691Skan} 65169691Skan 66169691Skan 67169691Skan#ifdef __ARM_EABI_UNWINDER__ 68169691Skan// The ARM EABI __cxa_call_unexpected has the same semantics as the generic 69169691Skan// routine, but the exception specification has a different format. 70169691Skanextern "C" void 71169691Skan__cxa_call_unexpected(void* exc_obj_in) 72169691Skan{ 73169691Skan _Unwind_Exception* exc_obj 74169691Skan = reinterpret_cast<_Unwind_Exception*>(exc_obj_in); 75169691Skan 76169691Skan int rtti_count = 0; 77169691Skan _Unwind_Word rtti_stride = 0; 78169691Skan _Unwind_Word* rtti_list = NULL; 79169691Skan bool foreign_exception; 80169691Skan std::unexpected_handler unexpectedHandler = NULL; 81169691Skan std::terminate_handler terminateHandler = NULL; 82169691Skan __cxa_exception* xh; 83169691Skan if (__is_gxx_exception_class(exc_obj->exception_class)) 84169691Skan { 85169691Skan // Save data from the EO, which may be clobbered by _cxa_begin_catch. 86169691Skan xh = __get_exception_header_from_ue(exc_obj); 87169691Skan unexpectedHandler = xh->unexpectedHandler; 88169691Skan terminateHandler = xh->terminateHandler; 89169691Skan rtti_count = exc_obj->barrier_cache.bitpattern[1]; 90169691Skan 91169691Skan rtti_stride = exc_obj->barrier_cache.bitpattern[3]; 92169691Skan rtti_list = (_Unwind_Word*) exc_obj->barrier_cache.bitpattern[4]; 93169691Skan foreign_exception = false; 94169691Skan } 95169691Skan else 96169691Skan foreign_exception = true; 97169691Skan 98169691Skan /* This must be called after extracting data from the EO, but before 99169691Skan calling unexpected(). */ 100169691Skan __cxa_begin_catch(exc_obj); 101169691Skan 102169691Skan // This function is a handler for our exception argument. If we exit 103169691Skan // by throwing a different exception, we'll need the original cleaned up. 104169691Skan struct end_catch_protect 105169691Skan { 106169691Skan end_catch_protect() { } 107169691Skan ~end_catch_protect() { __cxa_end_catch(); } 108169691Skan } end_catch_protect_obj; 109169691Skan 110169691Skan 111169691Skan try 112169691Skan { 113169691Skan if (foreign_exception) 114169691Skan std::unexpected(); 115169691Skan else 116169691Skan __unexpected(unexpectedHandler); 117169691Skan } 118169691Skan catch(...) 119169691Skan { 120169691Skan /* See if the new exception matches the rtti list. */ 121169691Skan if (foreign_exception) 122169691Skan std::terminate(); 123169691Skan 124169691Skan // Get the exception thrown from unexpected. 125169691Skan 126169691Skan __cxa_eh_globals* globals = __cxa_get_globals_fast(); 127169691Skan __cxa_exception* new_xh = globals->caughtExceptions; 128169691Skan void* new_ptr = new_xh + 1; 129169691Skan const std::type_info* catch_type; 130169691Skan int n; 131169691Skan bool bad_exception_allowed = false; 132169691Skan const std::type_info& bad_exc = typeid(std::bad_exception); 133169691Skan 134169691Skan // Check the new exception against the rtti list 135169691Skan for (n = 0; n < rtti_count; n++) 136169691Skan { 137169691Skan _Unwind_Word offset; 138169691Skan 139169691Skan offset = (_Unwind_Word) &rtti_list[n * (rtti_stride >> 2)]; 140169691Skan offset = _Unwind_decode_target2(offset); 141169691Skan catch_type = (const std::type_info*) (offset); 142169691Skan 143169691Skan if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false, 144169691Skan &new_ptr) != ctm_failed) 145169691Skan __throw_exception_again; 146169691Skan 147169691Skan if (catch_type->__do_catch(&bad_exc, 0, 1)) 148169691Skan bad_exception_allowed = true; 149169691Skan } 150169691Skan 151169691Skan // If the exception spec allows std::bad_exception, throw that. 152169691Skan#ifdef __EXCEPTIONS 153169691Skan if (bad_exception_allowed) 154169691Skan throw std::bad_exception(); 155169691Skan#endif 156169691Skan 157169691Skan // Otherwise, die. 158169691Skan __terminate(terminateHandler); 159169691Skan } 160169691Skan} 161169691Skan#endif // __ARM_EABI_UNWINDER__ 162