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