1*c05d8e5dSAndroid Build Coastguard Worker //===------------------------- cxa_handlers.cpp ---------------------------===// 2*c05d8e5dSAndroid Build Coastguard Worker // 3*c05d8e5dSAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*c05d8e5dSAndroid Build Coastguard Worker // 5*c05d8e5dSAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open 6*c05d8e5dSAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details. 7*c05d8e5dSAndroid Build Coastguard Worker // 8*c05d8e5dSAndroid Build Coastguard Worker // 9*c05d8e5dSAndroid Build Coastguard Worker // This file implements the functionality associated with the terminate_handler, 10*c05d8e5dSAndroid Build Coastguard Worker // unexpected_handler, and new_handler. 11*c05d8e5dSAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 12*c05d8e5dSAndroid Build Coastguard Worker 13*c05d8e5dSAndroid Build Coastguard Worker #include <stdexcept> 14*c05d8e5dSAndroid Build Coastguard Worker #include <new> 15*c05d8e5dSAndroid Build Coastguard Worker #include <exception> 16*c05d8e5dSAndroid Build Coastguard Worker #include "abort_message.h" 17*c05d8e5dSAndroid Build Coastguard Worker #include "cxxabi.h" 18*c05d8e5dSAndroid Build Coastguard Worker #include "cxa_handlers.hpp" 19*c05d8e5dSAndroid Build Coastguard Worker #include "cxa_exception.hpp" 20*c05d8e5dSAndroid Build Coastguard Worker #include "private_typeinfo.h" 21*c05d8e5dSAndroid Build Coastguard Worker #include "include/atomic_support.h" 22*c05d8e5dSAndroid Build Coastguard Worker 23*c05d8e5dSAndroid Build Coastguard Worker namespace std 24*c05d8e5dSAndroid Build Coastguard Worker { 25*c05d8e5dSAndroid Build Coastguard Worker 26*c05d8e5dSAndroid Build Coastguard Worker unexpected_handler get_unexpected()27*c05d8e5dSAndroid Build Coastguard Workerget_unexpected() _NOEXCEPT 28*c05d8e5dSAndroid Build Coastguard Worker { 29*c05d8e5dSAndroid Build Coastguard Worker return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire); 30*c05d8e5dSAndroid Build Coastguard Worker } 31*c05d8e5dSAndroid Build Coastguard Worker 32*c05d8e5dSAndroid Build Coastguard Worker void __unexpected(unexpected_handler func)33*c05d8e5dSAndroid Build Coastguard Worker__unexpected(unexpected_handler func) 34*c05d8e5dSAndroid Build Coastguard Worker { 35*c05d8e5dSAndroid Build Coastguard Worker func(); 36*c05d8e5dSAndroid Build Coastguard Worker // unexpected handler should not return 37*c05d8e5dSAndroid Build Coastguard Worker abort_message("unexpected_handler unexpectedly returned"); 38*c05d8e5dSAndroid Build Coastguard Worker } 39*c05d8e5dSAndroid Build Coastguard Worker 40*c05d8e5dSAndroid Build Coastguard Worker __attribute__((noreturn)) 41*c05d8e5dSAndroid Build Coastguard Worker void unexpected()42*c05d8e5dSAndroid Build Coastguard Workerunexpected() 43*c05d8e5dSAndroid Build Coastguard Worker { 44*c05d8e5dSAndroid Build Coastguard Worker __unexpected(get_unexpected()); 45*c05d8e5dSAndroid Build Coastguard Worker } 46*c05d8e5dSAndroid Build Coastguard Worker 47*c05d8e5dSAndroid Build Coastguard Worker terminate_handler get_terminate()48*c05d8e5dSAndroid Build Coastguard Workerget_terminate() _NOEXCEPT 49*c05d8e5dSAndroid Build Coastguard Worker { 50*c05d8e5dSAndroid Build Coastguard Worker return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire); 51*c05d8e5dSAndroid Build Coastguard Worker } 52*c05d8e5dSAndroid Build Coastguard Worker 53*c05d8e5dSAndroid Build Coastguard Worker void __terminate(terminate_handler func)54*c05d8e5dSAndroid Build Coastguard Worker__terminate(terminate_handler func) _NOEXCEPT 55*c05d8e5dSAndroid Build Coastguard Worker { 56*c05d8e5dSAndroid Build Coastguard Worker #ifndef _LIBCXXABI_NO_EXCEPTIONS 57*c05d8e5dSAndroid Build Coastguard Worker try 58*c05d8e5dSAndroid Build Coastguard Worker { 59*c05d8e5dSAndroid Build Coastguard Worker #endif // _LIBCXXABI_NO_EXCEPTIONS 60*c05d8e5dSAndroid Build Coastguard Worker func(); 61*c05d8e5dSAndroid Build Coastguard Worker // handler should not return 62*c05d8e5dSAndroid Build Coastguard Worker abort_message("terminate_handler unexpectedly returned"); 63*c05d8e5dSAndroid Build Coastguard Worker #ifndef _LIBCXXABI_NO_EXCEPTIONS 64*c05d8e5dSAndroid Build Coastguard Worker } 65*c05d8e5dSAndroid Build Coastguard Worker catch (...) 66*c05d8e5dSAndroid Build Coastguard Worker { 67*c05d8e5dSAndroid Build Coastguard Worker // handler should not throw exception 68*c05d8e5dSAndroid Build Coastguard Worker abort_message("terminate_handler unexpectedly threw an exception"); 69*c05d8e5dSAndroid Build Coastguard Worker } 70*c05d8e5dSAndroid Build Coastguard Worker #endif // _LIBCXXABI_NO_EXCEPTIONS 71*c05d8e5dSAndroid Build Coastguard Worker } 72*c05d8e5dSAndroid Build Coastguard Worker 73*c05d8e5dSAndroid Build Coastguard Worker __attribute__((noreturn)) 74*c05d8e5dSAndroid Build Coastguard Worker void terminate()75*c05d8e5dSAndroid Build Coastguard Workerterminate() _NOEXCEPT 76*c05d8e5dSAndroid Build Coastguard Worker { 77*c05d8e5dSAndroid Build Coastguard Worker // If there might be an uncaught exception 78*c05d8e5dSAndroid Build Coastguard Worker using namespace __cxxabiv1; 79*c05d8e5dSAndroid Build Coastguard Worker __cxa_eh_globals* globals = __cxa_get_globals_fast(); 80*c05d8e5dSAndroid Build Coastguard Worker if (globals) 81*c05d8e5dSAndroid Build Coastguard Worker { 82*c05d8e5dSAndroid Build Coastguard Worker __cxa_exception* exception_header = globals->caughtExceptions; 83*c05d8e5dSAndroid Build Coastguard Worker if (exception_header) 84*c05d8e5dSAndroid Build Coastguard Worker { 85*c05d8e5dSAndroid Build Coastguard Worker _Unwind_Exception* unwind_exception = 86*c05d8e5dSAndroid Build Coastguard Worker reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; 87*c05d8e5dSAndroid Build Coastguard Worker if (__isOurExceptionClass(unwind_exception)) 88*c05d8e5dSAndroid Build Coastguard Worker __terminate(exception_header->terminateHandler); 89*c05d8e5dSAndroid Build Coastguard Worker } 90*c05d8e5dSAndroid Build Coastguard Worker } 91*c05d8e5dSAndroid Build Coastguard Worker __terminate(get_terminate()); 92*c05d8e5dSAndroid Build Coastguard Worker } 93*c05d8e5dSAndroid Build Coastguard Worker 94*c05d8e5dSAndroid Build Coastguard Worker extern "C" { 95*c05d8e5dSAndroid Build Coastguard Worker new_handler __cxa_new_handler = 0; 96*c05d8e5dSAndroid Build Coastguard Worker } 97*c05d8e5dSAndroid Build Coastguard Worker 98*c05d8e5dSAndroid Build Coastguard Worker new_handler set_new_handler(new_handler handler)99*c05d8e5dSAndroid Build Coastguard Workerset_new_handler(new_handler handler) _NOEXCEPT 100*c05d8e5dSAndroid Build Coastguard Worker { 101*c05d8e5dSAndroid Build Coastguard Worker return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel); 102*c05d8e5dSAndroid Build Coastguard Worker } 103*c05d8e5dSAndroid Build Coastguard Worker 104*c05d8e5dSAndroid Build Coastguard Worker new_handler get_new_handler()105*c05d8e5dSAndroid Build Coastguard Workerget_new_handler() _NOEXCEPT 106*c05d8e5dSAndroid Build Coastguard Worker { 107*c05d8e5dSAndroid Build Coastguard Worker return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire); 108*c05d8e5dSAndroid Build Coastguard Worker } 109*c05d8e5dSAndroid Build Coastguard Worker 110*c05d8e5dSAndroid Build Coastguard Worker } // std 111