| 1 | // -*- C++ -*- Exception handling and frame unwind runtime interface routines.␍␊ |
| 2 | // Copyright (C) 2001 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, 59 Temple Place - Suite 330,␍␊ |
| 19 | // Boston, MA 02111-1307, 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 | // This is derived from the C++ ABI for IA-64. Where we diverge␍␊ |
| 31 | // for cross-architecture compatibility are noted with "@@@".␍␊ |
| 32 | ␍␊ |
| 33 | #ifndef _UNWIND_CXX_H␍␊ |
| 34 | #define _UNWIND_CXX_H 1␍␊ |
| 35 | ␍␊ |
| 36 | // Level 2: C++ ABI␍␊ |
| 37 | ␍␊ |
| 38 | #include <typeinfo>␍␊ |
| 39 | #include <exception>␍␊ |
| 40 | #include <cstddef>␍␊ |
| 41 | #include "unwind.h"␍␊ |
| 42 | ␍␊ |
| 43 | #pragma GCC visibility push(default)␍␊ |
| 44 | ␍␊ |
| 45 | namespace __cxxabiv1␍␊ |
| 46 | {␍␊ |
| 47 | ␍␊ |
| 48 | #ifdef __UCLIBCXX_EXCEPTION_SUPPORT__␍␊ |
| 49 | ␍␊ |
| 50 | // A C++ exception object consists of a header, which is a wrapper around␍␊ |
| 51 | // an unwind object header with additional C++ specific information,␍␊ |
| 52 | // followed by the exception object itself.␍␊ |
| 53 | ␍␊ |
| 54 | struct __cxa_exception␍␊ |
| 55 | { ␍␊ |
| 56 | // Manage the exception object itself.␍␊ |
| 57 | std::type_info *exceptionType;␍␊ |
| 58 | void (*exceptionDestructor)(void *); ␍␊ |
| 59 | ␍␊ |
| 60 | // The C++ standard has entertaining rules wrt calling set_terminate␍␊ |
| 61 | // and set_unexpected in the middle of the exception cleanup process.␍␊ |
| 62 | std::unexpected_handler unexpectedHandler;␍␊ |
| 63 | std::terminate_handler terminateHandler;␍␊ |
| 64 | ␍␊ |
| 65 | // The caught exception stack threads through here.␍␊ |
| 66 | __cxa_exception *nextException;␍␊ |
| 67 | ␍␊ |
| 68 | // How many nested handlers have caught this exception. A negated␍␊ |
| 69 | // value is a signal that this object has been rethrown.␍␊ |
| 70 | int handlerCount;␍␊ |
| 71 | ␍␊ |
| 72 | // Cache parsed handler data from the personality routine Phase 1␍␊ |
| 73 | // for Phase 2 and __cxa_call_unexpected.␍␊ |
| 74 | int handlerSwitchValue;␍␊ |
| 75 | const unsigned char *actionRecord;␍␊ |
| 76 | const unsigned char *languageSpecificData;␍␊ |
| 77 | _Unwind_Ptr catchTemp;␍␊ |
| 78 | void *adjustedPtr;␍␊ |
| 79 | ␍␊ |
| 80 | // The generic exception header. Must be last.␍␊ |
| 81 | _Unwind_Exception unwindHeader;␍␊ |
| 82 | };␍␊ |
| 83 | ␍␊ |
| 84 | ␉// Each thread in a C++ program has access to a __cxa_eh_globals object.␍␊ |
| 85 | struct __cxa_eh_globals␍␊ |
| 86 | {␍␊ |
| 87 | __cxa_exception *caughtExceptions;␍␊ |
| 88 | unsigned int uncaughtExceptions;␍␊ |
| 89 | };␍␊ |
| 90 | ␍␊ |
| 91 | ␍␊ |
| 92 | // The __cxa_eh_globals for the current thread can be obtained by using␍␊ |
| 93 | // either of the following functions. The "fast" version assumes at least␍␊ |
| 94 | // one prior call of __cxa_get_globals has been made from the current␍␊ |
| 95 | // thread, so no initialization is necessary.␍␊ |
| 96 | extern "C" __cxa_eh_globals *__cxa_get_globals () throw();␍␊ |
| 97 | extern "C" __cxa_eh_globals *__cxa_get_globals_fast () throw();␍␊ |
| 98 | #endif␍␊ |
| 99 | ␍␊ |
| 100 | #ifdef __UCLIBCXX_EXCEPTION_SUPPORT__␍␊ |
| 101 | // Allocate memory for the exception plus the thown object.␍␊ |
| 102 | extern "C" void *__cxa_allocate_exception(std::size_t thrown_size) throw();␍␊ |
| 103 | ␍␊ |
| 104 | // Free the space allocated for the exception.␍␊ |
| 105 | extern "C" void __cxa_free_exception(void *thrown_exception) throw();␍␊ |
| 106 | ␍␊ |
| 107 | // Throw the exception.␍␊ |
| 108 | extern "C" void __cxa_throw (void *thrown_exception,␍␊ |
| 109 | ␉␉␉ std::type_info *tinfo,␍␊ |
| 110 | ␉␉␉ void (*dest) (void *))␍␊ |
| 111 | __attribute__((noreturn));␍␊ |
| 112 | ␍␊ |
| 113 | // Used to implement exception handlers.␍␊ |
| 114 | extern "C" void *__cxa_begin_catch (void *) throw();␍␊ |
| 115 | extern "C" void __cxa_end_catch ();␍␊ |
| 116 | extern "C" void __cxa_rethrow () __attribute__((noreturn));␍␊ |
| 117 | #endif␍␊ |
| 118 | ␉␍␊ |
| 119 | // These facilitate code generation for recurring situations.␍␊ |
| 120 | extern "C" void __cxa_bad_cast ();␍␊ |
| 121 | extern "C" void __cxa_bad_typeid ();␍␊ |
| 122 | ␍␊ |
| 123 | // @@@ These are not directly specified by the IA-64 C++ ABI.␍␊ |
| 124 | ␍␊ |
| 125 | // Handles re-checking the exception specification if unexpectedHandler␍␊ |
| 126 | // throws, and if bad_exception needs to be thrown. Called from the␍␊ |
| 127 | // compiler.␍␊ |
| 128 | extern "C" void __cxa_call_unexpected (void *) __attribute__((noreturn));␍␊ |
| 129 | ␍␊ |
| 130 | // Invokes given handler, dying appropriately if the user handler was␍␊ |
| 131 | // so inconsiderate as to return.␍␊ |
| 132 | extern void __terminate(std::terminate_handler) __attribute__((noreturn));␍␊ |
| 133 | extern void __unexpected(std::unexpected_handler) __attribute__((noreturn));␍␊ |
| 134 | ␍␊ |
| 135 | // The current installed user handlers.␍␊ |
| 136 | extern std::terminate_handler __terminate_handler;␍␊ |
| 137 | extern std::unexpected_handler __unexpected_handler;␍␊ |
| 138 | ␍␊ |
| 139 | // These are explicitly GNU C++ specific.␍␊ |
| 140 | ␍␊ |
| 141 | // This is the exception class we report -- "GNUCC++\0".␍␊ |
| 142 | const _Unwind_Exception_Class __gxx_exception_class␍␊ |
| 143 | = ((((((((_Unwind_Exception_Class) 'G' ␍␊ |
| 144 | ␉ << 8 | (_Unwind_Exception_Class) 'N')␍␊ |
| 145 | ␉<< 8 | (_Unwind_Exception_Class) 'U')␍␊ |
| 146 | << 8 | (_Unwind_Exception_Class) 'C')␍␊ |
| 147 | << 8 | (_Unwind_Exception_Class) 'C')␍␊ |
| 148 | << 8 | (_Unwind_Exception_Class) '+')␍␊ |
| 149 | << 8 | (_Unwind_Exception_Class) '+')␍␊ |
| 150 | << 8 | (_Unwind_Exception_Class) '\0');␍␊ |
| 151 | ␍␊ |
| 152 | // GNU C++ personality routine, Version 0.␍␊ |
| 153 | extern "C" _Unwind_Reason_Code __gxx_personality_v0␍␊ |
| 154 | (int, _Unwind_Action, _Unwind_Exception_Class,␍␊ |
| 155 | struct _Unwind_Exception *, struct _Unwind_Context *);␍␊ |
| 156 | ␍␊ |
| 157 | // GNU C++ sjlj personality routine, Version 0.␍␊ |
| 158 | extern "C" _Unwind_Reason_Code __gxx_personality_sj0␍␊ |
| 159 | (int, _Unwind_Action, _Unwind_Exception_Class,␍␊ |
| 160 | struct _Unwind_Exception *, struct _Unwind_Context *);␍␊ |
| 161 | ␍␊ |
| 162 | ␉␍␊ |
| 163 | #ifdef __UCLIBCXX_EXCEPTION_SUPPORT__␍␊ |
| 164 | // Acquire the C++ exception header from the C++ object.␍␊ |
| 165 | static inline __cxa_exception *␍␊ |
| 166 | __get_exception_header_from_obj (void *ptr)␍␊ |
| 167 | {␍␊ |
| 168 | return reinterpret_cast<__cxa_exception *>(ptr) - 1;␍␊ |
| 169 | }␍␊ |
| 170 | ␍␊ |
| 171 | // Acquire the C++ exception header from the generic exception header.␍␊ |
| 172 | static inline __cxa_exception *␍␊ |
| 173 | __get_exception_header_from_ue (_Unwind_Exception *exc)␍␊ |
| 174 | {␍␊ |
| 175 | return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;␍␊ |
| 176 | }␍␊ |
| 177 | #endif␍␊ |
| 178 | } /* namespace __cxxabiv1 */␍␊ |
| 179 | ␍␊ |
| 180 | #pragma GCC visibility pop␍␊ |
| 181 | ␍␊ |
| 182 | #endif // _UNWIND_CXX_H␍␊ |
| 183 | |