From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/cpu_i386.c | 10 ++---- dlls/dbghelp/dbghelp_private.h | 22 ++++++------- dlls/dbghelp/msc.c | 5 ++- dlls/dbghelp/pdb.c | 58 +++++++++++++++++++++------------- 4 files changed, 50 insertions(+), 45 deletions(-)
diff --git a/dlls/dbghelp/cpu_i386.c b/dlls/dbghelp/cpu_i386.c index a322dfcdda3..42e4c882009 100644 --- a/dlls/dbghelp/cpu_i386.c +++ b/dlls/dbghelp/cpu_i386.c @@ -95,8 +95,7 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw, union ctx *pcontext, DWORD_PTR curr_pc) { DWORD64 xframe; - struct pdb_cmd_pair cpair[4]; - DWORD val32; + DWORD val32; WOW64_CONTEXT *context = &pcontext->x86;
if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe)) @@ -104,12 +103,9 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw, context->Esp = xframe; return TRUE; } - cpair[0].name = "$ebp"; cpair[0].pvalue = &context->Ebp; - cpair[1].name = "$esp"; cpair[1].pvalue = &context->Esp; - cpair[2].name = "$eip"; cpair[2].pvalue = &context->Eip; - cpair[3].name = NULL; cpair[3].pvalue = NULL;
- if (!pdb_virtual_unwind(csw, curr_pc, pcontext, cpair)) + if (!pdb_virtual_unwind(csw, curr_pc, pcontext) && + !old_pdb_virtual_unwind(csw, curr_pc, pcontext)) { /* do a simple unwind using ebp * we assume a "regular" prologue in the function has been used diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 21a0112ea89..8ec1fb3a285 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -827,14 +827,9 @@ extern BOOL pe_load_debug_directory(const struct process* pcs, const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg); extern DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* dbgdir, DWORD size, SYMSRV_INDEX_INFOW* info); -struct pdb_cmd_pair { - const char* name; - DWORD* pvalue; -}; -extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair); -extern DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); -extern DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); +extern DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); +extern DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info); +extern BOOL old_pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context);
/* path.c */ extern BOOL path_find_symbol_file(const struct process *pcs, const struct module *module, @@ -847,6 +842,12 @@ extern BOOL search_unix_path(const WCHAR *name, const WCHAR *path, BOOL (*match) extern const WCHAR* file_name(const WCHAR* str); extern const char* file_nameA(const char* str);
+/* pdb.c */ +extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context); +struct _PDB_FPO_DATA; +extern BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, struct _PDB_FPO_DATA* fpoext, + const char* cmd, WOW64_CONTEXT *context); + /* pe_module.c */ extern BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth, BOOL* is_builtin); extern struct module* @@ -1087,11 +1088,6 @@ extern struct symt_function* #define IFC_DEPTH(x) ((x) & IFC_DEPTH_MASK)
/* temporary helpers for PDB rewriting */ -struct _PDB_FPO_DATA; -extern BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, struct _PDB_FPO_DATA* fpoext, - const char* cmd, struct pdb_cmd_pair* cpair); -extern BOOL pdb_old_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair); struct pdb_reader; extern BOOL pdb_hack_get_main_info(struct module_format *modfmt, struct pdb_reader **pdb, unsigned *fpoext_stream); extern void pdb_reader_dispose(struct pdb_reader *pdb); diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index c5721720537..4fa1134b20c 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -4409,8 +4409,7 @@ DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info) return msc_get_file_indexinfo(image, dbg, num_directories, info); }
-BOOL pdb_old_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair) +BOOL old_pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context) { struct module_pair pair; struct pdb_module_info* pdb_info; @@ -4443,7 +4442,7 @@ BOOL pdb_old_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, debugstr_a(pdb_get_string_table_entry(strbase, fpoext[i].str_offset))); ret = pdb_fpo_unwind_parse_cmd_string(csw, &fpoext[i], pdb_get_string_table_entry(strbase, fpoext[i].str_offset), - cpair); + &context->x86); break; } } diff --git a/dlls/dbghelp/pdb.c b/dlls/dbghelp/pdb.c index c371cc73fd8..a8420d1c698 100644 --- a/dlls/dbghelp/pdb.c +++ b/dlls/dbghelp/pdb.c @@ -5070,8 +5070,7 @@ static BOOL pev_assign(struct pevaluator* pev) }
/* initializes the postfix evaluator */ -static void pev_init(struct pevaluator* pev, struct cpu_stack_walk* csw, - const PDB_FPO_DATA* fpoext, struct pdb_cmd_pair* cpair) +static void pev_init(struct pevaluator* pev, struct cpu_stack_walk* csw) { pev->csw = csw; pool_init(&pev->pool, 512); @@ -5079,29 +5078,41 @@ static void pev_init(struct pevaluator* pev, struct cpu_stack_walk* csw, pev->stk_index = 0; hash_table_init(&pev->pool, &pev->values, 8); pev->error[0] = '\0'; - for (; cpair->name; cpair++) - pev_set_value(pev, cpair->name, *cpair->pvalue); +} + +static void pev_push_context(struct pevaluator *pev, const WOW64_CONTEXT *context) +{ + pev_set_value(pev, "$ebp", context->Ebp); + pev_set_value(pev, "$esp", context->Esp); + pev_set_value(pev, "$eip", context->Eip); +} + +static void pev_pop_context(struct pevaluator *pev, WOW64_CONTEXT *context) +{ + DWORD_PTR val; + + if (pev_get_val(pev, "$ebp", &val)) context->Ebp = val; + if (pev_get_val(pev, "$esp", &val)) context->Esp = val; + if (pev_get_val(pev, "$eip", &val)) context->Eip = val; +} + +static void pev_push_fpodata(struct pevaluator *pev, const PDB_FPO_DATA* fpoext) +{ + pev_set_value(pev, ".raSearchStart", fpoext->start); pev_set_value(pev, ".cbLocals", fpoext->locals_size); pev_set_value(pev, ".cbParams", fpoext->params_size); pev_set_value(pev, ".cbSavedRegs", fpoext->savedregs_size); }
-static BOOL pev_free(struct pevaluator* pev, struct pdb_cmd_pair* cpair) +static BOOL pev_free(struct pevaluator* pev) { - DWORD_PTR val; - - if (cpair) for (; cpair->name; cpair++) - { - if (pev_get_val(pev, cpair->name, &val)) - *cpair->pvalue = val; - } pool_destroy(&pev->pool); return TRUE; }
-BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* fpoext, - const char* cmd, struct pdb_cmd_pair* cpair) +BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* fpoext, + const char* cmd, WOW64_CONTEXT *context) { char token[PEV_MAX_LEN]; char* ptok = token; @@ -5110,7 +5121,9 @@ BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* struct pevaluator pev;
if (!cmd) return FALSE; - pev_init(&pev, csw, fpoext, cpair); + pev_init(&pev, csw); + pev_push_context(&pev, context); + pev_push_fpodata(&pev, fpoext); for (ptr = cmd; !over; ptr++) { if (*ptr == ' ' || (over = *ptr == '\0')) @@ -5146,16 +5159,16 @@ BOOL pdb_fpo_unwind_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* *ptok++ = *ptr; } } - pev_free(&pev, cpair); + pev_pop_context(&pev, context); + pev_free(&pev); return TRUE; done: FIXME("Couldn't evaluate %s => %s\n", debugstr_a(cmd), pev.error); - pev_free(&pev, NULL); + pev_free(&pev); return FALSE; }
-BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, - union ctx *context, struct pdb_cmd_pair *cpair) +BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context) { struct pdb_reader *pdb; struct pdb_reader_walker walker; @@ -5165,9 +5178,10 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, BOOL ret = FALSE;
if (!module_init_pair(&pair, csw->hProcess, ip)) return FALSE; + if (!pair.effective->format_info[DFI_PDB]) return FALSE; if (!pdb_hack_get_main_info(pair.effective->format_info[DFI_PDB], &pdb, NULL)) return FALSE; - if (!pdb) - return pdb_old_virtual_unwind(csw, ip, context, cpair); + if (!pdb) return FALSE; + TRACE("searching %Ix => %Ix\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage); ip -= (DWORD_PTR)pair.effective->module.BaseOfImage;
@@ -5189,7 +5203,7 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, fpoext.savedregs_size, fpoext.flags, debugstr_a(cmd));
- ret = pdb_fpo_unwind_parse_cmd_string(csw, &fpoext, cmd, cpair); + ret = pdb_fpo_unwind_parse_cmd_string(csw, &fpoext, cmd, &context->x86); pdb_reader_free(pdb, cmd); break; }