// GNU D Compiler exception personality routines.
// Copyright (C) 2011-2022 Free Software Foundation, Inc.

// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.

// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

// This code is based on the libstdc++ exception handling routines.

module gcc.deh;

import gcc.unwind;
import gcc.unwind.pe;
import gcc.builtins;
import gcc.config;
import gcc.attributes;

extern(C)
{
    int _d_isbaseof(ClassInfo, ClassInfo) @nogc nothrow pure @safe;
    void _d_createTrace(Throwable, void*);
    void _d_print_throwable(Throwable t);
}

/**
 * Declare all known and handled exception classes.
 * D exceptions -- "GNUCD\0\0\0".
 * C++ exceptions -- "GNUCC++\0"
 * C++ dependent exceptions -- "GNUCC++\x01"
 */
static if (GNU_ARM_EABI_Unwinder)
{
    enum _Unwind_Exception_Class gdcExceptionClass = "GNUCD\0\0\0";
    enum _Unwind_Exception_Class gxxExceptionClass = "GNUCC++\0";
    enum _Unwind_Exception_Class gxxDependentExceptionClass = "GNUCC++\x01";
}
else
{
    enum _Unwind_Exception_Class gdcExceptionClass =
        (cast(_Unwind_Exception_Class)'G' << 56) |
        (cast(_Unwind_Exception_Class)'N' << 48) |
        (cast(_Unwind_Exception_Class)'U' << 40) |
        (cast(_Unwind_Exception_Class)'C' << 32) |
        (cast(_Unwind_Exception_Class)'D' << 24);

    enum _Unwind_Exception_Class gxxExceptionClass =
        (cast(_Unwind_Exception_Class)'G' << 56) |
        (cast(_Unwind_Exception_Class)'N' << 48) |
        (cast(_Unwind_Exception_Class)'U' << 40) |
        (cast(_Unwind_Exception_Class)'C' << 32) |
        (cast(_Unwind_Exception_Class)'C' << 24) |
        (cast(_Unwind_Exception_Class)'+' << 16) |
        (cast(_Unwind_Exception_Class)'+' <<  8) |
        (cast(_Unwind_Exception_Class)0 <<  0);

    enum _Unwind_Exception_Class gxxDependentExceptionClass =
        gxxExceptionClass + 1;
}

/**
 * Checks for GDC exception class.
 */
bool isGdcExceptionClass(_Unwind_Exception_Class c) @nogc
{
    static if (GNU_ARM_EABI_Unwinder)
    {
        return c[0] == gdcExceptionClass[0]
            && c[1] == gdcExceptionClass[1]
            && c[2] == gdcExceptionClass[2]
            && c[3] == gdcExceptionClass[3]
            && c[4] == gdcExceptionClass[4]
            && c[5] == gdcExceptionClass[5]
            && c[6] == gdcExceptionClass[6]
            && c[7] == gdcExceptionClass[7];
    }
    else
    {
        return c == gdcExceptionClass;
    }
}

/**
 * Checks for any C++ exception class.
 */
bool isGxxExceptionClass(_Unwind_Exception_Class c) @nogc
{
    static if (GNU_ARM_EABI_Unwinder)
    {
        return c[0] == gxxExceptionClass[0]
            && c[1] == gxxExceptionClass[1]
            && c[2] == gxxExceptionClass[2]
            && c[3] == gxxExceptionClass[3]
            && c[4] == gxxExceptionClass[4]
            && c[5] == gxxExceptionClass[5]
            && c[6] == gxxExceptionClass[6]
            && (c[7] == gxxExceptionClass[7]
                || c[7] == gxxDependentExceptionClass[7]);
    }
    else
    {
        return c == gxxExceptionClass
            || c == gxxDependentExceptionClass;
    }
}

/**
 * Checks for primary or dependent, but not that it is a C++ exception.
 */
bool isDependentException(_Unwind_Exception_Class c) @nogc
{
    static if (GNU_ARM_EABI_Unwinder)
        return (c[7] == '\x01');
    else
        return (c & 1);
}

