mirror of https://github.com/lianthony/NT4.0
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.8 KiB
189 lines
4.8 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
|
|
|
|
Tom Wood 23-Aug-1994
|
|
Add stack limit parameters to RtlVirtualUnwind.
|
|
|
|
--*/
|
|
#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 routine that called the routine
|
|
that called this routine, and 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 A and B 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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
CONTEXT ContextRecord;
|
|
ULONG EstablisherFrame;
|
|
PRUNTIME_FUNCTION FunctionEntry;
|
|
BOOLEAN InFunction;
|
|
ULONG NextPc;
|
|
ULONG HighLimit, LowLimit;
|
|
|
|
//
|
|
// 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 = ContextRecord.Lr;
|
|
|
|
//
|
|
// 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).
|
|
//
|
|
|
|
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,
|
|
0,
|
|
0xffffffff);
|
|
|
|
//
|
|
// Attempt to unwind to the caller of the caller of this routine (B).
|
|
//
|
|
|
|
FunctionEntry = RtlLookupFunctionEntry(NextPc);
|
|
if ((FunctionEntry != NULL) && (ContextRecord.Gpr1 < 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,
|
|
0,
|
|
0xffffffff);
|
|
|
|
*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) && (ContextRecord.Gpr1 < 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,
|
|
0,
|
|
0xffffffff);
|
|
|
|
|
|
*CallersCallersPc = (PVOID)NextPc;
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
USHORT
|
|
RtlCaptureStackBackTrace(
|
|
IN ULONG FramesToSkip,
|
|
IN ULONG FramesToCapture,
|
|
OUT PVOID *BackTrace,
|
|
OUT PULONG BackTraceHash
|
|
)
|
|
{
|
|
return 0;
|
|
}
|