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:
parent
a3a2e6413b
commit
3ce304e601
|
@ -63,13 +63,14 @@ enum st_mode {stm_start, stm_arm, stm_done};
|
|||
* modify (at least) context.Pc using unwind information
|
||||
* either out of debug info (dwarf), or simple Lr trace
|
||||
*/
|
||||
static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
|
||||
CONTEXT* context, DWORD_PTR curr_pc)
|
||||
static BOOL fetch_next_frame(struct cpu_stack_walk* csw, union ctx *pcontext,
|
||||
DWORD_PTR curr_pc)
|
||||
{
|
||||
DWORD_PTR xframe;
|
||||
CONTEXT *context = &pcontext->ctx;
|
||||
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->Pc = oldReturn;
|
||||
|
@ -82,7 +83,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
|
|||
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;
|
||||
|
||||
|
@ -109,8 +111,8 @@ static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
|
|||
}
|
||||
else
|
||||
{
|
||||
if (context->Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
|
||||
if (context->Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
|
||||
if (context->ctx.Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
|
||||
if (context->ctx.Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
|
||||
|
||||
if (frame->AddrReturn.Offset == 0) goto done_err;
|
||||
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));
|
||||
|
||||
/* set frame information */
|
||||
frame->AddrStack.Offset = context->Sp;
|
||||
frame->AddrReturn.Offset = context->Lr;
|
||||
frame->AddrFrame.Offset = context->R11;
|
||||
frame->AddrPC.Offset = context->Pc;
|
||||
frame->AddrStack.Offset = context->ctx.Sp;
|
||||
frame->AddrReturn.Offset = context->ctx.Lr;
|
||||
frame->AddrFrame.Offset = context->ctx.R11;
|
||||
frame->AddrPC.Offset = context->ctx.Pc;
|
||||
|
||||
frame->Far = TRUE;
|
||||
frame->Virtual = TRUE;
|
||||
|
@ -144,7 +146,8 @@ done_err:
|
|||
return FALSE;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
@ -159,9 +162,11 @@ static unsigned arm_map_dwarf_register(unsigned regno, BOOL eh_frame)
|
|||
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__
|
||||
CONTEXT *ctx = &pctx->ctx;
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case CV_ARM_R0 + 0: *size = sizeof(ctx->R0); return &ctx->R0;
|
||||
|
|
|
@ -65,13 +65,14 @@ enum st_mode {stm_start, stm_arm64, stm_done};
|
|||
* modify (at least) context.Pc using unwind information
|
||||
* either out of debug info (dwarf), or simple Lr trace
|
||||
*/
|
||||
static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
|
||||
CONTEXT* context, DWORD_PTR curr_pc)
|
||||
static BOOL fetch_next_frame(struct cpu_stack_walk* csw, union ctx *pcontext,
|
||||
DWORD_PTR curr_pc)
|
||||
{
|
||||
DWORD_PTR xframe;
|
||||
CONTEXT *context = &pcontext->ctx;
|
||||
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->Pc = oldReturn;
|
||||
|
@ -84,7 +85,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
|
|||
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;
|
||||
|
||||
|
@ -111,8 +113,8 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
|
|||
}
|
||||
else
|
||||
{
|
||||
if (context->Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
|
||||
if (context->Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
|
||||
if (context->ctx.Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
|
||||
if (context->ctx.Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
|
||||
|
||||
if (frame->AddrReturn.Offset == 0) goto done_err;
|
||||
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));
|
||||
|
||||
/* set frame information */
|
||||
frame->AddrStack.Offset = context->Sp;
|
||||
frame->AddrReturn.Offset = context->u.s.Lr;
|
||||
frame->AddrFrame.Offset = context->u.s.Fp;
|
||||
frame->AddrPC.Offset = context->Pc;
|
||||
frame->AddrStack.Offset = context->ctx.Sp;
|
||||
frame->AddrReturn.Offset = context->ctx.u.s.Lr;
|
||||
frame->AddrFrame.Offset = context->ctx.u.s.Fp;
|
||||
frame->AddrPC.Offset = context->ctx.Pc;
|
||||
|
||||
frame->Far = TRUE;
|
||||
frame->Virtual = TRUE;
|
||||
|
@ -146,7 +148,8 @@ done_err:
|
|||
return FALSE;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
@ -164,9 +167,11 @@ static unsigned arm64_map_dwarf_register(unsigned regno, BOOL eh_frame)
|
|||
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__
|
||||
CONTEXT *ctx = pctx;
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case CV_ARM64_X0 + 0:
|
||||
|
|
|
@ -86,20 +86,20 @@ static BOOL i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
/* fetch_next_frame32()
|
||||
*
|
||||
* modify (at least) context.{eip, esp, ebp} using unwind information
|
||||
* either out of debug info (dwarf, pdb), or simple stack unwind
|
||||
*/
|
||||
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;
|
||||
struct pdb_cmd_pair cpair[4];
|
||||
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;
|
||||
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[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
|
||||
* 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;
|
||||
}
|
||||
#endif
|
||||
|
||||
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 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;
|
||||
STACK16FRAME frame16;
|
||||
|
@ -157,10 +157,8 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
|
|||
WORD val16;
|
||||
DWORD val32;
|
||||
BOOL do_switch;
|
||||
#ifdef __i386__
|
||||
unsigned deltapc;
|
||||
CONTEXT _context;
|
||||
#endif
|
||||
union ctx _context;
|
||||
|
||||
/* sanity check */
|
||||
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),
|
||||
(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,
|
||||
* 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
|
||||
|
@ -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) */
|
||||
context = &_context;
|
||||
memset(context, 0, sizeof(*context));
|
||||
context->ContextFlags = CONTEXT_CONTROL | CONTEXT_SEGMENTS;
|
||||
if (frame->AddrPC.Mode != AddrModeFlat) context->SegCs = frame->AddrPC.Segment;
|
||||
context->Eip = frame->AddrPC.Offset;
|
||||
if (frame->AddrFrame.Mode != AddrModeFlat) context->SegSs = frame->AddrFrame.Segment;
|
||||
context->Ebp = frame->AddrFrame.Offset;
|
||||
if (frame->AddrStack.Mode != AddrModeFlat) context->SegSs = frame->AddrStack.Segment;
|
||||
context->Esp = frame->AddrStack.Offset;
|
||||
context->x86.ContextFlags = WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_SEGMENTS;
|
||||
if (frame->AddrPC.Mode != AddrModeFlat)
|
||||
context->x86.SegCs = frame->AddrPC.Segment;
|
||||
context->x86.Eip = frame->AddrPC.Offset;
|
||||
if (frame->AddrFrame.Mode != AddrModeFlat)
|
||||
context->x86.SegSs = frame->AddrFrame.Segment;
|
||||
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)
|
||||
{
|
||||
THREAD_BASIC_INFORMATION info;
|
||||
|
@ -396,18 +396,16 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef __i386__
|
||||
if (!fetch_next_frame32(csw, context, sw_xlat_addr(csw, &frame->AddrPC) - deltapc))
|
||||
goto done_err;
|
||||
|
||||
frame->AddrStack.Mode = frame->AddrFrame.Mode = frame->AddrPC.Mode = AddrModeFlat;
|
||||
frame->AddrStack.Offset = context->Esp;
|
||||
frame->AddrFrame.Offset = context->Ebp;
|
||||
if (frame->AddrReturn.Offset != context->Eip)
|
||||
frame->AddrStack.Offset = context->x86.Esp;
|
||||
frame->AddrFrame.Offset = context->x86.Ebp;
|
||||
if (frame->AddrReturn.Offset != context->x86.Eip)
|
||||
FIXME("new PC=%s different from Eip=%x\n",
|
||||
wine_dbgstr_longlong(frame->AddrReturn.Offset), context->Eip);
|
||||
frame->AddrPC.Offset = context->Eip;
|
||||
#endif
|
||||
wine_dbgstr_longlong(frame->AddrReturn.Offset), context->x86.Eip);
|
||||
frame->AddrPC.Offset = context->x86.Eip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
frame->Params[i] = val16;
|
||||
}
|
||||
#ifdef __i386__
|
||||
if (context)
|
||||
{
|
||||
#define SET(field, seg, reg) \
|
||||
switch (frame->field.Mode) \
|
||||
{ \
|
||||
case AddrModeFlat: context->reg = frame->field.Offset; break; \
|
||||
case AddrMode1616: context->seg = frame->field.Segment; context->reg = frame->field.Offset; break; \
|
||||
case AddrModeFlat: context->x86.reg = frame->field.Offset; break; \
|
||||
case AddrMode1616: context->x86.seg = frame->field.Segment; context->x86.reg = frame->field.Offset; break; \
|
||||
default: assert(0); \
|
||||
}
|
||||
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);
|
||||
#undef SET
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i;
|
||||
#ifdef __i386__
|
||||
CONTEXT newctx = *context;
|
||||
union ctx newctx = *context;
|
||||
|
||||
if (!fetch_next_frame32(csw, &newctx, frame->AddrPC.Offset - deltapc))
|
||||
goto done_err;
|
||||
frame->AddrReturn.Mode = AddrModeFlat;
|
||||
frame->AddrReturn.Offset = newctx.Eip;
|
||||
#endif
|
||||
frame->AddrReturn.Offset = newctx.x86.Eip;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(frame->Params); i++)
|
||||
{
|
||||
sw_read_mem(csw, frame->AddrFrame.Offset + (2 + i) * sizeof(DWORD), &val32, sizeof(val32));
|
||||
|
@ -568,9 +563,10 @@ reg: fop 31
|
|||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
}
|
||||
#endif
|
||||
FIXME("Unknown register %x\n", regno);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ static BOOL ppc_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
|||
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");
|
||||
return FALSE;
|
||||
|
@ -60,7 +61,7 @@ static unsigned ppc_map_dwarf_register(unsigned regno, BOOL eh_frame)
|
|||
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");
|
||||
return NULL;
|
||||
|
|
|
@ -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
|
||||
* 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 cfa;
|
||||
RUNTIME_FUNCTION* rtf;
|
||||
DWORD64 base;
|
||||
CONTEXT *context = &pcontext->ctx;
|
||||
|
||||
if (!curr_pc || !(base = sw_module_base(csw, curr_pc))) return FALSE;
|
||||
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);
|
||||
}
|
||||
else if (dwarf2_virtual_unwind(csw, curr_pc, context, &cfa))
|
||||
else if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &cfa))
|
||||
{
|
||||
context->Rsp = cfa;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -643,8 +645,8 @@ static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (context->Rsp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
|
||||
if (context->Rip != frame->AddrPC.Offset) FIXME("inconsistent Instruction Pointer\n");
|
||||
if (context->ctx.Rsp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
|
||||
if (context->ctx.Rip != frame->AddrPC.Offset) FIXME("inconsistent Instruction Pointer\n");
|
||||
|
||||
if (frame->AddrReturn.Offset == 0) goto done_err;
|
||||
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));
|
||||
|
||||
/* set frame information */
|
||||
frame->AddrStack.Offset = context->Rsp;
|
||||
frame->AddrFrame.Offset = context->Rbp;
|
||||
frame->AddrPC.Offset = context->Rip;
|
||||
frame->AddrStack.Offset = context->ctx.Rsp;
|
||||
frame->AddrFrame.Offset = context->ctx.Rbp;
|
||||
frame->AddrPC.Offset = context->ctx.Rip;
|
||||
if (1)
|
||||
{
|
||||
CONTEXT newctx = *context;
|
||||
union ctx newctx = *context;
|
||||
|
||||
if (!fetch_next_frame(csw, &newctx, frame->AddrPC.Offset - deltapc, NULL))
|
||||
goto done_err;
|
||||
frame->AddrReturn.Mode = AddrModeFlat;
|
||||
frame->AddrReturn.Offset = newctx.Rip;
|
||||
frame->AddrReturn.Offset = newctx.ctx.Rip;
|
||||
}
|
||||
|
||||
frame->Far = TRUE;
|
||||
|
@ -687,7 +689,8 @@ done_err:
|
|||
return FALSE;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
@ -777,9 +780,11 @@ static unsigned x86_64_map_dwarf_register(unsigned regno, BOOL eh_frame)
|
|||
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__
|
||||
CONTEXT *ctx = &pctx->ctx;
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case CV_AMD64_RAX: *size = sizeof(ctx->Rax); return &ctx->Rax;
|
||||
|
|
|
@ -511,6 +511,12 @@ struct dump_context
|
|||
MINIDUMP_CALLBACK_INFORMATION* cb;
|
||||
};
|
||||
|
||||
union ctx
|
||||
{
|
||||
CONTEXT ctx;
|
||||
WOW64_CONTEXT x86;
|
||||
};
|
||||
|
||||
enum cpu_addr {cpu_addr_pc, cpu_addr_stack, cpu_addr_frame};
|
||||
struct cpu
|
||||
{
|
||||
|
@ -523,7 +529,8 @@ struct cpu
|
|||
enum cpu_addr, ADDRESS64* addr);
|
||||
|
||||
/* 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 */
|
||||
void* (*find_runtime_function)(struct module*, DWORD64 addr);
|
||||
|
@ -532,7 +539,7 @@ struct cpu
|
|||
unsigned (*map_dwarf_register)(unsigned regno, BOOL eh_frame);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* minidump per CPU extension */
|
||||
|
@ -645,8 +652,8 @@ struct pdb_cmd_pair {
|
|||
const char* name;
|
||||
DWORD* pvalue;
|
||||
};
|
||||
extern BOOL pdb_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
|
||||
CONTEXT* context, struct pdb_cmd_pair* cpair) DECLSPEC_HIDDEN;
|
||||
extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
|
||||
union ctx *context, struct pdb_cmd_pair *cpair) DECLSPEC_HIDDEN;
|
||||
|
||||
/* path.c */
|
||||
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,
|
||||
const struct elf_thunk_area* thunks,
|
||||
struct image_file_map* fmap) DECLSPEC_HIDDEN;
|
||||
extern BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
|
||||
CONTEXT* context, ULONG_PTR* cfa) DECLSPEC_HIDDEN;
|
||||
extern BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
|
||||
union ctx *ctx, ULONG_PTR *cfa) DECLSPEC_HIDDEN;
|
||||
|
||||
/* stack.c */
|
||||
extern BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -3008,7 +3008,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
|
|||
}
|
||||
|
||||
/* 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;
|
||||
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 */
|
||||
static void set_context_reg(struct cpu_stack_walk* csw, CONTEXT *context, ULONG_PTR dw_reg,
|
||||
ULONG_PTR val, BOOL isdebuggee)
|
||||
static void set_context_reg(struct cpu_stack_walk* csw, union ctx *context,
|
||||
ULONG_PTR dw_reg, ULONG_PTR val, BOOL isdebuggee)
|
||||
{
|
||||
unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), 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 */
|
||||
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 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,
|
||||
const unsigned char* zp, CONTEXT *context)
|
||||
const unsigned char* zp, union ctx *context)
|
||||
{
|
||||
dwarf2_traverse_context_t ctx;
|
||||
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,
|
||||
CONTEXT *context, struct frame_state *state, ULONG_PTR* cfa)
|
||||
union ctx *context, struct frame_state *state, ULONG_PTR* cfa)
|
||||
{
|
||||
unsigned int i;
|
||||
ULONG_PTR value;
|
||||
CONTEXT new_context = *context;
|
||||
union ctx new_context = *context;
|
||||
|
||||
switch (state->cfa_rule)
|
||||
{
|
||||
|
@ -3240,7 +3241,8 @@ static void apply_frame_state(const struct module* module, struct cpu_stack_walk
|
|||
* 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 frame_info info;
|
||||
|
|
|
@ -3196,8 +3196,8 @@ done:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL pdb_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
|
||||
CONTEXT* context, struct pdb_cmd_pair* cpair)
|
||||
BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
|
||||
union ctx *context, struct pdb_cmd_pair *cpair)
|
||||
{
|
||||
struct module_pair pair;
|
||||
struct pdb_module_info* pdb_info;
|
||||
|
|
Loading…
Reference in New Issue