From bef7e1f202d9676256ad8e187d83ce0b468b9614 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Tue, 19 Oct 2021 15:51:18 +0200 Subject: [PATCH] dbghelp: Start implementing StackWalkEx. Simple copy of StackWalk implementation. Signed-off-by: Eric Pouech Signed-off-by: Alexandre Julliard --- dlls/dbghelp/dbghelp.spec | 2 +- dlls/dbghelp/stack.c | 75 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/dlls/dbghelp/dbghelp.spec b/dlls/dbghelp/dbghelp.spec index e45ac48acb2..e96c2e0d3fd 100644 --- a/dlls/dbghelp/dbghelp.spec +++ b/dlls/dbghelp/dbghelp.spec @@ -32,7 +32,7 @@ @ stdcall SearchTreeForFileW(wstr wstr ptr) @ stdcall StackWalk(long long long ptr ptr ptr ptr ptr ptr) @ stdcall StackWalk64(long long long ptr ptr ptr ptr ptr ptr) -@ stub StackWalkEx +@ stdcall StackWalkEx(long long long ptr ptr ptr ptr ptr ptr long) @ stub SymAddSourceStream @ stub SymAddSourceStreamA @ stub SymAddSourceStreamW diff --git a/dlls/dbghelp/stack.c b/dlls/dbghelp/stack.c index d04c0163c92..6c70fc805cb 100644 --- a/dlls/dbghelp/stack.c +++ b/dlls/dbghelp/stack.c @@ -245,6 +245,81 @@ BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread, return TRUE; } +/* all the fields of STACKFRAME64 are present in STACKFRAME_EX at same offset + * So casting down a STACKFRAME_EX into a STACKFRAME64 is valid! + */ +C_ASSERT(sizeof(STACKFRAME64) == FIELD_OFFSET(STACKFRAME_EX, StackFrameSize)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, AddrPC) == FIELD_OFFSET(STACKFRAME_EX, AddrPC)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, AddrReturn) == FIELD_OFFSET(STACKFRAME_EX, AddrReturn)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, AddrFrame) == FIELD_OFFSET(STACKFRAME_EX, AddrFrame)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, AddrStack) == FIELD_OFFSET(STACKFRAME_EX, AddrStack)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, AddrBStore) == FIELD_OFFSET(STACKFRAME_EX, AddrBStore)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, FuncTableEntry) == FIELD_OFFSET(STACKFRAME_EX, FuncTableEntry)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, Params) == FIELD_OFFSET(STACKFRAME_EX, Params)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, Far) == FIELD_OFFSET(STACKFRAME_EX, Far)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, Virtual) == FIELD_OFFSET(STACKFRAME_EX, Virtual)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, Reserved) == FIELD_OFFSET(STACKFRAME_EX, Reserved)); +C_ASSERT(FIELD_OFFSET(STACKFRAME64, KdHelp) == FIELD_OFFSET(STACKFRAME_EX, KdHelp)); + +/*********************************************************************** + * StackWalkEx (DBGHELP.@) + */ +BOOL WINAPI StackWalkEx(DWORD MachineType, HANDLE hProcess, HANDLE hThread, + LPSTACKFRAME_EX frame, PVOID ctx, + PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr, + DWORD flags) +{ + struct cpu_stack_walk csw; + struct cpu* cpu; + + TRACE("(%d, %p, %p, %p, %p, %p, %p, %p, %p, 0x%x)\n", + MachineType, hProcess, hThread, frame, ctx, + f_read_mem, FunctionTableAccessRoutine, + GetModuleBaseRoutine, f_xlat_adr, flags); + + if (!(cpu = cpu_find(MachineType))) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (frame->StackFrameSize != sizeof(*frame)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (flags != 0) + { + FIXME("Unsupported yet flags 0x%x\n", flags); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (frame->InlineFrameContext != INLINE_FRAME_CONTEXT_IGNORE) + { + FIXME("Inlined contexts are not supported yet\n"); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + csw.hProcess = hProcess; + csw.hThread = hThread; + csw.is32 = FALSE; + csw.cpu = cpu; + /* sigh... MS isn't even consistent in the func prototypes */ + csw.u.s64.f_read_mem = (f_read_mem) ? f_read_mem : read_mem64; + csw.u.s64.f_xlat_adr = (f_xlat_adr) ? f_xlat_adr : addr_to_linear; + csw.u.s64.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess64; + csw.u.s64.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase64; + + if (!cpu->stack_walk(&csw, (STACKFRAME64*)frame, ctx)) return FALSE; + + /* we don't handle KdHelp */ + + return TRUE; +} + /****************************************************************** * SymRegisterFunctionEntryCallback (DBGHELP.@) *