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