]>
Commit | Line | Data |
---|---|---|
52a11cbf | 1 | // -*- C++ -*- Exception handling and frame unwind runtime interface routines. |
a5544970 | 2 | // Copyright (C) 2001-2019 Free Software Foundation, Inc. |
52a11cbf | 3 | // |
cbecceb9 | 4 | // This file is part of GCC. |
52a11cbf | 5 | // |
cbecceb9 | 6 | // GCC is free software; you can redistribute it and/or modify |
52a11cbf | 7 | // it under the terms of the GNU General Public License as published by |
748086b7 | 8 | // the Free Software Foundation; either version 3, or (at your option) |
52a11cbf RH |
9 | // any later version. |
10 | // | |
cbecceb9 | 11 | // GCC is distributed in the hope that it will be useful, |
52a11cbf RH |
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 | // | |
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
52a11cbf | 19 | |
748086b7 JJ |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
daa19534 | 24 | |
52a11cbf RH |
25 | // This is derived from the C++ ABI for IA-64. Where we diverge |
26 | // for cross-architecture compatibility are noted with "@@@". | |
27 | ||
3d7c150e BK |
28 | #ifndef _UNWIND_CXX_H |
29 | #define _UNWIND_CXX_H 1 | |
52a11cbf RH |
30 | |
31 | // Level 2: C++ ABI | |
32 | ||
33 | #include <typeinfo> | |
34 | #include <exception> | |
35 | #include <cstddef> | |
36 | #include "unwind.h" | |
30a333ce | 37 | #include <bits/atomic_word.h> |
50da34bb | 38 | #include <cxxabi.h> |
52a11cbf | 39 | |
83c214a8 TT |
40 | #ifdef _GLIBCXX_HAVE_SYS_SDT_H |
41 | #include <sys/sdt.h> | |
42 | /* We only want to use stap probes starting with v3. Earlier versions | |
43 | added too much startup cost. */ | |
44 | #if defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3 | |
45 | #define PROBE2(name, arg1, arg2) STAP_PROBE2 (libstdcxx, name, arg1, arg2) | |
46 | #endif | |
47 | #endif | |
48 | ||
49 | #ifndef PROBE2 | |
50 | #define PROBE2(name, arg1, arg2) | |
51 | #endif | |
52 | ||
723acbd5 MM |
53 | #pragma GCC visibility push(default) |
54 | ||
52a11cbf RH |
55 | namespace __cxxabiv1 |
56 | { | |
57 | ||
30a333ce PC |
58 | // A primary C++ exception object consists of a header, which is a wrapper |
59 | // around an unwind object header with additional C++ specific information, | |
52a11cbf RH |
60 | // followed by the exception object itself. |
61 | ||
62 | struct __cxa_exception | |
30a333ce | 63 | { |
52a11cbf RH |
64 | // Manage the exception object itself. |
65 | std::type_info *exceptionType; | |
2ecb85c8 | 66 | void (_GLIBCXX_CDTOR_CALLABI *exceptionDestructor)(void *); |
52a11cbf RH |
67 | |
68 | // The C++ standard has entertaining rules wrt calling set_terminate | |
69 | // and set_unexpected in the middle of the exception cleanup process. | |
70 | std::unexpected_handler unexpectedHandler; | |
71 | std::terminate_handler terminateHandler; | |
72 | ||
73 | // The caught exception stack threads through here. | |
74 | __cxa_exception *nextException; | |
75 | ||
76 | // How many nested handlers have caught this exception. A negated | |
77 | // value is a signal that this object has been rethrown. | |
78 | int handlerCount; | |
79 | ||
617a1b71 PB |
80 | #ifdef __ARM_EABI_UNWINDER__ |
81 | // Stack of exceptions in cleanups. | |
82 | __cxa_exception* nextPropagatingException; | |
83 | ||
3941b260 | 84 | // The number of active cleanup handlers for this exception. |
617a1b71 PB |
85 | int propagationCount; |
86 | #else | |
52a11cbf RH |
87 | // Cache parsed handler data from the personality routine Phase 1 |
88 | // for Phase 2 and __cxa_call_unexpected. | |
89 | int handlerSwitchValue; | |
90 | const unsigned char *actionRecord; | |
91 | const unsigned char *languageSpecificData; | |
cb94b155 | 92 | _Unwind_Ptr catchTemp; |
52a11cbf | 93 | void *adjustedPtr; |
617a1b71 | 94 | #endif |
52a11cbf RH |
95 | |
96 | // The generic exception header. Must be last. | |
97 | _Unwind_Exception unwindHeader; | |
98 | }; | |
99 | ||
c4bca01b JJ |
100 | struct __cxa_refcounted_exception |
101 | { | |
102 | // Manage this header. | |
103 | _Atomic_word referenceCount; | |
104 | // __cxa_exception must be last, and no padding can be after it. | |
105 | __cxa_exception exc; | |
106 | }; | |
107 | ||
30a333ce PC |
108 | // A dependent C++ exception object consists of a wrapper around an unwind |
109 | // object header with additional C++ specific information, containing a pointer | |
110 | // to a primary exception object. | |
111 | ||
112 | struct __cxa_dependent_exception | |
113 | { | |
114 | // The primary exception this thing depends on. | |
115 | void *primaryException; | |
116 | ||
3941b260 JW |
117 | // Unused member to get similar layout to __cxa_exception, otherwise the |
118 | // alignment requirements of _Unwind_Exception would require padding bytes | |
119 | // before the unwindHeader member. | |
120 | void (_GLIBCXX_CDTOR_CALLABI *__padding)(void *); | |
121 | ||
30a333ce PC |
122 | // The C++ standard has entertaining rules wrt calling set_terminate |
123 | // and set_unexpected in the middle of the exception cleanup process. | |
124 | std::unexpected_handler unexpectedHandler; | |
125 | std::terminate_handler terminateHandler; | |
126 | ||
127 | // The caught exception stack threads through here. | |
128 | __cxa_exception *nextException; | |
129 | ||
130 | // How many nested handlers have caught this exception. A negated | |
131 | // value is a signal that this object has been rethrown. | |
132 | int handlerCount; | |
133 | ||
134 | #ifdef __ARM_EABI_UNWINDER__ | |
135 | // Stack of exceptions in cleanups. | |
136 | __cxa_exception* nextPropagatingException; | |
137 | ||
3941b260 | 138 | // The number of active cleanup handlers for this exception. |
30a333ce PC |
139 | int propagationCount; |
140 | #else | |
141 | // Cache parsed handler data from the personality routine Phase 1 | |
142 | // for Phase 2 and __cxa_call_unexpected. | |
143 | int handlerSwitchValue; | |
144 | const unsigned char *actionRecord; | |
145 | const unsigned char *languageSpecificData; | |
146 | _Unwind_Ptr catchTemp; | |
147 | void *adjustedPtr; | |
148 | #endif | |
149 | ||
150 | // The generic exception header. Must be last. | |
151 | _Unwind_Exception unwindHeader; | |
152 | }; | |
153 | ||
52a11cbf RH |
154 | // Each thread in a C++ program has access to a __cxa_eh_globals object. |
155 | struct __cxa_eh_globals | |
156 | { | |
157 | __cxa_exception *caughtExceptions; | |
158 | unsigned int uncaughtExceptions; | |
617a1b71 PB |
159 | #ifdef __ARM_EABI_UNWINDER__ |
160 | __cxa_exception* propagatingExceptions; | |
161 | #endif | |
52a11cbf RH |
162 | }; |
163 | ||
52a11cbf RH |
164 | // @@@ These are not directly specified by the IA-64 C++ ABI. |
165 | ||
166 | // Handles re-checking the exception specification if unexpectedHandler | |
167 | // throws, and if bad_exception needs to be thrown. Called from the | |
168 | // compiler. | |
93f1d855 PC |
169 | extern "C" void __cxa_call_unexpected (void *) __attribute__((__noreturn__)); |
170 | extern "C" void __cxa_call_terminate (_Unwind_Exception*) throw () | |
171 | __attribute__((__noreturn__)); | |
617a1b71 PB |
172 | |
173 | #ifdef __ARM_EABI_UNWINDER__ | |
174 | // Arm EABI specified routines. | |
175 | typedef enum { | |
176 | ctm_failed = 0, | |
177 | ctm_succeeded = 1, | |
178 | ctm_succeeded_with_ptr_to_base = 2 | |
179 | } __cxa_type_match_result; | |
93f1d855 PC |
180 | extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception*, |
181 | const std::type_info*, | |
182 | bool, void**); | |
183 | extern "C" bool __cxa_begin_cleanup (_Unwind_Exception*); | |
617a1b71 PB |
184 | extern "C" void __cxa_end_cleanup (void); |
185 | #endif | |
52a11cbf | 186 | |
0a35513e AH |
187 | // Handles cleanup from transactional memory restart. |
188 | extern "C" void __cxa_tm_cleanup (void *, void *, unsigned int) throw(); | |
189 | ||
52a11cbf RH |
190 | // Invokes given handler, dying appropriately if the user handler was |
191 | // so inconsiderate as to return. | |
93f1d855 PC |
192 | extern void __terminate(std::terminate_handler) throw () |
193 | __attribute__((__noreturn__)); | |
194 | extern void __unexpected(std::unexpected_handler) | |
195 | __attribute__((__noreturn__)); | |
52a11cbf RH |
196 | |
197 | // The current installed user handlers. | |
198 | extern std::terminate_handler __terminate_handler; | |
199 | extern std::unexpected_handler __unexpected_handler; | |
200 | ||
201 | // These are explicitly GNU C++ specific. | |
202 | ||
617a1b71 PB |
203 | // Acquire the C++ exception header from the C++ object. |
204 | static inline __cxa_exception * | |
205 | __get_exception_header_from_obj (void *ptr) | |
206 | { | |
207 | return reinterpret_cast<__cxa_exception *>(ptr) - 1; | |
208 | } | |
209 | ||
210 | // Acquire the C++ exception header from the generic exception header. | |
211 | static inline __cxa_exception * | |
212 | __get_exception_header_from_ue (_Unwind_Exception *exc) | |
213 | { | |
214 | return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; | |
215 | } | |
216 | ||
c4bca01b JJ |
217 | // Acquire the C++ refcounted exception header from the C++ object. |
218 | static inline __cxa_refcounted_exception * | |
219 | __get_refcounted_exception_header_from_obj (void *ptr) | |
220 | { | |
221 | return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1; | |
222 | } | |
223 | ||
224 | // Acquire the C++ refcounted exception header from the generic exception | |
225 | // header. | |
226 | static inline __cxa_refcounted_exception * | |
227 | __get_refcounted_exception_header_from_ue (_Unwind_Exception *exc) | |
228 | { | |
229 | return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1; | |
230 | } | |
231 | ||
30a333ce PC |
232 | static inline __cxa_dependent_exception * |
233 | __get_dependent_exception_from_ue (_Unwind_Exception *exc) | |
234 | { | |
235 | return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1; | |
236 | } | |
237 | ||
4c470097 | 238 | #ifdef __ARM_EABI_UNWINDER__ |
617a1b71 PB |
239 | static inline bool |
240 | __is_gxx_exception_class(_Unwind_Exception_Class c) | |
241 | { | |
242 | // TODO: Take advantage of the fact that c will always be word aligned. | |
243 | return c[0] == 'G' | |
244 | && c[1] == 'N' | |
245 | && c[2] == 'U' | |
246 | && c[3] == 'C' | |
247 | && c[4] == 'C' | |
248 | && c[5] == '+' | |
249 | && c[6] == '+' | |
30a333ce PC |
250 | && (c[7] == '\0' || c[7] == '\x01'); |
251 | } | |
252 | ||
253 | // Only checks for primary or dependent, but not that it is a C++ exception at | |
254 | // all. | |
255 | static inline bool | |
256 | __is_dependent_exception(_Unwind_Exception_Class c) | |
257 | { | |
258 | return c[7] == '\x01'; | |
617a1b71 PB |
259 | } |
260 | ||
261 | static inline void | |
30a333ce | 262 | __GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c) |
617a1b71 PB |
263 | { |
264 | c[0] = 'G'; | |
265 | c[1] = 'N'; | |
266 | c[2] = 'U'; | |
267 | c[3] = 'C'; | |
268 | c[4] = 'C'; | |
269 | c[5] = '+'; | |
270 | c[6] = '+'; | |
271 | c[7] = '\0'; | |
272 | } | |
273 | ||
30a333ce PC |
274 | static inline void |
275 | __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(_Unwind_Exception_Class c) | |
276 | { | |
277 | c[0] = 'G'; | |
278 | c[1] = 'N'; | |
279 | c[2] = 'U'; | |
280 | c[3] = 'C'; | |
281 | c[4] = 'C'; | |
282 | c[5] = '+'; | |
283 | c[6] = '+'; | |
284 | c[7] = '\x01'; | |
285 | } | |
286 | ||
e32717fc JM |
287 | static inline bool |
288 | __is_gxx_forced_unwind_class(_Unwind_Exception_Class c) | |
289 | { | |
290 | return c[0] == 'G' | |
291 | && c[1] == 'N' | |
292 | && c[2] == 'U' | |
293 | && c[3] == 'C' | |
294 | && c[4] == 'F' | |
295 | && c[5] == 'O' | |
296 | && c[6] == 'R' | |
297 | && c[7] == '\0'; | |
298 | } | |
299 | ||
300 | static inline void | |
301 | __GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c) | |
302 | { | |
303 | c[0] = 'G'; | |
304 | c[1] = 'N'; | |
305 | c[2] = 'U'; | |
306 | c[3] = 'C'; | |
307 | c[4] = 'F'; | |
308 | c[5] = 'O'; | |
309 | c[6] = 'R'; | |
310 | c[7] = '\0'; | |
311 | } | |
4c470097 AT |
312 | |
313 | static inline void* | |
314 | __gxx_caught_object(_Unwind_Exception* eo) | |
315 | { | |
316 | return (void*)eo->barrier_cache.bitpattern[0]; | |
317 | } | |
318 | #else // !__ARM_EABI_UNWINDER__ | |
30a333ce PC |
319 | // This is the primary exception class we report -- "GNUCC++\0". |
320 | const _Unwind_Exception_Class __gxx_primary_exception_class | |
52a11cbf RH |
321 | = ((((((((_Unwind_Exception_Class) 'G' |
322 | << 8 | (_Unwind_Exception_Class) 'N') | |
323 | << 8 | (_Unwind_Exception_Class) 'U') | |
324 | << 8 | (_Unwind_Exception_Class) 'C') | |
325 | << 8 | (_Unwind_Exception_Class) 'C') | |
326 | << 8 | (_Unwind_Exception_Class) '+') | |
327 | << 8 | (_Unwind_Exception_Class) '+') | |
328 | << 8 | (_Unwind_Exception_Class) '\0'); | |
329 | ||
30a333ce PC |
330 | // This is the dependent (from std::rethrow_exception) exception class we report |
331 | // "GNUCC++\x01" | |
332 | const _Unwind_Exception_Class __gxx_dependent_exception_class | |
333 | = ((((((((_Unwind_Exception_Class) 'G' | |
334 | << 8 | (_Unwind_Exception_Class) 'N') | |
335 | << 8 | (_Unwind_Exception_Class) 'U') | |
336 | << 8 | (_Unwind_Exception_Class) 'C') | |
337 | << 8 | (_Unwind_Exception_Class) 'C') | |
338 | << 8 | (_Unwind_Exception_Class) '+') | |
339 | << 8 | (_Unwind_Exception_Class) '+') | |
340 | << 8 | (_Unwind_Exception_Class) '\x01'); | |
341 | ||
617a1b71 PB |
342 | static inline bool |
343 | __is_gxx_exception_class(_Unwind_Exception_Class c) | |
344 | { | |
30a333ce PC |
345 | return c == __gxx_primary_exception_class |
346 | || c == __gxx_dependent_exception_class; | |
617a1b71 PB |
347 | } |
348 | ||
30a333ce PC |
349 | // Only checks for primary or dependent, but not that it is a C++ exception at |
350 | // all. | |
351 | static inline bool | |
352 | __is_dependent_exception(_Unwind_Exception_Class c) | |
353 | { | |
354 | return (c & 1); | |
355 | } | |
356 | ||
357 | #define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class | |
358 | #define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \ | |
359 | c = __gxx_dependent_exception_class | |
617a1b71 | 360 | |
52a11cbf RH |
361 | // GNU C++ personality routine, Version 0. |
362 | extern "C" _Unwind_Reason_Code __gxx_personality_v0 | |
363 | (int, _Unwind_Action, _Unwind_Exception_Class, | |
364 | struct _Unwind_Exception *, struct _Unwind_Context *); | |
365 | ||
366 | // GNU C++ sjlj personality routine, Version 0. | |
367 | extern "C" _Unwind_Reason_Code __gxx_personality_sj0 | |
368 | (int, _Unwind_Action, _Unwind_Exception_Class, | |
369 | struct _Unwind_Exception *, struct _Unwind_Context *); | |
370 | ||
617a1b71 PB |
371 | static inline void* |
372 | __gxx_caught_object(_Unwind_Exception* eo) | |
52a11cbf | 373 | { |
30a333ce | 374 | // Bad as it looks, this actually works for dependent exceptions too. |
617a1b71 PB |
375 | __cxa_exception* header = __get_exception_header_from_ue (eo); |
376 | return header->adjustedPtr; | |
52a11cbf | 377 | } |
617a1b71 | 378 | #endif // !__ARM_EABI_UNWINDER__ |
52a11cbf | 379 | |
30a333ce PC |
380 | static inline void* |
381 | __get_object_from_ue(_Unwind_Exception* eo) throw() | |
382 | { | |
383 | return __is_dependent_exception (eo->exception_class) ? | |
384 | __get_dependent_exception_from_ue (eo)->primaryException : | |
385 | eo + 1; | |
386 | } | |
387 | ||
388 | static inline void * | |
389 | __get_object_from_ambiguous_exception(__cxa_exception *p_or_d) throw() | |
390 | { | |
391 | return __get_object_from_ue (&p_or_d->unwindHeader); | |
392 | } | |
393 | ||
394 | ||
52a11cbf RH |
395 | } /* namespace __cxxabiv1 */ |
396 | ||
723acbd5 MM |
397 | #pragma GCC visibility pop |
398 | ||
3d7c150e | 399 | #endif // _UNWIND_CXX_H |