Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

189 lines
4.9 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
getcalr.c
Abstract:
This module implements the routine RtlGetCallerAddress. It will
return the address of the caller, and the callers caller to the
specified procedure.
Author:
Larry Osterman (larryo) 18-Mar-1991 (with help from DaveC)
Revision History:
18-Mar-1991 larryo
Created
Thomas Van Baak (tvb) 5-May-1992
Adapted for Alpha AXP.
--*/
#include "ntrtlp.h"
//
// Undefine get callers address since it is defined as a macro.
//
#undef RtlGetCallersAddress
VOID
RtlGetCallersAddress (
OUT PVOID *CallersPc,
OUT PVOID *CallersCallersPc
)
/*++
Routine Description:
This routine returns the address of the call to the routine that called
this routine, and the address of the call to the routine that called
the routine that called this routine. For example, if A called B called
C which called this routine, the return addresses in B and A would be
returned.
Arguments:
CallersPc - Supplies a pointer to a variable that receives the address
of the caller of the caller of this routine (B).
CallersCallersPc - Supplies a pointer to a variable that receives the
address of the caller of the caller of the caller of this routine
(A).
Return Value:
None.
Note:
If either of the calling stack frames exceeds the limits of the stack,
they are set to NULL.
--*/
{
#ifdef REALLY_GET_CALLERS_CALLER
CONTEXT ContextRecord;
FRAME_POINTERS EstablisherFrame;
PRUNTIME_FUNCTION FunctionEntry;
BOOLEAN InFunction;
ULONG HighLimit, LowLimit;
ULONG NextPc;
//
// Assume the function table entries for the various routines cannot be
// found or there are not four procedure activation records on the stack.
//
*CallersPc = NULL;
*CallersCallersPc = NULL;
//
// Capture the current context.
//
RtlCaptureContext(&ContextRecord);
NextPc = (ULONG)ContextRecord.IntRa;
//
// Get the high and low limits of the current thread's stack.
//
RtlpGetStackLimits(&LowLimit, &HighLimit);
//
// Attempt to unwind to the caller of this routine (C). The FunctionEntry
// returned here will be that of this routine since NextPc was the return
// address of our call to RtlCaptureContext. For the purposes of this
// function, the +4 and -4 adjustments to NextPc are unnecessary.
//
FunctionEntry = RtlLookupFunctionEntry(NextPc);
if (FunctionEntry != NULL) {
//
// A function entry was found for this routine. Virtually unwind
// to the caller of this routine (C).
//
NextPc = RtlVirtualUnwind(NextPc,
FunctionEntry,
&ContextRecord,
&InFunction,
&EstablisherFrame,
NULL);
//
// Attempt to unwind to the caller of the caller of this routine (B).
//
FunctionEntry = RtlLookupFunctionEntry(NextPc);
if ((FunctionEntry != NULL) && ((ULONG)ContextRecord.IntSp < HighLimit)) {
//
// A function table entry was found for the caller of the caller
// of this routine (B). Virtually unwind to the caller of the
// caller of this routine (B).
//
NextPc = RtlVirtualUnwind(NextPc,
FunctionEntry,
&ContextRecord,
&InFunction,
&EstablisherFrame,
NULL);
*CallersPc = (PVOID)NextPc;
//
// Attempt to unwind to the caller of the caller of the caller
// of the caller of this routine (A).
//
FunctionEntry = RtlLookupFunctionEntry(NextPc);
if ((FunctionEntry != NULL) && ((ULONG)ContextRecord.IntSp < HighLimit)) {
//
// A function table entry was found for the caller of the
// caller of the caller of this routine (A). Virtually unwind
// to the caller of the caller of the caller of this routine
// (A).
//
NextPc = RtlVirtualUnwind(NextPc,
FunctionEntry,
&ContextRecord,
&InFunction,
&EstablisherFrame,
NULL);
*CallersCallersPc = (PVOID)NextPc;
}
}
}
#else
*CallersPc = NULL;
*CallersCallersPc = NULL;
#endif
return;
}
USHORT
RtlCaptureStackBackTrace(
IN ULONG FramesToSkip,
IN ULONG FramesToCapture,
OUT PVOID *BackTrace,
OUT PULONG BackTraceHash
)
{
return 0;
}