[RTL/x64] Support frames to skip in flags to RtlWalkFrameChain

svn path=/trunk/; revision=76019
This commit is contained in:
Timo Kreuzer 2017-10-01 14:34:26 +00:00
parent 37630ef0ab
commit 555300d680

View file

@ -524,11 +524,14 @@ RtlWalkFrameChain(OUT PVOID *Callers,
ULONG64 ControlPc, ImageBase, EstablisherFrame; ULONG64 ControlPc, ImageBase, EstablisherFrame;
ULONG64 StackLow, StackHigh; ULONG64 StackLow, StackHigh;
PVOID HandlerData; PVOID HandlerData;
ULONG i; ULONG i, FramesToSkip;
PRUNTIME_FUNCTION FunctionEntry; PRUNTIME_FUNCTION FunctionEntry;
DPRINT("Enter RtlWalkFrameChain\n"); DPRINT("Enter RtlWalkFrameChain\n");
/* The upper bits in Flags define how many frames to skip */
FramesToSkip = Flags >> 8;
/* Capture the current Context */ /* Capture the current Context */
RtlCaptureContext(&Context); RtlCaptureContext(&Context);
ControlPc = Context.Rip; ControlPc = Context.Rip;
@ -537,12 +540,12 @@ RtlWalkFrameChain(OUT PVOID *Callers,
RtlpGetStackLimits(&StackLow, &StackHigh); RtlpGetStackLimits(&StackLow, &StackHigh);
/* Check if we want the user-mode stack frame */ /* Check if we want the user-mode stack frame */
if (Flags == 1) if (Flags & 1)
{ {
} }
/* Loop the frames */ /* Loop the frames */
for (i = 0; i < Count; i++) for (i = 0; i < FramesToSkip + Count; i++)
{ {
/* Lookup the FunctionEntry for the current ControlPc */ /* Lookup the FunctionEntry for the current ControlPc */
FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL); FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL);
@ -579,9 +582,14 @@ RtlWalkFrameChain(OUT PVOID *Callers,
break; break;
} }
/* Save this frame and continue with new Rip */ /* Continue with new Rip */
ControlPc = Context.Rip; ControlPc = Context.Rip;
Callers[i] = (PVOID)ControlPc;
/* Save value, if we are past the frames to skip */
if (i >= FramesToSkip)
{
Callers[i - FramesToSkip] = (PVOID)ControlPc;
}
} }
DPRINT("RtlWalkFrameChain returns %ld\n", i); DPRINT("RtlWalkFrameChain returns %ld\n", i);
@ -605,14 +613,8 @@ RtlGetCallersAddress(
* RtlWalkFrameChain -> RtlGetCallersAddress -> x -> y */ * RtlWalkFrameChain -> RtlGetCallersAddress -> x -> y */
Number = RtlWalkFrameChain(Callers, 4, 0); Number = RtlWalkFrameChain(Callers, 4, 0);
if (CallersAddress) *CallersAddress = (Number >= 3) ? Callers[2] : NULL;
{ *CallersCaller = (Number == 4) ? Callers[3] : NULL;
*CallersAddress = (Number >= 3) ? Callers[2] : NULL;
}
if (CallersCaller)
{
*CallersCaller = (Number == 4) ? Callers[3] : NULL;
}
return; return;
} }