/**
 * A D exception object consists of a header, which is a wrapper
 * around an unwind object header with additional D specific
 * information, prefixed by the exception object itself.
 */
struct ExceptionHeader
{
    // Because of a lack of __aligned__ style attribute, our object
    // and the unwind object are the first two fields.
    static if (Throwable.alignof < _Unwind_Exception.alignof)
        ubyte[_Unwind_Exception.alignof - Throwable.alignof] pad;

    // The object being thrown.  The compiled code expects this to
    // be immediately before the generic exception header.
    Throwable object;

    // The generic exception header.
    _Unwind_Exception unwindHeader;

    static assert(unwindHeader.offsetof - object.offsetof == object.sizeof);

    // Cache handler details between Phase 1 and Phase 2.
    static if (GNU_ARM_EABI_Unwinder)
    {
        // Nothing here yet.
    }
    else
    {
        // Which catch was found.
        int handler;

        // Language Specific Data Area for function enclosing the handler.
        const(ubyte)* languageSpecificData;

        // Pointer to catch code.
        _Unwind_Ptr landingPad;

        // Canonical Frame Address (CFA) for the enclosing handler.
        _Unwind_Word canonicalFrameAddress;
    }

    // Stack other thrown exceptions in current thread through here.
    ExceptionHeader* next;

    // Thread local stack of chained exceptions.
    static ExceptionHeader* stack;

    // Pre-allocate storage for 1 instance per thread.
    // Use calloc/free for multiple exceptions in flight.
    static ExceptionHeader ehstorage;

    /**
     * Allocate and initialize an ExceptionHeader.
     */
    static ExceptionHeader* create(Throwable o) @nogc
    {
        auto eh = &ehstorage;

        // Check exception object in use.
        if (eh.object)
        {
            eh = cast(ExceptionHeader*) __builtin_calloc(ExceptionHeader.sizeof, 1);
            // Out of memory while throwing - not much else can be done.
            if (!eh)
                terminate("out of memory", __LINE__);
        }
        eh.object = o;

        eh.unwindHeader.exception_class = gdcExceptionClass;

        return eh;
    }

    /**
     * Free ExceptionHeader that was created by create().
     */
    static void free(ExceptionHeader* eh) @nogc
    {
        __builtin_memset(eh, 0, ExceptionHeader.sizeof);
        if (eh != &ehstorage)
            __builtin_free(eh);
    }

    /**
     * Push this onto stack of chained exceptions.
     */
    void push() @nogc
    {
        next = stack;
        stack = &this;
    }

    /**
     * Pop and return top of chained exception stack.
     */
    static ExceptionHeader* pop() @nogc
    {
        auto eh = stack;
        stack = eh.next;
        return eh;
    }

    /**
     * Save stage1 handler information in the exception object.
     */
    static void save(_Unwind_Exception* unwindHeader,
                     _Unwind_Word cfa, int handler,
                     const(ubyte)* lsda, _Unwind_Ptr landingPad) @nogc
    {
        static if (GNU_ARM_EABI_Unwinder)
        {
            unwindHeader.barrier_cache.sp = cfa;
            unwindHeader.barrier_cache.bitpattern[1] = cast(_uw)handler;
            unwindHeader.barrier_cache.bitpattern[2] = cast(_uw)lsda;
            unwindHeader.barrier_cache.bitpattern[3] = cast(_uw)landingPad;
        }
        else
        {
            ExceptionHeader* eh = toExceptionHeader(unwindHeader);
            eh.canonicalFrameAddress = cfa;
            eh.handler = handler;
            eh.languageSpecificData = lsda;
            eh.landingPad = landingPad;
        }
    }

