dbghelp: Use WOW64_CONTEXT instead of CONTEXT for i386 backend.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2018-07-31 11:17:34 -05:00 committed by Alexandre Julliard
parent a3a2e6413b
commit 3ce304e601
8 changed files with 110 additions and 90 deletions

View File

@ -63,13 +63,14 @@ enum st_mode {stm_start, stm_arm, stm_done};
* modify (at least) context.Pc using unwind information * modify (at least) context.Pc using unwind information
* either out of debug info (dwarf), or simple Lr trace * either out of debug info (dwarf), or simple Lr trace
*/ */
static BOOL fetch_next_frame(struct cpu_stack_walk* csw, static BOOL fetch_next_frame(struct cpu_stack_walk* csw, union ctx *pcontext,
CONTEXT* context, DWORD_PTR curr_pc) DWORD_PTR curr_pc)
{ {
DWORD_PTR xframe; DWORD_PTR xframe;
CONTEXT *context = &pcontext->ctx;
DWORD oldReturn = context->Lr; DWORD oldReturn = context->Lr;
if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe)) if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe))
{ {
context->Sp = xframe; context->Sp = xframe;
context->Pc = oldReturn; context->Pc = oldReturn;
@ -82,7 +83,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
return TRUE; return TRUE;
} }
static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL arm_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
union ctx *context)
{ {
unsigned deltapc = curr_count <= 1 ? 0 : 4; unsigned deltapc = curr_count <= 1 ? 0 : 4;
@ -109,8 +111,8 @@ static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
} }
else else
{ {
if (context->Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n"); if (context->ctx.Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
if (context->Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n"); if (context->ctx.Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
if (frame->AddrReturn.Offset == 0) goto done_err; if (frame->AddrReturn.Offset == 0) goto done_err;
if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc)) if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc))
@ -120,10 +122,10 @@ static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
memset(&frame->Params, 0, sizeof(frame->Params)); memset(&frame->Params, 0, sizeof(frame->Params));
/* set frame information */ /* set frame information */
frame->AddrStack.Offset = context->Sp; frame->AddrStack.Offset = context->ctx.Sp;
frame->AddrReturn.Offset = context->Lr; frame->AddrReturn.Offset = context->ctx.Lr;
frame->AddrFrame.Offset = context->R11; frame->AddrFrame.Offset = context->ctx.R11;
frame->AddrPC.Offset = context->Pc; frame->AddrPC.Offset = context->ctx.Pc;
frame->Far = TRUE; frame->Far = TRUE;
frame->Virtual = TRUE; frame->Virtual = TRUE;
@ -144,7 +146,8 @@ done_err:
return FALSE; return FALSE;
} }
#else #else
static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL arm_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
union ctx *context)
{ {
return FALSE; return FALSE;
} }
@ -159,9 +162,11 @@ static unsigned arm_map_dwarf_register(unsigned regno, BOOL eh_frame)
return CV_ARM_NOREG; return CV_ARM_NOREG;
} }
static void* arm_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size) static void *arm_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{ {
#ifdef __arm__ #ifdef __arm__
CONTEXT *ctx = &pctx->ctx;
switch (regno) switch (regno)
{ {
case CV_ARM_R0 + 0: *size = sizeof(ctx->R0); return &ctx->R0; case CV_ARM_R0 + 0: *size = sizeof(ctx->R0); return &ctx->R0;

View File

@ -65,13 +65,14 @@ enum st_mode {stm_start, stm_arm64, stm_done};
* modify (at least) context.Pc using unwind information * modify (at least) context.Pc using unwind information
* either out of debug info (dwarf), or simple Lr trace * either out of debug info (dwarf), or simple Lr trace
*/ */
static BOOL fetch_next_frame(struct cpu_stack_walk* csw, static BOOL fetch_next_frame(struct cpu_stack_walk* csw, union ctx *pcontext,
CONTEXT* context, DWORD_PTR curr_pc) DWORD_PTR curr_pc)
{ {
DWORD_PTR xframe; DWORD_PTR xframe;
CONTEXT *context = &pcontext->ctx;
DWORD_PTR oldReturn = context->u.s.Lr; DWORD_PTR oldReturn = context->u.s.Lr;
if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe)) if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe))
{ {
context->Sp = xframe; context->Sp = xframe;
context->Pc = oldReturn; context->Pc = oldReturn;
@ -84,7 +85,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
return TRUE; return TRUE;
} }
static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL arm64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
union ctx *context)
{ {
unsigned deltapc = curr_count <= 1 ? 0 : 4; unsigned deltapc = curr_count <= 1 ? 0 : 4;
@ -111,8 +113,8 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
} }
else else
{ {
if (context->Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n"); if (context->ctx.Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
if (context->Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n"); if (context->ctx.Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
if (frame->AddrReturn.Offset == 0) goto done_err; if (frame->AddrReturn.Offset == 0) goto done_err;
if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc)) if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc))
@ -122,10 +124,10 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
memset(&frame->Params, 0, sizeof(frame->Params)); memset(&frame->Params, 0, sizeof(frame->Params));
/* set frame information */ /* set frame information */
frame->AddrStack.Offset = context->Sp; frame->AddrStack.Offset = context->ctx.Sp;
frame->AddrReturn.Offset = context->u.s.Lr; frame->AddrReturn.Offset = context->ctx.u.s.Lr;
frame->AddrFrame.Offset = context->u.s.Fp; frame->AddrFrame.Offset = context->ctx.u.s.Fp;
frame->AddrPC.Offset = context->Pc; frame->AddrPC.Offset = context->ctx.Pc;
frame->Far = TRUE; frame->Far = TRUE;
frame->Virtual = TRUE; frame->Virtual = TRUE;
@ -146,7 +148,8 @@ done_err:
return FALSE; return FALSE;
} }
#else #else
static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, STACKFRAME64 *frame,
union ctx *ctx)
{ {
return FALSE; return FALSE;
} }
@ -164,9 +167,11 @@ static unsigned arm64_map_dwarf_register(unsigned regno, BOOL eh_frame)
return CV_ARM64_NOREG; return CV_ARM64_NOREG;
} }
static void* arm64_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size) static void *arm64_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{ {
#ifdef __aarch64__ #ifdef __aarch64__
CONTEXT *ctx = pctx;
switch (regno) switch (regno)
{ {
case CV_ARM64_X0 + 0: case CV_ARM64_X0 + 0:

View File

@ -86,20 +86,20 @@ static BOOL i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
return FALSE; return FALSE;
} }
#ifdef __i386__
/* fetch_next_frame32() /* fetch_next_frame32()
* *
* modify (at least) context.{eip, esp, ebp} using unwind information * modify (at least) context.{eip, esp, ebp} using unwind information
* either out of debug info (dwarf, pdb), or simple stack unwind * either out of debug info (dwarf, pdb), or simple stack unwind
*/ */
static BOOL fetch_next_frame32(struct cpu_stack_walk* csw, static BOOL fetch_next_frame32(struct cpu_stack_walk* csw,
CONTEXT* context, DWORD_PTR curr_pc) union ctx *pcontext, DWORD_PTR curr_pc)
{ {
DWORD_PTR xframe; DWORD_PTR xframe;
struct pdb_cmd_pair cpair[4]; struct pdb_cmd_pair cpair[4];
DWORD val32; DWORD val32;
WOW64_CONTEXT *context = &pcontext->x86;
if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe)) if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe))
{ {
context->Esp = xframe; context->Esp = xframe;
return TRUE; return TRUE;
@ -109,7 +109,7 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw,
cpair[2].name = "$eip"; cpair[2].pvalue = &context->Eip; cpair[2].name = "$eip"; cpair[2].pvalue = &context->Eip;
cpair[3].name = NULL; cpair[3].pvalue = NULL; cpair[3].name = NULL; cpair[3].pvalue = NULL;
if (!pdb_virtual_unwind(csw, curr_pc, context, cpair)) if (!pdb_virtual_unwind(csw, curr_pc, pcontext, cpair))
{ {
/* do a simple unwind using ebp /* do a simple unwind using ebp
* we assume a "regular" prologue in the function has been used * we assume a "regular" prologue in the function has been used
@ -130,7 +130,6 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw,
} }
return TRUE; return TRUE;
} }
#endif
enum st_mode {stm_start, stm_32bit, stm_16bit, stm_done}; enum st_mode {stm_start, stm_32bit, stm_16bit, stm_done};
@ -147,7 +146,8 @@ enum st_mode {stm_start, stm_32bit, stm_16bit, stm_done};
#define set_curr_mode(m) {frame->Reserved[__CurrentModeCount] &= ~0x0F; frame->Reserved[__CurrentModeCount] |= (m & 0x0F);} #define set_curr_mode(m) {frame->Reserved[__CurrentModeCount] &= ~0x0F; frame->Reserved[__CurrentModeCount] |= (m & 0x0F);}
#define inc_curr_count() (frame->Reserved[__CurrentModeCount] += 0x10) #define inc_curr_count() (frame->Reserved[__CurrentModeCount] += 0x10)
static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL i386_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
union ctx *context)
{ {
STACK32FRAME frame32; STACK32FRAME frame32;
STACK16FRAME frame16; STACK16FRAME frame16;
@ -157,10 +157,8 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
WORD val16; WORD val16;
DWORD val32; DWORD val32;
BOOL do_switch; BOOL do_switch;
#ifdef __i386__
unsigned deltapc; unsigned deltapc;
CONTEXT _context; union ctx _context;
#endif
/* sanity check */ /* sanity check */
if (curr_mode >= stm_done) return FALSE; if (curr_mode >= stm_done) return FALSE;
@ -174,7 +172,6 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
wine_dbgstr_longlong(curr_count), wine_dbgstr_longlong(curr_count),
(void*)(DWORD_PTR)curr_switch, (void*)(DWORD_PTR)next_switch); (void*)(DWORD_PTR)curr_switch, (void*)(DWORD_PTR)next_switch);
#ifdef __i386__
/* if we're at first call (which doesn't actually unwind, it just computes ReturnPC, /* if we're at first call (which doesn't actually unwind, it just computes ReturnPC,
* or if we're doing the first real unwind (count == 1), then we can directly use * or if we're doing the first real unwind (count == 1), then we can directly use
* eip. otherwise, eip is *after* the insn that actually made the call to * eip. otherwise, eip is *after* the insn that actually made the call to
@ -190,15 +187,18 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
/* setup a pseudo context for the rest of the code (esp. unwinding) */ /* setup a pseudo context for the rest of the code (esp. unwinding) */
context = &_context; context = &_context;
memset(context, 0, sizeof(*context)); memset(context, 0, sizeof(*context));
context->ContextFlags = CONTEXT_CONTROL | CONTEXT_SEGMENTS; context->x86.ContextFlags = WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_SEGMENTS;
if (frame->AddrPC.Mode != AddrModeFlat) context->SegCs = frame->AddrPC.Segment; if (frame->AddrPC.Mode != AddrModeFlat)
context->Eip = frame->AddrPC.Offset; context->x86.SegCs = frame->AddrPC.Segment;
if (frame->AddrFrame.Mode != AddrModeFlat) context->SegSs = frame->AddrFrame.Segment; context->x86.Eip = frame->AddrPC.Offset;
context->Ebp = frame->AddrFrame.Offset; if (frame->AddrFrame.Mode != AddrModeFlat)
if (frame->AddrStack.Mode != AddrModeFlat) context->SegSs = frame->AddrStack.Segment; context->x86.SegSs = frame->AddrFrame.Segment;
context->Esp = frame->AddrStack.Offset; context->x86.Ebp = frame->AddrFrame.Offset;
if (frame->AddrStack.Mode != AddrModeFlat)
context->x86.SegSs = frame->AddrStack.Segment;
context->x86.Esp = frame->AddrStack.Offset;
} }
#endif
if (curr_mode == stm_start) if (curr_mode == stm_start)
{ {
THREAD_BASIC_INFORMATION info; THREAD_BASIC_INFORMATION info;
@ -396,18 +396,16 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
} }
else else
{ {
#ifdef __i386__
if (!fetch_next_frame32(csw, context, sw_xlat_addr(csw, &frame->AddrPC) - deltapc)) if (!fetch_next_frame32(csw, context, sw_xlat_addr(csw, &frame->AddrPC) - deltapc))
goto done_err; goto done_err;
frame->AddrStack.Mode = frame->AddrFrame.Mode = frame->AddrPC.Mode = AddrModeFlat; frame->AddrStack.Mode = frame->AddrFrame.Mode = frame->AddrPC.Mode = AddrModeFlat;
frame->AddrStack.Offset = context->Esp; frame->AddrStack.Offset = context->x86.Esp;
frame->AddrFrame.Offset = context->Ebp; frame->AddrFrame.Offset = context->x86.Ebp;
if (frame->AddrReturn.Offset != context->Eip) if (frame->AddrReturn.Offset != context->x86.Eip)
FIXME("new PC=%s different from Eip=%x\n", FIXME("new PC=%s different from Eip=%x\n",
wine_dbgstr_longlong(frame->AddrReturn.Offset), context->Eip); wine_dbgstr_longlong(frame->AddrReturn.Offset), context->x86.Eip);
frame->AddrPC.Offset = context->Eip; frame->AddrPC.Offset = context->x86.Eip;
#endif
} }
} }
} }
@ -454,14 +452,13 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
sw_read_mem(csw, p + (2 + i) * sizeof(WORD), &val16, sizeof(val16)); sw_read_mem(csw, p + (2 + i) * sizeof(WORD), &val16, sizeof(val16));
frame->Params[i] = val16; frame->Params[i] = val16;
} }
#ifdef __i386__
if (context) if (context)
{ {
#define SET(field, seg, reg) \ #define SET(field, seg, reg) \
switch (frame->field.Mode) \ switch (frame->field.Mode) \
{ \ { \
case AddrModeFlat: context->reg = frame->field.Offset; break; \ case AddrModeFlat: context->x86.reg = frame->field.Offset; break; \
case AddrMode1616: context->seg = frame->field.Segment; context->reg = frame->field.Offset; break; \ case AddrMode1616: context->x86.seg = frame->field.Segment; context->x86.reg = frame->field.Offset; break; \
default: assert(0); \ default: assert(0); \
} }
SET(AddrStack, SegSs, Esp); SET(AddrStack, SegSs, Esp);
@ -469,19 +466,17 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
SET(AddrReturn, SegCs, Eip); SET(AddrReturn, SegCs, Eip);
#undef SET #undef SET
} }
#endif
} }
else else
{ {
unsigned int i; unsigned int i;
#ifdef __i386__ union ctx newctx = *context;
CONTEXT newctx = *context;
if (!fetch_next_frame32(csw, &newctx, frame->AddrPC.Offset - deltapc)) if (!fetch_next_frame32(csw, &newctx, frame->AddrPC.Offset - deltapc))
goto done_err; goto done_err;
frame->AddrReturn.Mode = AddrModeFlat; frame->AddrReturn.Mode = AddrModeFlat;
frame->AddrReturn.Offset = newctx.Eip; frame->AddrReturn.Offset = newctx.x86.Eip;
#endif
for (i = 0; i < ARRAY_SIZE(frame->Params); i++) for (i = 0; i < ARRAY_SIZE(frame->Params); i++)
{ {
sw_read_mem(csw, frame->AddrFrame.Offset + (2 + i) * sizeof(DWORD), &val32, sizeof(val32)); sw_read_mem(csw, frame->AddrFrame.Offset + (2 + i) * sizeof(DWORD), &val32, sizeof(val32));
@ -568,9 +563,10 @@ reg: fop 31
return reg; return reg;
} }
static void* i386_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size) static void *i386_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{ {
#ifdef __i386__ WOW64_CONTEXT *ctx = &pctx->x86;
switch (regno) switch (regno)
{ {
case CV_REG_EAX: *size = sizeof(ctx->Eax); return &ctx->Eax; case CV_REG_EAX: *size = sizeof(ctx->Eax); return &ctx->Eax;
@ -611,7 +607,6 @@ static void* i386_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size
case CV_REG_GS: *size = sizeof(ctx->SegGs); return &ctx->SegGs; case CV_REG_GS: *size = sizeof(ctx->SegGs); return &ctx->SegGs;
} }
#endif
FIXME("Unknown register %x\n", regno); FIXME("Unknown register %x\n", regno);
return NULL; return NULL;
} }

View File

@ -48,7 +48,8 @@ static BOOL ppc_get_addr(HANDLE hThread, const CONTEXT* ctx,
return FALSE; return FALSE;
} }
static BOOL ppc_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL ppc_stack_walk(struct cpu_stack_walk* csw, STACKFRAME64 *frame,
union ctx *ctx)
{ {
FIXME("not done\n"); FIXME("not done\n");
return FALSE; return FALSE;
@ -60,7 +61,7 @@ static unsigned ppc_map_dwarf_register(unsigned regno, BOOL eh_frame)
return 0; return 0;
} }
static void* ppc_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size) static void *ppc_fetch_context_reg(union ctx *ctx, unsigned regno, unsigned *size)
{ {
FIXME("NIY\n"); FIXME("NIY\n");
return NULL; return NULL;

View File

@ -576,12 +576,13 @@ static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw,
* modify (at least) context.{rip, rsp, rbp} using unwind information * modify (at least) context.{rip, rsp, rbp} using unwind information
* either out of PE exception handlers, debug info (dwarf), or simple stack unwind * either out of PE exception handlers, debug info (dwarf), or simple stack unwind
*/ */
static BOOL fetch_next_frame(struct cpu_stack_walk* csw, CONTEXT* context, static BOOL fetch_next_frame(struct cpu_stack_walk *csw, union ctx *pcontext,
DWORD_PTR curr_pc, void** prtf) DWORD_PTR curr_pc, void** prtf)
{ {
DWORD_PTR cfa; DWORD_PTR cfa;
RUNTIME_FUNCTION* rtf; RUNTIME_FUNCTION* rtf;
DWORD64 base; DWORD64 base;
CONTEXT *context = &pcontext->ctx;
if (!curr_pc || !(base = sw_module_base(csw, curr_pc))) return FALSE; if (!curr_pc || !(base = sw_module_base(csw, curr_pc))) return FALSE;
rtf = sw_table_access(csw, curr_pc); rtf = sw_table_access(csw, curr_pc);
@ -590,7 +591,7 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw, CONTEXT* context,
{ {
return interpret_function_table_entry(csw, context, rtf, base); return interpret_function_table_entry(csw, context, rtf, base);
} }
else if (dwarf2_virtual_unwind(csw, curr_pc, context, &cfa)) else if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &cfa))
{ {
context->Rsp = cfa; context->Rsp = cfa;
TRACE("next function rip=%016lx\n", context->Rip); TRACE("next function rip=%016lx\n", context->Rip);
@ -608,7 +609,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw, CONTEXT* context,
return default_unwind(csw, context); return default_unwind(csw, context);
} }
static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL x86_64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
union ctx *context)
{ {
unsigned deltapc = curr_count <= 1 ? 0 : 1; unsigned deltapc = curr_count <= 1 ? 0 : 1;
@ -643,8 +645,8 @@ static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame,
} }
else else
{ {
if (context->Rsp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n"); if (context->ctx.Rsp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
if (context->Rip != frame->AddrPC.Offset) FIXME("inconsistent Instruction Pointer\n"); if (context->ctx.Rip != frame->AddrPC.Offset) FIXME("inconsistent Instruction Pointer\n");
if (frame->AddrReturn.Offset == 0) goto done_err; if (frame->AddrReturn.Offset == 0) goto done_err;
if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc, &frame->FuncTableEntry)) if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc, &frame->FuncTableEntry))
@ -655,17 +657,17 @@ static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame,
memset(&frame->Params, 0, sizeof(frame->Params)); memset(&frame->Params, 0, sizeof(frame->Params));
/* set frame information */ /* set frame information */
frame->AddrStack.Offset = context->Rsp; frame->AddrStack.Offset = context->ctx.Rsp;
frame->AddrFrame.Offset = context->Rbp; frame->AddrFrame.Offset = context->ctx.Rbp;
frame->AddrPC.Offset = context->Rip; frame->AddrPC.Offset = context->ctx.Rip;
if (1) if (1)
{ {
CONTEXT newctx = *context; union ctx newctx = *context;
if (!fetch_next_frame(csw, &newctx, frame->AddrPC.Offset - deltapc, NULL)) if (!fetch_next_frame(csw, &newctx, frame->AddrPC.Offset - deltapc, NULL))
goto done_err; goto done_err;
frame->AddrReturn.Mode = AddrModeFlat; frame->AddrReturn.Mode = AddrModeFlat;
frame->AddrReturn.Offset = newctx.Rip; frame->AddrReturn.Offset = newctx.ctx.Rip;
} }
frame->Far = TRUE; frame->Far = TRUE;
@ -687,7 +689,8 @@ done_err:
return FALSE; return FALSE;
} }
#else #else
static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context) static BOOL x86_64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
union ctx *ctx)
{ {
return FALSE; return FALSE;
} }
@ -777,9 +780,11 @@ static unsigned x86_64_map_dwarf_register(unsigned regno, BOOL eh_frame)
return reg; return reg;
} }
static void* x86_64_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size) static void *x86_64_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{ {
#ifdef __x86_64__ #ifdef __x86_64__
CONTEXT *ctx = &pctx->ctx;
switch (regno) switch (regno)
{ {
case CV_AMD64_RAX: *size = sizeof(ctx->Rax); return &ctx->Rax; case CV_AMD64_RAX: *size = sizeof(ctx->Rax); return &ctx->Rax;

View File

@ -511,6 +511,12 @@ struct dump_context
MINIDUMP_CALLBACK_INFORMATION* cb; MINIDUMP_CALLBACK_INFORMATION* cb;
}; };
union ctx
{
CONTEXT ctx;
WOW64_CONTEXT x86;
};
enum cpu_addr {cpu_addr_pc, cpu_addr_stack, cpu_addr_frame}; enum cpu_addr {cpu_addr_pc, cpu_addr_stack, cpu_addr_frame};
struct cpu struct cpu
{ {
@ -523,7 +529,8 @@ struct cpu
enum cpu_addr, ADDRESS64* addr); enum cpu_addr, ADDRESS64* addr);
/* stack manipulation */ /* stack manipulation */
BOOL (*stack_walk)(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context); BOOL (*stack_walk)(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
union ctx *ctx);
/* module manipulation */ /* module manipulation */
void* (*find_runtime_function)(struct module*, DWORD64 addr); void* (*find_runtime_function)(struct module*, DWORD64 addr);
@ -532,7 +539,7 @@ struct cpu
unsigned (*map_dwarf_register)(unsigned regno, BOOL eh_frame); unsigned (*map_dwarf_register)(unsigned regno, BOOL eh_frame);
/* context related manipulation */ /* context related manipulation */
void* (*fetch_context_reg)(CONTEXT* context, unsigned regno, unsigned* size); void * (*fetch_context_reg)(union ctx *ctx, unsigned regno, unsigned *size);
const char* (*fetch_regname)(unsigned regno); const char* (*fetch_regname)(unsigned regno);
/* minidump per CPU extension */ /* minidump per CPU extension */
@ -645,8 +652,8 @@ struct pdb_cmd_pair {
const char* name; const char* name;
DWORD* pvalue; DWORD* pvalue;
}; };
extern BOOL pdb_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip, extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
CONTEXT* context, struct pdb_cmd_pair* cpair) DECLSPEC_HIDDEN; union ctx *context, struct pdb_cmd_pair *cpair) DECLSPEC_HIDDEN;
/* path.c */ /* path.c */
extern BOOL path_find_symbol_file(const struct process* pcs, PCSTR full_path, extern BOOL path_find_symbol_file(const struct process* pcs, PCSTR full_path,
@ -684,8 +691,8 @@ extern BOOL stabs_parse(struct module* module, unsigned long load_offset
extern BOOL dwarf2_parse(struct module* module, unsigned long load_offset, extern BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
const struct elf_thunk_area* thunks, const struct elf_thunk_area* thunks,
struct image_file_map* fmap) DECLSPEC_HIDDEN; struct image_file_map* fmap) DECLSPEC_HIDDEN;
extern BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip, extern BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
CONTEXT* context, ULONG_PTR* cfa) DECLSPEC_HIDDEN; union ctx *ctx, ULONG_PTR *cfa) DECLSPEC_HIDDEN;
/* stack.c */ /* stack.c */
extern BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz) DECLSPEC_HIDDEN; extern BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz) DECLSPEC_HIDDEN;

