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