    /**
     * Restore the catch handler data saved during phase1.
     */
    static void restore(_Unwind_Exception* unwindHeader, out int handler,
                        out const(ubyte)* lsda, out _Unwind_Ptr landingPad,
                        out _Unwind_Word cfa) @nogc
    {
        static if (GNU_ARM_EABI_Unwinder)
        {
            cfa = unwindHeader.barrier_cache.sp;
            handler = cast(int)unwindHeader.barrier_cache.bitpattern[1];
            lsda = cast(ubyte*)unwindHeader.barrier_cache.bitpattern[2];
            landingPad = cast(_Unwind_Ptr)unwindHeader.barrier_cache.bitpattern[3];
        }
        else
        {
            ExceptionHeader* eh = toExceptionHeader(unwindHeader);
            cfa = eh.canonicalFrameAddress;
            handler = eh.handler;
            lsda = eh.languageSpecificData;
            landingPad = cast(_Unwind_Ptr)eh.landingPad;
        }
    }

    /**
     * Convert from pointer to unwindHeader to pointer to ExceptionHeader
     * that it is embedded inside of.
     */
    static ExceptionHeader* toExceptionHeader(_Unwind_Exception* exc) @nogc
    {
        return cast(ExceptionHeader*)(cast(void*)exc - ExceptionHeader.unwindHeader.offsetof);
    }
}

/**
 * Map to C++ std::type_info's virtual functions from D,
 * being careful to not require linking with libstdc++.
 * So it is given a different name.
 */
extern(C++) interface CxxTypeInfo
{
    void dtor1();
    void dtor2();
    bool __is_pointer_p() const;
    bool __is_function_p() const;
    bool __do_catch(const CxxTypeInfo, void**, uint) const;
    bool __do_upcast(const void*, void**) const;
}

/**
 * Structure of a C++ exception, represented as a C structure.
 * See unwind-cxx.h for the full definition.
 */
struct CxaExceptionHeader
{
    union
    {
        CxxTypeInfo exceptionType;
        void* primaryException;
    }
    void function(void*) exceptionDestructor;
    void function() unexpectedHandler;
    void function() terminateHandler;
    CxaExceptionHeader* nextException;
    int handlerCount;

    static if (GNU_ARM_EABI_Unwinder)
    {
        CxaExceptionHeader* nextPropagatingException;
        int propagationCount;
    }
    else
    {
        int handlerSwitchValue;
        const(ubyte)* actionRecord;
        const(ubyte)* languageSpecificData;
        _Unwind_Ptr catchTemp;
        void* adjustedPtr;
    }

    _Unwind_Exception unwindHeader;

    /**
     * There's no saving between phases, so only cache pointer.
     * __cxa_begin_catch expects this to be set.
     */
    static void save(_Unwind_Exception* unwindHeader, void* thrownPtr) @nogc
    {
        static if (GNU_ARM_EABI_Unwinder)
            unwindHeader.barrier_cache.bitpattern[0] = cast(_uw) thrownPtr;
        else
        {
            auto eh = toExceptionHeader(unwindHeader);
            eh.adjustedPtr = thrownPtr;
        }
    }

    /**
     * Get pointer to the thrown object if the thrown object type behind the
     * exception is implicitly convertible to the catch type.
     */
    static void* getAdjustedPtr(_Unwind_Exception* exc, CxxTypeInfo catchType)
    {
        void* thrownPtr;

        // A dependent C++ exceptions is just a wrapper around the unwind header.
        // A primary C++ exception has the thrown object located immediately after it.
        if (isDependentException(exc.exception_class))
            thrownPtr = toExceptionHeader(exc).primaryException;
        else
            thrownPtr = cast(void*)(exc + 1);

        // Pointer types need to adjust the actual pointer, not the pointer that is
        // the exception object.  This also has the effect of passing pointer types
        // "by value" through the __cxa_begin_catch return value.
        const throw_type = (cast(CxaExceptionHeader*)thrownPtr - 1).exceptionType;

        if (throw_type.__is_pointer_p())
            thrownPtr = *cast(void**)thrownPtr;

        // Pointer adjustment may be necessary due to multiple inheritance
        if (catchType is throw_type
            || catchType.__do_catch(throw_type, &thrownPtr, 1))
            return thrownPtr;

        return null;
    }

