summaryrefslogtreecommitdiffstats
path: root/private/ntos/rtl/mips/getcalr.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/rtl/mips/getcalr.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/rtl/mips/getcalr.c')
-rw-r--r--private/ntos/rtl/mips/getcalr.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/private/ntos/rtl/mips/getcalr.c b/private/ntos/rtl/mips/getcalr.c
new file mode 100644
index 000000000..1b9df34fa
--- /dev/null
+++ b/private/ntos/rtl/mips/getcalr.c
@@ -0,0 +1,179 @@
+/*++
+
+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
+
+--*/
+#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 = (ULONG)ContextRecord.XIntRa;
+
+ //
+ // 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 | 1,
+ 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.XIntSp < 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 | 1,
+ 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.XIntSp < 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 | 1,
+ FunctionEntry,
+ &ContextRecord,
+ &InFunction,
+ &EstablisherFrame,
+ NULL);
+
+ *CallersCallersPc = (PVOID)NextPc;
+ }
+ }
+ }
+
+ return;
+}
+
+USHORT
+RtlCaptureStackBackTrace(
+ IN ULONG FramesToSkip,
+ IN ULONG FramesToCapture,
+ OUT PVOID *BackTrace,
+ OUT PULONG BackTraceHash
+ )
+{
+ return 0;
+}