Esempio n. 1
0
/*************************************************************
 *            __wine_exception_handler (NTDLL.@)
 *
 * Exception handler for exception blocks declared in Wine code.
 */
DWORD __wine_exception_handler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
                                CONTEXT *context, LPVOID pdispatcher )
{
    __WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;

    if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
        return ExceptionContinueSearch;
    if (wine_frame->u.filter)
    {
        EXCEPTION_POINTERS ptrs;
        ptrs.ExceptionRecord = record;
        ptrs.ContextRecord = context;
        switch(wine_frame->u.filter( &ptrs ))
        {
        case EXCEPTION_CONTINUE_SEARCH:
            return ExceptionContinueSearch;
        case EXCEPTION_CONTINUE_EXECUTION:
            return ExceptionContinueExecution;
        case EXCEPTION_EXECUTE_HANDLER:
            break;
        default:
            MESSAGE( "Invalid return value from exception filter\n" );
            assert( FALSE );
        }
    }
    /* hack to make GetExceptionCode() work in handler */
    wine_frame->ExceptionCode   = record->ExceptionCode;
    wine_frame->ExceptionRecord = wine_frame;

    RtlUnwind( frame, 0, record, 0 );
    __wine_pop_frame( frame );
    longjmp( wine_frame->jmp, 1 );
}
Esempio n. 2
0
VOID
longjmp (
    IN jmp_buf JumpBuffer,
    IN int ReturnValue
    )

/*++

Routine Description:

    This function executes a long jump operation by virtually unwinding to
    the caller of the corresponding call to set jump and then calling unwind
    to transfer control to the jump target.

Arguments:


    JumpBuffer - Supplies the address of a jump buffer that contains the
        virtual frame pointer and target address.

        N.B. This is an array of double to force quadword alignment.

    ReturnValue - Supplies the value that is to be returned to the caller
        of set jump.

Return Value:

    None.

--*/

{

    PULONG JumpArray;

    //
    // If the specified return value is zero, then set it to one.
    //

    if (ReturnValue == 0) {
        ReturnValue = 1;
    }

    //
    // Unwind to the caller of set jump and return the specified value.
    // There is no return from unwind.
    //

    JumpArray = (PULONG)&JumpBuffer[0];
    RtlUnwind((PVOID)JumpArray[0],
              (PVOID)JumpArray[1],
              NULL,
              (PVOID)ReturnValue);
}
Esempio n. 3
0
/*******************************************************************
 *		longjmp (MSVCRT.@)
 */
void __cdecl MSVCRT_longjmp(struct MSVCRT___JUMP_BUFFER *jmp, int retval)
{
    EXCEPTION_RECORD rec;

    if (!retval) retval = 1;
    if (jmp->Frame)
    {
        rec.ExceptionCode = STATUS_LONGJUMP;
        rec.ExceptionFlags = 0;
        rec.ExceptionRecord = NULL;
        rec.ExceptionAddress = NULL;
        rec.NumberParameters = 1;
        rec.ExceptionInformation[0] = (DWORD_PTR)jmp;
        RtlUnwind((void *)jmp->Frame, (void *)jmp->Pc, &rec, IntToPtr(retval));
    }
    longjmp_set_regs(jmp, retval);
}
Esempio n. 4
0
void longjmpex( jmp_buf jb, int ret )
{
    EXCEPTION_RECORD    er;
    _JUMPEXDATA         *jd = (_JUMPEXDATA *)jb;

    er.ExceptionCode           = 0xE5670123;
    er.ExceptionFlags          = 0x00000002;
    er.ExceptionRecord         = 0L;
    er.ExceptionAddress        = 0L;
    er.NumberParameters        = 1L;
    er.ExceptionInformation[0] = jd->sp;

    if( !_ProcSetsFP( RtlLookupFunctionEntry( jd->pc ) ) )
        RtlUnwind( (void *)jd->sp, (void *)jd->pc, &er, (void *)ret );
    else
        RtlUnwindRfp( jd->fp, jd->pc, &er, ret );
} /* longjmp() */
Esempio n. 5
0
void __stdcall _UnwindNestedFrames(
    EHRegistrationNode *pRN,        // Unwind up to (but not including) this frame
    EHExceptionRecord   *pExcept    // The exception that initiated this unwind
) {
    EHTRACE_ENTER;

    void* pReturnPoint;
    EHRegistrationNode *pDispatcherRN;  // Magic!

    __asm {
        //
        // Save the dispatcher's marker node
        //
        // NOTE: RtlUnwind will trash the callee-save regs EBX, ESI, and EDI.
        // We explicitly use them here in the inline-asm so they get preserved
        // and restored by the function prologue/epilogue.
        //
        mov     esi, dword ptr FS:[0]   // use ESI
        mov     pDispatcherRN, esi
    }

    __asm mov pReturnPoint, offset ReturnPoint
    RtlUnwind(pRN, pReturnPoint, (PEXCEPTION_RECORD)pExcept, nullptr);

ReturnPoint:

    PER_FLAGS(pExcept) &= ~EXCEPTION_UNWINDING; // Clear the 'Unwinding' flag
                                                // in case exception is rethrown
    __asm {
        //
        // Re-link the dispatcher's marker node
        //
        mov     edi, dword ptr FS:[0]   // Get the current head (use EDI)
        mov     ebx, pDispatcherRN      // Get the saved head (use EBX)
        mov     [ebx], edi              // Link saved head to current head
        mov     dword ptr FS:[0], ebx   // Make saved head current head
        }

    EHTRACE_EXIT;

    return;
    }
Esempio n. 6
0
void CPPLIB( PdUnwind )         // UNWIND USING PROCEDURE DESCRIPTORS
    ( FsExcRec* exc_rec )       // - exception record
{
    DISPATCH_EXC* dispatch;     // - dispatch control
    RW_DTREG* rw;               // - R/W block being dispatched
    void* frame;                // - frame for rtn. (SP or FP)
    void* pc;                   // - PC for continuation (after the setjmp)
    _CONTEXT ctx;               // - context for function
    unsigned save_area[3*2];    // - save area

    RtlCaptureContext( &ctx );
    pc = CPPLIB( PdCtx )( &ctx, save_area );
    if( pc ) {
        dispatch = exc_rec->dispatch;
        rw = dispatch->rw;
        frame = (void*)( (char*)rw - rw->base.ro->fun.rw_offset );
        if( procSetsFP( dispatch->pdata ) ) {
            RtlUnwindRfp( frame, pc, exc_rec, save_area );
        } else {
            RtlUnwind( frame, pc, exc_rec, save_area );
        }
    }
}
Esempio n. 7
0
void _global_unwind2(PEXCEPTION_FRAME frame) {
  RtlUnwind(frame, 0, 0, 0);
}