    /**
     * Convert from pointer to unwindHeader to pointer to CxaExceptionHeader
     * that it is embedded inside of.
     */
    static CxaExceptionHeader* toExceptionHeader(_Unwind_Exception* exc) @nogc
    {
        return cast(CxaExceptionHeader*)(exc + 1) - 1;
    }
}

/**
 * Called if exception handling must be abandoned for any reason.
 */
private void terminate(string msg, uint line) @nogc
{
    import core.stdc.stdio;
    import core.stdc.stdlib;

    static bool terminating;
    if (terminating)
    {
        fputs("terminate called recursively\n", stderr);
        abort();
    }
    terminating = true;

    fprintf(stderr, "gcc.deh(%u): %.*s\n", line, cast(int)msg.length, msg.ptr);

    abort();
}

/**
 * Called when fibers switch contexts.
 */
extern(C) void* _d_eh_swapContext(void* newContext) nothrow @nogc
{
    auto old = ExceptionHeader.stack;
    ExceptionHeader.stack = cast(ExceptionHeader*)newContext;
    return old;
}

/**
 * Called before starting a catch.  Returns the exception object.
 */
extern(C) void* __gdc_begin_catch(_Unwind_Exception* unwindHeader)
{
    ExceptionHeader* header = ExceptionHeader.toExceptionHeader(unwindHeader);

    void* objectp = cast(void*)header.object;
    // Remove our reference to the exception. We should not decrease its refcount,
    // because we pass the object on to the caller.
    header.object = null;

    // Something went wrong when stacking up chained headers...
    if (header != ExceptionHeader.pop())
        terminate("catch error", __LINE__);

    // Handling for this exception is complete.
    _Unwind_DeleteException(&header.unwindHeader);

    return objectp;
}

/**
 * Perform a throw, D style. Throw will unwind through this call,
 * so there better not be any handlers or exception thrown here.
 */
extern(C) void _d_throw(Throwable object)
{
    // If possible, avoid always allocating new memory for exception headers.
    ExceptionHeader *eh = ExceptionHeader.create(object);

    // Add to thrown exception stack.
    eh.push();

    // Increment reference count if object is a refcounted Throwable.
    auto refcount = object.refcount();
    if (refcount)
        object.refcount() = refcount + 1;

    // Called by unwinder when exception object needs destruction by other than our code.
    extern(C) void exception_cleanup(_Unwind_Reason_Code code, _Unwind_Exception* exc)
    {
        // If we haven't been caught by a foreign handler, then this is
        // some sort of unwind error.  In that case just die immediately.
        // _Unwind_DeleteException in the HP-UX IA64 libunwind library
        //  returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT
        // like the GCC _Unwind_DeleteException function does.
        if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
            terminate("uncaught exception", __LINE__);

        auto eh = ExceptionHeader.toExceptionHeader(exc);
        ExceptionHeader.free(eh);
    }

    eh.unwindHeader.exception_cleanup = &exception_cleanup;

    // Runtime now expects us to do this first before unwinding.
    _d_createTrace(eh.object, null);

    // We're happy with setjmp/longjmp exceptions or region-based
    // exception handlers: entry points are provided here for both.
    _Unwind_Reason_Code r = void;

    version (GNU_SjLj_Exceptions)
        r = _Unwind_SjLj_RaiseException(&eh.unwindHeader);
    else
        r = _Unwind_RaiseException(&eh.unwindHeader);

    // If code == _URC_END_OF_STACK, then we reached top of stack without finding
    // a handler for the exception.  Since each thread is run in a try/catch,
    // this oughtn't happen.  If code is something else, we encountered some sort
    // of heinous lossage from which we could not recover.  As is the way of such
    // things, almost certainly we will have crashed before now, rather than
    // actually being able to diagnose the problem.
    if (r == _URC_END_OF_STACK)
    {
        __gdc_begin_catch(&eh.unwindHeader);
        _d_print_throwable(object);
        terminate("uncaught exception", __LINE__);
    }

    terminate("unwind error", __LINE__);
}

static if (GNU_ARM_EABI_Unwinder)
{
    enum personality_fn_attributes = attribute("target", ("general-regs-only"));
}
else
{
    enum personality_fn_attributes = "";
}

