[PATCH 01/11] [DbgHelp]: in i386 stack unwinder, ensure we always return decent 64bit values
Eric Pouech
eric.pouech at orange.fr
Sun Mar 13 15:30:12 CDT 2011
A+
---
dlls/dbghelp/cpu_i386.c | 41 +++++++++++++++++++++++------------------
1 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/dlls/dbghelp/cpu_i386.c b/dlls/dbghelp/cpu_i386.c
index 61ed427..6913b1b 100644
--- a/dlls/dbghelp/cpu_i386.c
+++ b/dlls/dbghelp/cpu_i386.c
@@ -105,7 +105,8 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
char ch;
ADDRESS64 tmp;
DWORD p;
- WORD val;
+ WORD val16;
+ DWORD val32;
BOOL do_switch;
unsigned deltapc = 1;
#ifdef __i386__
@@ -360,9 +361,9 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(WORD);
/* "pop up" previous BP value */
if (!sw_read_mem(csw, sw_xlat_addr(csw, &frame->AddrFrame),
- &val, sizeof(WORD)))
+ &val16, sizeof(WORD)))
goto done_err;
- frame->AddrFrame.Offset = val;
+ frame->AddrFrame.Offset = val16;
}
else
{
@@ -394,9 +395,9 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
#endif
frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(DWORD);
/* "pop up" previous EBP value */
- if (!sw_read_mem(csw, frame->AddrFrame.Offset,
- &frame->AddrFrame.Offset, sizeof(DWORD)))
+ if (!sw_read_mem(csw, frame->AddrFrame.Offset, &val32, sizeof(DWORD)))
goto done_err;
+ frame->AddrFrame.Offset = val32;
}
}
}
@@ -406,30 +407,30 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
unsigned int i;
p = sw_xlat_addr(csw, &frame->AddrFrame);
- if (!sw_read_mem(csw, p + sizeof(WORD), &val, sizeof(WORD)))
+ if (!sw_read_mem(csw, p + sizeof(WORD), &val16, sizeof(WORD)))
goto done_err;
- frame->AddrReturn.Offset = val;
+ frame->AddrReturn.Offset = val16;
/* get potential cs if a far call was used */
- if (!sw_read_mem(csw, p + 2 * sizeof(WORD), &val, sizeof(WORD)))
+ if (!sw_read_mem(csw, p + 2 * sizeof(WORD), &val16, sizeof(WORD)))
goto done_err;
if (frame->AddrFrame.Offset & 1)
- frame->AddrReturn.Segment = val; /* far call assumed */
+ frame->AddrReturn.Segment = val16; /* far call assumed */
else
{
/* not explicitly marked as far call,
* but check whether it could be anyway
*/
- if ((val & 7) == 7 && val != frame->AddrReturn.Segment)
+ if ((val16 & 7) == 7 && val16 != frame->AddrReturn.Segment)
{
LDT_ENTRY le;
- if (GetThreadSelectorEntry(csw->hThread, val, &le) &&
+ if (GetThreadSelectorEntry(csw->hThread, val16, &le) &&
(le.HighWord.Bits.Type & 0x08)) /* code segment */
{
/* it is very uncommon to push a code segment cs as
* a parameter, so this should work in most cases
*/
- frame->AddrReturn.Segment = val;
+ frame->AddrReturn.Segment = val16;
}
}
}
@@ -440,21 +441,25 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
*/
for (i = 0; i < sizeof(frame->Params) / sizeof(frame->Params[0]); i++)
{
- sw_read_mem(csw, p + (2 + i) * sizeof(WORD), &val, sizeof(val));
- frame->Params[i] = val;
+ sw_read_mem(csw, p + (2 + i) * sizeof(WORD), &val16, sizeof(val16));
+ frame->Params[i] = val16;
}
}
else
{
- if (!sw_read_mem(csw, frame->AddrFrame.Offset + sizeof(DWORD),
- &frame->AddrReturn.Offset, sizeof(DWORD)))
+ unsigned int i;
+ if (!sw_read_mem(csw, frame->AddrFrame.Offset + sizeof(DWORD), &val32, sizeof(DWORD)))
{
WARN("Cannot read new frame offset %p\n",
(void*)(DWORD_PTR)(frame->AddrFrame.Offset + (int)sizeof(DWORD)));
goto done_err;
}
- sw_read_mem(csw, frame->AddrFrame.Offset + 2 * sizeof(DWORD),
- frame->Params, sizeof(frame->Params));
+ frame->AddrReturn.Offset = val32;
+ for (i = 0; i < sizeof(frame->Params) / sizeof(frame->Params[0]); i++)
+ {
+ sw_read_mem(csw, frame->AddrFrame.Offset + (2 + i) * sizeof(DWORD), &val32, sizeof(val32));
+ frame->Params[i] = val32;
+ }
}
#ifdef __i386__
if (context)
More information about the wine-patches
mailing list