Author: tkreuzer
Date: Sun Oct 1 14:36:21 2017
New Revision: 76020
URL:
http://svn.reactos.org/svn/reactos?rev=76020&view=rev
Log:
[RTL/x64] Fix logic in RtlpTryToUnwindEpilog
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:36:21 2017
@@ -295,9 +295,9 @@
}
}
- /* Loop the following instructions */
- EndAddress = FunctionEntry->EndAddress + ImageBase;
- while((DWORD64)InstrPtr < EndAddress)
+ /* Loop the following instructions before the ret */
+ EndAddress = FunctionEntry->EndAddress + ImageBase - 1;
+ while ((DWORD64)InstrPtr < EndAddress)
{
Instr = *(DWORD*)InstrPtr;
@@ -315,20 +315,28 @@
if ( (Instr & 0xf8fb) == 0x5841 )
{
/* Opcode is pop r8 .. r15 */
- Reg = (Instr & 0x7) + 8;
+ Reg = ((Instr >> 8) & 0x7) + 8;
PopReg(&LocalContext, Reg);
InstrPtr += 2;
continue;
}
- /* Check for retn / retf */
- if ( (Instr & 0xf7) == 0xc3 )
- {
- /* We are finished */
- break;
- }
-
/* Opcode not allowed for Epilog */
+ return FALSE;
+ }
+
+ /* Check if we are at the ret instruction */
+ if ((DWORD64)InstrPtr != EndAddress)
+ {
+ /* If we went past the end of the function, something is broken! */
+ ASSERT((DWORD64)InstrPtr <= EndAddress);
+ return FALSE;
+ }
+
+ /* Make sure this is really a ret instruction */
+ if (*InstrPtr != 0xc3)
+ {
+ ASSERT(FALSE);
return FALSE;
}
@@ -414,7 +422,7 @@
}
}
- /* Process the left Ops */
+ /* Process the remaining unwind ops */
while (i < UnwindInfo->CountOfCodes)
{
UnwindCode = UnwindInfo->UnwindCode[i];