···11+//===-------------------------- abort_message.h-----------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//===----------------------------------------------------------------------===//
99+1010+#ifndef __ABORT_MESSAGE_H_
1111+#define __ABORT_MESSAGE_H_
1212+1313+#include <stdio.h>
1414+1515+#pragma GCC visibility push(hidden)
1616+1717+#ifdef __cplusplus
1818+extern "C" {
1919+#endif
2020+2121+__attribute__((visibility("hidden"), noreturn))
2222+ void abort_message(const char* format, ...)
2323+ __attribute__((format(printf, 1, 2)));
2424+2525+2626+#ifdef __cplusplus
2727+}
2828+#endif
2929+3030+#pragma GCC visibility pop
3131+3232+#endif
3333+
···11+//===------------------------ cxa_aux_runtime.cpp -------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//
99+// This file implements the "Auxiliary Runtime APIs"
1010+// http://www.codesourcery.com/public/cxx-abi/abi-eh.html#cxx-aux
1111+//===----------------------------------------------------------------------===//
1212+1313+#include "cxxabi.h"
1414+#include <typeinfo>
1515+1616+namespace __cxxabiv1
1717+{
1818+1919+extern "C"
2020+{
2121+2222+LIBCXXABI_NORETURN
2323+void __cxa_bad_cast (void) {
2424+ throw std::bad_cast();
2525+}
2626+2727+LIBCXXABI_NORETURN
2828+void __cxa_bad_typeid(void) {
2929+ throw std::bad_typeid();
3030+}
3131+3232+} // extern "C"
3333+3434+} // abi
···11+//===------------------------- cxa_exception.cpp --------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//
99+// This file implements the "Exception Handling APIs"
1010+// http://www.codesourcery.com/public/cxx-abi/abi-eh.html
1111+//
1212+//===----------------------------------------------------------------------===//
1313+1414+#include "cxxabi.h"
1515+1616+#include <exception> // for std::terminate
1717+#include <cstdlib> // for malloc, free
1818+#include <string> // for memset
1919+#include <pthread.h>
2020+2121+#include "cxa_exception.hpp"
2222+#include "cxa_handlers.hpp"
2323+2424+// +---------------------------+-----------------------------+---------------+
2525+// | __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object |
2626+// +---------------------------+-----------------------------+---------------+
2727+// ^
2828+// |
2929+// +-------------------------------------------------------+
3030+// |
3131+// +---------------------------+-----------------------------+
3232+// | __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 |
3333+// +---------------------------+-----------------------------+
3434+3535+namespace __cxxabiv1 {
3636+3737+#pragma GCC visibility push(default)
3838+3939+// Utility routines
4040+static
4141+inline
4242+__cxa_exception*
4343+cxa_exception_from_thrown_object(void* thrown_object)
4444+{
4545+ return static_cast<__cxa_exception*>(thrown_object) - 1;
4646+}
4747+4848+// Note: This is never called when exception_header is masquerading as a
4949+// __cxa_dependent_exception.
5050+static
5151+inline
5252+void*
5353+thrown_object_from_cxa_exception(__cxa_exception* exception_header)
5454+{
5555+ return static_cast<void*>(exception_header + 1);
5656+}
5757+5858+// Get the exception object from the unwind pointer.
5959+// Relies on the structure layout, where the unwind pointer is right in
6060+// front of the user's exception object
6161+static
6262+inline
6363+__cxa_exception*
6464+cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception)
6565+{
6666+ return cxa_exception_from_thrown_object(unwind_exception + 1 );
6767+}
6868+6969+static
7070+inline
7171+size_t
7272+cxa_exception_size_from_exception_thrown_size(size_t size)
7373+{
7474+ return size + sizeof (__cxa_exception);
7575+}
7676+7777+static void setExceptionClass(_Unwind_Exception* unwind_exception) {
7878+ unwind_exception->exception_class = kOurExceptionClass;
7979+}
8080+8181+static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) {
8282+ unwind_exception->exception_class = kOurDependentExceptionClass;
8383+}
8484+8585+// Is it one of ours?
8686+static bool isOurExceptionClass(const _Unwind_Exception* unwind_exception) {
8787+ return (unwind_exception->exception_class & get_vendor_and_language) ==
8888+ (kOurExceptionClass & get_vendor_and_language);
8989+}
9090+9191+static bool isDependentException(_Unwind_Exception* unwind_exception) {
9292+ return (unwind_exception->exception_class & 0xFF) == 0x01;
9393+}
9494+9595+// This does not need to be atomic
9696+static inline int incrementHandlerCount(__cxa_exception *exception) {
9797+ return ++exception->handlerCount;
9898+}
9999+100100+// This does not need to be atomic
101101+static inline int decrementHandlerCount(__cxa_exception *exception) {
102102+ return --exception->handlerCount;
103103+}
104104+105105+#include "fallback_malloc.ipp"
106106+107107+// Allocate some memory from _somewhere_
108108+static void *do_malloc(size_t size) {
109109+ void *ptr = std::malloc(size);
110110+ if (NULL == ptr) // if malloc fails, fall back to emergency stash
111111+ ptr = fallback_malloc(size);
112112+ return ptr;
113113+}
114114+115115+static void do_free(void *ptr) {
116116+ is_fallback_ptr(ptr) ? fallback_free(ptr) : std::free(ptr);
117117+}
118118+119119+/*
120120+ If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
121121+ stored in exc is called. Otherwise the exceptionDestructor stored in
122122+ exc is called, and then the memory for the exception is deallocated.
123123+124124+ This is never called for a __cxa_dependent_exception.
125125+*/
126126+static
127127+void
128128+exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)
129129+{
130130+ __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception);
131131+ if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
132132+ std::__terminate(exception_header->terminateHandler);
133133+ // Just in case there exists a dependent exception that is pointing to this,
134134+ // check the reference count and only destroy this if that count goes to zero.
135135+ __cxa_decrement_exception_refcount(unwind_exception + 1);
136136+}
137137+138138+static LIBCXXABI_NORETURN void failed_throw(__cxa_exception* exception_header) {
139139+// Section 2.5.3 says:
140140+// * For purposes of this ABI, several things are considered exception handlers:
141141+// ** A terminate() call due to a throw.
142142+// and
143143+// * Upon entry, Following initialization of the catch parameter,
144144+// a handler must call:
145145+// * void *__cxa_begin_catch(void *exceptionObject );
146146+ (void) __cxa_begin_catch(&exception_header->unwindHeader);
147147+ std::__terminate(exception_header->terminateHandler);
148148+}
149149+150150+extern "C" {
151151+152152+// Allocate a __cxa_exception object, and zero-fill it.
153153+// Reserve "thrown_size" bytes on the end for the user's exception
154154+// object. Zero-fill the object. If memory can't be allocated, call
155155+// std::terminate. Return a pointer to the memory to be used for the
156156+// user's exception object.
157157+void * __cxa_allocate_exception (size_t thrown_size) throw() {
158158+ size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size);
159159+ __cxa_exception* exception_header = static_cast<__cxa_exception*>(do_malloc(actual_size));
160160+ if (NULL == exception_header)
161161+ std::terminate();
162162+ std::memset(exception_header, 0, actual_size);
163163+ return thrown_object_from_cxa_exception(exception_header);
164164+}
165165+166166+167167+// Free a __cxa_exception object allocated with __cxa_allocate_exception.
168168+void __cxa_free_exception (void * thrown_object) throw() {
169169+ do_free(cxa_exception_from_thrown_object(thrown_object));
170170+}
171171+172172+173173+// This function shall allocate a __cxa_dependent_exception and
174174+// return a pointer to it. (Really to the object, not past its' end).
175175+// Otherwise, it will work like __cxa_allocate_exception.
176176+void * __cxa_allocate_dependent_exception () {
177177+ size_t actual_size = sizeof(__cxa_dependent_exception);
178178+ void *ptr = do_malloc(actual_size);
179179+ if (NULL == ptr)
180180+ std::terminate();
181181+ std::memset(ptr, 0, actual_size);
182182+ return ptr;
183183+}
184184+185185+186186+// This function shall free a dependent_exception.
187187+// It does not affect the reference count of the primary exception.
188188+void __cxa_free_dependent_exception (void * dependent_exception) {
189189+ do_free(dependent_exception);
190190+}
191191+192192+193193+// 2.4.3 Throwing the Exception Object
194194+/*
195195+After constructing the exception object with the throw argument value,
196196+the generated code calls the __cxa_throw runtime library routine. This
197197+routine never returns.
198198+199199+The __cxa_throw routine will do the following:
200200+201201+* Obtain the __cxa_exception header from the thrown exception object address,
202202+which can be computed as follows:
203203+ __cxa_exception *header = ((__cxa_exception *) thrown_exception - 1);
204204+* Save the current unexpected_handler and terminate_handler in the __cxa_exception header.
205205+* Save the tinfo and dest arguments in the __cxa_exception header.
206206+* Set the exception_class field in the unwind header. This is a 64-bit value
207207+representing the ASCII string "XXXXC++\0", where "XXXX" is a
208208+vendor-dependent string. That is, for implementations conforming to this
209209+ABI, the low-order 4 bytes of this 64-bit value will be "C++\0".
210210+* Increment the uncaught_exception flag.
211211+* Call _Unwind_RaiseException in the system unwind library, Its argument is the
212212+pointer to the thrown exception, which __cxa_throw itself received as an argument.
213213+__Unwind_RaiseException begins the process of stack unwinding, described
214214+in Section 2.5. In special cases, such as an inability to find a
215215+handler, _Unwind_RaiseException may return. In that case, __cxa_throw
216216+will call terminate, assuming that there was no handler for the
217217+exception.
218218+*/
219219+LIBCXXABI_NORETURN
220220+void
221221+__cxa_throw(void* thrown_object, std::type_info* tinfo, void (*dest)(void*))
222222+{
223223+ __cxa_eh_globals *globals = __cxa_get_globals();
224224+ __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
225225+226226+ exception_header->unexpectedHandler = std::get_unexpected();
227227+ exception_header->terminateHandler = std::get_terminate();
228228+ exception_header->exceptionType = tinfo;
229229+ exception_header->exceptionDestructor = dest;
230230+ setExceptionClass(&exception_header->unwindHeader);
231231+ exception_header->referenceCount = 1; // This is a newly allocated exception, no need for thread safety.
232232+ globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local
233233+234234+ exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
235235+#if __arm__
236236+ _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
237237+#else
238238+ _Unwind_RaiseException(&exception_header->unwindHeader);
239239+#endif
240240+ // This only happens when there is no handler, or some unexpected unwinding
241241+ // error happens.
242242+ failed_throw(exception_header);
243243+}
244244+245245+246246+// 2.5.3 Exception Handlers
247247+/*
248248+The adjusted pointer is computed by the personality routine during phase 1
249249+ and saved in the exception header (either __cxa_exception or
250250+ __cxa_dependent_exception).
251251+252252+ Requires: exception is native
253253+*/
254254+void*
255255+__cxa_get_exception_ptr(void* unwind_exception) throw()
256256+{
257257+ return cxa_exception_from_exception_unwind_exception
258258+ (
259259+ static_cast<_Unwind_Exception*>(unwind_exception)
260260+ )->adjustedPtr;
261261+}
262262+263263+/*
264264+This routine can catch foreign or native exceptions. If native, the exception
265265+can be a primary or dependent variety. This routine may remain blissfully
266266+ignorant of whether the native exception is primary or dependent.
267267+268268+If the exception is native:
269269+* Increment's the exception's handler count.
270270+* Push the exception on the stack of currently-caught exceptions if it is not
271271+ already there (from a rethrow).
272272+* Decrements the uncaught_exception count.
273273+* Returns the adjusted pointer to the exception object, which is stored in
274274+ the __cxa_exception by the personality routine.
275275+276276+If the exception is foreign, this means it did not originate from one of throw
277277+routines. The foreign exception does not necessarily have a __cxa_exception
278278+header. However we can catch it here with a catch (...), or with a call
279279+to terminate or unexpected during unwinding.
280280+* Do not try to increment the exception's handler count, we don't know where
281281+ it is.
282282+* Push the exception on the stack of currently-caught exceptions only if the
283283+ stack is empty. The foreign exception has no way to link to the current
284284+ top of stack. If the stack is not empty, call terminate. Even with an
285285+ empty stack, this is hacked in by pushing a pointer to an imaginary
286286+ __cxa_exception block in front of the foreign exception. It would be better
287287+ if the __cxa_eh_globals structure had a stack of _Unwind_Exception, but it
288288+ doesn't. It has a stack of __cxa_exception (which has a next* in it).
289289+* Do not decrement the uncaught_exception count because we didn't increment it
290290+ in __cxa_throw (or one of our rethrow functions).
291291+* If we haven't terminated, assume the exception object is just past the
292292+ _Unwind_Exception and return a pointer to that.
293293+*/
294294+void*
295295+__cxa_begin_catch(void* unwind_arg) throw()
296296+{
297297+ _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
298298+ bool native_exception = isOurExceptionClass(unwind_exception);
299299+ __cxa_eh_globals* globals = __cxa_get_globals();
300300+ // exception_header is a hackish offset from a foreign exception, but it
301301+ // works as long as we're careful not to try to access any __cxa_exception
302302+ // parts.
303303+ __cxa_exception* exception_header =
304304+ cxa_exception_from_exception_unwind_exception
305305+ (
306306+ static_cast<_Unwind_Exception*>(unwind_exception)
307307+ );
308308+ if (native_exception)
309309+ {
310310+ // Increment the handler count, removing the flag about being rethrown
311311+ exception_header->handlerCount = exception_header->handlerCount < 0 ?
312312+ -exception_header->handlerCount + 1 : exception_header->handlerCount + 1;
313313+ // place the exception on the top of the stack if it's not already
314314+ // there by a previous rethrow
315315+ if (exception_header != globals->caughtExceptions)
316316+ {
317317+ exception_header->nextException = globals->caughtExceptions;
318318+ globals->caughtExceptions = exception_header;
319319+ }
320320+ globals->uncaughtExceptions -= 1; // Not atomically, since globals are thread-local
321321+ return exception_header->adjustedPtr;
322322+ }
323323+ // Else this is a foreign exception
324324+ // If the caughtExceptions stack is not empty, terminate
325325+ if (globals->caughtExceptions != 0)
326326+ std::terminate();
327327+ // Push the foreign exception on to the stack
328328+ globals->caughtExceptions = exception_header;
329329+ return unwind_exception + 1;
330330+}
331331+332332+333333+/*
334334+Upon exit for any reason, a handler must call:
335335+ void __cxa_end_catch ();
336336+337337+This routine can be called for either a native or foreign exception.
338338+For a native exception:
339339+* Locates the most recently caught exception and decrements its handler count.
340340+* Removes the exception from the caught exception stack, if the handler count goes to zero.
341341+* If the handler count goes down to zero, and the exception was not re-thrown
342342+ by throw, it locates the primary exception (which may be the same as the one
343343+ it's handling) and decrements its reference count. If that reference count
344344+ goes to zero, the function destroys the exception. In any case, if the current
345345+ exception is a dependent exception, it destroys that.
346346+347347+For a foreign exception:
348348+* If it has been rethrown, there is nothing to do.
349349+* Otherwise delete the exception and pop the catch stack to empty.
350350+*/
351351+void __cxa_end_catch()
352352+{
353353+ static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),
354354+ "sizeof(__cxa_exception) must be equal to sizeof(__cxa_dependent_exception)");
355355+ __cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch
356356+ __cxa_exception* exception_header = globals->caughtExceptions;
357357+ // If we've rethrown a foreign exception, then globals->caughtExceptions
358358+ // will have been made an empty stack by __cxa_rethrow() and there is
359359+ // nothing more to be done. Do nothing!
360360+ if (NULL != exception_header)
361361+ {
362362+ bool native_exception = isOurExceptionClass(&exception_header->unwindHeader);
363363+ if (native_exception)
364364+ {
365365+ // This is a native exception
366366+ if (exception_header->handlerCount < 0)
367367+ {
368368+ // The exception has been rethrown by __cxa_rethrow, so don't delete it
369369+ if (0 == incrementHandlerCount(exception_header))
370370+ {
371371+ // Remove from the chain of uncaught exceptions
372372+ globals->caughtExceptions = exception_header->nextException;
373373+ // but don't destroy
374374+ }
375375+ // Keep handlerCount negative in case there are nested catch's
376376+ // that need to be told that this exception is rethrown. Don't
377377+ // erase this rethrow flag until the exception is recaught.
378378+ }
379379+ else
380380+ {
381381+ // The native exception has not been rethrown
382382+ if (0 == decrementHandlerCount(exception_header))
383383+ {
384384+ // Remove from the chain of uncaught exceptions
385385+ globals->caughtExceptions = exception_header->nextException;
386386+ // Destroy this exception, being careful to distinguish
387387+ // between dependent and primary exceptions
388388+ if (isDependentException(&exception_header->unwindHeader))
389389+ {
390390+ // Reset exception_header to primaryException and deallocate the dependent exception
391391+ __cxa_dependent_exception* dep_exception_header =
392392+ reinterpret_cast<__cxa_dependent_exception*>(exception_header);
393393+ exception_header =
394394+ cxa_exception_from_thrown_object(dep_exception_header->primaryException);
395395+ __cxa_free_dependent_exception(dep_exception_header);
396396+ }
397397+ // Destroy the primary exception only if its referenceCount goes to 0
398398+ // (this decrement must be atomic)
399399+ __cxa_decrement_exception_refcount(thrown_object_from_cxa_exception(exception_header));
400400+ }
401401+ }
402402+ }
403403+ else
404404+ {
405405+ // The foreign exception has not been rethrown. Pop the stack
406406+ // and delete it. If there are nested catch's and they try
407407+ // to touch a foreign exception in any way, that is undefined
408408+ // behavior. They likely can't since the only way to catch
409409+ // a foreign exception is with catch (...)!
410410+ _Unwind_DeleteException(&globals->caughtExceptions->unwindHeader);
411411+ globals->caughtExceptions = 0;
412412+ }
413413+ }
414414+}
415415+416416+// Note: exception_header may be masquerading as a __cxa_dependent_exception
417417+// and that's ok. exceptionType is there too.
418418+// However watch out for foreign exceptions. Return null for them.
419419+std::type_info * __cxa_current_exception_type() {
420420+// get the current exception
421421+ __cxa_eh_globals *globals = __cxa_get_globals_fast();
422422+ if (NULL == globals)
423423+ return NULL; // If there have never been any exceptions, there are none now.
424424+ __cxa_exception *exception_header = globals->caughtExceptions;
425425+ if (NULL == exception_header)
426426+ return NULL; // No current exception
427427+ if (!isOurExceptionClass(&exception_header->unwindHeader))
428428+ return NULL;
429429+ return exception_header->exceptionType;
430430+}
431431+432432+// 2.5.4 Rethrowing Exceptions
433433+/* This routine can rethrow native or foreign exceptions.
434434+If the exception is native:
435435+* marks the exception object on top of the caughtExceptions stack
436436+ (in an implementation-defined way) as being rethrown.
437437+* If the caughtExceptions stack is empty, it calls terminate()
438438+ (see [C++FDIS] [except.throw], 15.1.8).
439439+* It then calls _Unwind_RaiseException which should not return
440440+ (terminate if it does).
441441+ Note: exception_header may be masquerading as a __cxa_dependent_exception
442442+ and that's ok.
443443+*/
444444+LIBCXXABI_NORETURN
445445+void
446446+__cxa_rethrow()
447447+{
448448+ __cxa_eh_globals* globals = __cxa_get_globals();
449449+ __cxa_exception* exception_header = globals->caughtExceptions;
450450+ if (NULL == exception_header)
451451+ std::terminate(); // throw; called outside of a exception handler
452452+ bool native_exception = isOurExceptionClass(&exception_header->unwindHeader);
453453+ if (native_exception)
454454+ {
455455+ // Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch)
456456+ exception_header->handlerCount = -exception_header->handlerCount;
457457+ globals->uncaughtExceptions += 1;
458458+ // __cxa_end_catch will remove this exception from the caughtExceptions stack if necessary
459459+ }
460460+ else // this is a foreign exception
461461+ {
462462+ // The only way to communicate to __cxa_end_catch that we've rethrown
463463+ // a foreign exception, so don't delete us, is to pop the stack here
464464+ // which must be empty afterwards. Then __cxa_end_catch will do
465465+ // nothing
466466+ globals->caughtExceptions = 0;
467467+ }
468468+#if __arm__
469469+ _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
470470+#else
471471+ _Unwind_RaiseException(&exception_header->unwindHeader);
472472+#endif
473473+474474+ // If we get here, some kind of unwinding error has occurred.
475475+ // There is some weird code generation bug happening with
476476+ // Apple clang version 4.0 (tags/Apple/clang-418.0.2) (based on LLVM 3.1svn)
477477+ // If we call failed_throw here. Turns up with -O2 or higher, and -Os.
478478+ __cxa_begin_catch(&exception_header->unwindHeader);
479479+ if (native_exception)
480480+ std::__terminate(exception_header->terminateHandler);
481481+ // Foreign exception: can't get exception_header->terminateHandler
482482+ std::terminate();
483483+}
484484+485485+/*
486486+ If thrown_object is not null, atomically increment the referenceCount field
487487+ of the __cxa_exception header associated with the thrown object referred to
488488+ by thrown_object.
489489+490490+ Requires: If thrown_object is not NULL, it is a native exception.
491491+*/
492492+void
493493+__cxa_increment_exception_refcount(void* thrown_object) throw()
494494+{
495495+ if (thrown_object != NULL )
496496+ {
497497+ __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
498498+ __sync_add_and_fetch(&exception_header->referenceCount, 1);
499499+ }
500500+}
501501+502502+/*
503503+ If thrown_object is not null, atomically decrement the referenceCount field
504504+ of the __cxa_exception header associated with the thrown object referred to
505505+ by thrown_object. If the referenceCount drops to zero, destroy and
506506+ deallocate the exception.
507507+508508+ Requires: If thrown_object is not NULL, it is a native exception.
509509+*/
510510+void
511511+__cxa_decrement_exception_refcount(void* thrown_object) throw()
512512+{
513513+ if (thrown_object != NULL )
514514+ {
515515+ __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
516516+ if (__sync_sub_and_fetch(&exception_header->referenceCount, size_t(1)) == 0)
517517+ {
518518+ if (NULL != exception_header->exceptionDestructor)
519519+ exception_header->exceptionDestructor(thrown_object);
520520+ __cxa_free_exception(thrown_object);
521521+ }
522522+ }
523523+}
524524+525525+/*
526526+ Returns a pointer to the thrown object (if any) at the top of the
527527+ caughtExceptions stack. Atommically increment the exception's referenceCount.
528528+ If there is no such thrown object or if the thrown object is foreign,
529529+ returns null.
530530+531531+ We can use __cxa_get_globals_fast here to get the globals because if there have
532532+ been no exceptions thrown, ever, on this thread, we can return NULL without
533533+ the need to allocate the exception-handling globals.
534534+*/
535535+void*
536536+__cxa_current_primary_exception() throw()
537537+{
538538+// get the current exception
539539+ __cxa_eh_globals* globals = __cxa_get_globals_fast();
540540+ if (NULL == globals)
541541+ return NULL; // If there are no globals, there is no exception
542542+ __cxa_exception* exception_header = globals->caughtExceptions;
543543+ if (NULL == exception_header)
544544+ return NULL; // No current exception
545545+ if (!isOurExceptionClass(&exception_header->unwindHeader))
546546+ return NULL; // Can't capture a foreign exception (no way to refcount it)
547547+ if (isDependentException(&exception_header->unwindHeader)) {
548548+ __cxa_dependent_exception* dep_exception_header =
549549+ reinterpret_cast<__cxa_dependent_exception*>(exception_header);
550550+ exception_header = cxa_exception_from_thrown_object(dep_exception_header->primaryException);
551551+ }
552552+ void* thrown_object = thrown_object_from_cxa_exception(exception_header);
553553+ __cxa_increment_exception_refcount(thrown_object);
554554+ return thrown_object;
555555+}
556556+557557+/*
558558+ If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
559559+ stored in exc is called. Otherwise the referenceCount stored in the
560560+ primary exception is decremented, destroying the primary if necessary.
561561+ Finally the dependent exception is destroyed.
562562+*/
563563+static
564564+void
565565+dependent_exception_cleanup(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)
566566+{
567567+ __cxa_dependent_exception* dep_exception_header =
568568+ reinterpret_cast<__cxa_dependent_exception*>(unwind_exception + 1) - 1;
569569+ if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
570570+ std::__terminate(dep_exception_header->terminateHandler);
571571+ __cxa_decrement_exception_refcount(dep_exception_header->primaryException);
572572+ __cxa_free_dependent_exception(dep_exception_header);
573573+}
574574+575575+/*
576576+ If thrown_object is not null, allocate, initialize and thow a dependent
577577+ exception.
578578+*/
579579+void
580580+__cxa_rethrow_primary_exception(void* thrown_object)
581581+{
582582+ if ( thrown_object != NULL )
583583+ {
584584+ // thrown_object guaranteed to be native because
585585+ // __cxa_current_primary_exception returns NULL for foreign exceptions
586586+ __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
587587+ __cxa_dependent_exception* dep_exception_header =
588588+ static_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception());
589589+ dep_exception_header->primaryException = thrown_object;
590590+ __cxa_increment_exception_refcount(thrown_object);
591591+ dep_exception_header->exceptionType = exception_header->exceptionType;
592592+ dep_exception_header->unexpectedHandler = std::get_unexpected();
593593+ dep_exception_header->terminateHandler = std::get_terminate();
594594+ setDependentExceptionClass(&dep_exception_header->unwindHeader);
595595+ __cxa_get_globals()->uncaughtExceptions += 1;
596596+ dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup;
597597+#if __arm__
598598+ _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader);
599599+#else
600600+ _Unwind_RaiseException(&dep_exception_header->unwindHeader);
601601+#endif
602602+ // Some sort of unwinding error. Note that terminate is a handler.
603603+ __cxa_begin_catch(&dep_exception_header->unwindHeader);
604604+ }
605605+ // If we return client will call terminate()
606606+}
607607+608608+bool
609609+__cxa_uncaught_exception() throw()
610610+{
611611+ // This does not report foreign exceptions in flight
612612+ __cxa_eh_globals* globals = __cxa_get_globals_fast();
613613+ if (globals == 0)
614614+ return false;
615615+ return globals->uncaughtExceptions != 0;
616616+}
617617+618618+} // extern "C"
619619+620620+#pragma GCC visibility pop
621621+622622+} // abi
···11+//===--------------------- cxa_exception_storage.cpp ----------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//
99+// This file implements the storage for the "Caught Exception Stack"
1010+// http://www.codesourcery.com/public/cxx-abi/abi-eh.html (section 2.2.2)
1111+//
1212+//===----------------------------------------------------------------------===//
1313+1414+#include "cxa_exception.hpp"
1515+1616+#ifdef HAS_THREAD_LOCAL
1717+1818+namespace __cxxabiv1 {
1919+2020+namespace {
2121+ __cxa_eh_globals * __globals () {
2222+ static thread_local __cxa_eh_globals eh_globals;
2323+ return &eh_globals;
2424+ }
2525+ }
2626+2727+extern "C" {
2828+ __cxa_eh_globals * __cxa_get_globals () { return __globals (); }
2929+ __cxa_eh_globals * __cxa_get_globals_fast () { return __globals (); }
3030+ }
3131+}
3232+3333+#else
3434+3535+#include <pthread.h>
3636+#include <cstdlib> // for calloc, free
3737+#include "abort_message.h"
3838+3939+// In general, we treat all pthread errors as fatal.
4040+// We cannot call std::terminate() because that will in turn
4141+// call __cxa_get_globals() and cause infinite recursion.
4242+4343+namespace __cxxabiv1 {
4444+namespace {
4545+ pthread_key_t key_;
4646+ pthread_once_t flag_ = PTHREAD_ONCE_INIT;
4747+4848+ void destruct_ (void *p) {
4949+ std::free ( p );
5050+ if ( 0 != ::pthread_setspecific ( key_, NULL ) )
5151+ abort_message("cannot zero out thread value for __cxa_get_globals()");
5252+ }
5353+5454+ void construct_ () {
5555+ if ( 0 != pthread_key_create ( &key_, destruct_ ) )
5656+ abort_message("cannot create pthread key for __cxa_get_globals()");
5757+ }
5858+}
5959+6060+extern "C" {
6161+ __cxa_eh_globals * __cxa_get_globals () {
6262+ // Try to get the globals for this thread
6363+ __cxa_eh_globals* retVal = __cxa_get_globals_fast ();
6464+6565+ // If this is the first time we've been asked for these globals, create them
6666+ if ( NULL == retVal ) {
6767+ retVal = static_cast<__cxa_eh_globals*>
6868+ (std::calloc (1, sizeof (__cxa_eh_globals)));
6969+ if ( NULL == retVal )
7070+ abort_message("cannot allocate __cxa_eh_globals");
7171+ if ( 0 != pthread_setspecific ( key_, retVal ) )
7272+ abort_message("pthread_setspecific failure in __cxa_get_globals()");
7373+ }
7474+ return retVal;
7575+ }
7676+7777+ // Note that this implementation will reliably return NULL if not
7878+ // preceeded by a call to __cxa_get_globals(). This is an extension
7979+ // to the Itanium ABI and is taken advantage of in several places in
8080+ // libc++abi.
8181+ __cxa_eh_globals * __cxa_get_globals_fast () {
8282+ // First time through, create the key.
8383+ if (0 != pthread_once(&flag_, construct_))
8484+ abort_message("pthread_once failure in __cxa_get_globals_fast()");
8585+// static int init = construct_();
8686+ return static_cast<__cxa_eh_globals*>(::pthread_getspecific(key_));
8787+ }
8888+8989+}
9090+}
9191+#endif
+231
src/libunwind-darwin-gcc/src-cxxabi/cxa_guard.cpp
···11+//===---------------------------- cxa_guard.cpp ---------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//===----------------------------------------------------------------------===//
99+1010+#include "abort_message.h"
1111+1212+#include <pthread.h>
1313+#include <stdint.h>
1414+1515+/*
1616+ This implementation must be careful to not call code external to this file
1717+ which will turn around and try to call __cxa_guard_acquire reentrantly.
1818+ For this reason, the headers of this file are as restricted as possible.
1919+ Previous implementations of this code for __APPLE__ have used
2020+ pthread_mutex_lock and the abort_message utility without problem. This
2121+ implementation also uses pthread_cond_wait which has tested to not be a
2222+ problem.
2323+*/
2424+2525+namespace __cxxabiv1
2626+{
2727+2828+namespace
2929+{
3030+3131+#if __arm__
3232+3333+// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must
3434+// be statically initialized to 0.
3535+typedef uint32_t guard_type;
3636+3737+// Test the lowest bit.
3838+inline bool is_initialized(guard_type* guard_object) {
3939+ return (*guard_object) & 1;
4040+}
4141+4242+inline void set_initialized(guard_type* guard_object) {
4343+ *guard_object |= 1;
4444+}
4545+4646+#else
4747+4848+typedef uint64_t guard_type;
4949+5050+bool is_initialized(guard_type* guard_object) {
5151+ char* initialized = (char*)guard_object;
5252+ return *initialized;
5353+}
5454+5555+void set_initialized(guard_type* guard_object) {
5656+ char* initialized = (char*)guard_object;
5757+ *initialized = 1;
5858+}
5959+6060+#endif
6161+6262+pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER;
6363+pthread_cond_t guard_cv = PTHREAD_COND_INITIALIZER;
6464+6565+#if defined(__APPLE__) && !defined(__arm__)
6666+6767+typedef uint32_t lock_type;
6868+6969+#if __LITTLE_ENDIAN__
7070+7171+inline
7272+lock_type
7373+get_lock(uint64_t x)
7474+{
7575+ return static_cast<lock_type>(x >> 32);
7676+}
7777+7878+inline
7979+void
8080+set_lock(uint64_t& x, lock_type y)
8181+{
8282+ x = static_cast<uint64_t>(y) << 32;
8383+}
8484+8585+#else // __LITTLE_ENDIAN__
8686+8787+inline
8888+lock_type
8989+get_lock(uint64_t x)
9090+{
9191+ return static_cast<lock_type>(x);
9292+}
9393+9494+inline
9595+void
9696+set_lock(uint64_t& x, lock_type y)
9797+{
9898+ x = y;
9999+}
100100+101101+#endif // __LITTLE_ENDIAN__
102102+103103+#else // !__APPLE__ || __arm__
104104+105105+typedef bool lock_type;
106106+107107+inline
108108+lock_type
109109+get_lock(uint64_t x)
110110+{
111111+ union
112112+ {
113113+ uint64_t guard;
114114+ uint8_t lock[2];
115115+ } f = {x};
116116+ return f.lock[1] != 0;
117117+}
118118+119119+inline
120120+void
121121+set_lock(uint64_t& x, lock_type y)
122122+{
123123+ union
124124+ {
125125+ uint64_t guard;
126126+ uint8_t lock[2];
127127+ } f = {0};
128128+ f.lock[1] = y;
129129+ x = f.guard;
130130+}
131131+132132+inline
133133+lock_type
134134+get_lock(uint32_t x)
135135+{
136136+ union
137137+ {
138138+ uint32_t guard;
139139+ uint8_t lock[2];
140140+ } f = {x};
141141+ return f.lock[1] != 0;
142142+}
143143+144144+inline
145145+void
146146+set_lock(uint32_t& x, lock_type y)
147147+{
148148+ union
149149+ {
150150+ uint32_t guard;
151151+ uint8_t lock[2];
152152+ } f = {0};
153153+ f.lock[1] = y;
154154+ x = f.guard;
155155+}
156156+157157+#endif // __APPLE__
158158+159159+} // unnamed namespace
160160+161161+extern "C"
162162+{
163163+164164+int __cxa_guard_acquire(guard_type* guard_object)
165165+{
166166+ char* initialized = (char*)guard_object;
167167+ if (pthread_mutex_lock(&guard_mut))
168168+ abort_message("__cxa_guard_acquire failed to acquire mutex");
169169+ int result = *initialized == 0;
170170+ if (result)
171171+ {
172172+#if defined(__APPLE__) && !defined(__arm__)
173173+ const lock_type id = pthread_mach_thread_np(pthread_self());
174174+ lock_type lock = get_lock(*guard_object);
175175+ if (lock)
176176+ {
177177+ // if this thread set lock for this same guard_object, abort
178178+ if (lock == id)
179179+ abort_message("__cxa_guard_acquire detected deadlock");
180180+ do
181181+ {
182182+ if (pthread_cond_wait(&guard_cv, &guard_mut))
183183+ abort_message("__cxa_guard_acquire condition variable wait failed");
184184+ lock = get_lock(*guard_object);
185185+ } while (lock);
186186+ result = !is_initialized(guard_object);
187187+ if (result)
188188+ set_lock(*guard_object, id);
189189+ }
190190+ else
191191+ set_lock(*guard_object, id);
192192+#else // !__APPLE__ || __arm__
193193+ while (get_lock(*guard_object))
194194+ if (pthread_cond_wait(&guard_cv, &guard_mut))
195195+ abort_message("__cxa_guard_acquire condition variable wait failed");
196196+ result = *initialized == 0;
197197+ if (result)
198198+ set_lock(*guard_object, true);
199199+#endif // !__APPLE__ || __arm__
200200+ }
201201+ if (pthread_mutex_unlock(&guard_mut))
202202+ abort_message("__cxa_guard_acquire failed to release mutex");
203203+ return result;
204204+}
205205+206206+void __cxa_guard_release(guard_type* guard_object)
207207+{
208208+ if (pthread_mutex_lock(&guard_mut))
209209+ abort_message("__cxa_guard_release failed to acquire mutex");
210210+ *guard_object = 0;
211211+ set_initialized(guard_object);
212212+ if (pthread_mutex_unlock(&guard_mut))
213213+ abort_message("__cxa_guard_release failed to release mutex");
214214+ if (pthread_cond_broadcast(&guard_cv))
215215+ abort_message("__cxa_guard_release failed to broadcast condition variable");
216216+}
217217+218218+void __cxa_guard_abort(guard_type* guard_object)
219219+{
220220+ if (pthread_mutex_lock(&guard_mut))
221221+ abort_message("__cxa_guard_abort failed to acquire mutex");
222222+ *guard_object = 0;
223223+ if (pthread_mutex_unlock(&guard_mut))
224224+ abort_message("__cxa_guard_abort failed to release mutex");
225225+ if (pthread_cond_broadcast(&guard_cv))
226226+ abort_message("__cxa_guard_abort failed to broadcast condition variable");
227227+}
228228+229229+} // extern "C"
230230+231231+} // __cxxabiv1
···11+//===------------------------- cxa_handlers.cpp ---------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//
99+// This file implements the functionality associated with the terminate_handler,
1010+// unexpected_handler, and new_handler.
1111+//===----------------------------------------------------------------------===//
1212+1313+#include <stdexcept>
1414+#include <new>
1515+#include <exception>
1616+#include "abort_message.h"
1717+#include "cxxabi.h"
1818+#include "cxa_handlers.hpp"
1919+#include "cxa_exception.hpp"
2020+#include "private_typeinfo.h"
2121+2222+namespace std
2323+{
2424+2525+unexpected_handler
2626+get_unexpected() _NOEXCEPT
2727+{
2828+ return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0);
2929+// The above is safe but overkill on x86
3030+// Using of C++11 atomics this should be rewritten
3131+// return __cxa_unexpected_handler.load(memory_order_acq);
3232+}
3333+3434+__attribute__((visibility("hidden"), noreturn))
3535+void
3636+__unexpected(unexpected_handler func)
3737+{
3838+ func();
3939+ // unexpected handler should not return
4040+ abort_message("unexpected_handler unexpectedly returned");
4141+}
4242+4343+__attribute__((noreturn))
4444+void
4545+unexpected()
4646+{
4747+ __unexpected(get_unexpected());
4848+}
4949+5050+terminate_handler
5151+get_terminate() _NOEXCEPT
5252+{
5353+ return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0);
5454+// The above is safe but overkill on x86
5555+// Using of C++11 atomics this should be rewritten
5656+// return __cxa_terminate_handler.load(memory_order_acq);
5757+}
5858+5959+__attribute__((visibility("hidden"), noreturn))
6060+void
6161+__terminate(terminate_handler func) _NOEXCEPT
6262+{
6363+#if __has_feature(cxx_exceptions)
6464+ try
6565+ {
6666+#endif // __has_feature(cxx_exceptions)
6767+ func();
6868+ // handler should not return
6969+ abort_message("terminate_handler unexpectedly returned");
7070+#if __has_feature(cxx_exceptions)
7171+ }
7272+ catch (...)
7373+ {
7474+ // handler should not throw exception
7575+ abort_message("terminate_handler unexpectedly threw an exception");
7676+ }
7777+#endif // #if __has_feature(cxx_exceptions)
7878+}
7979+8080+__attribute__((noreturn))
8181+void
8282+terminate() _NOEXCEPT
8383+{
8484+ // If there might be an uncaught exception
8585+ using namespace __cxxabiv1;
8686+ __cxa_eh_globals* globals = __cxa_get_globals_fast();
8787+ if (globals)
8888+ {
8989+ __cxa_exception* exception_header = globals->caughtExceptions;
9090+ if (exception_header)
9191+ {
9292+ _Unwind_Exception* unwind_exception =
9393+ reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
9494+ bool native_exception =
9595+ (unwind_exception->exception_class & get_vendor_and_language) ==
9696+ (kOurExceptionClass & get_vendor_and_language);
9797+ if (native_exception)
9898+ __terminate(exception_header->terminateHandler);
9999+ }
100100+ }
101101+ __terminate(get_terminate());
102102+}
103103+104104+extern "C" new_handler __cxa_new_handler = 0;
105105+// In the future these will become:
106106+// std::atomic<std::new_handler> __cxa_new_handler(0);
107107+108108+new_handler
109109+set_new_handler(new_handler handler) _NOEXCEPT
110110+{
111111+ return __sync_swap(&__cxa_new_handler, handler);
112112+// Using of C++11 atomics this should be rewritten
113113+// return __cxa_new_handler.exchange(handler, memory_order_acq_rel);
114114+}
115115+116116+new_handler
117117+get_new_handler() _NOEXCEPT
118118+{
119119+ return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0);
120120+// The above is safe but overkill on x86
121121+// Using of C++11 atomics this should be rewritten
122122+// return __cxa_new_handler.load(memory_order_acq);
123123+}
124124+125125+} // std
···11+//===------------------------- cxa_handlers.cpp ---------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//
99+// This file implements the functionality associated with the terminate_handler,
1010+// unexpected_handler, and new_handler.
1111+//===----------------------------------------------------------------------===//
1212+1313+#ifndef _CXA_HANDLERS_H
1414+#define _CXA_HANDLERS_H
1515+1616+#include <exception>
1717+1818+namespace std
1919+{
2020+2121+__attribute__((visibility("hidden"), noreturn))
2222+void
2323+__unexpected(unexpected_handler func);
2424+2525+__attribute__((visibility("hidden"), noreturn))
2626+void
2727+__terminate(terminate_handler func) _NOEXCEPT;
2828+2929+} // std
3030+3131+extern "C"
3232+{
3333+3434+extern void (*__cxa_terminate_handler)();
3535+extern void (*__cxa_unexpected_handler)();
3636+extern void (*__cxa_new_handler)();
3737+3838+/*
3939+4040+ At some point in the future these three symbols will become
4141+ C++11 atomic variables:
4242+4343+ extern std::atomic<std::terminate_handler> __cxa_terminate_handler;
4444+ extern std::atomic<std::unexpected_handler> __cxa_unexpected_handler;
4545+ extern std::atomic<std::new_handler> __cxa_new_handler;
4646+4747+ This change will not impact their ABI. But it will allow for a
4848+ portible performance optimization.
4949+5050+*/
5151+5252+} // extern "C"
5353+5454+#endif // _CXA_HANDLERS_H
···11+//===------------------------- cxa_exception.cpp --------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//
99+// This file implements the "Exception Handling APIs"
1010+// http://www.codesourcery.com/public/cxx-abi/abi-eh.html
1111+// http://www.intel.com/design/itanium/downloads/245358.htm
1212+//
1313+//===----------------------------------------------------------------------===//
1414+1515+#include "unwind.h"
1616+#include "cxa_exception.hpp"
1717+#include "cxa_handlers.hpp"
1818+#include "private_typeinfo.h"
1919+#include <typeinfo>
2020+#include <stdlib.h>
2121+#include <assert.h>
2222+2323+/*
2424+ Exception Header Layout:
2525+2626++---------------------------+-----------------------------+---------------+
2727+| __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object |
2828++---------------------------+-----------------------------+---------------+
2929+ ^
3030+ |
3131+ +-------------------------------------------------------+
3232+ |
3333++---------------------------+-----------------------------+
3434+| __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 |
3535++---------------------------+-----------------------------+
3636+3737+ Exception Handling Table Layout:
3838+3939++-----------------+--------+
4040+| lpStartEncoding | (char) |
4141++---------+-------+--------+---------------+-----------------------+
4242+| lpStart | (encoded wtih lpStartEncoding) | defaults to funcStart |
4343++---------+-----+--------+-----------------+---------------+-------+
4444+| ttypeEncoding | (char) | Encoding of the type_info table |
4545++---------------+-+------+----+----------------------------+----------------+
4646+| classInfoOffset | (ULEB128) | Offset to type_info table, defaults to null |
4747++-----------------++--------+-+----------------------------+----------------+
4848+| callSiteEncoding | (char) | Encoding for Call Site Table |
4949++------------------+--+-----+-----+------------------------+--------------------------+
5050+| callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table |
5151++---------------------+-----------+---------------------------------------------------+
5252+#if !__arm__
5353++---------------------+-----------+------------------------------------------------+
5454+| Beginning of Call Site Table The current ip lies within the |
5555+| ... (start, length) range of one of these |
5656+| call sites. There may be action needed. |
5757+| +-------------+---------------------------------+------------------------------+ |
5858+| | start | (encoded with callSiteEncoding) | offset relative to funcStart | |
5959+| | length | (encoded with callSiteEncoding) | length of code fragment | |
6060+| | landingPad | (encoded with callSiteEncoding) | offset relative to lpStart | |
6161+| | actionEntry | (ULEB128) | Action Table Index 1-based | |
6262+| | | | actionEntry == 0 -> cleanup | |
6363+| +-------------+---------------------------------+------------------------------+ |
6464+| ... |
6565++----------------------------------------------------------------------------------+
6666+#else // __arm_
6767++---------------------+-----------+------------------------------------------------+
6868+| Beginning of Call Site Table The current ip is a 1-based index into |
6969+| ... this table. Or it is -1 meaning no |
7070+| action is needed. Or it is 0 meaning |
7171+| terminate. |
7272+| +-------------+---------------------------------+------------------------------+ |
7373+| | landingPad | (ULEB128) | offset relative to lpStart | |
7474+| | actionEntry | (ULEB128) | Action Table Index 1-based | |
7575+| | | | actionEntry == 0 -> cleanup | |
7676+| +-------------+---------------------------------+------------------------------+ |
7777+| ... |
7878++----------------------------------------------------------------------------------+
7979+#endif // __arm_
8080++---------------------------------------------------------------------+
8181+| Beginning of Action Table ttypeIndex == 0 : cleanup |
8282+| ... ttypeIndex > 0 : catch |
8383+| ttypeIndex < 0 : exception spec |
8484+| +--------------+-----------+--------------------------------------+ |
8585+| | ttypeIndex | (SLEB128) | Index into type_info Table (1-based) | |
8686+| | actionOffset | (SLEB128) | Offset into next Action Table entry | |
8787+| +--------------+-----------+--------------------------------------+ |
8888+| ... |
8989++---------------------------------------------------------------------+-----------------+
9090+| type_info Table, but classInfoOffset does *not* point here! |
9191+| +----------------+------------------------------------------------+-----------------+ |
9292+| | Nth type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == N | |
9393+| +----------------+------------------------------------------------+-----------------+ |
9494+| ... |
9595+| +----------------+------------------------------------------------+-----------------+ |
9696+| | 1st type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == 1 | |
9797+| +----------------+------------------------------------------------+-----------------+ |
9898+| +---------------------------------------+-----------+------------------------------+ |
9999+| | 1st ttypeIndex for 1st exception spec | (ULEB128) | classInfoOffset points here! | |
100100+| | ... | (ULEB128) | | |
101101+| | Mth ttypeIndex for 1st exception spec | (ULEB128) | | |
102102+| | 0 | (ULEB128) | | |
103103+| +---------------------------------------+------------------------------------------+ |
104104+| ... |
105105+| +---------------------------------------+------------------------------------------+ |
106106+| | 0 | (ULEB128) | throw() | |
107107+| +---------------------------------------+------------------------------------------+ |
108108+| ... |
109109+| +---------------------------------------+------------------------------------------+ |
110110+| | 1st ttypeIndex for Nth exception spec | (ULEB128) | | |
111111+| | ... | (ULEB128) | | |
112112+| | Mth ttypeIndex for Nth exception spec | (ULEB128) | | |
113113+| | 0 | (ULEB128) | | |
114114+| +---------------------------------------+------------------------------------------+ |
115115++---------------------------------------------------------------------------------------+
116116+117117+Notes:
118118+119119+* ttypeIndex in the Action Table, and in the exception spec table, is an index,
120120+ not a byte count, if positive. It is a negative index offset of
121121+ classInfoOffset and the sizeof entry depends on ttypeEncoding.
122122+ But if ttypeIndex is negative, it is a positive 1-based byte offset into the
123123+ type_info Table.
124124+ And if ttypeIndex is zero, it refers to a catch (...).
125125+126126+* landingPad can be 0, this implies there is nothing to be done.
127127+128128+* landingPad != 0 and actionEntry == 0 implies a cleanup needs to be done
129129+ @landingPad.
130130+131131+* A cleanup can also be found under landingPad != 0 and actionEntry != 0 in
132132+ the Action Table with ttypeIndex == 0.
133133+*/
134134+135135+namespace __cxxabiv1
136136+{
137137+138138+extern "C"
139139+{
140140+141141+// private API
142142+143143+// Heavily borrowed from llvm/examples/ExceptionDemo/ExceptionDemo.cpp
144144+145145+// DWARF Constants
146146+enum
147147+{
148148+ DW_EH_PE_absptr = 0x00,
149149+ DW_EH_PE_uleb128 = 0x01,
150150+ DW_EH_PE_udata2 = 0x02,
151151+ DW_EH_PE_udata4 = 0x03,
152152+ DW_EH_PE_udata8 = 0x04,
153153+ DW_EH_PE_sleb128 = 0x09,
154154+ DW_EH_PE_sdata2 = 0x0A,
155155+ DW_EH_PE_sdata4 = 0x0B,
156156+ DW_EH_PE_sdata8 = 0x0C,
157157+ DW_EH_PE_pcrel = 0x10,
158158+ DW_EH_PE_textrel = 0x20,
159159+ DW_EH_PE_datarel = 0x30,
160160+ DW_EH_PE_funcrel = 0x40,
161161+ DW_EH_PE_aligned = 0x50,
162162+ DW_EH_PE_indirect = 0x80,
163163+ DW_EH_PE_omit = 0xFF
164164+};
165165+166166+/// Read a uleb128 encoded value and advance pointer
167167+/// See Variable Length Data Appendix C in:
168168+/// @link http://dwarfstd.org/Dwarf4.pdf @unlink
169169+/// @param data reference variable holding memory pointer to decode from
170170+/// @returns decoded value
171171+static
172172+uintptr_t
173173+readULEB128(const uint8_t** data)
174174+{
175175+ uintptr_t result = 0;
176176+ uintptr_t shift = 0;
177177+ unsigned char byte;
178178+ const uint8_t *p = *data;
179179+ do
180180+ {
181181+ byte = *p++;
182182+ result |= static_cast<uintptr_t>(byte & 0x7F) << shift;
183183+ shift += 7;
184184+ } while (byte & 0x80);
185185+ *data = p;
186186+ return result;
187187+}
188188+189189+/// Read a sleb128 encoded value and advance pointer
190190+/// See Variable Length Data Applendix C in:
191191+/// @link http://dwarfstd.org/Dwarf4.pdf @unlink
192192+/// @param data reference variable holding memory pointer to decode from
193193+/// @returns decoded value
194194+static
195195+intptr_t
196196+readSLEB128(const uint8_t** data)
197197+{
198198+ uintptr_t result = 0;
199199+ uintptr_t shift = 0;
200200+ unsigned char byte;
201201+ const uint8_t *p = *data;
202202+ do
203203+ {
204204+ byte = *p++;
205205+ result |= static_cast<uintptr_t>(byte & 0x7F) << shift;
206206+ shift += 7;
207207+ } while (byte & 0x80);
208208+ *data = p;
209209+ if ((byte & 0x40) && (shift < (sizeof(result) << 3)))
210210+ result |= static_cast<uintptr_t>(~0) << shift;
211211+ return static_cast<intptr_t>(result);
212212+}
213213+214214+/// Read a pointer encoded value and advance pointer
215215+/// See Variable Length Data in:
216216+/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
217217+/// @param data reference variable holding memory pointer to decode from
218218+/// @param encoding dwarf encoding type
219219+/// @returns decoded value
220220+static
221221+uintptr_t
222222+readEncodedPointer(const uint8_t** data, uint8_t encoding)
223223+{
224224+ uintptr_t result = 0;
225225+ if (encoding == DW_EH_PE_omit)
226226+ return result;
227227+ const uint8_t* p = *data;
228228+ // first get value
229229+ switch (encoding & 0x0F)
230230+ {
231231+ case DW_EH_PE_absptr:
232232+ result = *((uintptr_t*)p);
233233+ p += sizeof(uintptr_t);
234234+ break;
235235+ case DW_EH_PE_uleb128:
236236+ result = readULEB128(&p);
237237+ break;
238238+ case DW_EH_PE_sleb128:
239239+ result = static_cast<uintptr_t>(readSLEB128(&p));
240240+ break;
241241+ case DW_EH_PE_udata2:
242242+ result = *((uint16_t*)p);
243243+ p += sizeof(uint16_t);
244244+ break;
245245+ case DW_EH_PE_udata4:
246246+ result = *((uint32_t*)p);
247247+ p += sizeof(uint32_t);
248248+ break;
249249+ case DW_EH_PE_udata8:
250250+ result = static_cast<uintptr_t>(*((uint64_t*)p));
251251+ p += sizeof(uint64_t);
252252+ break;
253253+ case DW_EH_PE_sdata2:
254254+ result = static_cast<uintptr_t>(*((int16_t*)p));
255255+ p += sizeof(int16_t);
256256+ break;
257257+ case DW_EH_PE_sdata4:
258258+ result = static_cast<uintptr_t>(*((int32_t*)p));
259259+ p += sizeof(int32_t);
260260+ break;
261261+ case DW_EH_PE_sdata8:
262262+ result = static_cast<uintptr_t>(*((int64_t*)p));
263263+ p += sizeof(int64_t);
264264+ break;
265265+ default:
266266+ // not supported
267267+ abort();
268268+ break;
269269+ }
270270+ // then add relative offset
271271+ switch (encoding & 0x70)
272272+ {
273273+ case DW_EH_PE_absptr:
274274+ // do nothing
275275+ break;
276276+ case DW_EH_PE_pcrel:
277277+ if (result)
278278+ result += (uintptr_t)(*data);
279279+ break;
280280+ case DW_EH_PE_textrel:
281281+ case DW_EH_PE_datarel:
282282+ case DW_EH_PE_funcrel:
283283+ case DW_EH_PE_aligned:
284284+ default:
285285+ // not supported
286286+ abort();
287287+ break;
288288+ }
289289+ // then apply indirection
290290+ if (result && (encoding & DW_EH_PE_indirect))
291291+ result = *((uintptr_t*)result);
292292+ *data = p;
293293+ return result;
294294+}
295295+296296+static
297297+void
298298+call_terminate(bool native_exception, _Unwind_Exception* unwind_exception)
299299+{
300300+ __cxa_begin_catch(unwind_exception);
301301+ if (native_exception)
302302+ {
303303+ // Use the stored terminate_handler if possible
304304+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
305305+ std::__terminate(exception_header->terminateHandler);
306306+ }
307307+ std::terminate();
308308+}
309309+310310+static
311311+const __shim_type_info*
312312+get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,
313313+ uint8_t ttypeEncoding, bool native_exception,
314314+ _Unwind_Exception* unwind_exception)
315315+{
316316+ if (classInfo == 0)
317317+ {
318318+ // this should not happen. Indicates corrupted eh_table.
319319+ call_terminate(native_exception, unwind_exception);
320320+ }
321321+ switch (ttypeEncoding & 0x0F)
322322+ {
323323+ case DW_EH_PE_absptr:
324324+ ttypeIndex *= sizeof(void*);
325325+ break;
326326+ case DW_EH_PE_udata2:
327327+ case DW_EH_PE_sdata2:
328328+ ttypeIndex *= 2;
329329+ break;
330330+ case DW_EH_PE_udata4:
331331+ case DW_EH_PE_sdata4:
332332+ ttypeIndex *= 4;
333333+ break;
334334+ case DW_EH_PE_udata8:
335335+ case DW_EH_PE_sdata8:
336336+ ttypeIndex *= 8;
337337+ break;
338338+ default:
339339+ // this should not happen. Indicates corrupted eh_table.
340340+ call_terminate(native_exception, unwind_exception);
341341+ }
342342+ classInfo -= ttypeIndex;
343343+ return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding);
344344+}
345345+346346+/*
347347+ This is checking a thrown exception type, excpType, against a posibly empty
348348+ list of catchType's which make up an exception spec.
349349+350350+ An exception spec acts like a catch handler, but in reverse. This "catch
351351+ handler" will catch an excpType if and only if none of the catchType's in
352352+ the list will catch a excpType. If any catchType in the list can catch an
353353+ excpType, then this exception spec does not catch the excpType.
354354+*/
355355+static
356356+bool
357357+exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
358358+ uint8_t ttypeEncoding, const __shim_type_info* excpType,
359359+ void* adjustedPtr, _Unwind_Exception* unwind_exception)
360360+{
361361+ if (classInfo == 0)
362362+ {
363363+ // this should not happen. Indicates corrupted eh_table.
364364+ call_terminate(false, unwind_exception);
365365+ }
366366+ // specIndex is negative of 1-based byte offset into classInfo;
367367+ specIndex = -specIndex;
368368+ --specIndex;
369369+ const uint8_t* temp = classInfo + specIndex;
370370+ // If any type in the spec list can catch excpType, return false, else return true
371371+ // adjustments to adjustedPtr are ignored.
372372+ while (true)
373373+ {
374374+ uint64_t ttypeIndex = readULEB128(&temp);
375375+ if (ttypeIndex == 0)
376376+ break;
377377+ const __shim_type_info* catchType = get_shim_type_info(ttypeIndex,
378378+ classInfo,
379379+ ttypeEncoding,
380380+ true,
381381+ unwind_exception);
382382+ void* tempPtr = adjustedPtr;
383383+ if (catchType->can_catch(excpType, tempPtr))
384384+ return false;
385385+ }
386386+ return true;
387387+}
388388+389389+static
390390+void*
391391+get_thrown_object_ptr(_Unwind_Exception* unwind_exception)
392392+{
393393+ // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1
394394+ // Regardless, this library is prohibited from touching a foreign exception
395395+ void* adjustedPtr = unwind_exception + 1;
396396+ if (unwind_exception->exception_class == kOurDependentExceptionClass)
397397+ adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException;
398398+ return adjustedPtr;
399399+}
400400+401401+namespace
402402+{
403403+404404+struct scan_results
405405+{
406406+ int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup
407407+ const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance.
408408+ const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected
409409+ uintptr_t landingPad; // null -> nothing found, else something found
410410+ void* adjustedPtr; // Used in cxa_exception.cpp
411411+ _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR,
412412+ // _URC_FATAL_PHASE2_ERROR,
413413+ // _URC_CONTINUE_UNWIND,
414414+ // _URC_HANDLER_FOUND
415415+};
416416+417417+} // unnamed namespace
418418+419419+static
420420+void
421421+set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
422422+ const scan_results& results)
423423+{
424424+#if __arm__
425425+ _Unwind_SetGR(context, 0, reinterpret_cast<uintptr_t>(unwind_exception));
426426+ _Unwind_SetGR(context, 1, static_cast<uintptr_t>(results.ttypeIndex));
427427+#else
428428+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
429429+ reinterpret_cast<uintptr_t>(unwind_exception));
430430+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
431431+ static_cast<uintptr_t>(results.ttypeIndex));
432432+#endif
433433+ _Unwind_SetIP(context, results.landingPad);
434434+}
435435+436436+/*
437437+ There are 3 types of scans needed:
438438+439439+ 1. Scan for handler with native or foreign exception. If handler found,
440440+ save state and return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.
441441+ May also report an error on invalid input.
442442+ May terminate for invalid exception table.
443443+ _UA_SEARCH_PHASE
444444+445445+ 2. Scan for handler with foreign exception. Must return _URC_HANDLER_FOUND,
446446+ or call terminate.
447447+ _UA_CLEANUP_PHASE && _UA_HANDLER_FRAME && !native_exception
448448+449449+ 3. Scan for cleanups. If a handler is found and this isn't forced unwind,
450450+ then terminate, otherwise ignore the handler and keep looking for cleanup.
451451+ If a cleanup is found, return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.
452452+ May also report an error on invalid input.
453453+ May terminate for invalid exception table.
454454+ _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME
455455+*/
456456+457457+static
458458+void
459459+scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception,
460460+ _Unwind_Exception* unwind_exception, _Unwind_Context* context)
461461+{
462462+ // Initialize results to found nothing but an error
463463+ results.ttypeIndex = 0;
464464+ results.actionRecord = 0;
465465+ results.languageSpecificData = 0;
466466+ results.landingPad = 0;
467467+ results.adjustedPtr = 0;
468468+ results.reason = _URC_FATAL_PHASE1_ERROR;
469469+ // Check for consistent actions
470470+ if (actions & _UA_SEARCH_PHASE)
471471+ {
472472+ // Do Phase 1
473473+ if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND))
474474+ {
475475+ // None of these flags should be set during Phase 1
476476+ // Client error
477477+ results.reason = _URC_FATAL_PHASE1_ERROR;
478478+ return;
479479+ }
480480+ }
481481+ else if (actions & _UA_CLEANUP_PHASE)
482482+ {
483483+ if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND))
484484+ {
485485+ // _UA_HANDLER_FRAME should only be set if phase 1 found a handler.
486486+ // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.
487487+ // Client error
488488+ results.reason = _URC_FATAL_PHASE2_ERROR;
489489+ return;
490490+ }
491491+ }
492492+ else // Niether _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set
493493+ {
494494+ // One of these should be set.
495495+ // Client error
496496+ results.reason = _URC_FATAL_PHASE1_ERROR;
497497+ return;
498498+ }
499499+ // Start scan by getting exception table address
500500+ const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
501501+ if (lsda == 0)
502502+ {
503503+ // There is no exception table
504504+ results.reason = _URC_CONTINUE_UNWIND;
505505+ return;
506506+ }
507507+ results.languageSpecificData = lsda;
508508+ // Get the current instruction pointer and offset it before next
509509+ // instruction in the current frame which threw the exception.
510510+ uintptr_t ip = _Unwind_GetIP(context) - 1;
511511+ // Get beginning current frame's code (as defined by the
512512+ // emitted dwarf code)
513513+ uintptr_t funcStart = _Unwind_GetRegionStart(context);
514514+#if __arm__
515515+ if (ip == uintptr_t(-1))
516516+ {
517517+ // no action
518518+ results.reason = _URC_CONTINUE_UNWIND;
519519+ return;
520520+ }
521521+ else if (ip == 0)
522522+ call_terminate(native_exception, unwind_exception);
523523+ // ip is 1-based index into call site table
524524+#else // __arm__
525525+ uintptr_t ipOffset = ip - funcStart;
526526+#endif // __arm__
527527+ const uint8_t* classInfo = NULL;
528528+ // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
529529+ // dwarf emission
530530+ // Parse LSDA header.
531531+ uint8_t lpStartEncoding = *lsda++;
532532+ const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
533533+ if (lpStart == 0)
534534+ lpStart = (const uint8_t*)funcStart;
535535+ uint8_t ttypeEncoding = *lsda++;
536536+ if (ttypeEncoding != DW_EH_PE_omit)
537537+ {
538538+ // Calculate type info locations in emitted dwarf code which
539539+ // were flagged by type info arguments to llvm.eh.selector
540540+ // intrinsic
541541+ uintptr_t classInfoOffset = readULEB128(&lsda);
542542+ classInfo = lsda + classInfoOffset;
543543+ }
544544+ // Walk call-site table looking for range that
545545+ // includes current PC.
546546+ uint8_t callSiteEncoding = *lsda++;
547547+#if __arm__
548548+ (void)callSiteEncoding; // On arm callSiteEncoding is never used
549549+#endif
550550+ uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
551551+ const uint8_t* callSiteTableStart = lsda;
552552+ const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
553553+ const uint8_t* actionTableStart = callSiteTableEnd;
554554+ const uint8_t* callSitePtr = callSiteTableStart;
555555+ while (true)
556556+ {
557557+ // There is one entry per call site.
558558+#if !__arm__
559559+ // The call sites are non-overlapping in [start, start+length)
560560+ // The call sites are ordered in increasing value of start
561561+ uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
562562+ uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
563563+ uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
564564+ uintptr_t actionEntry = readULEB128(&callSitePtr);
565565+ if ((start <= ipOffset) && (ipOffset < (start + length)))
566566+#else // __arm__
567567+ // ip is 1-based index into this table
568568+ uintptr_t landingPad = readULEB128(&callSitePtr);
569569+ uintptr_t actionEntry = readULEB128(&callSitePtr);
570570+ if (--ip == 0)
571571+#endif // __arm__
572572+ {
573573+ // Found the call site containing ip.
574574+#if !__arm__
575575+ if (landingPad == 0)
576576+ {
577577+ // No handler here
578578+ results.reason = _URC_CONTINUE_UNWIND;
579579+ return;
580580+ }
581581+ landingPad = (uintptr_t)lpStart + landingPad;
582582+#else // __arm__
583583+ ++landingPad;
584584+#endif // __arm__
585585+ if (actionEntry == 0)
586586+ {
587587+ // Found a cleanup
588588+ // If this is a type 1 or type 2 search, there are no handlers
589589+ // If this is a type 3 search, you want to install the cleanup.
590590+ if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))
591591+ {
592592+ results.ttypeIndex = 0; // Redundant but clarifying
593593+ results.landingPad = landingPad;
594594+ results.reason = _URC_HANDLER_FOUND;
595595+ return;
596596+ }
597597+ // No handler here
598598+ results.reason = _URC_CONTINUE_UNWIND;
599599+ return;
600600+ }
601601+ // Convert 1-based byte offset into
602602+ const uint8_t* action = actionTableStart + (actionEntry - 1);
603603+ // Scan action entries until you find a matching handler, cleanup, or the end of action list
604604+ while (true)
605605+ {
606606+ const uint8_t* actionRecord = action;
607607+ int64_t ttypeIndex = readSLEB128(&action);
608608+ if (ttypeIndex > 0)
609609+ {
610610+ // Found a catch, does it actually catch?
611611+ // First check for catch (...)
612612+ const __shim_type_info* catchType =
613613+ get_shim_type_info(static_cast<uint64_t>(ttypeIndex),
614614+ classInfo, ttypeEncoding,
615615+ native_exception, unwind_exception);
616616+ if (catchType == 0)
617617+ {
618618+ // Found catch (...) catches everything, including foreign exceptions
619619+ // If this is a type 1 search save state and return _URC_HANDLER_FOUND
620620+ // If this is a type 2 search save state and return _URC_HANDLER_FOUND
621621+ // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
622622+ // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
623623+ if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))
624624+ {
625625+ // Save state and return _URC_HANDLER_FOUND
626626+ results.ttypeIndex = ttypeIndex;
627627+ results.actionRecord = actionRecord;
628628+ results.landingPad = landingPad;
629629+ results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
630630+ results.reason = _URC_HANDLER_FOUND;
631631+ return;
632632+ }
633633+ else if (!(actions & _UA_FORCE_UNWIND))
634634+ {
635635+ // It looks like the exception table has changed
636636+ // on us. Likely stack corruption!
637637+ call_terminate(native_exception, unwind_exception);
638638+ }
639639+ }
640640+ // Else this is a catch (T) clause and will never
641641+ // catch a foreign exception
642642+ else if (native_exception)
643643+ {
644644+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
645645+ void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
646646+ const __shim_type_info* excpType =
647647+ static_cast<const __shim_type_info*>(exception_header->exceptionType);
648648+ if (adjustedPtr == 0 || excpType == 0)
649649+ {
650650+ // Something very bad happened
651651+ call_terminate(native_exception, unwind_exception);
652652+ }
653653+ if (catchType->can_catch(excpType, adjustedPtr))
654654+ {
655655+ // Found a matching handler
656656+ // If this is a type 1 search save state and return _URC_HANDLER_FOUND
657657+ // If this is a type 3 search and !_UA_FORCE_UNWIND, we should have found this in phase 1!
658658+ // If this is a type 3 search and _UA_FORCE_UNWIND, ignore handler and continue scan
659659+ if (actions & _UA_SEARCH_PHASE)
660660+ {
661661+ // Save state and return _URC_HANDLER_FOUND
662662+ results.ttypeIndex = ttypeIndex;
663663+ results.actionRecord = actionRecord;
664664+ results.landingPad = landingPad;
665665+ results.adjustedPtr = adjustedPtr;
666666+ results.reason = _URC_HANDLER_FOUND;
667667+ return;
668668+ }
669669+ else if (!(actions & _UA_FORCE_UNWIND))
670670+ {
671671+ // It looks like the exception table has changed
672672+ // on us. Likely stack corruption!
673673+ call_terminate(native_exception, unwind_exception);
674674+ }
675675+ }
676676+ }
677677+ // Scan next action ...
678678+ }
679679+ else if (ttypeIndex < 0)
680680+ {
681681+ // Found an exception spec. If this is a foreign exception,
682682+ // it is always caught.
683683+ if (native_exception)
684684+ {
685685+ // Does the exception spec catch this native exception?
686686+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
687687+ void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
688688+ const __shim_type_info* excpType =
689689+ static_cast<const __shim_type_info*>(exception_header->exceptionType);
690690+ if (adjustedPtr == 0 || excpType == 0)
691691+ {
692692+ // Something very bad happened
693693+ call_terminate(native_exception, unwind_exception);
694694+ }
695695+ if (exception_spec_can_catch(ttypeIndex, classInfo,
696696+ ttypeEncoding, excpType,
697697+ adjustedPtr, unwind_exception))
698698+ {
699699+ // native exception caught by exception spec
700700+ // If this is a type 1 search, save state and return _URC_HANDLER_FOUND
701701+ // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
702702+ // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
703703+ if (actions & _UA_SEARCH_PHASE)
704704+ {
705705+ // Save state and return _URC_HANDLER_FOUND
706706+ results.ttypeIndex = ttypeIndex;
707707+ results.actionRecord = actionRecord;
708708+ results.landingPad = landingPad;
709709+ results.adjustedPtr = adjustedPtr;
710710+ results.reason = _URC_HANDLER_FOUND;
711711+ return;
712712+ }
713713+ else if (!(actions & _UA_FORCE_UNWIND))
714714+ {
715715+ // It looks like the exception table has changed
716716+ // on us. Likely stack corruption!
717717+ call_terminate(native_exception, unwind_exception);
718718+ }
719719+ }
720720+ }
721721+ else
722722+ {
723723+ // foreign exception caught by exception spec
724724+ // If this is a type 1 search, save state and return _URC_HANDLER_FOUND
725725+ // If this is a type 2 search, save state and return _URC_HANDLER_FOUND
726726+ // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
727727+ // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
728728+ if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))
729729+ {
730730+ // Save state and return _URC_HANDLER_FOUND
731731+ results.ttypeIndex = ttypeIndex;
732732+ results.actionRecord = actionRecord;
733733+ results.landingPad = landingPad;
734734+ results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
735735+ results.reason = _URC_HANDLER_FOUND;
736736+ return;
737737+ }
738738+ else if (!(actions & _UA_FORCE_UNWIND))
739739+ {
740740+ // It looks like the exception table has changed
741741+ // on us. Likely stack corruption!
742742+ call_terminate(native_exception, unwind_exception);
743743+ }
744744+ }
745745+ // Scan next action ...
746746+ }
747747+ else // ttypeIndex == 0
748748+ {
749749+ // Found a cleanup
750750+ // If this is a type 1 search, ignore it and continue scan
751751+ // If this is a type 2 search, ignore it and continue scan
752752+ // If this is a type 3 search, save state and return _URC_HANDLER_FOUND
753753+ if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))
754754+ {
755755+ // Save state and return _URC_HANDLER_FOUND
756756+ results.ttypeIndex = ttypeIndex;
757757+ results.actionRecord = actionRecord;
758758+ results.landingPad = landingPad;
759759+ results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
760760+ results.reason = _URC_HANDLER_FOUND;
761761+ return;
762762+ }
763763+ }
764764+ const uint8_t* temp = action;
765765+ int64_t actionOffset = readSLEB128(&temp);
766766+ if (actionOffset == 0)
767767+ {
768768+ // End of action list, no matching handler or cleanup found
769769+ results.reason = _URC_CONTINUE_UNWIND;
770770+ return;
771771+ }
772772+ // Go to next action
773773+ action += actionOffset;
774774+ } // there is no break out of this loop, only return
775775+ }
776776+#if !__arm__
777777+ else if (ipOffset < start)
778778+ {
779779+ // There is no call site for this ip
780780+ // Something bad has happened. We should never get here.
781781+ // Possible stack corruption.
782782+ call_terminate(native_exception, unwind_exception);
783783+ }
784784+#endif // !__arm__
785785+ } // there is no break out of this loop, only return
786786+}
787787+788788+// public API
789789+790790+/*
791791+The personality function branches on actions like so:
792792+793793+_UA_SEARCH_PHASE
794794+795795+ If _UA_CLEANUP_PHASE or _UA_HANDLER_FRAME or _UA_FORCE_UNWIND there's
796796+ an error from above, return _URC_FATAL_PHASE1_ERROR.
797797+798798+ Scan for anything that could stop unwinding:
799799+800800+ 1. A catch clause that will catch this exception
801801+ (will never catch foreign).
802802+ 2. A catch (...) (will always catch foreign).
803803+ 3. An exception spec that will catch this exception
804804+ (will always catch foreign).
805805+ If a handler is found
806806+ If not foreign
807807+ Save state in header
808808+ return _URC_HANDLER_FOUND
809809+ Else a handler not found
810810+ return _URC_CONTINUE_UNWIND
811811+812812+_UA_CLEANUP_PHASE
813813+814814+ If _UA_HANDLER_FRAME
815815+ If _UA_FORCE_UNWIND
816816+ How did this happen? return _URC_FATAL_PHASE2_ERROR
817817+ If foreign
818818+ Do _UA_SEARCH_PHASE to recover state
819819+ else
820820+ Recover state from header
821821+ Transfer control to landing pad. return _URC_INSTALL_CONTEXT
822822+823823+ Else
824824+825825+ This branch handles both normal C++ non-catching handlers (cleanups)
826826+ and forced unwinding.
827827+ Scan for anything that can not stop unwinding:
828828+829829+ 1. A cleanup.
830830+831831+ If a cleanup is found
832832+ transfer control to it. return _URC_INSTALL_CONTEXT
833833+ Else a cleanup is not found: return _URC_CONTINUE_UNWIND
834834+*/
835835+836836+_Unwind_Reason_Code
837837+#if __arm__
838838+__gxx_personality_sj0
839839+#else
840840+__gxx_personality_v0
841841+#endif
842842+ (int version, _Unwind_Action actions, uint64_t exceptionClass,
843843+ _Unwind_Exception* unwind_exception, _Unwind_Context* context)
844844+{
845845+ if (version != 1 || unwind_exception == 0 || context == 0)
846846+ return _URC_FATAL_PHASE1_ERROR;
847847+ bool native_exception = (exceptionClass & get_vendor_and_language) ==
848848+ (kOurExceptionClass & get_vendor_and_language);
849849+ scan_results results;
850850+ if (actions & _UA_SEARCH_PHASE)
851851+ {
852852+ // Phase 1 search: All we're looking for in phase 1 is a handler that
853853+ // halts unwinding
854854+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
855855+ if (results.reason == _URC_HANDLER_FOUND)
856856+ {
857857+ // Found one. Can we cache the results somewhere to optimize phase 2?
858858+ if (native_exception)
859859+ {
860860+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
861861+ exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
862862+ exception_header->actionRecord = results.actionRecord;
863863+ exception_header->languageSpecificData = results.languageSpecificData;
864864+ exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad);
865865+ exception_header->adjustedPtr = results.adjustedPtr;
866866+ }
867867+ return _URC_HANDLER_FOUND;
868868+ }
869869+ // Did not find a catching-handler. Return the results of the scan
870870+ // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE1_ERROR
871871+ // if we were called improperly).
872872+ return results.reason;
873873+ }
874874+ if (actions & _UA_CLEANUP_PHASE)
875875+ {
876876+ // Phase 2 search:
877877+ // Did we find a catching handler in phase 1?
878878+ if (actions & _UA_HANDLER_FRAME)
879879+ {
880880+ // Yes, phase 1 said we have a catching handler here.
881881+ // Did we cache the results of the scan?
882882+ if (native_exception)
883883+ {
884884+ // Yes, reload the results from the cache.
885885+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
886886+ results.ttypeIndex = exception_header->handlerSwitchValue;
887887+ results.actionRecord = exception_header->actionRecord;
888888+ results.languageSpecificData = exception_header->languageSpecificData;
889889+ results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp);
890890+ results.adjustedPtr = exception_header->adjustedPtr;
891891+ }
892892+ else
893893+ {
894894+ // No, do the scan again to reload the results.
895895+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
896896+ // Phase 1 told us we would find a handler. Now in Phase 2 we
897897+ // didn't find a handler. The eh table should not be changing!
898898+ if (results.reason != _URC_HANDLER_FOUND)
899899+ call_terminate(native_exception, unwind_exception);
900900+ }
901901+ // Jump to the handler
902902+ set_registers(unwind_exception, context, results);
903903+ return _URC_INSTALL_CONTEXT;
904904+ }
905905+ // Either we didn't do a phase 1 search (due to forced unwinding), or
906906+ // phase 1 reported no catching-handlers.
907907+ // Search for a (non-catching) cleanup
908908+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
909909+ if (results.reason == _URC_HANDLER_FOUND)
910910+ {
911911+ // Found a non-catching handler. Jump to it:
912912+ set_registers(unwind_exception, context, results);
913913+ return _URC_INSTALL_CONTEXT;
914914+ }
915915+ // Did not find a cleanup. Return the results of the scan
916916+ // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR
917917+ // if we were called improperly).
918918+ return results.reason;
919919+ }
920920+ // We were called improperly: neither a phase 1 or phase 2 search
921921+ return _URC_FATAL_PHASE1_ERROR;
922922+}
923923+924924+__attribute__((noreturn))
925925+void
926926+__cxa_call_unexpected(void* arg)
927927+{
928928+ _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
929929+ if (unwind_exception == 0)
930930+ call_terminate(false, unwind_exception);
931931+ __cxa_begin_catch(unwind_exception);
932932+ bool native_old_exception =
933933+ (unwind_exception->exception_class & get_vendor_and_language) ==
934934+ (kOurExceptionClass & get_vendor_and_language);
935935+ std::unexpected_handler u_handler;
936936+ std::terminate_handler t_handler;
937937+ __cxa_exception* old_exception_header = 0;
938938+ int64_t ttypeIndex;
939939+ const uint8_t* lsda;
940940+ if (native_old_exception)
941941+ {
942942+ old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
943943+ t_handler = old_exception_header->terminateHandler;
944944+ u_handler = old_exception_header->unexpectedHandler;
945945+ // If std::__unexpected(u_handler) rethrows the same exception,
946946+ // these values get overwritten by the rethrow. So save them now:
947947+ ttypeIndex = old_exception_header->handlerSwitchValue;
948948+ lsda = old_exception_header->languageSpecificData;
949949+ }
950950+ else
951951+ {
952952+ t_handler = std::get_terminate();
953953+ u_handler = std::get_unexpected();
954954+ }
955955+ try
956956+ {
957957+ std::__unexpected(u_handler);
958958+ }
959959+ catch (...)
960960+ {
961961+ // If the old exception is foreign, then all we can do is terminate.
962962+ // We have no way to recover the needed old exception spec. There's
963963+ // no way to pass that information here. And the personality routine
964964+ // can't call us directly and do anything but terminate() if we throw
965965+ // from here.
966966+ if (native_old_exception)
967967+ {
968968+ // Have:
969969+ // old_exception_header->languageSpecificData
970970+ // old_exception_header->actionRecord
971971+ // Need
972972+ // const uint8_t* classInfo
973973+ // uint8_t ttypeEncoding
974974+ uint8_t lpStartEncoding = *lsda++;
975975+ const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
976976+ (void)lpStart; // purposefully unused. Just needed to increment lsda.
977977+ uint8_t ttypeEncoding = *lsda++;
978978+ if (ttypeEncoding == DW_EH_PE_omit)
979979+ std::__terminate(t_handler);
980980+ uintptr_t classInfoOffset = readULEB128(&lsda);
981981+ const uint8_t* classInfo = lsda + classInfoOffset;
982982+ // Is this new exception catchable by the exception spec at ttypeIndex?
983983+ // The answer is obviously yes if the new and old exceptions are the same exception
984984+ // If no
985985+ // throw;
986986+ __cxa_eh_globals* globals = __cxa_get_globals_fast();
987987+ __cxa_exception* new_exception_header = globals->caughtExceptions;
988988+ if (new_exception_header == 0)
989989+ // This shouldn't be able to happen!
990990+ std::__terminate(t_handler);
991991+ bool native_new_exception =
992992+ (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) ==
993993+ (kOurExceptionClass & get_vendor_and_language);
994994+ void* adjustedPtr;
995995+ if (native_new_exception && (new_exception_header != old_exception_header))
996996+ {
997997+ const __shim_type_info* excpType =
998998+ static_cast<const __shim_type_info*>(new_exception_header->exceptionType);
999999+ adjustedPtr =
10001000+ new_exception_header->unwindHeader.exception_class == kOurDependentExceptionClass ?
10011001+ ((__cxa_dependent_exception*)new_exception_header)->primaryException :
10021002+ new_exception_header + 1;
10031003+ if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
10041004+ excpType, adjustedPtr, unwind_exception))
10051005+ {
10061006+ // We need to __cxa_end_catch, but for the old exception,
10071007+ // not the new one. This is a little tricky ...
10081008+ // Disguise new_exception_header as a rethrown exception, but
10091009+ // don't actually rethrow it. This means you can temporarily
10101010+ // end the catch clause enclosing new_exception_header without
10111011+ // __cxa_end_catch destroying new_exception_header.
10121012+ new_exception_header->handlerCount = -new_exception_header->handlerCount;
10131013+ globals->uncaughtExceptions += 1;
10141014+ // Call __cxa_end_catch for new_exception_header
10151015+ __cxa_end_catch();
10161016+ // Call __cxa_end_catch for old_exception_header
10171017+ __cxa_end_catch();
10181018+ // Renter this catch clause with new_exception_header
10191019+ __cxa_begin_catch(&new_exception_header->unwindHeader);
10201020+ // Rethrow new_exception_header
10211021+ throw;
10221022+ }
10231023+ }
10241024+ // Will a std::bad_exception be catchable by the exception spec at
10251025+ // ttypeIndex?
10261026+ // If no
10271027+ // throw std::bad_exception();
10281028+ const __shim_type_info* excpType =
10291029+ static_cast<const __shim_type_info*>(&typeid(std::bad_exception));
10301030+ std::bad_exception be;
10311031+ adjustedPtr = &be;
10321032+ if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
10331033+ excpType, adjustedPtr, unwind_exception))
10341034+ {
10351035+ // We need to __cxa_end_catch for both the old exception and the
10361036+ // new exception. Technically we should do it in that order.
10371037+ // But it is expedent to do it in the opposite order:
10381038+ // Call __cxa_end_catch for new_exception_header
10391039+ __cxa_end_catch();
10401040+ // Throw std::bad_exception will __cxa_end_catch for
10411041+ // old_exception_header
10421042+ throw be;
10431043+ }
10441044+ }
10451045+ }
10461046+ std::__terminate(t_handler);
10471047+}
10481048+10491049+} // extern "C"
10501050+10511051+} // __cxxabiv1
···11+//===------------------------- cxa_unexpected.cpp -------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//===----------------------------------------------------------------------===//
99+1010+#include <exception>
1111+#include <cxxabi.h>
1212+#include "cxa_exception.hpp"
1313+1414+namespace __cxxabiv1
1515+{
1616+1717+#pragma GCC visibility push(default)
1818+1919+extern "C"
2020+{
2121+2222+}
2323+2424+#pragma GCC visibility pop
2525+2626+} // namespace __cxxabiv1
2727+
···11+//===-------------------------- cxa_vector.cpp ---------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//
99+// This file implements the "Array Construction and Destruction APIs"
1010+// http://www.codesourcery.com/public/cxx-abi/abi.html#array-ctor
1111+//
1212+//===----------------------------------------------------------------------===//
1313+1414+#include "cxxabi.h"
1515+1616+#include <exception> // for std::terminate
1717+1818+namespace __cxxabiv1 {
1919+2020+#pragma mark --Helper routines and classes --
2121+2222+namespace {
2323+ inline static size_t __get_element_count ( void *p ) {
2424+ return static_cast <size_t *> (p)[-1];
2525+ }
2626+2727+ inline static void __set_element_count ( void *p, size_t element_count ) {
2828+ static_cast <size_t *> (p)[-1] = element_count;
2929+ }
3030+3131+3232+// A pair of classes to simplify exception handling and control flow.
3333+// They get passed a block of memory in the constructor, and unless the
3434+// 'release' method is called, they deallocate the memory in the destructor.
3535+// Prefered usage is to allocate some memory, attach it to one of these objects,
3636+// and then, when all the operations to set up the memory block have succeeded,
3737+// call 'release'. If any of the setup operations fail, or an exception is
3838+// thrown, then the block is automatically deallocated.
3939+//
4040+// The only difference between these two classes is the signature for the
4141+// deallocation function (to match new2/new3 and delete2/delete3.
4242+ class st_heap_block2 {
4343+ public:
4444+ typedef void (*dealloc_f)(void *);
4545+4646+ st_heap_block2 ( dealloc_f dealloc, void *ptr )
4747+ : dealloc_ ( dealloc ), ptr_ ( ptr ), enabled_ ( true ) {}
4848+ ~st_heap_block2 () { if ( enabled_ ) dealloc_ ( ptr_ ) ; }
4949+ void release () { enabled_ = false; }
5050+5151+ private:
5252+ dealloc_f dealloc_;
5353+ void *ptr_;
5454+ bool enabled_;
5555+ };
5656+5757+ class st_heap_block3 {
5858+ public:
5959+ typedef void (*dealloc_f)(void *, size_t);
6060+6161+ st_heap_block3 ( dealloc_f dealloc, void *ptr, size_t size )
6262+ : dealloc_ ( dealloc ), ptr_ ( ptr ), size_ ( size ), enabled_ ( true ) {}
6363+ ~st_heap_block3 () { if ( enabled_ ) dealloc_ ( ptr_, size_ ) ; }
6464+ void release () { enabled_ = false; }
6565+6666+ private:
6767+ dealloc_f dealloc_;
6868+ void *ptr_;
6969+ size_t size_;
7070+ bool enabled_;
7171+ };
7272+7373+ class st_cxa_cleanup {
7474+ public:
7575+ typedef void (*destruct_f)(void *);
7676+7777+ st_cxa_cleanup ( void *ptr, size_t &idx, size_t element_size, destruct_f destructor )
7878+ : ptr_ ( ptr ), idx_ ( idx ), element_size_ ( element_size ),
7979+ destructor_ ( destructor ), enabled_ ( true ) {}
8080+ ~st_cxa_cleanup () {
8181+ if ( enabled_ )
8282+ __cxa_vec_cleanup ( ptr_, idx_, element_size_, destructor_ );
8383+ }
8484+8585+ void release () { enabled_ = false; }
8686+8787+ private:
8888+ void *ptr_;
8989+ size_t &idx_;
9090+ size_t element_size_;
9191+ destruct_f destructor_;
9292+ bool enabled_;
9393+ };
9494+9595+ class st_terminate {
9696+ public:
9797+ st_terminate ( bool enabled = true ) : enabled_ ( enabled ) {}
9898+ ~st_terminate () { if ( enabled_ ) std::terminate (); }
9999+ void release () { enabled_ = false; }
100100+ private:
101101+ bool enabled_ ;
102102+ };
103103+}
104104+105105+#pragma mark --Externally visible routines--
106106+107107+extern "C" {
108108+109109+// Equivalent to
110110+//
111111+// __cxa_vec_new2(element_count, element_size, padding_size, constructor,
112112+// destructor, &::operator new[], &::operator delete[])
113113+void* __cxa_vec_new(
114114+ size_t element_count, size_t element_size, size_t padding_size,
115115+ void (*constructor)(void*), void (*destructor)(void*) ) {
116116+117117+ return __cxa_vec_new2 ( element_count, element_size, padding_size,
118118+ constructor, destructor, &::operator new [], &::operator delete [] );
119119+}
120120+121121+122122+123123+// Given the number and size of elements for an array and the non-negative
124124+// size of prefix padding for a cookie, allocate space (using alloc) for
125125+// the array preceded by the specified padding, initialize the cookie if
126126+// the padding is non-zero, and call the given constructor on each element.
127127+// Return the address of the array proper, after the padding.
128128+//
129129+// If alloc throws an exception, rethrow the exception. If alloc returns
130130+// NULL, return NULL. If the constructor throws an exception, call
131131+// destructor for any already constructed elements, and rethrow the
132132+// exception. If the destructor throws an exception, call std::terminate.
133133+//
134134+// The constructor may be NULL, in which case it must not be called. If the
135135+// padding_size is zero, the destructor may be NULL; in that case it must
136136+// not be called.
137137+//
138138+// Neither alloc nor dealloc may be NULL.
139139+void* __cxa_vec_new2(
140140+ size_t element_count, size_t element_size, size_t padding_size,
141141+ void (*constructor)(void*), void (*destructor)(void*),
142142+ void* (*alloc)(size_t), void (*dealloc)(void*) ) {
143143+144144+ const size_t heap_size = element_count * element_size + padding_size;
145145+ char * const heap_block = static_cast<char *> ( alloc ( heap_size ));
146146+ char *vec_base = heap_block;
147147+148148+ if ( NULL != vec_base ) {
149149+ st_heap_block2 heap ( dealloc, heap_block );
150150+151151+ // put the padding before the array elements
152152+ if ( 0 != padding_size ) {
153153+ vec_base += padding_size;
154154+ __set_element_count ( vec_base, element_count );
155155+ }
156156+157157+ // Construct the elements
158158+ __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor );
159159+ heap.release (); // We're good!
160160+ }
161161+162162+ return vec_base;
163163+}
164164+165165+166166+// Same as __cxa_vec_new2 except that the deallocation function takes both
167167+// the object address and its size.
168168+void* __cxa_vec_new3(
169169+ size_t element_count, size_t element_size, size_t padding_size,
170170+ void (*constructor)(void*), void (*destructor)(void*),
171171+ void* (*alloc)(size_t), void (*dealloc)(void*, size_t) ) {
172172+173173+ const size_t heap_size = element_count * element_size + padding_size;
174174+ char * const heap_block = static_cast<char *> ( alloc ( heap_size ));
175175+ char *vec_base = heap_block;
176176+177177+ if ( NULL != vec_base ) {
178178+ st_heap_block3 heap ( dealloc, heap_block, heap_size );
179179+180180+ // put the padding before the array elements
181181+ if ( 0 != padding_size ) {
182182+ vec_base += padding_size;
183183+ __set_element_count ( vec_base, element_count );
184184+ }
185185+186186+ // Construct the elements
187187+ __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor );
188188+ heap.release (); // We're good!
189189+ }
190190+191191+ return vec_base;
192192+}
193193+194194+195195+// Given the (data) addresses of a destination and a source array, an
196196+// element count and an element size, call the given copy constructor to
197197+// copy each element from the source array to the destination array. The
198198+// copy constructor's arguments are the destination address and source
199199+// address, respectively. If an exception occurs, call the given destructor
200200+// (if non-NULL) on each copied element and rethrow. If the destructor
201201+// throws an exception, call terminate(). The constructor and or destructor
202202+// pointers may be NULL. If either is NULL, no action is taken when it
203203+// would have been called.
204204+205205+void __cxa_vec_cctor( void* dest_array, void* src_array,
206206+ size_t element_count, size_t element_size,
207207+ void (*constructor) (void*, void*), void (*destructor)(void*) ) {
208208+209209+ if ( NULL != constructor ) {
210210+ size_t idx = 0;
211211+ char *src_ptr = static_cast<char *>(src_array);
212212+ char *dest_ptr = static_cast<char *>(dest_array);
213213+ st_cxa_cleanup cleanup ( dest_array, idx, element_size, destructor );
214214+215215+ for ( idx = 0; idx < element_count;
216216+ ++idx, src_ptr += element_size, dest_ptr += element_size )
217217+ constructor ( dest_ptr, src_ptr );
218218+ cleanup.release (); // We're good!
219219+ }
220220+}
221221+222222+223223+// Given the (data) address of an array, not including any cookie padding,
224224+// and the number and size of its elements, call the given constructor on
225225+// each element. If the constructor throws an exception, call the given
226226+// destructor for any already-constructed elements, and rethrow the
227227+// exception. If the destructor throws an exception, call terminate(). The
228228+// constructor and/or destructor pointers may be NULL. If either is NULL,
229229+// no action is taken when it would have been called.
230230+void __cxa_vec_ctor(
231231+ void* array_address, size_t element_count, size_t element_size,
232232+ void (*constructor)(void*), void (*destructor)(void*) ) {
233233+234234+ if ( NULL != constructor ) {
235235+ size_t idx;
236236+ char *ptr = static_cast <char *> ( array_address );
237237+ st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor );
238238+239239+ // Construct the elements
240240+ for ( idx = 0; idx < element_count; ++idx, ptr += element_size )
241241+ constructor ( ptr );
242242+ cleanup.release (); // We're good!
243243+ }
244244+}
245245+246246+// Given the (data) address of an array, the number of elements, and the
247247+// size of its elements, call the given destructor on each element. If the
248248+// destructor throws an exception, rethrow after destroying the remaining
249249+// elements if possible. If the destructor throws a second exception, call
250250+// terminate(). The destructor pointer may be NULL, in which case this
251251+// routine does nothing.
252252+void __cxa_vec_dtor(
253253+ void* array_address, size_t element_count, size_t element_size,
254254+ void (*destructor)(void*) ) {
255255+256256+ if ( NULL != destructor ) {
257257+ char *ptr = static_cast <char *> (array_address);
258258+ size_t idx = element_count;
259259+ st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor );
260260+ {
261261+ st_terminate exception_guard (__cxa_uncaught_exception ());
262262+ ptr += element_count * element_size; // one past the last element
263263+264264+ while ( idx-- > 0 ) {
265265+ ptr -= element_size;
266266+ destructor ( ptr );
267267+ }
268268+ exception_guard.release (); // We're good !
269269+ }
270270+ cleanup.release (); // We're still good!
271271+ }
272272+}
273273+274274+// Given the (data) address of an array, the number of elements, and the
275275+// size of its elements, call the given destructor on each element. If the
276276+// destructor throws an exception, call terminate(). The destructor pointer
277277+// may be NULL, in which case this routine does nothing.
278278+void __cxa_vec_cleanup( void* array_address, size_t element_count,
279279+ size_t element_size, void (*destructor)(void*) ) {
280280+281281+ if ( NULL != destructor ) {
282282+ char *ptr = static_cast <char *> (array_address);
283283+ size_t idx = element_count;
284284+ st_terminate exception_guard;
285285+286286+ ptr += element_count * element_size; // one past the last element
287287+ while ( idx-- > 0 ) {
288288+ ptr -= element_size;
289289+ destructor ( ptr );
290290+ }
291291+ exception_guard.release (); // We're done!
292292+ }
293293+}
294294+295295+296296+// If the array_address is NULL, return immediately. Otherwise, given the
297297+// (data) address of an array, the non-negative size of prefix padding for
298298+// the cookie, and the size of its elements, call the given destructor on
299299+// each element, using the cookie to determine the number of elements, and
300300+// then delete the space by calling ::operator delete[](void *). If the
301301+// destructor throws an exception, rethrow after (a) destroying the
302302+// remaining elements, and (b) deallocating the storage. If the destructor
303303+// throws a second exception, call terminate(). If padding_size is 0, the
304304+// destructor pointer must be NULL. If the destructor pointer is NULL, no
305305+// destructor call is to be made.
306306+//
307307+// The intent of this function is to permit an implementation to call this
308308+// function when confronted with an expression of the form delete[] p in
309309+// the source code, provided that the default deallocation function can be
310310+// used. Therefore, the semantics of this function are consistent with
311311+// those required by the standard. The requirement that the deallocation
312312+// function be called even if the destructor throws an exception derives
313313+// from the resolution to DR 353 to the C++ standard, which was adopted in
314314+// April, 2003.
315315+void __cxa_vec_delete( void* array_address,
316316+ size_t element_size, size_t padding_size, void (*destructor)(void*) ) {
317317+318318+ __cxa_vec_delete2 ( array_address, element_size, padding_size,
319319+ destructor, &::operator delete [] );
320320+}
321321+322322+323323+// Same as __cxa_vec_delete, except that the given function is used for
324324+// deallocation instead of the default delete function. If dealloc throws
325325+// an exception, the result is undefined. The dealloc pointer may not be
326326+// NULL.
327327+void __cxa_vec_delete2( void* array_address,
328328+ size_t element_size, size_t padding_size,
329329+ void (*destructor)(void*), void (*dealloc)(void*) ) {
330330+331331+ if ( NULL != array_address ) {
332332+ char *vec_base = static_cast <char *> (array_address);
333333+ char *heap_block = vec_base - padding_size;
334334+ st_heap_block2 heap ( dealloc, heap_block );
335335+336336+ if ( 0 != padding_size && NULL != destructor ) // call the destructors
337337+ __cxa_vec_dtor ( array_address, __get_element_count ( vec_base ),
338338+ element_size, destructor );
339339+ }
340340+}
341341+342342+343343+// Same as __cxa_vec_delete, except that the given function is used for
344344+// deallocation instead of the default delete function. The deallocation
345345+// function takes both the object address and its size. If dealloc throws
346346+// an exception, the result is undefined. The dealloc pointer may not be
347347+// NULL.
348348+void __cxa_vec_delete3( void* array_address,
349349+ size_t element_size, size_t padding_size,
350350+ void (*destructor)(void*), void (*dealloc) (void*, size_t)) {
351351+352352+ if ( NULL != array_address ) {
353353+ char *vec_base = static_cast <char *> (array_address);
354354+ char *heap_block = vec_base - padding_size;
355355+ const size_t element_count = padding_size ? __get_element_count ( vec_base ) : 0;
356356+ const size_t heap_block_size = element_size * element_count + padding_size;
357357+ st_heap_block3 heap ( dealloc, heap_block, heap_block_size );
358358+359359+ if ( 0 != padding_size && NULL != destructor ) // call the destructors
360360+ __cxa_vec_dtor ( array_address, element_count, element_size, destructor );
361361+ }
362362+}
363363+364364+365365+} // extern "C"
366366+367367+} // abi
···11+//===-------------------------- cxa_virtual.cpp ---------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//===----------------------------------------------------------------------===//
99+1010+#include "cxxabi.h"
1111+#include "abort_message.h"
1212+1313+namespace __cxxabiv1
1414+{
1515+1616+extern "C"
1717+{
1818+1919+LIBCXXABI_NORETURN
2020+void __cxa_pure_virtual(void) {
2121+ abort_message("Pure virtual function called!");
2222+}
2323+2424+LIBCXXABI_NORETURN
2525+void __cxa_deleted_virtual(void) {
2626+ abort_message("Deleted virtual function called!");
2727+}
2828+2929+} // extern "C"
3030+3131+} // abi
+41
src/libunwind-darwin-gcc/src-cxxabi/exception.cpp
···11+//===---------------------------- exception.cpp ---------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//===----------------------------------------------------------------------===//
99+1010+#include <exception>
1111+1212+#pragma GCC visibility push(default)
1313+1414+namespace std
1515+{
1616+1717+// exception
1818+1919+exception::~exception() _NOEXCEPT
2020+{
2121+}
2222+2323+const char* exception::what() const _NOEXCEPT
2424+{
2525+ return "std::exception";
2626+}
2727+2828+// bad_exception
2929+3030+bad_exception::~bad_exception() _NOEXCEPT
3131+{
3232+}
3333+3434+const char* bad_exception::what() const _NOEXCEPT
3535+{
3636+ return "std::bad_exception";
3737+}
3838+3939+} // std
4040+4141+#pragma GCC visibility pop
···11+//===----------------------- private_typeinfo.cpp -------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//===----------------------------------------------------------------------===//
99+1010+#include "private_typeinfo.h"
1111+1212+namespace __cxxabiv1
1313+{
1414+1515+#pragma GCC visibility push(hidden)
1616+1717+// __shim_type_info
1818+1919+__shim_type_info::~__shim_type_info()
2020+{
2121+}
2222+2323+void __shim_type_info::noop1() const {}
2424+void __shim_type_info::noop2() const {}
2525+2626+// __fundamental_type_info
2727+2828+// This miraculously (compiler magic) emits the type_info's for:
2929+// 1. all of the fundamental types
3030+// 2. pointers to all of the fundamental types
3131+// 3. pointers to all of the const fundamental types
3232+__fundamental_type_info::~__fundamental_type_info()
3333+{
3434+}
3535+3636+// __array_type_info
3737+3838+__array_type_info::~__array_type_info()
3939+{
4040+}
4141+4242+// __function_type_info
4343+4444+__function_type_info::~__function_type_info()
4545+{
4646+}
4747+4848+// __enum_type_info
4949+5050+__enum_type_info::~__enum_type_info()
5151+{
5252+}
5353+5454+// __class_type_info
5555+5656+__class_type_info::~__class_type_info()
5757+{
5858+}
5959+6060+// __si_class_type_info
6161+6262+__si_class_type_info::~__si_class_type_info()
6363+{
6464+}
6565+6666+// __vmi_class_type_info
6767+6868+__vmi_class_type_info::~__vmi_class_type_info()
6969+{
7070+}
7171+7272+// __pbase_type_info
7373+7474+__pbase_type_info::~__pbase_type_info()
7575+{
7676+}
7777+7878+// __pointer_type_info
7979+8080+__pointer_type_info::~__pointer_type_info()
8181+{
8282+}
8383+8484+// __pointer_to_member_type_info
8585+8686+__pointer_to_member_type_info::~__pointer_to_member_type_info()
8787+{
8888+}
8989+9090+// can_catch
9191+9292+// A handler is a match for an exception object of type E if
9393+// 1. The handler is of type cv T or cv T& and E and T are the same type
9494+// (ignoring the top-level cv-qualifiers), or
9595+// 2. the handler is of type cv T or cv T& and T is an unambiguous public
9696+// base class of E, or
9797+// 3. the handler is of type cv1 T* cv2 and E is a pointer type that can be
9898+// converted to the type of the handler by either or both of
9999+// A. a standard pointer conversion (4.10) not involving conversions to
100100+// pointers to private or protected or ambiguous classes
101101+// B. a qualification conversion
102102+// 4. the handler is a pointer or pointer to member type and E is
103103+// std::nullptr_t.
104104+105105+// adjustedPtr:
106106+//
107107+// catch (A& a) : adjustedPtr == &a
108108+// catch (A* a) : adjustedPtr == a
109109+// catch (A** a) : adjustedPtr == a
110110+//
111111+// catch (D2& d2) : adjustedPtr == &d2 (d2 is base class of thrown object)
112112+// catch (D2* d2) : adjustedPtr == d2
113113+// catch (D2*& d2) : adjustedPtr == d2
114114+//
115115+// catch (...) : adjustedPtr == & of the exception
116116+117117+// Handles bullet 1
118118+bool
119119+__fundamental_type_info::can_catch(const __shim_type_info* thrown_type,
120120+ void*&) const
121121+{
122122+ return this == thrown_type;
123123+}
124124+125125+bool
126126+__array_type_info::can_catch(const __shim_type_info*, void*&) const
127127+{
128128+ // We can get here if someone tries to catch an array by reference.
129129+ // However if someone tries to throw an array, it immediately gets
130130+ // converted to a pointer, which will not convert back to an array
131131+ // at the catch clause. So this can never catch anything.
132132+ return false;
133133+}
134134+135135+bool
136136+__function_type_info::can_catch(const __shim_type_info*, void*&) const
137137+{
138138+ // We can get here if someone tries to catch a function by reference.
139139+ // However if someone tries to throw a function, it immediately gets
140140+ // converted to a pointer, which will not convert back to a function
141141+ // at the catch clause. So this can never catch anything.
142142+ return false;
143143+}
144144+145145+// Handles bullet 1
146146+bool
147147+__enum_type_info::can_catch(const __shim_type_info* thrown_type,
148148+ void*&) const
149149+{
150150+ return this == thrown_type;
151151+}
152152+153153+#pragma clang diagnostic push
154154+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
155155+156156+// Handles bullets 1 and 2
157157+bool
158158+__class_type_info::can_catch(const __shim_type_info* thrown_type,
159159+ void*& adjustedPtr) const
160160+{
161161+ // bullet 1
162162+ if (this == thrown_type)
163163+ return true;
164164+ const __class_type_info* thrown_class_type =
165165+ dynamic_cast<const __class_type_info*>(thrown_type);
166166+ if (thrown_class_type == 0)
167167+ return false;
168168+ // bullet 2
169169+ __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0};
170170+ info.number_of_dst_type = 1;
171171+ thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
172172+ if (info.path_dst_ptr_to_static_ptr == public_path)
173173+ {
174174+ adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
175175+ return true;
176176+ }
177177+ return false;
178178+}
179179+180180+#pragma clang diagnostic pop
181181+182182+void
183183+__class_type_info::process_found_base_class(__dynamic_cast_info* info,
184184+ void* adjustedPtr,
185185+ int path_below) const
186186+{
187187+ if (info->dst_ptr_leading_to_static_ptr == 0)
188188+ {
189189+ // First time here
190190+ info->dst_ptr_leading_to_static_ptr = adjustedPtr;
191191+ info->path_dst_ptr_to_static_ptr = path_below;
192192+ info->number_to_static_ptr = 1;
193193+ }
194194+ else if (info->dst_ptr_leading_to_static_ptr == adjustedPtr)
195195+ {
196196+ // We've been here before. Update path to "most public"
197197+ if (info->path_dst_ptr_to_static_ptr == not_public_path)
198198+ info->path_dst_ptr_to_static_ptr = path_below;
199199+ }
200200+ else
201201+ {
202202+ // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)
203203+ // to a static_type
204204+ info->number_to_static_ptr += 1;
205205+ info->path_dst_ptr_to_static_ptr = not_public_path;
206206+ info->search_done = true;
207207+ }
208208+}
209209+210210+void
211211+__class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
212212+ void* adjustedPtr,
213213+ int path_below) const
214214+{
215215+ if (this == info->static_type)
216216+ process_found_base_class(info, adjustedPtr, path_below);
217217+}
218218+219219+void
220220+__si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
221221+ void* adjustedPtr,
222222+ int path_below) const
223223+{
224224+ if (this == info->static_type)
225225+ process_found_base_class(info, adjustedPtr, path_below);
226226+ else
227227+ __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below);
228228+}
229229+230230+void
231231+__base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
232232+ void* adjustedPtr,
233233+ int path_below) const
234234+{
235235+ ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
236236+ if (__offset_flags & __virtual_mask)
237237+ {
238238+ const char* vtable = *static_cast<const char*const*>(adjustedPtr);
239239+ offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
240240+ }
241241+ __base_type->has_unambiguous_public_base(info,
242242+ static_cast<char*>(adjustedPtr) + offset_to_base,
243243+ (__offset_flags & __public_mask) ?
244244+ path_below :
245245+ not_public_path);
246246+}
247247+248248+void
249249+__vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
250250+ void* adjustedPtr,
251251+ int path_below) const
252252+{
253253+ if (this == info->static_type)
254254+ process_found_base_class(info, adjustedPtr, path_below);
255255+ else
256256+ {
257257+ typedef const __base_class_type_info* Iter;
258258+ const Iter e = __base_info + __base_count;
259259+ Iter p = __base_info;
260260+ p->has_unambiguous_public_base(info, adjustedPtr, path_below);
261261+ if (++p < e)
262262+ {
263263+ do
264264+ {
265265+ p->has_unambiguous_public_base(info, adjustedPtr, path_below);
266266+ if (info->search_done)
267267+ break;
268268+ } while (++p < e);
269269+ }
270270+ }
271271+}
272272+273273+// Handles bullets 1 and 4 for both pointers and member pointers
274274+bool
275275+__pbase_type_info::can_catch(const __shim_type_info* thrown_type,
276276+ void*&) const
277277+{
278278+ if (this == thrown_type)
279279+ return true;
280280+ return thrown_type == &typeid(std::nullptr_t);
281281+}
282282+283283+#pragma clang diagnostic push
284284+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
285285+286286+// Handles bullets 1, 3 and 4
287287+bool
288288+__pointer_type_info::can_catch(const __shim_type_info* thrown_type,
289289+ void*& adjustedPtr) const
290290+{
291291+ // Do the dereference adjustment
292292+ adjustedPtr = *static_cast<void**>(adjustedPtr);
293293+ // bullets 1 and 4
294294+ if (__pbase_type_info::can_catch(thrown_type, adjustedPtr))
295295+ return true;
296296+ // bullet 3
297297+ const __pointer_type_info* thrown_pointer_type =
298298+ dynamic_cast<const __pointer_type_info*>(thrown_type);
299299+ if (thrown_pointer_type == 0)
300300+ return false;
301301+ // bullet 3B
302302+ if (thrown_pointer_type->__flags & ~__flags)
303303+ return false;
304304+ if (__pointee == thrown_pointer_type->__pointee)
305305+ return true;
306306+ // bullet 3A
307307+ if (__pointee == &typeid(void))
308308+ return true;
309309+ const __class_type_info* catch_class_type =
310310+ dynamic_cast<const __class_type_info*>(__pointee);
311311+ if (catch_class_type == 0)
312312+ return false;
313313+ const __class_type_info* thrown_class_type =
314314+ dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee);
315315+ if (thrown_class_type == 0)
316316+ return false;
317317+ __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0};
318318+ info.number_of_dst_type = 1;
319319+ thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
320320+ if (info.path_dst_ptr_to_static_ptr == public_path)
321321+ {
322322+ adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
323323+ return true;
324324+ }
325325+ return false;
326326+}
327327+328328+#pragma clang diagnostic pop
329329+330330+#pragma GCC visibility pop
331331+#pragma GCC visibility push(default)
332332+333333+#pragma clang diagnostic push
334334+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
335335+336336+// __dynamic_cast
337337+338338+// static_ptr: pointer to an object of type static_type; nonnull, and since the
339339+// object is polymorphic, *(void**)static_ptr is a virtual table pointer.
340340+// static_ptr is &v in the expression dynamic_cast<T>(v).
341341+// static_type: static type of the object pointed to by static_ptr.
342342+// dst_type: destination type of the cast (the "T" in "dynamic_cast<T>(v)").
343343+// src2dst_offset: a static hint about the location of the
344344+// source subobject with respect to the complete object;
345345+// special negative values are:
346346+// -1: no hint
347347+// -2: static_type is not a public base of dst_type
348348+// -3: static_type is a multiple public base type but never a
349349+// virtual base type
350350+// otherwise, the static_type type is a unique public nonvirtual
351351+// base type of dst_type at offset src2dst_offset from the
352352+// origin of dst_type.
353353+//
354354+// (dynamic_ptr, dynamic_type) are the run time type of the complete object
355355+// referred to by static_ptr and a pointer to it. These can be found from
356356+// static_ptr for polymorphic types.
357357+// static_type is guaranteed to be a polymorphic type.
358358+//
359359+// (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward. Each
360360+// node of the tree represents a base class/object of its parent (or parents) below.
361361+// Each node is uniquely represented by a pointer to the object, and a pointer
362362+// to a type_info - its type. Different nodes may have the same pointer and
363363+// different nodes may have the same type. But only one node has a specific
364364+// (pointer-value, type) pair. In C++ two objects of the same type can not
365365+// share the same address.
366366+//
367367+// There are two flavors of nodes which have the type dst_type:
368368+// 1. Those that are derived from (below) (static_ptr, static_type).
369369+// 2. Those that are not derived from (below) (static_ptr, static_type).
370370+//
371371+// Invariants of the DAG:
372372+//
373373+// There is at least one path from the root (dynamic_ptr, dynamic_type) to
374374+// the node (static_ptr, static_type). This path may or may not be public.
375375+// There may be more than one such path (some public some not). Such a path may
376376+// or may not go through a node having type dst_type.
377377+//
378378+// No node of type T appears above a node of the same type. That means that
379379+// there is only one node with dynamic_type. And if dynamic_type == dst_type,
380380+// then there is only one dst_type in the DAG.
381381+//
382382+// No node of type dst_type appears above a node of type static_type. Such
383383+// DAG's are possible in C++, but the compiler computes those dynamic_casts at
384384+// compile time, and only calls __dynamic_cast when dst_type lies below
385385+// static_type in the DAG.
386386+//
387387+// dst_type != static_type: The compiler computes the dynamic_cast in this case too.
388388+// dynamic_type != static_type: The compiler computes the dynamic_cast in this case too.
389389+//
390390+// Returns:
391391+//
392392+// If there is exactly one dst_type of flavor 1, and
393393+// If there is a public path from that dst_type to (static_ptr, static_type), or
394394+// If there are 0 dst_types of flavor 2, and there is a public path from
395395+// (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public
396396+// path from (dynamic_ptr, dynamic_type) to the one dst_type, then return
397397+// a pointer to that dst_type.
398398+// Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and
399399+// if there is a public path from (dynamic_ptr, dynamic_type) to
400400+// (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type)
401401+// to the one dst_type, then return a pointer to that one dst_type.
402402+// Else return nullptr.
403403+//
404404+// If dynamic_type == dst_type, then the above algorithm collapses to the
405405+// following cheaper algorithm:
406406+//
407407+// If there is a public path from (dynamic_ptr, dynamic_type) to
408408+// (static_ptr, static_type), then return dynamic_ptr.
409409+// Else return nullptr.
410410+extern "C"
411411+void*
412412+__dynamic_cast(const void* static_ptr,
413413+ const __class_type_info* static_type,
414414+ const __class_type_info* dst_type,
415415+ std::ptrdiff_t src2dst_offset)
416416+{
417417+ // Possible future optimization: Take advantage of src2dst_offset
418418+ // Currently clang always sets src2dst_offset to -1 (no hint).
419419+420420+ // Get (dynamic_ptr, dynamic_type) from static_ptr
421421+ void** vtable = *(void***)static_ptr;
422422+ ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);
423423+ const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
424424+ const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);
425425+426426+ // Initialize answer to nullptr. This will be changed from the search
427427+ // results if a non-null answer is found. Regardless, this is what will
428428+ // be returned.
429429+ const void* dst_ptr = 0;
430430+ // Initialize info struct for this search.
431431+ __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
432432+433433+ // Find out if we can use a giant short cut in the search
434434+ if (dynamic_type == dst_type)
435435+ {
436436+ // Using giant short cut. Add that information to info.
437437+ info.number_of_dst_type = 1;
438438+ // Do the search
439439+ dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path);
440440+ // Query the search.
441441+ if (info.path_dst_ptr_to_static_ptr == public_path)
442442+ dst_ptr = dynamic_ptr;
443443+ }
444444+ else
445445+ {
446446+ // Not using giant short cut. Do the search
447447+ dynamic_type->search_below_dst(&info, dynamic_ptr, public_path);
448448+ // Query the search.
449449+ switch (info.number_to_static_ptr)
450450+ {
451451+ case 0:
452452+ if (info.number_to_dst_ptr == 1 &&
453453+ info.path_dynamic_ptr_to_static_ptr == public_path &&
454454+ info.path_dynamic_ptr_to_dst_ptr == public_path)
455455+ dst_ptr = info.dst_ptr_not_leading_to_static_ptr;
456456+ break;
457457+ case 1:
458458+ if (info.path_dst_ptr_to_static_ptr == public_path ||
459459+ (
460460+ info.number_to_dst_ptr == 0 &&
461461+ info.path_dynamic_ptr_to_static_ptr == public_path &&
462462+ info.path_dynamic_ptr_to_dst_ptr == public_path
463463+ )
464464+ )
465465+ dst_ptr = info.dst_ptr_leading_to_static_ptr;
466466+ break;
467467+ }
468468+ }
469469+ return const_cast<void*>(dst_ptr);
470470+}
471471+472472+#pragma clang diagnostic pop
473473+474474+#pragma GCC visibility pop
475475+#pragma GCC visibility push(hidden)
476476+477477+// Call this function when you hit a static_type which is a base (above) a dst_type.
478478+// Let caller know you hit a static_type. But only start recording details if
479479+// this is (static_ptr, static_type) -- the node we are casting from.
480480+// If this is (static_ptr, static_type)
481481+// Record the path (public or not) from the dst_type to here. There may be
482482+// multiple paths from the same dst_type to here, record the "most public" one.
483483+// Record the dst_ptr as pointing to (static_ptr, static_type).
484484+// If more than one (dst_ptr, dst_type) points to (static_ptr, static_type),
485485+// then mark this dyanmic_cast as ambiguous and stop the search.
486486+void
487487+__class_type_info::process_static_type_above_dst(__dynamic_cast_info* info,
488488+ const void* dst_ptr,
489489+ const void* current_ptr,
490490+ int path_below) const
491491+{
492492+ // Record that we found a static_type
493493+ info->found_any_static_type = true;
494494+ if (current_ptr == info->static_ptr)
495495+ {
496496+ // Record that we found (static_ptr, static_type)
497497+ info->found_our_static_ptr = true;
498498+ if (info->dst_ptr_leading_to_static_ptr == 0)
499499+ {
500500+ // First time here
501501+ info->dst_ptr_leading_to_static_ptr = dst_ptr;
502502+ info->path_dst_ptr_to_static_ptr = path_below;
503503+ info->number_to_static_ptr = 1;
504504+ // If there is only one dst_type in the entire tree and the path from
505505+ // there to here is public then we are done!
506506+ if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
507507+ info->search_done = true;
508508+ }
509509+ else if (info->dst_ptr_leading_to_static_ptr == dst_ptr)
510510+ {
511511+ // We've been here before. Update path to "most public"
512512+ if (info->path_dst_ptr_to_static_ptr == not_public_path)
513513+ info->path_dst_ptr_to_static_ptr = path_below;
514514+ // If there is only one dst_type in the entire tree and the path from
515515+ // there to here is public then we are done!
516516+ if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
517517+ info->search_done = true;
518518+ }
519519+ else
520520+ {
521521+ // We've detected an ambiguous cast from (static_ptr, static_type)
522522+ // to a dst_type
523523+ info->number_to_static_ptr += 1;
524524+ info->search_done = true;
525525+ }
526526+ }
527527+}
528528+529529+// Call this function when you hit a static_type which is not a base (above) a dst_type.
530530+// If this is (static_ptr, static_type)
531531+// Record the path (public or not) from (dynamic_ptr, dynamic_type) to here. There may be
532532+// multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one.
533533+void
534534+__class_type_info::process_static_type_below_dst(__dynamic_cast_info* info,
535535+ const void* current_ptr,
536536+ int path_below) const
537537+{
538538+ if (current_ptr == info->static_ptr)
539539+ {
540540+ // Record the most public path from (dynamic_ptr, dynamic_type) to
541541+ // (static_ptr, static_type)
542542+ if (info->path_dynamic_ptr_to_static_ptr != public_path)
543543+ info->path_dynamic_ptr_to_static_ptr = path_below;
544544+ }
545545+}
546546+547547+// Call this function when searching below a dst_type node. This function searches
548548+// for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes.
549549+// If it finds a static_type node, there is no need to further search base classes
550550+// above.
551551+// If it finds a dst_type node it should search base classes using search_above_dst
552552+// to find out if this dst_type points to (static_ptr, static_type) or not.
553553+// Either way, the dst_type is recorded as one of two "flavors": one that does
554554+// or does not point to (static_ptr, static_type).
555555+// If this is neither a static_type nor a dst_type node, continue searching
556556+// base classes above.
557557+// All the hoopla surrounding the search code is doing nothing but looking for
558558+// excuses to stop the search prematurely (break out of the for-loop). That is,
559559+// the algorithm below is simply an optimization of this:
560560+// void
561561+// __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,
562562+// const void* current_ptr,
563563+// int path_below) const
564564+// {
565565+// typedef const __base_class_type_info* Iter;
566566+// if (this == info->static_type)
567567+// process_static_type_below_dst(info, current_ptr, path_below);
568568+// else if (this == info->dst_type)
569569+// {
570570+// // Record the most public access path that got us here
571571+// if (info->path_dynamic_ptr_to_dst_ptr != public_path)
572572+// info->path_dynamic_ptr_to_dst_ptr = path_below;
573573+// bool does_dst_type_point_to_our_static_type = false;
574574+// for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p)
575575+// {
576576+// p->search_above_dst(info, current_ptr, current_ptr, public_path);
577577+// if (info->found_our_static_ptr)
578578+// does_dst_type_point_to_our_static_type = true;
579579+// // break out early here if you can detect it doesn't matter if you do
580580+// }
581581+// if (!does_dst_type_point_to_our_static_type)
582582+// {
583583+// // We found a dst_type that doesn't point to (static_ptr, static_type)
584584+// // So record the address of this dst_ptr and increment the
585585+// // count of the number of such dst_types found in the tree.
586586+// info->dst_ptr_not_leading_to_static_ptr = current_ptr;
587587+// info->number_to_dst_ptr += 1;
588588+// }
589589+// }
590590+// else
591591+// {
592592+// // This is not a static_type and not a dst_type.
593593+// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)
594594+// {
595595+// p->search_below_dst(info, current_ptr, public_path);
596596+// // break out early here if you can detect it doesn't matter if you do
597597+// }
598598+// }
599599+// }
600600+void
601601+__vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,
602602+ const void* current_ptr,
603603+ int path_below) const
604604+{
605605+ typedef const __base_class_type_info* Iter;
606606+ if (this == info->static_type)
607607+ process_static_type_below_dst(info, current_ptr, path_below);
608608+ else if (this == info->dst_type)
609609+ {
610610+ // We've been here before if we've recorded current_ptr in one of these
611611+ // two places:
612612+ if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
613613+ current_ptr == info->dst_ptr_not_leading_to_static_ptr)
614614+ {
615615+ // We've seen this node before, and therefore have already searched
616616+ // its base classes above.
617617+ // Update path to here that is "most public".
618618+ if (path_below == public_path)
619619+ info->path_dynamic_ptr_to_dst_ptr = public_path;
620620+ }
621621+ else // We have haven't been here before
622622+ {
623623+ // Record the access path that got us here
624624+ // If there is more than one dst_type this path doesn't matter.
625625+ info->path_dynamic_ptr_to_dst_ptr = path_below;
626626+ // Only search above here if dst_type derives from static_type, or
627627+ // if it is unknown if dst_type derives from static_type.
628628+ if (info->is_dst_type_derived_from_static_type != no)
629629+ {
630630+ // Set up flags to record results from all base classes
631631+ bool is_dst_type_derived_from_static_type = false;
632632+ bool does_dst_type_point_to_our_static_type = false;
633633+ // We've found a dst_type with a potentially public path to here.
634634+ // We have to assume the path is public because it may become
635635+ // public later (if we get back to here with a public path).
636636+ // We can stop looking above if:
637637+ // 1. We've found a public path to (static_ptr, static_type).
638638+ // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.
639639+ // This is detected at the (static_ptr, static_type).
640640+ // 3. We can prove that there is no public path to (static_ptr, static_type)
641641+ // above here.
642642+ const Iter e = __base_info + __base_count;
643643+ for (Iter p = __base_info; p < e; ++p)
644644+ {
645645+ // Zero out found flags
646646+ info->found_our_static_ptr = false;
647647+ info->found_any_static_type = false;
648648+ p->search_above_dst(info, current_ptr, current_ptr, public_path);
649649+ if (info->search_done)
650650+ break;
651651+ if (info->found_any_static_type)
652652+ {
653653+ is_dst_type_derived_from_static_type = true;
654654+ if (info->found_our_static_ptr)
655655+ {
656656+ does_dst_type_point_to_our_static_type = true;
657657+ // If we found what we're looking for, stop looking above.
658658+ if (info->path_dst_ptr_to_static_ptr == public_path)
659659+ break;
660660+ // We found a private path to (static_ptr, static_type)
661661+ // If there is no diamond then there is only one path
662662+ // to (static_ptr, static_type) and we just found it.
663663+ if (!(__flags & __diamond_shaped_mask))
664664+ break;
665665+ }
666666+ else
667667+ {
668668+ // If we found a static_type that isn't the one we're looking
669669+ // for, and if there are no repeated types above here,
670670+ // then stop looking.
671671+ if (!(__flags & __non_diamond_repeat_mask))
672672+ break;
673673+ }
674674+ }
675675+ }
676676+ if (!does_dst_type_point_to_our_static_type)
677677+ {
678678+ // We found a dst_type that doesn't point to (static_ptr, static_type)
679679+ // So record the address of this dst_ptr and increment the
680680+ // count of the number of such dst_types found in the tree.
681681+ info->dst_ptr_not_leading_to_static_ptr = current_ptr;
682682+ info->number_to_dst_ptr += 1;
683683+ // If there exists another dst with a private path to
684684+ // (static_ptr, static_type), then the cast from
685685+ // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous,
686686+ // so stop search.
687687+ if (info->number_to_static_ptr == 1 &&
688688+ info->path_dst_ptr_to_static_ptr == not_public_path)
689689+ info->search_done = true;
690690+ }
691691+ // If we found no static_type,s then dst_type doesn't derive
692692+ // from static_type, else it does. Record this result so that
693693+ // next time we hit a dst_type we will know not to search above
694694+ // it if it doesn't derive from static_type.
695695+ if (is_dst_type_derived_from_static_type)
696696+ info->is_dst_type_derived_from_static_type = yes;
697697+ else
698698+ info->is_dst_type_derived_from_static_type = no;
699699+ }
700700+ }
701701+ }
702702+ else
703703+ {
704704+ // This is not a static_type and not a dst_type.
705705+ const Iter e = __base_info + __base_count;
706706+ Iter p = __base_info;
707707+ p->search_below_dst(info, current_ptr, path_below);
708708+ if (++p < e)
709709+ {
710710+ if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1)
711711+ {
712712+ // If there are multiple paths to a base above from here, or if
713713+ // a dst_type pointing to (static_ptr, static_type) has been found,
714714+ // then there is no way to break out of this loop early unless
715715+ // something below detects the search is done.
716716+ do
717717+ {
718718+ if (info->search_done)
719719+ break;
720720+ p->search_below_dst(info, current_ptr, path_below);
721721+ } while (++p < e);
722722+ }
723723+ else if (__flags & __non_diamond_repeat_mask)
724724+ {
725725+ // There are not multiple paths to any base class from here and a
726726+ // dst_type pointing to (static_ptr, static_type) has not yet been
727727+ // found.
728728+ do
729729+ {
730730+ if (info->search_done)
731731+ break;
732732+ // If we just found a dst_type with a public path to (static_ptr, static_type),
733733+ // then the only reason to continue the search is to make sure
734734+ // no other dst_type points to (static_ptr, static_type).
735735+ // If !diamond, then we don't need to search here.
736736+ if (info->number_to_static_ptr == 1 &&
737737+ info->path_dst_ptr_to_static_ptr == public_path)
738738+ break;
739739+ p->search_below_dst(info, current_ptr, path_below);
740740+ } while (++p < e);
741741+ }
742742+ else
743743+ {
744744+ // There are no repeated types above this node.
745745+ // There are no nodes with multiple parents above this node.
746746+ // no dst_type has been found to (static_ptr, static_type)
747747+ do
748748+ {
749749+ if (info->search_done)
750750+ break;
751751+ // If we just found a dst_type with a public path to (static_ptr, static_type),
752752+ // then the only reason to continue the search is to make sure sure
753753+ // no other dst_type points to (static_ptr, static_type).
754754+ // If !diamond, then we don't need to search here.
755755+ // if we just found a dst_type with a private path to (static_ptr, static_type),
756756+ // then we're only looking for a public path to (static_ptr, static_type)
757757+ // and to check for other dst_types.
758758+ // If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type)
759759+ // and not a dst_type under here.
760760+ if (info->number_to_static_ptr == 1)
761761+ break;
762762+ p->search_below_dst(info, current_ptr, path_below);
763763+ } while (++p < e);
764764+ }
765765+ }
766766+ }
767767+}
768768+769769+// This is the same algorithm as __vmi_class_type_info::search_below_dst but
770770+// simplified to the case that there is only a single base class.
771771+void
772772+__si_class_type_info::search_below_dst(__dynamic_cast_info* info,
773773+ const void* current_ptr,
774774+ int path_below) const
775775+{
776776+ if (this == info->static_type)
777777+ process_static_type_below_dst(info, current_ptr, path_below);
778778+ else if (this == info->dst_type)
779779+ {
780780+ // We've been here before if we've recorded current_ptr in one of these
781781+ // two places:
782782+ if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
783783+ current_ptr == info->dst_ptr_not_leading_to_static_ptr)
784784+ {
785785+ // We've seen this node before, and therefore have already searched
786786+ // its base classes above.
787787+ // Update path to here that is "most public".
788788+ if (path_below == public_path)
789789+ info->path_dynamic_ptr_to_dst_ptr = public_path;
790790+ }
791791+ else // We have haven't been here before
792792+ {
793793+ // Record the access path that got us here
794794+ // If there is more than one dst_type this path doesn't matter.
795795+ info->path_dynamic_ptr_to_dst_ptr = path_below;
796796+ // Only search above here if dst_type derives from static_type, or
797797+ // if it is unknown if dst_type derives from static_type.
798798+ if (info->is_dst_type_derived_from_static_type != no)
799799+ {
800800+ // Set up flags to record results from all base classes
801801+ bool is_dst_type_derived_from_static_type = false;
802802+ bool does_dst_type_point_to_our_static_type = false;
803803+ // Zero out found flags
804804+ info->found_our_static_ptr = false;
805805+ info->found_any_static_type = false;
806806+ __base_type->search_above_dst(info, current_ptr, current_ptr, public_path);
807807+ if (info->found_any_static_type)
808808+ {
809809+ is_dst_type_derived_from_static_type = true;
810810+ if (info->found_our_static_ptr)
811811+ does_dst_type_point_to_our_static_type = true;
812812+ }
813813+ if (!does_dst_type_point_to_our_static_type)
814814+ {
815815+ // We found a dst_type that doesn't point to (static_ptr, static_type)
816816+ // So record the address of this dst_ptr and increment the
817817+ // count of the number of such dst_types found in the tree.
818818+ info->dst_ptr_not_leading_to_static_ptr = current_ptr;
819819+ info->number_to_dst_ptr += 1;
820820+ // If there exists another dst with a private path to
821821+ // (static_ptr, static_type), then the cast from
822822+ // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.
823823+ if (info->number_to_static_ptr == 1 &&
824824+ info->path_dst_ptr_to_static_ptr == not_public_path)
825825+ info->search_done = true;
826826+ }
827827+ // If we found no static_type,s then dst_type doesn't derive
828828+ // from static_type, else it does. Record this result so that
829829+ // next time we hit a dst_type we will know not to search above
830830+ // it if it doesn't derive from static_type.
831831+ if (is_dst_type_derived_from_static_type)
832832+ info->is_dst_type_derived_from_static_type = yes;
833833+ else
834834+ info->is_dst_type_derived_from_static_type = no;
835835+ }
836836+ }
837837+ }
838838+ else
839839+ {
840840+ // This is not a static_type and not a dst_type
841841+ __base_type->search_below_dst(info, current_ptr, path_below);
842842+ }
843843+}
844844+845845+// This is the same algorithm as __vmi_class_type_info::search_below_dst but
846846+// simplified to the case that there is no base class.
847847+void
848848+__class_type_info::search_below_dst(__dynamic_cast_info* info,
849849+ const void* current_ptr,
850850+ int path_below) const
851851+{
852852+ typedef const __base_class_type_info* Iter;
853853+ if (this == info->static_type)
854854+ process_static_type_below_dst(info, current_ptr, path_below);
855855+ else if (this == info->dst_type)
856856+ {
857857+ // We've been here before if we've recorded current_ptr in one of these
858858+ // two places:
859859+ if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
860860+ current_ptr == info->dst_ptr_not_leading_to_static_ptr)
861861+ {
862862+ // We've seen this node before, and therefore have already searched
863863+ // its base classes above.
864864+ // Update path to here that is "most public".
865865+ if (path_below == public_path)
866866+ info->path_dynamic_ptr_to_dst_ptr = public_path;
867867+ }
868868+ else // We have haven't been here before
869869+ {
870870+ // Record the access path that got us here
871871+ // If there is more than one dst_type this path doesn't matter.
872872+ info->path_dynamic_ptr_to_dst_ptr = path_below;
873873+ // We found a dst_type that doesn't point to (static_ptr, static_type)
874874+ // So record the address of this dst_ptr and increment the
875875+ // count of the number of such dst_types found in the tree.
876876+ info->dst_ptr_not_leading_to_static_ptr = current_ptr;
877877+ info->number_to_dst_ptr += 1;
878878+ // If there exists another dst with a private path to
879879+ // (static_ptr, static_type), then the cast from
880880+ // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.
881881+ if (info->number_to_static_ptr == 1 &&
882882+ info->path_dst_ptr_to_static_ptr == not_public_path)
883883+ info->search_done = true;
884884+ // We found that dst_type does not derive from static_type
885885+ info->is_dst_type_derived_from_static_type = no;
886886+ }
887887+ }
888888+}
889889+890890+// Call this function when searching above a dst_type node. This function searches
891891+// for a public path to (static_ptr, static_type).
892892+// This function is guaranteed not to find a node of type dst_type.
893893+// Theoretically this is a very simple function which just stops if it finds a
894894+// static_type node: All the hoopla surrounding the search code is doing
895895+// nothing but looking for excuses to stop the search prematurely (break out of
896896+// the for-loop). That is, the algorithm below is simply an optimization of this:
897897+// void
898898+// __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,
899899+// const void* dst_ptr,
900900+// const void* current_ptr,
901901+// int path_below) const
902902+// {
903903+// if (this == info->static_type)
904904+// process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
905905+// else
906906+// {
907907+// typedef const __base_class_type_info* Iter;
908908+// // This is not a static_type and not a dst_type
909909+// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)
910910+// {
911911+// p->search_above_dst(info, dst_ptr, current_ptr, public_path);
912912+// // break out early here if you can detect it doesn't matter if you do
913913+// }
914914+// }
915915+// }
916916+void
917917+__vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,
918918+ const void* dst_ptr,
919919+ const void* current_ptr,
920920+ int path_below) const
921921+{
922922+ if (this == info->static_type)
923923+ process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
924924+ else
925925+ {
926926+ typedef const __base_class_type_info* Iter;
927927+ // This is not a static_type and not a dst_type
928928+ // Save flags so they can be restored when returning to nodes below.
929929+ bool found_our_static_ptr = info->found_our_static_ptr;
930930+ bool found_any_static_type = info->found_any_static_type;
931931+ // We've found a dst_type below with a path to here. If the path
932932+ // to here is not public, there may be another path to here that
933933+ // is public. So we have to assume that the path to here is public.
934934+ // We can stop looking above if:
935935+ // 1. We've found a public path to (static_ptr, static_type).
936936+ // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.
937937+ // This is detected at the (static_ptr, static_type).
938938+ // 3. We can prove that there is no public path to (static_ptr, static_type)
939939+ // above here.
940940+ const Iter e = __base_info + __base_count;
941941+ Iter p = __base_info;
942942+ // Zero out found flags
943943+ info->found_our_static_ptr = false;
944944+ info->found_any_static_type = false;
945945+ p->search_above_dst(info, dst_ptr, current_ptr, path_below);
946946+ if (++p < e)
947947+ {
948948+ do
949949+ {
950950+ if (info->search_done)
951951+ break;
952952+ if (info->found_our_static_ptr)
953953+ {
954954+ // If we found what we're looking for, stop looking above.
955955+ if (info->path_dst_ptr_to_static_ptr == public_path)
956956+ break;
957957+ // We found a private path to (static_ptr, static_type)
958958+ // If there is no diamond then there is only one path
959959+ // to (static_ptr, static_type) from here and we just found it.
960960+ if (!(__flags & __diamond_shaped_mask))
961961+ break;
962962+ }
963963+ else if (info->found_any_static_type)
964964+ {
965965+ // If we found a static_type that isn't the one we're looking
966966+ // for, and if there are no repeated types above here,
967967+ // then stop looking.
968968+ if (!(__flags & __non_diamond_repeat_mask))
969969+ break;
970970+ }
971971+ // Zero out found flags
972972+ info->found_our_static_ptr = false;
973973+ info->found_any_static_type = false;
974974+ p->search_above_dst(info, dst_ptr, current_ptr, path_below);
975975+ } while (++p < e);
976976+ }
977977+ // Restore flags
978978+ info->found_our_static_ptr = found_our_static_ptr;
979979+ info->found_any_static_type = found_any_static_type;
980980+ }
981981+}
982982+983983+// This is the same algorithm as __vmi_class_type_info::search_above_dst but
984984+// simplified to the case that there is only a single base class.
985985+void
986986+__si_class_type_info::search_above_dst(__dynamic_cast_info* info,
987987+ const void* dst_ptr,
988988+ const void* current_ptr,
989989+ int path_below) const
990990+{
991991+ if (this == info->static_type)
992992+ process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
993993+ else
994994+ __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below);
995995+}
996996+997997+// This is the same algorithm as __vmi_class_type_info::search_above_dst but
998998+// simplified to the case that there is no base class.
999999+void
10001000+__class_type_info::search_above_dst(__dynamic_cast_info* info,
10011001+ const void* dst_ptr,
10021002+ const void* current_ptr,
10031003+ int path_below) const
10041004+{
10051005+ if (this == info->static_type)
10061006+ process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
10071007+}
10081008+10091009+// The search functions for __base_class_type_info are simply convenience
10101010+// functions for adjusting the current_ptr and path_below as the search is
10111011+// passed up to the base class node.
10121012+10131013+void
10141014+__base_class_type_info::search_above_dst(__dynamic_cast_info* info,
10151015+ const void* dst_ptr,
10161016+ const void* current_ptr,
10171017+ int path_below) const
10181018+{
10191019+ ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
10201020+ if (__offset_flags & __virtual_mask)
10211021+ {
10221022+ const char* vtable = *static_cast<const char*const*>(current_ptr);
10231023+ offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
10241024+ }
10251025+ __base_type->search_above_dst(info, dst_ptr,
10261026+ static_cast<const char*>(current_ptr) + offset_to_base,
10271027+ (__offset_flags & __public_mask) ?
10281028+ path_below :
10291029+ not_public_path);
10301030+}
10311031+10321032+void
10331033+__base_class_type_info::search_below_dst(__dynamic_cast_info* info,
10341034+ const void* current_ptr,
10351035+ int path_below) const
10361036+{
10371037+ ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
10381038+ if (__offset_flags & __virtual_mask)
10391039+ {
10401040+ const char* vtable = *static_cast<const char*const*>(current_ptr);
10411041+ offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
10421042+ }
10431043+ __base_type->search_below_dst(info,
10441044+ static_cast<const char*>(current_ptr) + offset_to_base,
10451045+ (__offset_flags & __public_mask) ?
10461046+ path_below :
10471047+ not_public_path);
10481048+}
10491049+10501050+#pragma GCC visibility pop
10511051+10521052+} // __cxxabiv1
···11+//===----------------------------- typeinfo.cpp ---------------------------===//
22+//
33+// The LLVM Compiler Infrastructure
44+//
55+// This file is dual licensed under the MIT and the University of Illinois Open
66+// Source Licenses. See LICENSE.TXT for details.
77+//
88+//===----------------------------------------------------------------------===//
99+1010+#include <typeinfo>
1111+1212+namespace std
1313+{
1414+1515+// type_info
1616+1717+type_info::~type_info()
1818+{
1919+}
2020+2121+// bad_cast
2222+2323+bad_cast::bad_cast() _NOEXCEPT
2424+{
2525+}
2626+2727+bad_cast::~bad_cast() _NOEXCEPT
2828+{
2929+}
3030+3131+const char*
3232+bad_cast::what() const _NOEXCEPT
3333+{
3434+ return "std::bad_cast";
3535+}
3636+3737+// bad_typeid
3838+3939+bad_typeid::bad_typeid() _NOEXCEPT
4040+{
4141+}
4242+4343+bad_typeid::~bad_typeid() _NOEXCEPT
4444+{
4545+}
4646+4747+const char*
4848+bad_typeid::what() const _NOEXCEPT
4949+{
5050+ return "std::bad_typeid";
5151+}
5252+5353+} // std
+155
src/libunwind-darwin-gcc/src-unwind/darwin-crt2.c
···11+/* KeyMgr backwards-compatibility support for Darwin.
22+ Copyright (C) 2001, 2002, 2004, 2009 Free Software Foundation, Inc.
33+44+This file is part of GCC.
55+66+GCC is free software; you can redistribute it and/or modify it under
77+the terms of the GNU General Public License as published by the Free
88+Software Foundation; either version 3, or (at your option) any later
99+version.
1010+1111+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1212+WARRANTY; without even the implied warranty of MERCHANTABILITY or
1313+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1414+for more details.
1515+1616+Under Section 7 of GPL version 3, you are granted additional
1717+permissions described in the GCC Runtime Library Exception, version
1818+3.1, as published by the Free Software Foundation.
1919+2020+You should have received a copy of the GNU General Public License and
2121+a copy of the GCC Runtime Library Exception along with this program;
2222+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2323+<http://www.gnu.org/licenses/>. */
2424+2525+/* It is incorrect to include config.h here, because this file is being
2626+ compiled for the target, and hence definitions concerning only the host
2727+ do not apply. */
2828+2929+#include "tconfig.h"
3030+#include "tsystem.h"
3131+3232+/* This file doesn't do anything useful on non-powerpc targets, since they
3333+ don't have backwards compatibility anyway. */
3434+3535+//#ifdef __ppc__
3636+3737+/* Homemade decls substituting for getsect.h and dyld.h, so cross
3838+ compilation works. */
3939+struct mach_header;
4040+extern char *getsectdatafromheader (struct mach_header *, const char *,
4141+ const char *, unsigned long *);
4242+extern void _dyld_register_func_for_add_image
4343+ (void (*) (struct mach_header *, unsigned long));
4444+extern void _dyld_register_func_for_remove_image
4545+ (void (*) (struct mach_header *, unsigned long));
4646+4747+__attribute__((constructor))
4848+static void __darwin_gcc3_preregister_frame_info (void);
4949+5050+/* These are from "keymgr.h". */
5151+// extern void _init_keymgr (void);
5252+extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
5353+extern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr);
5454+5555+//extern void *__keymgr_global[];
5656+typedef struct _Sinfo_Node {
5757+ unsigned int size ; /*size of this node*/
5858+ unsigned short major_version ; /*API major version.*/
5959+ unsigned short minor_version ; /*API minor version.*/
6060+ } _Tinfo_Node ;
6161+6262+/* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */
6363+#define KEYMGR_API_MAJOR_GCC3 3
6464+/* ... with these keys. */
6565+#define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */
6666+#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */
6767+6868+/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */
6969+struct live_images {
7070+ unsigned long this_size; /* sizeof (live_images) */
7171+ struct mach_header *mh; /* the image info */
7272+ unsigned long vm_slide;
7373+ void (*destructor)(struct live_images *); /* destructor for this */
7474+ struct live_images *next;
7575+ unsigned int examined_p;
7676+ void *fde;
7777+ void *object_info;
7878+ unsigned long info[2]; /* Future use. */
7979+};
8080+8181+8282+/* These routines are used only on Darwin versions before 10.2.
8383+ Later versions have equivalent code in the system.
8484+ Eventually, they might go away, although it might be a long time... */
8585+8686+static void darwin_unwind_dyld_remove_image_hook
8787+ (struct mach_header *m, unsigned long s);
8888+static void darwin_unwind_dyld_remove_image_hook
8989+ (struct mach_header *m, unsigned long s);
9090+extern void __darwin_gcc3_preregister_frame_info (void);
9191+9292+static void
9393+darwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide)
9494+{
9595+ struct live_images *l = (struct live_images *)calloc (1, sizeof (*l));
9696+ l->mh = mh;
9797+ l->vm_slide = slide;
9898+ l->this_size = sizeof (*l);
9999+ l->next = (struct live_images *)
100100+ _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
101101+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l);
102102+}
103103+104104+static void
105105+darwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s)
106106+{
107107+ struct live_images *top, **lip, *destroy = NULL;
108108+109109+ /* Look for it in the list of live images and delete it. */
110110+111111+ top = (struct live_images *)
112112+ _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
113113+ for (lip = ⊤ *lip != NULL; lip = &(*lip)->next)
114114+ {
115115+ if ((*lip)->mh == m && (*lip)->vm_slide == s)
116116+ {
117117+ destroy = *lip;
118118+ *lip = destroy->next; /* unlink DESTROY */
119119+120120+ if (destroy->this_size != sizeof (*destroy)) /* sanity check */
121121+ abort ();
122122+123123+ break;
124124+ }
125125+ }
126126+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top);
127127+128128+ /* Now that we have unlinked this from the image list, toss it. */
129129+ if (destroy != NULL)
130130+ {
131131+ if (destroy->destructor != NULL)
132132+ (*destroy->destructor) (destroy);
133133+ free (destroy);
134134+ }
135135+}
136136+137137+void
138138+__darwin_gcc3_preregister_frame_info (void)
139139+{
140140+#if 0
141141+ const _Tinfo_Node *info;
142142+ _init_keymgr ();
143143+ info = (_Tinfo_Node *)__keymgr_global[2];
144144+ if (info != NULL)
145145+ {
146146+ if (info->major_version >= KEYMGR_API_MAJOR_GCC3)
147147+ return;
148148+ /* Otherwise, use our own add_image_hooks. */
149149+ }
150150+#endif
151151+ _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook);
152152+ _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook);
153153+}
154154+155155+// #endif /* __ppc__ */
···2525/* This is derived from the C++ ABI for IA-64. Where we diverge
2626 for cross-architecture compatibility are noted with "@@@". */
27272828-#ifndef _UNWIND_H
2929-#define _UNWIND_H
2828+#ifndef _UNWIND_HX
2929+#define _UNWIND_HX
30303131#ifndef HIDE_EXPORTS
3232#pragma GCC visibility push(default)
···4545#if defined(__ia64__) && defined(__hpux__)
4646typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
4747#else
4848-typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
4848+typedef unsigned long _Unwind_Ptr /*__attribute__((__mode__(__pointer__)))*/;
4949#endif
5050-typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
5050+typedef unsigned long _Unwind_Internal_Ptr /*__attribute__((__mode__(__pointer__)))*/;
51515252/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
5353 consumer of an exception. We'll go along with this for now even on
5454 32-bit machines. We'll need to provide some other option for
5555 16-bit machines and for machines with > 8 bits per byte. */
5656-typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
5656+typedef unsigned long long _Unwind_Exception_Class /*__attribute__((__mode__(__DI__)))*/;
57575858/* The unwind interface uses reason codes in several contexts to
5959 identify the reasons for failures or other actions. */
6060-#ifndef __clang__
6060+6161typedef enum
6262{
6363 _URC_NO_REASON = 0,
···7070 _URC_INSTALL_CONTEXT = 7,
7171 _URC_CONTINUE_UNWIND = 8
7272} _Unwind_Reason_Code;
7373-#endif
7373+74747575/* The unwind interface uses a pointer to an exception header object
7676 as its representation of an exception being thrown. In general, the