Author: tkreuzer Date: Sun Oct 1 14:34:26 2017 New Revision: 76019
URL: http://svn.reactos.org/svn/reactos?rev=76019&view=rev Log: [RTL/x64] Support frames to skip in flags to RtlWalkFrameChain
Modified: trunk/reactos/sdk/lib/rtl/amd64/unwind.c
Modified: trunk/reactos/sdk/lib/rtl/amd64/unwind.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/rtl/amd64/unwind.c?... ============================================================================== --- trunk/reactos/sdk/lib/rtl/amd64/unwind.c [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/rtl/amd64/unwind.c [iso-8859-1] Sun Oct 1 14:34:26 2017 @@ -524,10 +524,13 @@ ULONG64 ControlPc, ImageBase, EstablisherFrame; ULONG64 StackLow, StackHigh; PVOID HandlerData; - ULONG i; + ULONG i, FramesToSkip; PRUNTIME_FUNCTION FunctionEntry;
DPRINT("Enter RtlWalkFrameChain\n"); + + /* The upper bits in Flags define how many frames to skip */ + FramesToSkip = Flags >> 8;
/* Capture the current Context */ RtlCaptureContext(&Context); @@ -537,12 +540,12 @@ RtlpGetStackLimits(&StackLow, &StackHigh);
/* Check if we want the user-mode stack frame */ - if (Flags == 1) + if (Flags & 1) { }
/* Loop the frames */ - for (i = 0; i < Count; i++) + for (i = 0; i < FramesToSkip + Count; i++) { /* Lookup the FunctionEntry for the current ControlPc */ FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL); @@ -579,9 +582,14 @@ break; }
- /* Save this frame and continue with new Rip */ + /* Continue with new 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); @@ -605,14 +613,8 @@ * RtlWalkFrameChain -> RtlGetCallersAddress -> x -> y */ Number = RtlWalkFrameChain(Callers, 4, 0);
- if (CallersAddress) - { - *CallersAddress = (Number >= 3) ? Callers[2] : NULL; - } - if (CallersCaller) - { - *CallersCaller = (Number == 4) ? Callers[3] : NULL; - } + *CallersAddress = (Number >= 3) ? Callers[2] : NULL; + *CallersCaller = (Number == 4) ? Callers[3] : NULL;
return; }