View File

@ -3008,7 +3008,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
} }
/* retrieve a context register from its dwarf number */ /* retrieve a context register from its dwarf number */
static ULONG_PTR get_context_reg(CONTEXT *context, ULONG_PTR dw_reg) static ULONG_PTR get_context_reg(union ctx *context, ULONG_PTR dw_reg)
{ {
unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz; unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz;
ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz); ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz);
@ -3022,8 +3022,8 @@ static ULONG_PTR get_context_reg(CONTEXT *context, ULONG_PTR dw_reg)
} }
/* set a context register from its dwarf number */ /* set a context register from its dwarf number */
static void set_context_reg(struct cpu_stack_walk* csw, CONTEXT *context, ULONG_PTR dw_reg, static void set_context_reg(struct cpu_stack_walk* csw, union ctx *context,
ULONG_PTR val, BOOL isdebuggee) ULONG_PTR dw_reg, ULONG_PTR val, BOOL isdebuggee)
{ {
unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz; unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz;
ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz); ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz);
@ -3056,7 +3056,8 @@ static void set_context_reg(struct cpu_stack_walk* csw, CONTEXT *context, ULONG_
} }
/* copy a register from one context to another using dwarf number */ /* copy a register from one context to another using dwarf number */
static void copy_context_reg(CONTEXT *dstcontext, ULONG_PTR dwregdst, CONTEXT* srccontext, ULONG_PTR dwregsrc) static void copy_context_reg(union ctx *dstcontext, ULONG_PTR dwregdst,
union ctx *srccontext, ULONG_PTR dwregsrc)
{ {
unsigned regdstno = dbghelp_current_cpu->map_dwarf_register(dwregdst, TRUE), szdst; unsigned regdstno = dbghelp_current_cpu->map_dwarf_register(dwregdst, TRUE), szdst;
unsigned regsrcno = dbghelp_current_cpu->map_dwarf_register(dwregsrc, TRUE), szsrc; unsigned regsrcno = dbghelp_current_cpu->map_dwarf_register(dwregsrc, TRUE), szsrc;
@ -3073,7 +3074,7 @@ static void copy_context_reg(CONTEXT *dstcontext, ULONG_PTR dwregdst, CONTEXT* s
} }
static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_walk* csw, static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_walk* csw,
const unsigned char* zp, CONTEXT *context) const unsigned char* zp, union ctx *context)
{ {
dwarf2_traverse_context_t ctx; dwarf2_traverse_context_t ctx;
ULONG_PTR reg, sz, tmp, stack[64]; ULONG_PTR reg, sz, tmp, stack[64];
@ -3184,11 +3185,11 @@ static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_w
} }
static void apply_frame_state(const struct module* module, struct cpu_stack_walk* csw, static void apply_frame_state(const struct module* module, struct cpu_stack_walk* csw,
CONTEXT *context, struct frame_state *state, ULONG_PTR* cfa) union ctx *context, struct frame_state *state, ULONG_PTR* cfa)
{ {
unsigned int i; unsigned int i;
ULONG_PTR value; ULONG_PTR value;
CONTEXT new_context = *context; union ctx new_context = *context;
switch (state->cfa_rule) switch (state->cfa_rule)
{ {
@ -3240,7 +3241,8 @@ static void apply_frame_state(const struct module* module, struct cpu_stack_walk
* dwarf2_virtual_unwind * dwarf2_virtual_unwind
* *
*/ */
BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, ULONG_PTR ip, CONTEXT* context, ULONG_PTR* cfa) BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip,
union ctx *context, ULONG_PTR *cfa)
{ {
struct module_pair pair; struct module_pair pair;
struct frame_info info; struct frame_info info;

View File

@ -3196,8 +3196,8 @@ done:
return FALSE; return FALSE;
} }
BOOL pdb_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip, BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
CONTEXT* context, struct pdb_cmd_pair* cpair) union ctx *context, struct pdb_cmd_pair *cpair)
{ {
struct module_pair pair; struct module_pair pair;
struct pdb_module_info* pdb_info; struct pdb_module_info* pdb_info;