summaryrefslogblamecommitdiffstats
path: root/private/ntos/rtl/ppc/jumps.c
blob: 7613543182040b778982ba1cc95460e42f1ca28a (plain) (tree)
























































































































































                                                                            
/*++

Copyright (c) 1990  Microsoft Corporation

Module Name:

    jumps.c

Abstract:

    This module implements the C runtime library functions for set jump and
    long jump that are compatible with structured exception handling.

Author:

    David N. Cutler (davec) 15-Sep-1990

Environment:

    Any mode.

Revision History:

    Tom Wood  23-Aug-1994
    Add stack limit parameters to RtlVirtualUnwind.

--*/

#include "ntrtlp.h"
#include "setjmp.h"

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);
}

int
setjmp (
    IN jmp_buf JumpBuffer
    )

/*++

Routine Description:

    This function performs a set jump operation by capturing the current
    context, virtualy unwinding to the caller of set jump, and returns zero
    to the caller.

Arguments:

    JumpBuffer - Supplies the address of a jump buffer to store the virtual
        frame pointer and target address of the caller.

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

Return Value:

    A value of zero is returned.

--*/

{

    CONTEXT ContextRecord;
    ULONG EstablisherFrame;
    PRUNTIME_FUNCTION FunctionEntry;
    BOOLEAN InFunction;
    PULONG JumpArray;
    ULONG NextPc;

    //
    // Capture the current context, virtually unwind to the caller of set
    // jump, and return zero to the caller.
    //

    JumpArray = (PULONG)&JumpBuffer[0];
    RtlCaptureContext(&ContextRecord);
    NextPc = ContextRecord.Lr - 4;
    FunctionEntry = RtlLookupFunctionEntry(NextPc);
    NextPc = RtlVirtualUnwind(NextPc,
                              FunctionEntry,
                              &ContextRecord,
                              &InFunction,
                              &EstablisherFrame,
                              NULL,
                              0,
                              0xffffffff);

    JumpArray[1] = NextPc + 4;
    FunctionEntry = RtlLookupFunctionEntry(NextPc);
    NextPc = RtlVirtualUnwind(NextPc,
                              FunctionEntry,
                              &ContextRecord,
                              &InFunction,
                              &EstablisherFrame,
                              NULL,
                              0,
                              0xffffffff);

    JumpArray[0] = EstablisherFrame;
    return 0;
}