From 7470eb9ced8b0f1f1180fa4a6d305645cbd4704a Mon Sep 17 00:00:00 2001 From: winesync Date: Fri, 11 Sep 2020 13:20:36 +0200 Subject: [PATCH] [WINESYNC] dbghelp: Use WOW64_CONTEXT instead of CONTEXT for i386 backend. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard wine commit id 3ce304e60100962503bcded0adb69659f849d1b4 by Zebediah Figura --- dll/win32/dbghelp/compat.h | 68 +++++++++++++++++++++++++++ dll/win32/dbghelp/cpu_arm.c | 31 +++++++------ dll/win32/dbghelp/cpu_arm64.c | 29 +++++++----- dll/win32/dbghelp/cpu_i386.c | 71 +++++++++++++---------------- dll/win32/dbghelp/cpu_ppc.c | 5 +- dll/win32/dbghelp/cpu_x86_64.c | 29 +++++++----- dll/win32/dbghelp/dbghelp_private.h | 19 +++++--- dll/win32/dbghelp/dwarf.c | 18 ++++---- dll/win32/dbghelp/msc.c | 4 +- sdk/tools/winesync/dbghelp.cfg | 2 +- 10 files changed, 180 insertions(+), 96 deletions(-) diff --git a/dll/win32/dbghelp/compat.h b/dll/win32/dbghelp/compat.h index 8f6047ea120..4917889ca1c 100644 --- a/dll/win32/dbghelp/compat.h +++ b/dll/win32/dbghelp/compat.h @@ -202,6 +202,74 @@ typedef struct _EXCEPTION_RECORD { DWORD NumberParameters; ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD, *PEXCEPTION_RECORD; + +#define WOW64_CONTEXT_i386 0x00010000 +#define WOW64_CONTEXT_i486 0x00010000 +#define WOW64_CONTEXT_CONTROL (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000001)) +#define WOW64_CONTEXT_INTEGER (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000002)) +#define WOW64_CONTEXT_SEGMENTS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000004)) +#define WOW64_CONTEXT_FLOATING_POINT (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000008)) +#define WOW64_CONTEXT_DEBUG_REGISTERS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000010)) +#define WOW64_CONTEXT_EXTENDED_REGISTERS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000020)) +#define WOW64_CONTEXT_FULL (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS) +#define WOW64_CONTEXT_ALL (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | \ + WOW64_CONTEXT_SEGMENTS | WOW64_CONTEXT_FLOATING_POINT | \ + WOW64_CONTEXT_DEBUG_REGISTERS | WOW64_CONTEXT_EXTENDED_REGISTERS) + +#define WOW64_CONTEXT_XSTATE (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000040)) + +#define WOW64_CONTEXT_EXCEPTION_ACTIVE 0x08000000 +#define WOW64_CONTEXT_SERVICE_ACTIVE 0x10000000 +#define WOW64_CONTEXT_EXCEPTION_REQUEST 0x40000000 +#define WOW64_CONTEXT_EXCEPTION_REPORTING 0x80000000 + +#define WOW64_SIZE_OF_80387_REGISTERS 80 +#define WOW64_MAXIMUM_SUPPORTED_EXTENSION 512 + +typedef struct _WOW64_FLOATING_SAVE_AREA +{ + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE RegisterArea[WOW64_SIZE_OF_80387_REGISTERS]; + DWORD Cr0NpxState; +} WOW64_FLOATING_SAVE_AREA, *PWOW64_FLOATING_SAVE_AREA; + +#include "pshpack4.h" +typedef struct _WOW64_CONTEXT +{ + DWORD ContextFlags; + DWORD Dr0; + DWORD Dr1; + DWORD Dr2; + DWORD Dr3; + DWORD Dr6; + DWORD Dr7; + WOW64_FLOATING_SAVE_AREA FloatSave; + DWORD SegGs; + DWORD SegFs; + DWORD SegEs; + DWORD SegDs; + DWORD Edi; + DWORD Esi; + DWORD Ebx; + DWORD Edx; + DWORD Ecx; + DWORD Eax; + DWORD Ebp; + DWORD Eip; + DWORD SegCs; + DWORD EFlags; + DWORD Esp; + DWORD SegSs; + BYTE ExtendedRegisters[WOW64_MAXIMUM_SUPPORTED_EXTENSION]; +} WOW64_CONTEXT, *PWOW64_CONTEXT; +#include "poppack.h" + #if defined(TARGET_i386) #define SIZE_OF_80387_REGISTERS 80 #define CONTEXT_i386 0x10000 diff --git a/dll/win32/dbghelp/cpu_arm.c b/dll/win32/dbghelp/cpu_arm.c index 52461606a8b..3395b6e50cb 100644 --- a/dll/win32/dbghelp/cpu_arm.c +++ b/dll/win32/dbghelp/cpu_arm.c @@ -67,13 +67,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; @@ -86,7 +87,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; @@ -113,8 +115,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)) @@ -124,14 +126,14 @@ 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->AddrStack.Offset = context->ctx.Sp; + frame->AddrReturn.Offset = context->ctx.Lr; #ifdef __REACTOS__ - frame->AddrFrame.Offset = context->R11; + frame->AddrFrame.Offset = context->ctx.R11; #else - frame->AddrFrame.Offset = context->Fp; + frame->AddrFrame.Offset = context->ctx.Fp; #endif - frame->AddrPC.Offset = context->Pc; + frame->AddrPC.Offset = context->ctx.Pc; frame->Far = TRUE; frame->Virtual = TRUE; @@ -152,7 +154,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; } @@ -167,9 +170,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; diff --git a/dll/win32/dbghelp/cpu_arm64.c b/dll/win32/dbghelp/cpu_arm64.c index f50b3255bd0..7a4a94762e8 100644 --- a/dll/win32/dbghelp/cpu_arm64.c +++ b/dll/win32/dbghelp/cpu_arm64.c @@ -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: diff --git a/dll/win32/dbghelp/cpu_i386.c b/dll/win32/dbghelp/cpu_i386.c index e8056a78a3c..6ed98341343 100644 --- a/dll/win32/dbghelp/cpu_i386.c +++ b/dll/win32/dbghelp/cpu_i386.c @@ -90,22 +90,21 @@ static BOOL i386_get_addr(HANDLE hThread, const CONTEXT* ctx, #endif return FALSE; } -#endif /* DBGHELP_STATIC_LIB */ -#if defined(__i386__) && !defined(DBGHELP_STATIC_LIB) /* 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; @@ -115,9 +114,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; -#ifndef DBGHELP_STATIC_LIB - if (!pdb_virtual_unwind(csw, curr_pc, context, cpair)) -#endif + 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 @@ -138,7 +135,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}; @@ -155,8 +151,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) -#ifndef DBGHELP_STATIC_LIB -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; @@ -166,10 +162,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; @@ -183,7 +177,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 @@ -199,15 +192,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; @@ -405,18 +401,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; } } } @@ -463,14 +457,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); @@ -478,19 +471,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)); @@ -578,9 +569,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; @@ -621,7 +613,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; } diff --git a/dll/win32/dbghelp/cpu_ppc.c b/dll/win32/dbghelp/cpu_ppc.c index a48168594ef..e1e1cb332ca 100644 --- a/dll/win32/dbghelp/cpu_ppc.c +++ b/dll/win32/dbghelp/cpu_ppc.c @@ -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; diff --git a/dll/win32/dbghelp/cpu_x86_64.c b/dll/win32/dbghelp/cpu_x86_64.c index aa659fafe01..1087ce74646 100644 --- a/dll/win32/dbghelp/cpu_x86_64.c +++ b/dll/win32/dbghelp/cpu_x86_64.c @@ -574,12 +574,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); @@ -588,7 +589,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); @@ -606,7 +607,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; @@ -641,8 +643,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)) @@ -653,17 +655,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; @@ -685,7 +687,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; } @@ -775,9 +778,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; diff --git a/dll/win32/dbghelp/dbghelp_private.h b/dll/win32/dbghelp/dbghelp_private.h index 21198f400ab..6746494077a 100644 --- a/dll/win32/dbghelp/dbghelp_private.h +++ b/dll/win32/dbghelp/dbghelp_private.h @@ -541,6 +541,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 { @@ -553,7 +559,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); @@ -562,7 +569,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 */ @@ -677,8 +684,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, const struct module* module, @@ -716,8 +723,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; /* rsym.c */ extern BOOL rsym_parse(struct module* module, unsigned long load_offset, diff --git a/dll/win32/dbghelp/dwarf.c b/dll/win32/dbghelp/dwarf.c index 14b4a8594c7..b075bd0a591 100644 --- a/dll/win32/dbghelp/dwarf.c +++ b/dll/win32/dbghelp/dwarf.c @@ -3031,7 +3031,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); @@ -3045,8 +3045,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); @@ -3079,7 +3079,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; @@ -3096,7 +3097,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]; @@ -3207,11 +3208,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) { @@ -3263,7 +3264,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; diff --git a/dll/win32/dbghelp/msc.c b/dll/win32/dbghelp/msc.c index 62cd390ccd7..16c350184df 100644 --- a/dll/win32/dbghelp/msc.c +++ b/dll/win32/dbghelp/msc.c @@ -3199,8 +3199,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; diff --git a/sdk/tools/winesync/dbghelp.cfg b/sdk/tools/winesync/dbghelp.cfg index 9ca733f7598..f3ce74f8425 100644 --- a/sdk/tools/winesync/dbghelp.cfg +++ b/sdk/tools/winesync/dbghelp.cfg @@ -3,4 +3,4 @@ directories: files: include/dbghelp.h: sdk/include/psdk/dbghelp.h tags: - wine: 3ff8fa7ed1d28b38703125b0c8c632410e3fd980 + wine: 3ce304e60100962503bcded0adb69659f849d1b4