/**
 * Read and extract information from the LSDA (.gcc_except_table section).
 */
@personality_fn_attributes
_Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class exceptionClass,
                             _Unwind_Action actions, _Unwind_Exception* unwindHeader,
                             _Unwind_Context* context, _Unwind_Word cfa,
                             out _Unwind_Ptr landingPad, out int handler)
{
    // If no LSDA, then there are no handlers or cleanups.
    if (lsda is null)
        return CONTINUE_UNWINDING(unwindHeader, context);

    // Parse the LSDA header
    auto p = lsda;

    auto Start = (context ? _Unwind_GetRegionStart(context) : 0);

    // Find @LPStart, the base to which landing pad offsets are relative.
    ubyte LPStartEncoding = *p++;
    _Unwind_Ptr LPStart = 0;

    if (LPStartEncoding != DW_EH_PE_omit)
        LPStart = read_encoded_value(context, LPStartEncoding, p);
    else
        LPStart = Start;

    // Find @TType, the base of the handler and exception spec type data.
    ubyte TTypeEncoding = *p++;
    const(ubyte)* TType = null;

    if (TTypeEncoding != DW_EH_PE_omit)
    {
        static if (__traits(compiles, _TTYPE_ENCODING))
        {
            // Older ARM EABI toolchains set this value incorrectly, so use a
            // hardcoded OS-specific format.
            TTypeEncoding = _TTYPE_ENCODING;
        }
        auto TTbase = read_uleb128(p);
        TType = p + TTbase;
    }

    // The encoding and length of the call-site table; the action table
    // immediately follows.
    ubyte CSEncoding = *p++;
    auto CSTableSize = read_uleb128(p);
    const(ubyte)* actionTable = p + CSTableSize;

    auto TTypeBase = base_of_encoded_value(TTypeEncoding, context);

    // Get instruction pointer (ip) at start of instruction that threw.
    version (CRuntime_Glibc)
    {
        int ip_before_insn;
        auto ip = _Unwind_GetIPInfo(context, &ip_before_insn);
        if (!ip_before_insn)
            --ip;
    }
    else
    {
        auto ip = _Unwind_GetIP(context);
        --ip;
    }

    bool saw_cleanup = false;
    bool saw_handler = false;
    const(ubyte)* actionRecord = null;

    version (GNU_SjLj_Exceptions)
    {
        // The given "IP" is an index into the call-site table, with two
        // exceptions -- -1 means no-action, and 0 means terminate.
        // But since we're using uleb128 values, we've not got random
        // access to the array.
        if (cast(int) ip <= 0)
        {
            return _URC_CONTINUE_UNWIND;
        }
        else
        {
            _uleb128_t CSLandingPad, CSAction;
            do
            {
                CSLandingPad = read_uleb128(p);
                CSAction = read_uleb128(p);
            }
            while (--ip);

            // Can never have null landing pad for sjlj -- that would have
            // been indicated by a -1 call site index.
            landingPad = CSLandingPad + 1;
            if (CSAction)
                actionRecord = actionTable + CSAction - 1;
        }
    }
    else
    {
        // Search the call-site table for the action associated with this IP.
        while (p < actionTable)
        {
            // Note that all call-site encodings are "absolute" displacements.
            auto CSStart = read_encoded_value(null, CSEncoding, p);
            auto CSLen = read_encoded_value(null, CSEncoding, p);
            auto CSLandingPad = read_encoded_value(null, CSEncoding, p);
            auto CSAction = read_uleb128(p);

            // The table is sorted, so if we've passed the ip, stop.
            if (ip < Start + CSStart)
                p = actionTable;
            else if (ip < Start + CSStart + CSLen)
            {
                if (CSLandingPad)
                    landingPad = LPStart + CSLandingPad;
                if (CSAction)
                    actionRecord = actionTable + CSAction - 1;
                break;
            }
        }
    }

    if (landingPad == 0)
    {
        // IP is present, but has a null landing pad.
        // No cleanups or handlers to be run.
    }
    else if (actionRecord is null)
    {
        // If ip is present, has a non-null landing pad, and a null
        // action table offset, then there are only cleanups present.
        // Cleanups use a zero switch value, as set above.
        saw_cleanup = true;
    }
    else
    {
        // Otherwise we have a catch handler or exception specification.
        handler = actionTableLookup(actions, unwindHeader, actionRecord,
                                    lsda, exceptionClass, TTypeBase,
                                    TType, TTypeEncoding,
                                    saw_handler, saw_cleanup);
    }

    // IP is not in table.  No associated cleanups.
    if (!saw_handler && !saw_cleanup)
        return CONTINUE_UNWINDING(unwindHeader, context);

    if (actions & _UA_SEARCH_PHASE)
    {
        if (!saw_handler)
            return CONTINUE_UNWINDING(unwindHeader, context);

        // For domestic exceptions, we cache data from phase 1 for phase 2.
        if (isGdcExceptionClass(exceptionClass))
            ExceptionHeader.save(unwindHeader, cfa, handler, lsda, landingPad);

        return _URC_HANDLER_FOUND;
    }

    return 0;
}

