/*++ 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; }