From 066bb761cc17a585daa97f1524231cbd972fc4f1 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Tue, 26 Oct 2021 11:45:32 +0200 Subject: [PATCH] dbghelp: Add local scope information in struct process. - make SymSetContext() generate this information - let SymEnumSymboli() (when dealing with local symbols) use this information instead of the stack frame Signed-off-by: Eric Pouech Signed-off-by: Alexandre Julliard --- dlls/dbghelp/dbghelp.c | 14 ++++++++++++-- dlls/dbghelp/dbghelp_private.h | 2 ++ dlls/dbghelp/dwarf.c | 2 +- dlls/dbghelp/module.c | 10 +++++++++- dlls/dbghelp/symbol.c | 14 ++++++-------- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c index 00f02423fef..64ceb447ee9 100644 --- a/dlls/dbghelp/dbghelp.c +++ b/dlls/dbghelp/dbghelp.c @@ -606,11 +606,21 @@ BOOL WINAPI SymSetParentWindow(HWND hwnd) BOOL WINAPI SymSetContext(HANDLE hProcess, PIMAGEHLP_STACK_FRAME StackFrame, PIMAGEHLP_CONTEXT Context) { - struct process* pcs = process_find_by_handle(hProcess); + struct process* pcs; + struct module_pair pair; + struct symt_ht* sym; + + pair.pcs = pcs = process_find_by_handle(hProcess); if (!pcs) return FALSE; - if (!module_find_by_addr(pcs, StackFrame->InstructionOffset, DMT_UNKNOWN)) + pair.requested = module_find_by_addr(pair.pcs, StackFrame->InstructionOffset, DMT_UNKNOWN); + if (!module_get_debug(&pair)) return FALSE; return FALSE; + if ((sym = symt_find_nearest(pair.effective, StackFrame->InstructionOffset)) == NULL) return FALSE; + if (sym->symt.tag != SymTagFunction) return FALSE; + pcs->localscope_pc = StackFrame->InstructionOffset; + pcs->localscope_symt = &sym->symt; + if (pcs->ctx_frame.ReturnOffset == StackFrame->ReturnOffset && pcs->ctx_frame.FrameOffset == StackFrame->FrameOffset && pcs->ctx_frame.StackOffset == StackFrame->StackOffset) diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 6217701a457..7ab7d1b7fc3 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -438,6 +438,8 @@ struct process ULONG_PTR dbg_hdr_addr; IMAGEHLP_STACK_FRAME ctx_frame; + DWORD64 localscope_pc; + struct symt* localscope_symt; unsigned buffer_size; void* buffer; diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index e1c77569622..c503be4dcc1 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -3723,7 +3723,7 @@ static void dwarf2_location_compute(struct process* pcs, else { /* instruction pointer relative to compiland's start */ - ip = pcs->ctx_frame.InstructionOffset - ((struct symt_compiland*)func->container)->address; + ip = pcs->localscope_pc - ((struct symt_compiland*)func->container)->address; if ((err = loc_compute_frame(pcs, modfmt, func, ip, head, &frame)) == 0) { diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index f0fd2a55016..8168e727c52 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -1048,7 +1048,15 @@ BOOL WINAPI SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll) if (!pcs) return FALSE; module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN); if (!module) return FALSE; - return module_remove(pcs, module); + if (!module_remove(pcs, module)) return FALSE; + /* remove local scope if defined inside this module */ + if (pcs->localscope_pc >= module->module.BaseOfImage && + pcs->localscope_pc < module->module.BaseOfImage + module->module.ImageSize) + { + pcs->localscope_pc = 0; + pcs->localscope_symt = NULL; + } + return TRUE; } /****************************************************************** diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 82c69b2e848..0f53bcd023c 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -1028,7 +1028,7 @@ static BOOL symt_enum_locals_helper(struct module_pair* pair, struct symt_function* func, const struct vector* v) { struct symt* lsym = NULL; - DWORD_PTR pc = pair->pcs->ctx_frame.InstructionOffset; + DWORD_PTR pc = pair->pcs->localscope_pc; unsigned int i; WCHAR* nameW; BOOL ret; @@ -1074,21 +1074,19 @@ static BOOL symt_enum_locals(struct process* pcs, const WCHAR* mask, const struct sym_enum* se) { struct module_pair pair; - struct symt_ht* sym; - DWORD_PTR pc = pcs->ctx_frame.InstructionOffset; se->sym_info->SizeOfStruct = sizeof(*se->sym_info); se->sym_info->MaxNameLen = sizeof(se->buffer) - sizeof(SYMBOL_INFO); pair.pcs = pcs; - pair.requested = module_find_by_addr(pair.pcs, pc, DMT_UNKNOWN); + pair.requested = module_find_by_addr(pair.pcs, pcs->localscope_pc, DMT_UNKNOWN); if (!module_get_debug(&pair)) return FALSE; - if ((sym = symt_find_nearest(pair.effective, pc)) == NULL) return FALSE; - if (sym->symt.tag == SymTagFunction) + if (symt_check_tag(pcs->localscope_symt, SymTagFunction) || + symt_check_tag(pcs->localscope_symt, SymTagInlineSite)) { - return symt_enum_locals_helper(&pair, mask ? mask : L"*", se, (struct symt_function*)sym, - &((struct symt_function*)sym)->vchildren); + struct symt_function* func = (struct symt_function*)pcs->localscope_symt; + return symt_enum_locals_helper(&pair, mask ? mask : L"*", se, func, &func->vchildren); } return FALSE; }