/**
 * Look up and return the handler index of the classType in Action Table.
 */
int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,
                      const(ubyte)* actionRecord, const(ubyte)* lsda,
                      _Unwind_Exception_Class exceptionClass,
                      _Unwind_Ptr TTypeBase, const(ubyte)* TType,
                      ubyte TTypeEncoding,
                      out bool saw_handler, out bool saw_cleanup)
{
    ClassInfo thrownType;
    if (isGdcExceptionClass(exceptionClass))
    {
        thrownType = getClassInfo(unwindHeader, lsda);
    }

    while (1)
    {
        auto ap = actionRecord;
        auto ARFilter = read_sleb128(ap);
        auto apn = ap;
        auto ARDisp = read_sleb128(ap);

        if (ARFilter == 0)
        {
            // Zero filter values are cleanups.
            saw_cleanup = true;
        }
        else if (actions & _UA_FORCE_UNWIND)
        {
            // During forced unwinding, we only run cleanups.
        }
        else if (ARFilter > 0)
        {
            // Positive filter values are handlers.
            auto encodedSize = size_of_encoded_value(TTypeEncoding);

            // ARFilter is the negative index from TType, which is where
            // the ClassInfo is stored.
            const(ubyte)* tp = TType - ARFilter * encodedSize;

            auto entry = read_encoded_value_with_base(TTypeEncoding, TTypeBase, tp);
            ClassInfo ci = cast(ClassInfo)cast(void*)(entry);

            // D does not have catch-all handlers, and so the following
            // assumes that we will never handle a null value.
            assert(ci !is null);

            if (ci.classinfo is __cpp_type_info_ptr.classinfo
                && isGxxExceptionClass(exceptionClass))
            {
                // catchType is the catch clause type_info.
                auto catchType = cast(CxxTypeInfo)((cast(__cpp_type_info_ptr)cast(void*)ci).ptr);
                auto thrownPtr = CxaExceptionHeader.getAdjustedPtr(unwindHeader, catchType);

                if (thrownPtr !is null)
                {
                    if (actions & _UA_SEARCH_PHASE)
                        CxaExceptionHeader.save(unwindHeader, thrownPtr);
                    saw_handler = true;
                    return cast(int)ARFilter;
                }
            }
            else if (isGdcExceptionClass(exceptionClass)
                     && _d_isbaseof(thrownType, ci))
            {
                saw_handler = true;
                return cast(int)ARFilter;
            }
            else
            {
                // ??? What to do about other GNU language exceptions.
            }
        }
        else
        {
            // Negative filter values are exception specifications,
            // which D does not use.
            break;
        }

        if (ARDisp == 0)
            break;
        actionRecord = apn + ARDisp;
    }

    return 0;
}

/**
 * Look at the chain of inflight exceptions and pick the class type that'll
 * be looked for in catch clauses.
 */
