xref: /aosp_15_r20/external/libcxxabi/src/cxa_exception.cpp (revision c05d8e5dc3e10f6ce4317e8bc22cc4a25f55fa94)
1*c05d8e5dSAndroid Build Coastguard Worker //===------------------------- cxa_exception.cpp --------------------------===//
2*c05d8e5dSAndroid Build Coastguard Worker //
3*c05d8e5dSAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*c05d8e5dSAndroid Build Coastguard Worker //
5*c05d8e5dSAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*c05d8e5dSAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*c05d8e5dSAndroid Build Coastguard Worker //
8*c05d8e5dSAndroid Build Coastguard Worker //
9*c05d8e5dSAndroid Build Coastguard Worker //  This file implements the "Exception Handling APIs"
10*c05d8e5dSAndroid Build Coastguard Worker //  http://mentorembedded.github.io/cxx-abi/abi-eh.html
11*c05d8e5dSAndroid Build Coastguard Worker //
12*c05d8e5dSAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*c05d8e5dSAndroid Build Coastguard Worker 
14*c05d8e5dSAndroid Build Coastguard Worker #include "cxxabi.h"
15*c05d8e5dSAndroid Build Coastguard Worker 
16*c05d8e5dSAndroid Build Coastguard Worker #include <exception>        // for std::terminate
17*c05d8e5dSAndroid Build Coastguard Worker #include <cstring>          // for memset
18*c05d8e5dSAndroid Build Coastguard Worker #include "cxa_exception.hpp"
19*c05d8e5dSAndroid Build Coastguard Worker #include "cxa_handlers.hpp"
20*c05d8e5dSAndroid Build Coastguard Worker #include "fallback_malloc.h"
21*c05d8e5dSAndroid Build Coastguard Worker #include "include/atomic_support.h"
22*c05d8e5dSAndroid Build Coastguard Worker 
23*c05d8e5dSAndroid Build Coastguard Worker #if __has_feature(address_sanitizer)
24*c05d8e5dSAndroid Build Coastguard Worker extern "C" void __asan_handle_no_return(void);
25*c05d8e5dSAndroid Build Coastguard Worker #endif
26*c05d8e5dSAndroid Build Coastguard Worker 
27*c05d8e5dSAndroid Build Coastguard Worker // +---------------------------+-----------------------------+---------------+
28*c05d8e5dSAndroid Build Coastguard Worker // | __cxa_exception           | _Unwind_Exception CLNGC++\0 | thrown object |
29*c05d8e5dSAndroid Build Coastguard Worker // +---------------------------+-----------------------------+---------------+
30*c05d8e5dSAndroid Build Coastguard Worker //                                                           ^
31*c05d8e5dSAndroid Build Coastguard Worker //                                                           |
32*c05d8e5dSAndroid Build Coastguard Worker //   +-------------------------------------------------------+
33*c05d8e5dSAndroid Build Coastguard Worker //   |
34*c05d8e5dSAndroid Build Coastguard Worker // +---------------------------+-----------------------------+
35*c05d8e5dSAndroid Build Coastguard Worker // | __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 |
36*c05d8e5dSAndroid Build Coastguard Worker // +---------------------------+-----------------------------+
37*c05d8e5dSAndroid Build Coastguard Worker 
38*c05d8e5dSAndroid Build Coastguard Worker namespace __cxxabiv1 {
39*c05d8e5dSAndroid Build Coastguard Worker 
40*c05d8e5dSAndroid Build Coastguard Worker //  Utility routines
41*c05d8e5dSAndroid Build Coastguard Worker static
42*c05d8e5dSAndroid Build Coastguard Worker inline
43*c05d8e5dSAndroid Build Coastguard Worker __cxa_exception*
cxa_exception_from_thrown_object(void * thrown_object)44*c05d8e5dSAndroid Build Coastguard Worker cxa_exception_from_thrown_object(void* thrown_object)
45*c05d8e5dSAndroid Build Coastguard Worker {
46*c05d8e5dSAndroid Build Coastguard Worker     return static_cast<__cxa_exception*>(thrown_object) - 1;
47*c05d8e5dSAndroid Build Coastguard Worker }
48*c05d8e5dSAndroid Build Coastguard Worker 
49*c05d8e5dSAndroid Build Coastguard Worker // Note:  This is never called when exception_header is masquerading as a
50*c05d8e5dSAndroid Build Coastguard Worker //        __cxa_dependent_exception.
51*c05d8e5dSAndroid Build Coastguard Worker static
52*c05d8e5dSAndroid Build Coastguard Worker inline
53*c05d8e5dSAndroid Build Coastguard Worker void*
thrown_object_from_cxa_exception(__cxa_exception * exception_header)54*c05d8e5dSAndroid Build Coastguard Worker thrown_object_from_cxa_exception(__cxa_exception* exception_header)
55*c05d8e5dSAndroid Build Coastguard Worker {
56*c05d8e5dSAndroid Build Coastguard Worker     return static_cast<void*>(exception_header + 1);
57*c05d8e5dSAndroid Build Coastguard Worker }
58*c05d8e5dSAndroid Build Coastguard Worker 
59*c05d8e5dSAndroid Build Coastguard Worker //  Get the exception object from the unwind pointer.
60*c05d8e5dSAndroid Build Coastguard Worker //  Relies on the structure layout, where the unwind pointer is right in
61*c05d8e5dSAndroid Build Coastguard Worker //  front of the user's exception object
62*c05d8e5dSAndroid Build Coastguard Worker static
63*c05d8e5dSAndroid Build Coastguard Worker inline
64*c05d8e5dSAndroid Build Coastguard Worker __cxa_exception*
cxa_exception_from_exception_unwind_exception(_Unwind_Exception * unwind_exception)65*c05d8e5dSAndroid Build Coastguard Worker cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception)
66*c05d8e5dSAndroid Build Coastguard Worker {
67*c05d8e5dSAndroid Build Coastguard Worker     return cxa_exception_from_thrown_object(unwind_exception + 1 );
68*c05d8e5dSAndroid Build Coastguard Worker }
69*c05d8e5dSAndroid Build Coastguard Worker 
70*c05d8e5dSAndroid Build Coastguard Worker // Round s up to next multiple of a.
71*c05d8e5dSAndroid Build Coastguard Worker static inline
aligned_allocation_size(size_t s,size_t a)72*c05d8e5dSAndroid Build Coastguard Worker size_t aligned_allocation_size(size_t s, size_t a) {
73*c05d8e5dSAndroid Build Coastguard Worker     return (s + a - 1) & ~(a - 1);
74*c05d8e5dSAndroid Build Coastguard Worker }
75*c05d8e5dSAndroid Build Coastguard Worker 
76*c05d8e5dSAndroid Build Coastguard Worker static inline
cxa_exception_size_from_exception_thrown_size(size_t size)77*c05d8e5dSAndroid Build Coastguard Worker size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
78*c05d8e5dSAndroid Build Coastguard Worker     return aligned_allocation_size(size + sizeof (__cxa_exception),
79*c05d8e5dSAndroid Build Coastguard Worker                                    alignof(__cxa_exception));
80*c05d8e5dSAndroid Build Coastguard Worker }
81*c05d8e5dSAndroid Build Coastguard Worker 
__setExceptionClass(_Unwind_Exception * unwind_exception,uint64_t newValue)82*c05d8e5dSAndroid Build Coastguard Worker void __setExceptionClass(_Unwind_Exception* unwind_exception, uint64_t newValue) {
83*c05d8e5dSAndroid Build Coastguard Worker 	::memcpy(&unwind_exception->exception_class, &newValue, sizeof(newValue));
84*c05d8e5dSAndroid Build Coastguard Worker 	}
85*c05d8e5dSAndroid Build Coastguard Worker 
86*c05d8e5dSAndroid Build Coastguard Worker 
setOurExceptionClass(_Unwind_Exception * unwind_exception)87*c05d8e5dSAndroid Build Coastguard Worker static void setOurExceptionClass(_Unwind_Exception* unwind_exception) {
88*c05d8e5dSAndroid Build Coastguard Worker     __setExceptionClass(unwind_exception, kOurExceptionClass);
89*c05d8e5dSAndroid Build Coastguard Worker }
90*c05d8e5dSAndroid Build Coastguard Worker 
setDependentExceptionClass(_Unwind_Exception * unwind_exception)91*c05d8e5dSAndroid Build Coastguard Worker static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) {
92*c05d8e5dSAndroid Build Coastguard Worker     __setExceptionClass(unwind_exception, kOurDependentExceptionClass);
93*c05d8e5dSAndroid Build Coastguard Worker }
94*c05d8e5dSAndroid Build Coastguard Worker 
95*c05d8e5dSAndroid Build Coastguard Worker //  Is it one of ours?
__getExceptionClass(const _Unwind_Exception * unwind_exception)96*c05d8e5dSAndroid Build Coastguard Worker uint64_t __getExceptionClass(const _Unwind_Exception* unwind_exception) {
97*c05d8e5dSAndroid Build Coastguard Worker //	On x86 and some ARM unwinders, unwind_exception->exception_class is
98*c05d8e5dSAndroid Build Coastguard Worker //		a uint64_t. On other ARM unwinders, it is a char[8]
99*c05d8e5dSAndroid Build Coastguard Worker //	See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
100*c05d8e5dSAndroid Build Coastguard Worker //	So we just copy it into a uint64_t to be sure.
101*c05d8e5dSAndroid Build Coastguard Worker 	uint64_t exClass;
102*c05d8e5dSAndroid Build Coastguard Worker 	::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass));
103*c05d8e5dSAndroid Build Coastguard Worker 	return exClass;
104*c05d8e5dSAndroid Build Coastguard Worker }
105*c05d8e5dSAndroid Build Coastguard Worker 
__isOurExceptionClass(const _Unwind_Exception * unwind_exception)106*c05d8e5dSAndroid Build Coastguard Worker bool __isOurExceptionClass(const _Unwind_Exception* unwind_exception) {
107*c05d8e5dSAndroid Build Coastguard Worker     return (__getExceptionClass(unwind_exception) & get_vendor_and_language) ==
108*c05d8e5dSAndroid Build Coastguard Worker            (kOurExceptionClass                    & get_vendor_and_language);
109*c05d8e5dSAndroid Build Coastguard Worker }
110*c05d8e5dSAndroid Build Coastguard Worker 
isDependentException(_Unwind_Exception * unwind_exception)111*c05d8e5dSAndroid Build Coastguard Worker static bool isDependentException(_Unwind_Exception* unwind_exception) {
112*c05d8e5dSAndroid Build Coastguard Worker     return (__getExceptionClass(unwind_exception) & 0xFF) == 0x01;
113*c05d8e5dSAndroid Build Coastguard Worker }
114*c05d8e5dSAndroid Build Coastguard Worker 
115*c05d8e5dSAndroid Build Coastguard Worker //  This does not need to be atomic
incrementHandlerCount(__cxa_exception * exception)116*c05d8e5dSAndroid Build Coastguard Worker static inline int incrementHandlerCount(__cxa_exception *exception) {
117*c05d8e5dSAndroid Build Coastguard Worker     return ++exception->handlerCount;
118*c05d8e5dSAndroid Build Coastguard Worker }
119*c05d8e5dSAndroid Build Coastguard Worker 
120*c05d8e5dSAndroid Build Coastguard Worker //  This does not need to be atomic
decrementHandlerCount(__cxa_exception * exception)121*c05d8e5dSAndroid Build Coastguard Worker static inline  int decrementHandlerCount(__cxa_exception *exception) {
122*c05d8e5dSAndroid Build Coastguard Worker     return --exception->handlerCount;
123*c05d8e5dSAndroid Build Coastguard Worker }
124*c05d8e5dSAndroid Build Coastguard Worker 
125*c05d8e5dSAndroid Build Coastguard Worker /*
126*c05d8e5dSAndroid Build Coastguard Worker     If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
127*c05d8e5dSAndroid Build Coastguard Worker     stored in exc is called.  Otherwise the exceptionDestructor stored in
128*c05d8e5dSAndroid Build Coastguard Worker     exc is called, and then the memory for the exception is deallocated.
129*c05d8e5dSAndroid Build Coastguard Worker 
130*c05d8e5dSAndroid Build Coastguard Worker     This is never called for a __cxa_dependent_exception.
131*c05d8e5dSAndroid Build Coastguard Worker */
132*c05d8e5dSAndroid Build Coastguard Worker static
133*c05d8e5dSAndroid Build Coastguard Worker void
exception_cleanup_func(_Unwind_Reason_Code reason,_Unwind_Exception * unwind_exception)134*c05d8e5dSAndroid Build Coastguard Worker exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)
135*c05d8e5dSAndroid Build Coastguard Worker {
136*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception);
137*c05d8e5dSAndroid Build Coastguard Worker     if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
138*c05d8e5dSAndroid Build Coastguard Worker         std::__terminate(exception_header->terminateHandler);
139*c05d8e5dSAndroid Build Coastguard Worker     // Just in case there exists a dependent exception that is pointing to this,
140*c05d8e5dSAndroid Build Coastguard Worker     //    check the reference count and only destroy this if that count goes to zero.
141*c05d8e5dSAndroid Build Coastguard Worker     __cxa_decrement_exception_refcount(unwind_exception + 1);
142*c05d8e5dSAndroid Build Coastguard Worker }
143*c05d8e5dSAndroid Build Coastguard Worker 
failed_throw(__cxa_exception * exception_header)144*c05d8e5dSAndroid Build Coastguard Worker static _LIBCXXABI_NORETURN void failed_throw(__cxa_exception* exception_header) {
145*c05d8e5dSAndroid Build Coastguard Worker //  Section 2.5.3 says:
146*c05d8e5dSAndroid Build Coastguard Worker //      * For purposes of this ABI, several things are considered exception handlers:
147*c05d8e5dSAndroid Build Coastguard Worker //      ** A terminate() call due to a throw.
148*c05d8e5dSAndroid Build Coastguard Worker //  and
149*c05d8e5dSAndroid Build Coastguard Worker //      * Upon entry, Following initialization of the catch parameter,
150*c05d8e5dSAndroid Build Coastguard Worker //          a handler must call:
151*c05d8e5dSAndroid Build Coastguard Worker //      * void *__cxa_begin_catch(void *exceptionObject );
152*c05d8e5dSAndroid Build Coastguard Worker     (void) __cxa_begin_catch(&exception_header->unwindHeader);
153*c05d8e5dSAndroid Build Coastguard Worker     std::__terminate(exception_header->terminateHandler);
154*c05d8e5dSAndroid Build Coastguard Worker }
155*c05d8e5dSAndroid Build Coastguard Worker 
156*c05d8e5dSAndroid Build Coastguard Worker // Return the offset of the __cxa_exception header from the start of the
157*c05d8e5dSAndroid Build Coastguard Worker // allocated buffer. If __cxa_exception's alignment is smaller than the maximum
158*c05d8e5dSAndroid Build Coastguard Worker // useful alignment for the target machine, padding has to be inserted before
159*c05d8e5dSAndroid Build Coastguard Worker // the header to ensure the thrown object that follows the header is
160*c05d8e5dSAndroid Build Coastguard Worker // sufficiently aligned. This happens if _Unwind_exception isn't double-word
161*c05d8e5dSAndroid Build Coastguard Worker // aligned (on Darwin, for example).
get_cxa_exception_offset()162*c05d8e5dSAndroid Build Coastguard Worker static size_t get_cxa_exception_offset() {
163*c05d8e5dSAndroid Build Coastguard Worker   struct S {
164*c05d8e5dSAndroid Build Coastguard Worker   } __attribute__((aligned));
165*c05d8e5dSAndroid Build Coastguard Worker 
166*c05d8e5dSAndroid Build Coastguard Worker   // Compute the maximum alignment for the target machine.
167*c05d8e5dSAndroid Build Coastguard Worker   constexpr size_t alignment = std::alignment_of<S>::value;
168*c05d8e5dSAndroid Build Coastguard Worker   constexpr size_t excp_size = sizeof(__cxa_exception);
169*c05d8e5dSAndroid Build Coastguard Worker   constexpr size_t aligned_size =
170*c05d8e5dSAndroid Build Coastguard Worker       (excp_size + alignment - 1) / alignment * alignment;
171*c05d8e5dSAndroid Build Coastguard Worker   constexpr size_t offset = aligned_size - excp_size;
172*c05d8e5dSAndroid Build Coastguard Worker   static_assert((offset == 0 ||
173*c05d8e5dSAndroid Build Coastguard Worker                  std::alignment_of<_Unwind_Exception>::value < alignment),
174*c05d8e5dSAndroid Build Coastguard Worker                 "offset is non-zero only if _Unwind_Exception isn't aligned");
175*c05d8e5dSAndroid Build Coastguard Worker   return offset;
176*c05d8e5dSAndroid Build Coastguard Worker }
177*c05d8e5dSAndroid Build Coastguard Worker 
178*c05d8e5dSAndroid Build Coastguard Worker extern "C" {
179*c05d8e5dSAndroid Build Coastguard Worker 
180*c05d8e5dSAndroid Build Coastguard Worker //  Allocate a __cxa_exception object, and zero-fill it.
181*c05d8e5dSAndroid Build Coastguard Worker //  Reserve "thrown_size" bytes on the end for the user's exception
182*c05d8e5dSAndroid Build Coastguard Worker //  object. Zero-fill the object. If memory can't be allocated, call
183*c05d8e5dSAndroid Build Coastguard Worker //  std::terminate. Return a pointer to the memory to be used for the
184*c05d8e5dSAndroid Build Coastguard Worker //  user's exception object.
__cxa_allocate_exception(size_t thrown_size)185*c05d8e5dSAndroid Build Coastguard Worker void *__cxa_allocate_exception(size_t thrown_size) throw() {
186*c05d8e5dSAndroid Build Coastguard Worker     size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size);
187*c05d8e5dSAndroid Build Coastguard Worker 
188*c05d8e5dSAndroid Build Coastguard Worker     // Allocate extra space before the __cxa_exception header to ensure the
189*c05d8e5dSAndroid Build Coastguard Worker     // start of the thrown object is sufficiently aligned.
190*c05d8e5dSAndroid Build Coastguard Worker     size_t header_offset = get_cxa_exception_offset();
191*c05d8e5dSAndroid Build Coastguard Worker     char *raw_buffer =
192*c05d8e5dSAndroid Build Coastguard Worker         (char *)__aligned_malloc_with_fallback(header_offset + actual_size);
193*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == raw_buffer)
194*c05d8e5dSAndroid Build Coastguard Worker         std::terminate();
195*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception *exception_header =
196*c05d8e5dSAndroid Build Coastguard Worker         static_cast<__cxa_exception *>((void *)(raw_buffer + header_offset));
197*c05d8e5dSAndroid Build Coastguard Worker     std::memset(exception_header, 0, actual_size);
198*c05d8e5dSAndroid Build Coastguard Worker     return thrown_object_from_cxa_exception(exception_header);
199*c05d8e5dSAndroid Build Coastguard Worker }
200*c05d8e5dSAndroid Build Coastguard Worker 
201*c05d8e5dSAndroid Build Coastguard Worker 
202*c05d8e5dSAndroid Build Coastguard Worker //  Free a __cxa_exception object allocated with __cxa_allocate_exception.
__cxa_free_exception(void * thrown_object)203*c05d8e5dSAndroid Build Coastguard Worker void __cxa_free_exception(void *thrown_object) throw() {
204*c05d8e5dSAndroid Build Coastguard Worker     // Compute the size of the padding before the header.
205*c05d8e5dSAndroid Build Coastguard Worker     size_t header_offset = get_cxa_exception_offset();
206*c05d8e5dSAndroid Build Coastguard Worker     char *raw_buffer =
207*c05d8e5dSAndroid Build Coastguard Worker         ((char *)cxa_exception_from_thrown_object(thrown_object)) - header_offset;
208*c05d8e5dSAndroid Build Coastguard Worker     __aligned_free_with_fallback((void *)raw_buffer);
209*c05d8e5dSAndroid Build Coastguard Worker }
210*c05d8e5dSAndroid Build Coastguard Worker 
211*c05d8e5dSAndroid Build Coastguard Worker 
212*c05d8e5dSAndroid Build Coastguard Worker //  This function shall allocate a __cxa_dependent_exception and
213*c05d8e5dSAndroid Build Coastguard Worker //  return a pointer to it. (Really to the object, not past its' end).
214*c05d8e5dSAndroid Build Coastguard Worker //  Otherwise, it will work like __cxa_allocate_exception.
__cxa_allocate_dependent_exception()215*c05d8e5dSAndroid Build Coastguard Worker void * __cxa_allocate_dependent_exception () {
216*c05d8e5dSAndroid Build Coastguard Worker     size_t actual_size = sizeof(__cxa_dependent_exception);
217*c05d8e5dSAndroid Build Coastguard Worker     void *ptr = __aligned_malloc_with_fallback(actual_size);
218*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == ptr)
219*c05d8e5dSAndroid Build Coastguard Worker         std::terminate();
220*c05d8e5dSAndroid Build Coastguard Worker     std::memset(ptr, 0, actual_size);
221*c05d8e5dSAndroid Build Coastguard Worker     return ptr;
222*c05d8e5dSAndroid Build Coastguard Worker }
223*c05d8e5dSAndroid Build Coastguard Worker 
224*c05d8e5dSAndroid Build Coastguard Worker 
225*c05d8e5dSAndroid Build Coastguard Worker //  This function shall free a dependent_exception.
226*c05d8e5dSAndroid Build Coastguard Worker //  It does not affect the reference count of the primary exception.
__cxa_free_dependent_exception(void * dependent_exception)227*c05d8e5dSAndroid Build Coastguard Worker void __cxa_free_dependent_exception (void * dependent_exception) {
228*c05d8e5dSAndroid Build Coastguard Worker     __aligned_free_with_fallback(dependent_exception);
229*c05d8e5dSAndroid Build Coastguard Worker }
230*c05d8e5dSAndroid Build Coastguard Worker 
231*c05d8e5dSAndroid Build Coastguard Worker 
232*c05d8e5dSAndroid Build Coastguard Worker // 2.4.3 Throwing the Exception Object
233*c05d8e5dSAndroid Build Coastguard Worker /*
234*c05d8e5dSAndroid Build Coastguard Worker After constructing the exception object with the throw argument value,
235*c05d8e5dSAndroid Build Coastguard Worker the generated code calls the __cxa_throw runtime library routine. This
236*c05d8e5dSAndroid Build Coastguard Worker routine never returns.
237*c05d8e5dSAndroid Build Coastguard Worker 
238*c05d8e5dSAndroid Build Coastguard Worker The __cxa_throw routine will do the following:
239*c05d8e5dSAndroid Build Coastguard Worker 
240*c05d8e5dSAndroid Build Coastguard Worker * Obtain the __cxa_exception header from the thrown exception object address,
241*c05d8e5dSAndroid Build Coastguard Worker which can be computed as follows:
242*c05d8e5dSAndroid Build Coastguard Worker  __cxa_exception *header = ((__cxa_exception *) thrown_exception - 1);
243*c05d8e5dSAndroid Build Coastguard Worker * Save the current unexpected_handler and terminate_handler in the __cxa_exception header.
244*c05d8e5dSAndroid Build Coastguard Worker * Save the tinfo and dest arguments in the __cxa_exception header.
245*c05d8e5dSAndroid Build Coastguard Worker * Set the exception_class field in the unwind header. This is a 64-bit value
246*c05d8e5dSAndroid Build Coastguard Worker representing the ASCII string "XXXXC++\0", where "XXXX" is a
247*c05d8e5dSAndroid Build Coastguard Worker vendor-dependent string. That is, for implementations conforming to this
248*c05d8e5dSAndroid Build Coastguard Worker ABI, the low-order 4 bytes of this 64-bit value will be "C++\0".
249*c05d8e5dSAndroid Build Coastguard Worker * Increment the uncaught_exception flag.
250*c05d8e5dSAndroid Build Coastguard Worker * Call _Unwind_RaiseException in the system unwind library, Its argument is the
251*c05d8e5dSAndroid Build Coastguard Worker pointer to the thrown exception, which __cxa_throw itself received as an argument.
252*c05d8e5dSAndroid Build Coastguard Worker __Unwind_RaiseException begins the process of stack unwinding, described
253*c05d8e5dSAndroid Build Coastguard Worker in Section 2.5. In special cases, such as an inability to find a
254*c05d8e5dSAndroid Build Coastguard Worker handler, _Unwind_RaiseException may return. In that case, __cxa_throw
255*c05d8e5dSAndroid Build Coastguard Worker will call terminate, assuming that there was no handler for the
256*c05d8e5dSAndroid Build Coastguard Worker exception.
257*c05d8e5dSAndroid Build Coastguard Worker */
258*c05d8e5dSAndroid Build Coastguard Worker void
__cxa_throw(void * thrown_object,std::type_info * tinfo,void (* dest)(void *))259*c05d8e5dSAndroid Build Coastguard Worker __cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *)) {
260*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals *globals = __cxa_get_globals();
261*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
262*c05d8e5dSAndroid Build Coastguard Worker 
263*c05d8e5dSAndroid Build Coastguard Worker     exception_header->unexpectedHandler = std::get_unexpected();
264*c05d8e5dSAndroid Build Coastguard Worker     exception_header->terminateHandler  = std::get_terminate();
265*c05d8e5dSAndroid Build Coastguard Worker     exception_header->exceptionType = tinfo;
266*c05d8e5dSAndroid Build Coastguard Worker     exception_header->exceptionDestructor = dest;
267*c05d8e5dSAndroid Build Coastguard Worker     setOurExceptionClass(&exception_header->unwindHeader);
268*c05d8e5dSAndroid Build Coastguard Worker     exception_header->referenceCount = 1;  // This is a newly allocated exception, no need for thread safety.
269*c05d8e5dSAndroid Build Coastguard Worker     globals->uncaughtExceptions += 1;   // Not atomically, since globals are thread-local
270*c05d8e5dSAndroid Build Coastguard Worker 
271*c05d8e5dSAndroid Build Coastguard Worker     exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
272*c05d8e5dSAndroid Build Coastguard Worker 
273*c05d8e5dSAndroid Build Coastguard Worker #if __has_feature(address_sanitizer)
274*c05d8e5dSAndroid Build Coastguard Worker     // Inform the ASan runtime that now might be a good time to clean stuff up.
275*c05d8e5dSAndroid Build Coastguard Worker     __asan_handle_no_return();
276*c05d8e5dSAndroid Build Coastguard Worker #endif
277*c05d8e5dSAndroid Build Coastguard Worker 
278*c05d8e5dSAndroid Build Coastguard Worker #ifdef __USING_SJLJ_EXCEPTIONS__
279*c05d8e5dSAndroid Build Coastguard Worker     _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
280*c05d8e5dSAndroid Build Coastguard Worker #else
281*c05d8e5dSAndroid Build Coastguard Worker     _Unwind_RaiseException(&exception_header->unwindHeader);
282*c05d8e5dSAndroid Build Coastguard Worker #endif
283*c05d8e5dSAndroid Build Coastguard Worker     //  This only happens when there is no handler, or some unexpected unwinding
284*c05d8e5dSAndroid Build Coastguard Worker     //     error happens.
285*c05d8e5dSAndroid Build Coastguard Worker     failed_throw(exception_header);
286*c05d8e5dSAndroid Build Coastguard Worker }
287*c05d8e5dSAndroid Build Coastguard Worker 
288*c05d8e5dSAndroid Build Coastguard Worker 
289*c05d8e5dSAndroid Build Coastguard Worker // 2.5.3 Exception Handlers
290*c05d8e5dSAndroid Build Coastguard Worker /*
291*c05d8e5dSAndroid Build Coastguard Worker The adjusted pointer is computed by the personality routine during phase 1
292*c05d8e5dSAndroid Build Coastguard Worker   and saved in the exception header (either __cxa_exception or
293*c05d8e5dSAndroid Build Coastguard Worker   __cxa_dependent_exception).
294*c05d8e5dSAndroid Build Coastguard Worker 
295*c05d8e5dSAndroid Build Coastguard Worker   Requires:  exception is native
296*c05d8e5dSAndroid Build Coastguard Worker */
__cxa_get_exception_ptr(void * unwind_exception)297*c05d8e5dSAndroid Build Coastguard Worker void *__cxa_get_exception_ptr(void *unwind_exception) throw() {
298*c05d8e5dSAndroid Build Coastguard Worker #if defined(_LIBCXXABI_ARM_EHABI)
299*c05d8e5dSAndroid Build Coastguard Worker     return reinterpret_cast<void*>(
300*c05d8e5dSAndroid Build Coastguard Worker         static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);
301*c05d8e5dSAndroid Build Coastguard Worker #else
302*c05d8e5dSAndroid Build Coastguard Worker     return cxa_exception_from_exception_unwind_exception(
303*c05d8e5dSAndroid Build Coastguard Worker         static_cast<_Unwind_Exception*>(unwind_exception))->adjustedPtr;
304*c05d8e5dSAndroid Build Coastguard Worker #endif
305*c05d8e5dSAndroid Build Coastguard Worker }
306*c05d8e5dSAndroid Build Coastguard Worker 
307*c05d8e5dSAndroid Build Coastguard Worker #if defined(_LIBCXXABI_ARM_EHABI)
308*c05d8e5dSAndroid Build Coastguard Worker /*
309*c05d8e5dSAndroid Build Coastguard Worker The routine to be called before the cleanup.  This will save __cxa_exception in
310*c05d8e5dSAndroid Build Coastguard Worker __cxa_eh_globals, so that __cxa_end_cleanup() can recover later.
311*c05d8e5dSAndroid Build Coastguard Worker */
__cxa_begin_cleanup(void * unwind_arg)312*c05d8e5dSAndroid Build Coastguard Worker bool __cxa_begin_cleanup(void *unwind_arg) throw() {
313*c05d8e5dSAndroid Build Coastguard Worker     _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
314*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals* globals = __cxa_get_globals();
315*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header =
316*c05d8e5dSAndroid Build Coastguard Worker         cxa_exception_from_exception_unwind_exception(unwind_exception);
317*c05d8e5dSAndroid Build Coastguard Worker 
318*c05d8e5dSAndroid Build Coastguard Worker     if (__isOurExceptionClass(unwind_exception))
319*c05d8e5dSAndroid Build Coastguard Worker     {
320*c05d8e5dSAndroid Build Coastguard Worker         if (0 == exception_header->propagationCount)
321*c05d8e5dSAndroid Build Coastguard Worker         {
322*c05d8e5dSAndroid Build Coastguard Worker             exception_header->nextPropagatingException = globals->propagatingExceptions;
323*c05d8e5dSAndroid Build Coastguard Worker             globals->propagatingExceptions = exception_header;
324*c05d8e5dSAndroid Build Coastguard Worker         }
325*c05d8e5dSAndroid Build Coastguard Worker         ++exception_header->propagationCount;
326*c05d8e5dSAndroid Build Coastguard Worker     }
327*c05d8e5dSAndroid Build Coastguard Worker     else
328*c05d8e5dSAndroid Build Coastguard Worker     {
329*c05d8e5dSAndroid Build Coastguard Worker         // If the propagatingExceptions stack is not empty, since we can't
330*c05d8e5dSAndroid Build Coastguard Worker         // chain the foreign exception, terminate it.
331*c05d8e5dSAndroid Build Coastguard Worker         if (NULL != globals->propagatingExceptions)
332*c05d8e5dSAndroid Build Coastguard Worker             std::terminate();
333*c05d8e5dSAndroid Build Coastguard Worker         globals->propagatingExceptions = exception_header;
334*c05d8e5dSAndroid Build Coastguard Worker     }
335*c05d8e5dSAndroid Build Coastguard Worker     return true;
336*c05d8e5dSAndroid Build Coastguard Worker }
337*c05d8e5dSAndroid Build Coastguard Worker 
338*c05d8e5dSAndroid Build Coastguard Worker /*
339*c05d8e5dSAndroid Build Coastguard Worker The routine to be called after the cleanup has been performed.  It will get the
340*c05d8e5dSAndroid Build Coastguard Worker propagating __cxa_exception from __cxa_eh_globals, and continue the stack
341*c05d8e5dSAndroid Build Coastguard Worker unwinding with _Unwind_Resume.
342*c05d8e5dSAndroid Build Coastguard Worker 
343*c05d8e5dSAndroid Build Coastguard Worker According to ARM EHABI 8.4.1, __cxa_end_cleanup() should not clobber any
344*c05d8e5dSAndroid Build Coastguard Worker register, thus we have to write this function in assembly so that we can save
345*c05d8e5dSAndroid Build Coastguard Worker {r1, r2, r3}.  We don't have to save r0 because it is the return value and the
346*c05d8e5dSAndroid Build Coastguard Worker first argument to _Unwind_Resume().  The function also saves/restores r4 to
347*c05d8e5dSAndroid Build Coastguard Worker keep the stack aligned and to provide a temp register.  _Unwind_Resume never
348*c05d8e5dSAndroid Build Coastguard Worker returns and we need to keep the original lr so just branch to it.  When
349*c05d8e5dSAndroid Build Coastguard Worker targeting bare metal, the function also clobbers ip/r12 to hold the address of
350*c05d8e5dSAndroid Build Coastguard Worker _Unwind_Resume, which may be too far away for an ordinary branch.
351*c05d8e5dSAndroid Build Coastguard Worker */
352*c05d8e5dSAndroid Build Coastguard Worker __attribute__((used)) static _Unwind_Exception *
__cxa_end_cleanup_impl()353*c05d8e5dSAndroid Build Coastguard Worker __cxa_end_cleanup_impl()
354*c05d8e5dSAndroid Build Coastguard Worker {
355*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals* globals = __cxa_get_globals();
356*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header = globals->propagatingExceptions;
357*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == exception_header)
358*c05d8e5dSAndroid Build Coastguard Worker     {
359*c05d8e5dSAndroid Build Coastguard Worker         // It seems that __cxa_begin_cleanup() is not called properly.
360*c05d8e5dSAndroid Build Coastguard Worker         // We have no choice but terminate the program now.
361*c05d8e5dSAndroid Build Coastguard Worker         std::terminate();
362*c05d8e5dSAndroid Build Coastguard Worker     }
363*c05d8e5dSAndroid Build Coastguard Worker 
364*c05d8e5dSAndroid Build Coastguard Worker     if (__isOurExceptionClass(&exception_header->unwindHeader))
365*c05d8e5dSAndroid Build Coastguard Worker     {
366*c05d8e5dSAndroid Build Coastguard Worker         --exception_header->propagationCount;
367*c05d8e5dSAndroid Build Coastguard Worker         if (0 == exception_header->propagationCount)
368*c05d8e5dSAndroid Build Coastguard Worker         {
369*c05d8e5dSAndroid Build Coastguard Worker             globals->propagatingExceptions = exception_header->nextPropagatingException;
370*c05d8e5dSAndroid Build Coastguard Worker             exception_header->nextPropagatingException = NULL;
371*c05d8e5dSAndroid Build Coastguard Worker         }
372*c05d8e5dSAndroid Build Coastguard Worker     }
373*c05d8e5dSAndroid Build Coastguard Worker     else
374*c05d8e5dSAndroid Build Coastguard Worker     {
375*c05d8e5dSAndroid Build Coastguard Worker         globals->propagatingExceptions = NULL;
376*c05d8e5dSAndroid Build Coastguard Worker     }
377*c05d8e5dSAndroid Build Coastguard Worker     return &exception_header->unwindHeader;
378*c05d8e5dSAndroid Build Coastguard Worker }
379*c05d8e5dSAndroid Build Coastguard Worker 
380*c05d8e5dSAndroid Build Coastguard Worker asm("	.pushsection	.text.__cxa_end_cleanup,\"ax\",%progbits\n"
381*c05d8e5dSAndroid Build Coastguard Worker     "	.globl	__cxa_end_cleanup\n"
382*c05d8e5dSAndroid Build Coastguard Worker     "	.type	__cxa_end_cleanup,%function\n"
383*c05d8e5dSAndroid Build Coastguard Worker     "__cxa_end_cleanup:\n"
384*c05d8e5dSAndroid Build Coastguard Worker #if defined(__ARM_FEATURE_BTI_DEFAULT)
385*c05d8e5dSAndroid Build Coastguard Worker     "	bti\n"
386*c05d8e5dSAndroid Build Coastguard Worker #endif
387*c05d8e5dSAndroid Build Coastguard Worker     "	push	{r1, r2, r3, r4}\n"
388*c05d8e5dSAndroid Build Coastguard Worker     "	mov	r4, lr\n"
389*c05d8e5dSAndroid Build Coastguard Worker     "	bl	__cxa_end_cleanup_impl\n"
390*c05d8e5dSAndroid Build Coastguard Worker     "	mov	lr, r4\n"
391*c05d8e5dSAndroid Build Coastguard Worker #if defined(LIBCXXABI_BAREMETAL)
392*c05d8e5dSAndroid Build Coastguard Worker     "	ldr	r4,	=_Unwind_Resume\n"
393*c05d8e5dSAndroid Build Coastguard Worker     "	mov	ip,	r4\n"
394*c05d8e5dSAndroid Build Coastguard Worker #endif
395*c05d8e5dSAndroid Build Coastguard Worker     "	pop	{r1, r2, r3, r4}\n"
396*c05d8e5dSAndroid Build Coastguard Worker #if defined(LIBCXXABI_BAREMETAL)
397*c05d8e5dSAndroid Build Coastguard Worker     "	bx	ip\n"
398*c05d8e5dSAndroid Build Coastguard Worker #else
399*c05d8e5dSAndroid Build Coastguard Worker     "	b	_Unwind_Resume\n"
400*c05d8e5dSAndroid Build Coastguard Worker #endif
401*c05d8e5dSAndroid Build Coastguard Worker     "	.popsection");
402*c05d8e5dSAndroid Build Coastguard Worker #endif // defined(_LIBCXXABI_ARM_EHABI)
403*c05d8e5dSAndroid Build Coastguard Worker 
404*c05d8e5dSAndroid Build Coastguard Worker /*
405*c05d8e5dSAndroid Build Coastguard Worker This routine can catch foreign or native exceptions.  If native, the exception
406*c05d8e5dSAndroid Build Coastguard Worker can be a primary or dependent variety.  This routine may remain blissfully
407*c05d8e5dSAndroid Build Coastguard Worker ignorant of whether the native exception is primary or dependent.
408*c05d8e5dSAndroid Build Coastguard Worker 
409*c05d8e5dSAndroid Build Coastguard Worker If the exception is native:
410*c05d8e5dSAndroid Build Coastguard Worker * Increment's the exception's handler count.
411*c05d8e5dSAndroid Build Coastguard Worker * Push the exception on the stack of currently-caught exceptions if it is not
412*c05d8e5dSAndroid Build Coastguard Worker   already there (from a rethrow).
413*c05d8e5dSAndroid Build Coastguard Worker * Decrements the uncaught_exception count.
414*c05d8e5dSAndroid Build Coastguard Worker * Returns the adjusted pointer to the exception object, which is stored in
415*c05d8e5dSAndroid Build Coastguard Worker   the __cxa_exception by the personality routine.
416*c05d8e5dSAndroid Build Coastguard Worker 
417*c05d8e5dSAndroid Build Coastguard Worker If the exception is foreign, this means it did not originate from one of throw
418*c05d8e5dSAndroid Build Coastguard Worker routines.  The foreign exception does not necessarily have a __cxa_exception
419*c05d8e5dSAndroid Build Coastguard Worker header.  However we can catch it here with a catch (...), or with a call
420*c05d8e5dSAndroid Build Coastguard Worker to terminate or unexpected during unwinding.
421*c05d8e5dSAndroid Build Coastguard Worker * Do not try to increment the exception's handler count, we don't know where
422*c05d8e5dSAndroid Build Coastguard Worker   it is.
423*c05d8e5dSAndroid Build Coastguard Worker * Push the exception on the stack of currently-caught exceptions only if the
424*c05d8e5dSAndroid Build Coastguard Worker   stack is empty.  The foreign exception has no way to link to the current
425*c05d8e5dSAndroid Build Coastguard Worker   top of stack.  If the stack is not empty, call terminate.  Even with an
426*c05d8e5dSAndroid Build Coastguard Worker   empty stack, this is hacked in by pushing a pointer to an imaginary
427*c05d8e5dSAndroid Build Coastguard Worker   __cxa_exception block in front of the foreign exception.  It would be better
428*c05d8e5dSAndroid Build Coastguard Worker   if the __cxa_eh_globals structure had a stack of _Unwind_Exception, but it
429*c05d8e5dSAndroid Build Coastguard Worker   doesn't.  It has a stack of __cxa_exception (which has a next* in it).
430*c05d8e5dSAndroid Build Coastguard Worker * Do not decrement the uncaught_exception count because we didn't increment it
431*c05d8e5dSAndroid Build Coastguard Worker   in __cxa_throw (or one of our rethrow functions).
432*c05d8e5dSAndroid Build Coastguard Worker * If we haven't terminated, assume the exception object is just past the
433*c05d8e5dSAndroid Build Coastguard Worker   _Unwind_Exception and return a pointer to that.
434*c05d8e5dSAndroid Build Coastguard Worker */
435*c05d8e5dSAndroid Build Coastguard Worker void*
__cxa_begin_catch(void * unwind_arg)436*c05d8e5dSAndroid Build Coastguard Worker __cxa_begin_catch(void* unwind_arg) throw()
437*c05d8e5dSAndroid Build Coastguard Worker {
438*c05d8e5dSAndroid Build Coastguard Worker     _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
439*c05d8e5dSAndroid Build Coastguard Worker     bool native_exception = __isOurExceptionClass(unwind_exception);
440*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals* globals = __cxa_get_globals();
441*c05d8e5dSAndroid Build Coastguard Worker     // exception_header is a hackish offset from a foreign exception, but it
442*c05d8e5dSAndroid Build Coastguard Worker     //   works as long as we're careful not to try to access any __cxa_exception
443*c05d8e5dSAndroid Build Coastguard Worker     //   parts.
444*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header =
445*c05d8e5dSAndroid Build Coastguard Worker             cxa_exception_from_exception_unwind_exception
446*c05d8e5dSAndroid Build Coastguard Worker             (
447*c05d8e5dSAndroid Build Coastguard Worker                 static_cast<_Unwind_Exception*>(unwind_exception)
448*c05d8e5dSAndroid Build Coastguard Worker             );
449*c05d8e5dSAndroid Build Coastguard Worker     if (native_exception)
450*c05d8e5dSAndroid Build Coastguard Worker     {
451*c05d8e5dSAndroid Build Coastguard Worker         // Increment the handler count, removing the flag about being rethrown
452*c05d8e5dSAndroid Build Coastguard Worker         exception_header->handlerCount = exception_header->handlerCount < 0 ?
453*c05d8e5dSAndroid Build Coastguard Worker             -exception_header->handlerCount + 1 : exception_header->handlerCount + 1;
454*c05d8e5dSAndroid Build Coastguard Worker         //  place the exception on the top of the stack if it's not already
455*c05d8e5dSAndroid Build Coastguard Worker         //    there by a previous rethrow
456*c05d8e5dSAndroid Build Coastguard Worker         if (exception_header != globals->caughtExceptions)
457*c05d8e5dSAndroid Build Coastguard Worker         {
458*c05d8e5dSAndroid Build Coastguard Worker             exception_header->nextException = globals->caughtExceptions;
459*c05d8e5dSAndroid Build Coastguard Worker             globals->caughtExceptions = exception_header;
460*c05d8e5dSAndroid Build Coastguard Worker         }
461*c05d8e5dSAndroid Build Coastguard Worker         globals->uncaughtExceptions -= 1;   // Not atomically, since globals are thread-local
462*c05d8e5dSAndroid Build Coastguard Worker #if defined(_LIBCXXABI_ARM_EHABI)
463*c05d8e5dSAndroid Build Coastguard Worker         return reinterpret_cast<void*>(exception_header->unwindHeader.barrier_cache.bitpattern[0]);
464*c05d8e5dSAndroid Build Coastguard Worker #else
465*c05d8e5dSAndroid Build Coastguard Worker         return exception_header->adjustedPtr;
466*c05d8e5dSAndroid Build Coastguard Worker #endif
467*c05d8e5dSAndroid Build Coastguard Worker     }
468*c05d8e5dSAndroid Build Coastguard Worker     // Else this is a foreign exception
469*c05d8e5dSAndroid Build Coastguard Worker     // If the caughtExceptions stack is not empty, terminate
470*c05d8e5dSAndroid Build Coastguard Worker     if (globals->caughtExceptions != 0)
471*c05d8e5dSAndroid Build Coastguard Worker         std::terminate();
472*c05d8e5dSAndroid Build Coastguard Worker     // Push the foreign exception on to the stack
473*c05d8e5dSAndroid Build Coastguard Worker     globals->caughtExceptions = exception_header;
474*c05d8e5dSAndroid Build Coastguard Worker     return unwind_exception + 1;
475*c05d8e5dSAndroid Build Coastguard Worker }
476*c05d8e5dSAndroid Build Coastguard Worker 
477*c05d8e5dSAndroid Build Coastguard Worker 
478*c05d8e5dSAndroid Build Coastguard Worker /*
479*c05d8e5dSAndroid Build Coastguard Worker Upon exit for any reason, a handler must call:
480*c05d8e5dSAndroid Build Coastguard Worker     void __cxa_end_catch ();
481*c05d8e5dSAndroid Build Coastguard Worker 
482*c05d8e5dSAndroid Build Coastguard Worker This routine can be called for either a native or foreign exception.
483*c05d8e5dSAndroid Build Coastguard Worker For a native exception:
484*c05d8e5dSAndroid Build Coastguard Worker * Locates the most recently caught exception and decrements its handler count.
485*c05d8e5dSAndroid Build Coastguard Worker * Removes the exception from the caught exception stack, if the handler count goes to zero.
486*c05d8e5dSAndroid Build Coastguard Worker * If the handler count goes down to zero, and the exception was not re-thrown
487*c05d8e5dSAndroid Build Coastguard Worker   by throw, it locates the primary exception (which may be the same as the one
488*c05d8e5dSAndroid Build Coastguard Worker   it's handling) and decrements its reference count. If that reference count
489*c05d8e5dSAndroid Build Coastguard Worker   goes to zero, the function destroys the exception. In any case, if the current
490*c05d8e5dSAndroid Build Coastguard Worker   exception is a dependent exception, it destroys that.
491*c05d8e5dSAndroid Build Coastguard Worker 
492*c05d8e5dSAndroid Build Coastguard Worker For a foreign exception:
493*c05d8e5dSAndroid Build Coastguard Worker * If it has been rethrown, there is nothing to do.
494*c05d8e5dSAndroid Build Coastguard Worker * Otherwise delete the exception and pop the catch stack to empty.
495*c05d8e5dSAndroid Build Coastguard Worker */
__cxa_end_catch()496*c05d8e5dSAndroid Build Coastguard Worker void __cxa_end_catch() {
497*c05d8e5dSAndroid Build Coastguard Worker   static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),
498*c05d8e5dSAndroid Build Coastguard Worker                 "sizeof(__cxa_exception) must be equal to "
499*c05d8e5dSAndroid Build Coastguard Worker                 "sizeof(__cxa_dependent_exception)");
500*c05d8e5dSAndroid Build Coastguard Worker   static_assert(__builtin_offsetof(__cxa_exception, referenceCount) ==
501*c05d8e5dSAndroid Build Coastguard Worker                     __builtin_offsetof(__cxa_dependent_exception,
502*c05d8e5dSAndroid Build Coastguard Worker                                        primaryException),
503*c05d8e5dSAndroid Build Coastguard Worker                 "the layout of __cxa_exception must match the layout of "
504*c05d8e5dSAndroid Build Coastguard Worker                 "__cxa_dependent_exception");
505*c05d8e5dSAndroid Build Coastguard Worker   static_assert(__builtin_offsetof(__cxa_exception, handlerCount) ==
506*c05d8e5dSAndroid Build Coastguard Worker                     __builtin_offsetof(__cxa_dependent_exception, handlerCount),
507*c05d8e5dSAndroid Build Coastguard Worker                 "the layout of __cxa_exception must match the layout of "
508*c05d8e5dSAndroid Build Coastguard Worker                 "__cxa_dependent_exception");
509*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch
510*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header = globals->caughtExceptions;
511*c05d8e5dSAndroid Build Coastguard Worker     // If we've rethrown a foreign exception, then globals->caughtExceptions
512*c05d8e5dSAndroid Build Coastguard Worker     //    will have been made an empty stack by __cxa_rethrow() and there is
513*c05d8e5dSAndroid Build Coastguard Worker     //    nothing more to be done.  Do nothing!
514*c05d8e5dSAndroid Build Coastguard Worker     if (NULL != exception_header)
515*c05d8e5dSAndroid Build Coastguard Worker     {
516*c05d8e5dSAndroid Build Coastguard Worker         bool native_exception = __isOurExceptionClass(&exception_header->unwindHeader);
517*c05d8e5dSAndroid Build Coastguard Worker         if (native_exception)
518*c05d8e5dSAndroid Build Coastguard Worker         {
519*c05d8e5dSAndroid Build Coastguard Worker             // This is a native exception
520*c05d8e5dSAndroid Build Coastguard Worker             if (exception_header->handlerCount < 0)
521*c05d8e5dSAndroid Build Coastguard Worker             {
522*c05d8e5dSAndroid Build Coastguard Worker                 //  The exception has been rethrown by __cxa_rethrow, so don't delete it
523*c05d8e5dSAndroid Build Coastguard Worker                 if (0 == incrementHandlerCount(exception_header))
524*c05d8e5dSAndroid Build Coastguard Worker                 {
525*c05d8e5dSAndroid Build Coastguard Worker                     //  Remove from the chain of uncaught exceptions
526*c05d8e5dSAndroid Build Coastguard Worker                     globals->caughtExceptions = exception_header->nextException;
527*c05d8e5dSAndroid Build Coastguard Worker                     // but don't destroy
528*c05d8e5dSAndroid Build Coastguard Worker                 }
529*c05d8e5dSAndroid Build Coastguard Worker                 // Keep handlerCount negative in case there are nested catch's
530*c05d8e5dSAndroid Build Coastguard Worker                 //   that need to be told that this exception is rethrown.  Don't
531*c05d8e5dSAndroid Build Coastguard Worker                 //   erase this rethrow flag until the exception is recaught.
532*c05d8e5dSAndroid Build Coastguard Worker             }
533*c05d8e5dSAndroid Build Coastguard Worker             else
534*c05d8e5dSAndroid Build Coastguard Worker             {
535*c05d8e5dSAndroid Build Coastguard Worker                 // The native exception has not been rethrown
536*c05d8e5dSAndroid Build Coastguard Worker                 if (0 == decrementHandlerCount(exception_header))
537*c05d8e5dSAndroid Build Coastguard Worker                 {
538*c05d8e5dSAndroid Build Coastguard Worker                     //  Remove from the chain of uncaught exceptions
539*c05d8e5dSAndroid Build Coastguard Worker                     globals->caughtExceptions = exception_header->nextException;
540*c05d8e5dSAndroid Build Coastguard Worker                     // Destroy this exception, being careful to distinguish
541*c05d8e5dSAndroid Build Coastguard Worker                     //    between dependent and primary exceptions
542*c05d8e5dSAndroid Build Coastguard Worker                     if (isDependentException(&exception_header->unwindHeader))
543*c05d8e5dSAndroid Build Coastguard Worker                     {
544*c05d8e5dSAndroid Build Coastguard Worker                         // Reset exception_header to primaryException and deallocate the dependent exception
545*c05d8e5dSAndroid Build Coastguard Worker                         __cxa_dependent_exception* dep_exception_header =
546*c05d8e5dSAndroid Build Coastguard Worker                             reinterpret_cast<__cxa_dependent_exception*>(exception_header);
547*c05d8e5dSAndroid Build Coastguard Worker                         exception_header =
548*c05d8e5dSAndroid Build Coastguard Worker                             cxa_exception_from_thrown_object(dep_exception_header->primaryException);
549*c05d8e5dSAndroid Build Coastguard Worker                         __cxa_free_dependent_exception(dep_exception_header);
550*c05d8e5dSAndroid Build Coastguard Worker                     }
551*c05d8e5dSAndroid Build Coastguard Worker                     // Destroy the primary exception only if its referenceCount goes to 0
552*c05d8e5dSAndroid Build Coastguard Worker                     //    (this decrement must be atomic)
553*c05d8e5dSAndroid Build Coastguard Worker                     __cxa_decrement_exception_refcount(thrown_object_from_cxa_exception(exception_header));
554*c05d8e5dSAndroid Build Coastguard Worker                 }
555*c05d8e5dSAndroid Build Coastguard Worker             }
556*c05d8e5dSAndroid Build Coastguard Worker         }
557*c05d8e5dSAndroid Build Coastguard Worker         else
558*c05d8e5dSAndroid Build Coastguard Worker         {
559*c05d8e5dSAndroid Build Coastguard Worker             // The foreign exception has not been rethrown.  Pop the stack
560*c05d8e5dSAndroid Build Coastguard Worker             //    and delete it.  If there are nested catch's and they try
561*c05d8e5dSAndroid Build Coastguard Worker             //    to touch a foreign exception in any way, that is undefined
562*c05d8e5dSAndroid Build Coastguard Worker             //     behavior.  They likely can't since the only way to catch
563*c05d8e5dSAndroid Build Coastguard Worker             //     a foreign exception is with catch (...)!
564*c05d8e5dSAndroid Build Coastguard Worker             _Unwind_DeleteException(&globals->caughtExceptions->unwindHeader);
565*c05d8e5dSAndroid Build Coastguard Worker             globals->caughtExceptions = 0;
566*c05d8e5dSAndroid Build Coastguard Worker         }
567*c05d8e5dSAndroid Build Coastguard Worker     }
568*c05d8e5dSAndroid Build Coastguard Worker }
569*c05d8e5dSAndroid Build Coastguard Worker 
570*c05d8e5dSAndroid Build Coastguard Worker // Note:  exception_header may be masquerading as a __cxa_dependent_exception
571*c05d8e5dSAndroid Build Coastguard Worker //        and that's ok.  exceptionType is there too.
572*c05d8e5dSAndroid Build Coastguard Worker //        However watch out for foreign exceptions.  Return null for them.
__cxa_current_exception_type()573*c05d8e5dSAndroid Build Coastguard Worker std::type_info *__cxa_current_exception_type() {
574*c05d8e5dSAndroid Build Coastguard Worker //  get the current exception
575*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals *globals = __cxa_get_globals_fast();
576*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == globals)
577*c05d8e5dSAndroid Build Coastguard Worker         return NULL;     //  If there have never been any exceptions, there are none now.
578*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception *exception_header = globals->caughtExceptions;
579*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == exception_header)
580*c05d8e5dSAndroid Build Coastguard Worker         return NULL;        //  No current exception
581*c05d8e5dSAndroid Build Coastguard Worker     if (!__isOurExceptionClass(&exception_header->unwindHeader))
582*c05d8e5dSAndroid Build Coastguard Worker         return NULL;
583*c05d8e5dSAndroid Build Coastguard Worker     return exception_header->exceptionType;
584*c05d8e5dSAndroid Build Coastguard Worker }
585*c05d8e5dSAndroid Build Coastguard Worker 
586*c05d8e5dSAndroid Build Coastguard Worker // 2.5.4 Rethrowing Exceptions
587*c05d8e5dSAndroid Build Coastguard Worker /*  This routine can rethrow native or foreign exceptions.
588*c05d8e5dSAndroid Build Coastguard Worker If the exception is native:
589*c05d8e5dSAndroid Build Coastguard Worker * marks the exception object on top of the caughtExceptions stack
590*c05d8e5dSAndroid Build Coastguard Worker   (in an implementation-defined way) as being rethrown.
591*c05d8e5dSAndroid Build Coastguard Worker * If the caughtExceptions stack is empty, it calls terminate()
592*c05d8e5dSAndroid Build Coastguard Worker   (see [C++FDIS] [except.throw], 15.1.8).
593*c05d8e5dSAndroid Build Coastguard Worker * It then calls _Unwind_RaiseException which should not return
594*c05d8e5dSAndroid Build Coastguard Worker    (terminate if it does).
595*c05d8e5dSAndroid Build Coastguard Worker   Note:  exception_header may be masquerading as a __cxa_dependent_exception
596*c05d8e5dSAndroid Build Coastguard Worker          and that's ok.
597*c05d8e5dSAndroid Build Coastguard Worker */
__cxa_rethrow()598*c05d8e5dSAndroid Build Coastguard Worker void __cxa_rethrow() {
599*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals* globals = __cxa_get_globals();
600*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header = globals->caughtExceptions;
601*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == exception_header)
602*c05d8e5dSAndroid Build Coastguard Worker         std::terminate();      // throw; called outside of a exception handler
603*c05d8e5dSAndroid Build Coastguard Worker     bool native_exception = __isOurExceptionClass(&exception_header->unwindHeader);
604*c05d8e5dSAndroid Build Coastguard Worker     if (native_exception)
605*c05d8e5dSAndroid Build Coastguard Worker     {
606*c05d8e5dSAndroid Build Coastguard Worker         //  Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch)
607*c05d8e5dSAndroid Build Coastguard Worker         exception_header->handlerCount = -exception_header->handlerCount;
608*c05d8e5dSAndroid Build Coastguard Worker         globals->uncaughtExceptions += 1;
609*c05d8e5dSAndroid Build Coastguard Worker         //  __cxa_end_catch will remove this exception from the caughtExceptions stack if necessary
610*c05d8e5dSAndroid Build Coastguard Worker     }
611*c05d8e5dSAndroid Build Coastguard Worker     else  // this is a foreign exception
612*c05d8e5dSAndroid Build Coastguard Worker     {
613*c05d8e5dSAndroid Build Coastguard Worker         // The only way to communicate to __cxa_end_catch that we've rethrown
614*c05d8e5dSAndroid Build Coastguard Worker         //   a foreign exception, so don't delete us, is to pop the stack here
615*c05d8e5dSAndroid Build Coastguard Worker         //   which must be empty afterwards.  Then __cxa_end_catch will do
616*c05d8e5dSAndroid Build Coastguard Worker         //   nothing
617*c05d8e5dSAndroid Build Coastguard Worker         globals->caughtExceptions = 0;
618*c05d8e5dSAndroid Build Coastguard Worker     }
619*c05d8e5dSAndroid Build Coastguard Worker #ifdef __USING_SJLJ_EXCEPTIONS__
620*c05d8e5dSAndroid Build Coastguard Worker     _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
621*c05d8e5dSAndroid Build Coastguard Worker #else
622*c05d8e5dSAndroid Build Coastguard Worker     _Unwind_RaiseException(&exception_header->unwindHeader);
623*c05d8e5dSAndroid Build Coastguard Worker #endif
624*c05d8e5dSAndroid Build Coastguard Worker 
625*c05d8e5dSAndroid Build Coastguard Worker     //  If we get here, some kind of unwinding error has occurred.
626*c05d8e5dSAndroid Build Coastguard Worker     //  There is some weird code generation bug happening with
627*c05d8e5dSAndroid Build Coastguard Worker     //     Apple clang version 4.0 (tags/Apple/clang-418.0.2) (based on LLVM 3.1svn)
628*c05d8e5dSAndroid Build Coastguard Worker     //     If we call failed_throw here.  Turns up with -O2 or higher, and -Os.
629*c05d8e5dSAndroid Build Coastguard Worker     __cxa_begin_catch(&exception_header->unwindHeader);
630*c05d8e5dSAndroid Build Coastguard Worker     if (native_exception)
631*c05d8e5dSAndroid Build Coastguard Worker         std::__terminate(exception_header->terminateHandler);
632*c05d8e5dSAndroid Build Coastguard Worker     // Foreign exception: can't get exception_header->terminateHandler
633*c05d8e5dSAndroid Build Coastguard Worker     std::terminate();
634*c05d8e5dSAndroid Build Coastguard Worker }
635*c05d8e5dSAndroid Build Coastguard Worker 
636*c05d8e5dSAndroid Build Coastguard Worker /*
637*c05d8e5dSAndroid Build Coastguard Worker     If thrown_object is not null, atomically increment the referenceCount field
638*c05d8e5dSAndroid Build Coastguard Worker     of the __cxa_exception header associated with the thrown object referred to
639*c05d8e5dSAndroid Build Coastguard Worker     by thrown_object.
640*c05d8e5dSAndroid Build Coastguard Worker 
641*c05d8e5dSAndroid Build Coastguard Worker     Requires:  If thrown_object is not NULL, it is a native exception.
642*c05d8e5dSAndroid Build Coastguard Worker */
643*c05d8e5dSAndroid Build Coastguard Worker void
__cxa_increment_exception_refcount(void * thrown_object)644*c05d8e5dSAndroid Build Coastguard Worker __cxa_increment_exception_refcount(void *thrown_object) throw() {
645*c05d8e5dSAndroid Build Coastguard Worker     if (thrown_object != NULL )
646*c05d8e5dSAndroid Build Coastguard Worker     {
647*c05d8e5dSAndroid Build Coastguard Worker         __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
648*c05d8e5dSAndroid Build Coastguard Worker         std::__libcpp_atomic_add(&exception_header->referenceCount, size_t(1));
649*c05d8e5dSAndroid Build Coastguard Worker     }
650*c05d8e5dSAndroid Build Coastguard Worker }
651*c05d8e5dSAndroid Build Coastguard Worker 
652*c05d8e5dSAndroid Build Coastguard Worker /*
653*c05d8e5dSAndroid Build Coastguard Worker     If thrown_object is not null, atomically decrement the referenceCount field
654*c05d8e5dSAndroid Build Coastguard Worker     of the __cxa_exception header associated with the thrown object referred to
655*c05d8e5dSAndroid Build Coastguard Worker     by thrown_object.  If the referenceCount drops to zero, destroy and
656*c05d8e5dSAndroid Build Coastguard Worker     deallocate the exception.
657*c05d8e5dSAndroid Build Coastguard Worker 
658*c05d8e5dSAndroid Build Coastguard Worker     Requires:  If thrown_object is not NULL, it is a native exception.
659*c05d8e5dSAndroid Build Coastguard Worker */
660*c05d8e5dSAndroid Build Coastguard Worker _LIBCXXABI_NO_CFI
__cxa_decrement_exception_refcount(void * thrown_object)661*c05d8e5dSAndroid Build Coastguard Worker void __cxa_decrement_exception_refcount(void *thrown_object) throw() {
662*c05d8e5dSAndroid Build Coastguard Worker     if (thrown_object != NULL )
663*c05d8e5dSAndroid Build Coastguard Worker     {
664*c05d8e5dSAndroid Build Coastguard Worker         __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
665*c05d8e5dSAndroid Build Coastguard Worker         if (std::__libcpp_atomic_add(&exception_header->referenceCount, size_t(-1)) == 0)
666*c05d8e5dSAndroid Build Coastguard Worker         {
667*c05d8e5dSAndroid Build Coastguard Worker             if (NULL != exception_header->exceptionDestructor)
668*c05d8e5dSAndroid Build Coastguard Worker                 exception_header->exceptionDestructor(thrown_object);
669*c05d8e5dSAndroid Build Coastguard Worker             __cxa_free_exception(thrown_object);
670*c05d8e5dSAndroid Build Coastguard Worker         }
671*c05d8e5dSAndroid Build Coastguard Worker     }
672*c05d8e5dSAndroid Build Coastguard Worker }
673*c05d8e5dSAndroid Build Coastguard Worker 
674*c05d8e5dSAndroid Build Coastguard Worker /*
675*c05d8e5dSAndroid Build Coastguard Worker     Returns a pointer to the thrown object (if any) at the top of the
676*c05d8e5dSAndroid Build Coastguard Worker     caughtExceptions stack.  Atomically increment the exception's referenceCount.
677*c05d8e5dSAndroid Build Coastguard Worker     If there is no such thrown object or if the thrown object is foreign,
678*c05d8e5dSAndroid Build Coastguard Worker     returns null.
679*c05d8e5dSAndroid Build Coastguard Worker 
680*c05d8e5dSAndroid Build Coastguard Worker     We can use __cxa_get_globals_fast here to get the globals because if there have
681*c05d8e5dSAndroid Build Coastguard Worker     been no exceptions thrown, ever, on this thread, we can return NULL without
682*c05d8e5dSAndroid Build Coastguard Worker     the need to allocate the exception-handling globals.
683*c05d8e5dSAndroid Build Coastguard Worker */
__cxa_current_primary_exception()684*c05d8e5dSAndroid Build Coastguard Worker void *__cxa_current_primary_exception() throw() {
685*c05d8e5dSAndroid Build Coastguard Worker //  get the current exception
686*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals* globals = __cxa_get_globals_fast();
687*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == globals)
688*c05d8e5dSAndroid Build Coastguard Worker         return NULL;        //  If there are no globals, there is no exception
689*c05d8e5dSAndroid Build Coastguard Worker     __cxa_exception* exception_header = globals->caughtExceptions;
690*c05d8e5dSAndroid Build Coastguard Worker     if (NULL == exception_header)
691*c05d8e5dSAndroid Build Coastguard Worker         return NULL;        //  No current exception
692*c05d8e5dSAndroid Build Coastguard Worker     if (!__isOurExceptionClass(&exception_header->unwindHeader))
693*c05d8e5dSAndroid Build Coastguard Worker         return NULL;        // Can't capture a foreign exception (no way to refcount it)
694*c05d8e5dSAndroid Build Coastguard Worker     if (isDependentException(&exception_header->unwindHeader)) {
695*c05d8e5dSAndroid Build Coastguard Worker         __cxa_dependent_exception* dep_exception_header =
696*c05d8e5dSAndroid Build Coastguard Worker             reinterpret_cast<__cxa_dependent_exception*>(exception_header);
697*c05d8e5dSAndroid Build Coastguard Worker         exception_header = cxa_exception_from_thrown_object(dep_exception_header->primaryException);
698*c05d8e5dSAndroid Build Coastguard Worker     }
699*c05d8e5dSAndroid Build Coastguard Worker     void* thrown_object = thrown_object_from_cxa_exception(exception_header);
700*c05d8e5dSAndroid Build Coastguard Worker     __cxa_increment_exception_refcount(thrown_object);
701*c05d8e5dSAndroid Build Coastguard Worker     return thrown_object;
702*c05d8e5dSAndroid Build Coastguard Worker }
703*c05d8e5dSAndroid Build Coastguard Worker 
704*c05d8e5dSAndroid Build Coastguard Worker /*
705*c05d8e5dSAndroid Build Coastguard Worker     If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
706*c05d8e5dSAndroid Build Coastguard Worker     stored in exc is called.  Otherwise the referenceCount stored in the
707*c05d8e5dSAndroid Build Coastguard Worker     primary exception is decremented, destroying the primary if necessary.
708*c05d8e5dSAndroid Build Coastguard Worker     Finally the dependent exception is destroyed.
709*c05d8e5dSAndroid Build Coastguard Worker */
710*c05d8e5dSAndroid Build Coastguard Worker static
711*c05d8e5dSAndroid Build Coastguard Worker void
dependent_exception_cleanup(_Unwind_Reason_Code reason,_Unwind_Exception * unwind_exception)712*c05d8e5dSAndroid Build Coastguard Worker dependent_exception_cleanup(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)
713*c05d8e5dSAndroid Build Coastguard Worker {
714*c05d8e5dSAndroid Build Coastguard Worker     __cxa_dependent_exception* dep_exception_header =
715*c05d8e5dSAndroid Build Coastguard Worker                       reinterpret_cast<__cxa_dependent_exception*>(unwind_exception + 1) - 1;
716*c05d8e5dSAndroid Build Coastguard Worker     if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
717*c05d8e5dSAndroid Build Coastguard Worker         std::__terminate(dep_exception_header->terminateHandler);
718*c05d8e5dSAndroid Build Coastguard Worker     __cxa_decrement_exception_refcount(dep_exception_header->primaryException);
719*c05d8e5dSAndroid Build Coastguard Worker     __cxa_free_dependent_exception(dep_exception_header);
720*c05d8e5dSAndroid Build Coastguard Worker }
721*c05d8e5dSAndroid Build Coastguard Worker 
722*c05d8e5dSAndroid Build Coastguard Worker /*
723*c05d8e5dSAndroid Build Coastguard Worker     If thrown_object is not null, allocate, initialize and throw a dependent
724*c05d8e5dSAndroid Build Coastguard Worker     exception.
725*c05d8e5dSAndroid Build Coastguard Worker */
726*c05d8e5dSAndroid Build Coastguard Worker void
__cxa_rethrow_primary_exception(void * thrown_object)727*c05d8e5dSAndroid Build Coastguard Worker __cxa_rethrow_primary_exception(void* thrown_object)
728*c05d8e5dSAndroid Build Coastguard Worker {
729*c05d8e5dSAndroid Build Coastguard Worker     if ( thrown_object != NULL )
730*c05d8e5dSAndroid Build Coastguard Worker     {
731*c05d8e5dSAndroid Build Coastguard Worker         // thrown_object guaranteed to be native because
732*c05d8e5dSAndroid Build Coastguard Worker         //   __cxa_current_primary_exception returns NULL for foreign exceptions
733*c05d8e5dSAndroid Build Coastguard Worker         __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
734*c05d8e5dSAndroid Build Coastguard Worker         __cxa_dependent_exception* dep_exception_header =
735*c05d8e5dSAndroid Build Coastguard Worker             static_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception());
736*c05d8e5dSAndroid Build Coastguard Worker         dep_exception_header->primaryException = thrown_object;
737*c05d8e5dSAndroid Build Coastguard Worker         __cxa_increment_exception_refcount(thrown_object);
738*c05d8e5dSAndroid Build Coastguard Worker         dep_exception_header->exceptionType = exception_header->exceptionType;
739*c05d8e5dSAndroid Build Coastguard Worker         dep_exception_header->unexpectedHandler = std::get_unexpected();
740*c05d8e5dSAndroid Build Coastguard Worker         dep_exception_header->terminateHandler = std::get_terminate();
741*c05d8e5dSAndroid Build Coastguard Worker         setDependentExceptionClass(&dep_exception_header->unwindHeader);
742*c05d8e5dSAndroid Build Coastguard Worker         __cxa_get_globals()->uncaughtExceptions += 1;
743*c05d8e5dSAndroid Build Coastguard Worker         dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup;
744*c05d8e5dSAndroid Build Coastguard Worker #ifdef __USING_SJLJ_EXCEPTIONS__
745*c05d8e5dSAndroid Build Coastguard Worker         _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader);
746*c05d8e5dSAndroid Build Coastguard Worker #else
747*c05d8e5dSAndroid Build Coastguard Worker         _Unwind_RaiseException(&dep_exception_header->unwindHeader);
748*c05d8e5dSAndroid Build Coastguard Worker #endif
749*c05d8e5dSAndroid Build Coastguard Worker         // Some sort of unwinding error.  Note that terminate is a handler.
750*c05d8e5dSAndroid Build Coastguard Worker         __cxa_begin_catch(&dep_exception_header->unwindHeader);
751*c05d8e5dSAndroid Build Coastguard Worker     }
752*c05d8e5dSAndroid Build Coastguard Worker     // If we return client will call terminate()
753*c05d8e5dSAndroid Build Coastguard Worker }
754*c05d8e5dSAndroid Build Coastguard Worker 
755*c05d8e5dSAndroid Build Coastguard Worker bool
__cxa_uncaught_exception()756*c05d8e5dSAndroid Build Coastguard Worker __cxa_uncaught_exception() throw() { return __cxa_uncaught_exceptions() != 0; }
757*c05d8e5dSAndroid Build Coastguard Worker 
758*c05d8e5dSAndroid Build Coastguard Worker unsigned int
__cxa_uncaught_exceptions()759*c05d8e5dSAndroid Build Coastguard Worker __cxa_uncaught_exceptions() throw()
760*c05d8e5dSAndroid Build Coastguard Worker {
761*c05d8e5dSAndroid Build Coastguard Worker     // This does not report foreign exceptions in flight
762*c05d8e5dSAndroid Build Coastguard Worker     __cxa_eh_globals* globals = __cxa_get_globals_fast();
763*c05d8e5dSAndroid Build Coastguard Worker     if (globals == 0)
764*c05d8e5dSAndroid Build Coastguard Worker         return 0;
765*c05d8e5dSAndroid Build Coastguard Worker     return globals->uncaughtExceptions;
766*c05d8e5dSAndroid Build Coastguard Worker }
767*c05d8e5dSAndroid Build Coastguard Worker 
768*c05d8e5dSAndroid Build Coastguard Worker }  // extern "C"
769*c05d8e5dSAndroid Build Coastguard Worker 
770*c05d8e5dSAndroid Build Coastguard Worker }  // abi
771