ClassInfo getClassInfo(_Unwind_Exception* unwindHeader,
                       const(ubyte)* currentLsd) @nogc
{
    ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader);
    // The first thrown Exception at the top of the stack takes precedence
    // over others that are inflight, unless an Error was thrown, in which
    // case, we search for error handlers instead.
    Throwable ehobject = eh.object;
    for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next)
    {
        const(ubyte)* nextLsd = void;
        _Unwind_Ptr nextLandingPad = void;
        _Unwind_Word nextCfa = void;
        int nextHandler = void;

        ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa);

        // Don't combine when the exceptions are from different functions.
        if (currentLsd != nextLsd)
            break;

        Error e = cast(Error)ehobject;
        if (e is null || (cast(Error)ehn.object) !is null)
        {
            currentLsd = nextLsd;
            ehobject = ehn.object;
        }
    }
    return ehobject.classinfo;
}

/**
 * Called when the personality function has found neither a cleanup or handler.
 * To support ARM EABI personality routines, that must also unwind the stack.
 */
@personality_fn_attributes
_Unwind_Reason_Code CONTINUE_UNWINDING(_Unwind_Exception* unwindHeader, _Unwind_Context* context)
{
    static if (GNU_ARM_EABI_Unwinder)
    {
        if (__gnu_unwind_frame(unwindHeader, context) != _URC_OK)
            return _URC_FAILURE;
    }
    return _URC_CONTINUE_UNWIND;
}

/**
 * Using a different personality function name causes link failures
 * when trying to mix code using different exception handling models.
 */
version (GNU_SEH_Exceptions)
{
    enum PERSONALITY_FUNCTION = "__gdc_personality_imp";

    extern(C) EXCEPTION_DISPOSITION __gdc_personality_seh0(void* ms_exc, void* this_frame,
                                                           void* ms_orig_context, void* ms_disp)
    {
        return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
                                     ms_disp, &gdc_personality);
    }
}
else version (GNU_SjLj_Exceptions)
{
    enum PERSONALITY_FUNCTION = "__gdc_personality_sj0";

    private int __builtin_eh_return_data_regno(int x) { return x; }
}
else
{
    enum PERSONALITY_FUNCTION = "__gdc_personality_v0";
}

/**
 * The "personality" function, specific to each language.
 */
static if (GNU_ARM_EABI_Unwinder)
{
    pragma(mangle, PERSONALITY_FUNCTION)
    @personality_fn_attributes
    extern(C) _Unwind_Reason_Code gdc_personality(_Unwind_State state,
                                                  _Unwind_Exception* unwindHeader,
                                                  _Unwind_Context* context)
    {
        _Unwind_Action actions;

        switch (state & _US_ACTION_MASK)
        {
            case _US_VIRTUAL_UNWIND_FRAME:
                // If the unwind state pattern is (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND)
                // then we don't need to search for any handler as it is not a real exception.
                // Just unwind the stack.
                if (state & _US_FORCE_UNWIND)
                    return CONTINUE_UNWINDING(unwindHeader, context);
                actions = _UA_SEARCH_PHASE;
                break;

            case _US_UNWIND_FRAME_STARTING:
                actions = _UA_CLEANUP_PHASE;
                if (!(state & _US_FORCE_UNWIND)
                    && unwindHeader.barrier_cache.sp == _Unwind_GetGR(context, UNWIND_STACK_REG))
                    actions |= _UA_HANDLER_FRAME;
                break;

            case _US_UNWIND_FRAME_RESUME:
                return CONTINUE_UNWINDING(unwindHeader, context);

            default:
                terminate("unwind error", __LINE__);
        }
        actions |= state & _US_FORCE_UNWIND;

        // The dwarf unwinder assumes the context structure holds things like
        // the function and LSDA pointers.  The ARM implementation caches these
        // in the exception header (UCB).  To avoid rewriting everything we make
        // the virtual IP register point at the UCB.
        _Unwind_SetGR(context, UNWIND_POINTER_REG, cast(_Unwind_Ptr)unwindHeader);

        return __gdc_personality(actions, unwindHeader.exception_class,
                                 unwindHeader, context);
    }
}
else
{
    pragma(mangle, PERSONALITY_FUNCTION)
    extern(C) _Unwind_Reason_Code gdc_personality(int iversion,
                                                  _Unwind_Action actions,
                                                  _Unwind_Exception_Class exceptionClass,
                                                  _Unwind_Exception* unwindHeader,
                                                  _Unwind_Context* context)
    {
        // Interface version check.
        if (iversion != 1)
            return _URC_FATAL_PHASE1_ERROR;

        return __gdc_personality(actions, exceptionClass, unwindHeader, context);
    }
}

@personality_fn_attributes
private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions,
                                              _Unwind_Exception_Class exceptionClass,
                                              _Unwind_Exception* unwindHeader,
                                              _Unwind_Context* context)
{
    const(ubyte)* lsda;
    _Unwind_Ptr landingPad;
    _Unwind_Word cfa;
    int handler;

    // Shortcut for phase 2 found handler for domestic exception.
    if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
        && isGdcExceptionClass(exceptionClass))
    {
        ExceptionHeader.restore(unwindHeader, handler, lsda, landingPad, cfa);
        // Shouldn't have cached a null landing pad in phase 1.
        if (landingPad == 0)
            terminate("unwind error", __LINE__);
    }
    else
    {
        lsda = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);

        static if (GNU_ARM_EABI_Unwinder)
            cfa = _Unwind_GetGR(context, UNWIND_STACK_REG);
        else
            cfa = _Unwind_GetCFA(context);

        auto result = scanLSDA(lsda, exceptionClass, actions, unwindHeader,
                               context, cfa, landingPad, handler);

        // Positive on handler found in phase 1, continue unwinding, or failure.
        if (result)
            return result;
    }

    // Unexpected negative handler, call terminate directly.
    if (handler < 0)
        terminate("unwind error", __LINE__);

    // We can't use any of the deh routines with foreign exceptions,
    // because they all expect unwindHeader to be an ExceptionHeader.
    if (isGdcExceptionClass(exceptionClass))
    {
        // If there are any in-flight exceptions being thrown, chain our
        // current object onto the end of the prevous object.
        ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader);
        auto currentLsd = lsda;
        bool bypassed = false;

        while (eh.next)
        {
            ExceptionHeader* ehn = eh.next;
            const(ubyte)* nextLsd = void;
            _Unwind_Ptr nextLandingPad = void;
            _Unwind_Word nextCfa = void;
            int nextHandler = void;

            ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa);

            Error e = cast(Error)eh.object;
            if (e !is null && !cast(Error)ehn.object)
            {
                // We found an Error, bypass the exception chain.
                currentLsd = nextLsd;
                eh = ehn;
                bypassed = true;
                continue;
            }

            // Don't combine when the exceptions are from different functions.
            if (currentLsd != nextLsd)
                break;

            // Add our object onto the end of the existing chain and replace
            // our exception object with in-flight one.
            eh.object = Throwable.chainTogether(ehn.object, eh.object);

            if (nextHandler != handler && !bypassed)
            {
                handler = nextHandler;
                ExceptionHeader.save(unwindHeader, cfa, handler, lsda, landingPad);
            }

            // Exceptions chained, can now throw away the previous header.
            eh.next = ehn.next;
            _Unwind_DeleteException(&ehn.unwindHeader);
        }

        if (bypassed)
        {
            eh = ExceptionHeader.toExceptionHeader(unwindHeader);
            Error e = cast(Error)eh.object;
            auto ehn = eh.next;
            e.bypassedException = ehn.object;
            eh.next = ehn.next;
            _Unwind_DeleteException(&ehn.unwindHeader);
        }
    }

    // Set up registers and jump to cleanup or handler.
    // For targets with pointers smaller than the word size, we must extend the
    // pointer, and this extension is target dependent.
    _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
                  cast(_Unwind_Ptr)unwindHeader);
    _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), handler);
    _Unwind_SetIP(context, landingPad);

    return _URC_INSTALL_CONTEXT;
}
