From dc43edff39f38283b316b8dd0ad6840c3206e6fc Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 8 Nov 2004 20:26:22 +0000 Subject: [PATCH] - fixed loading stabs from PE modules compiled with MingW - enhance some loading logic between ELF/PE DLL pairs - removed unused indirect memory access function - get rid of some GCC generated symbols --- dlls/dbghelp/dbghelp_private.h | 17 +++-------------- dlls/dbghelp/elf_module.c | 32 ++++++++++++++++++++------------ dlls/dbghelp/memory.c | 15 --------------- dlls/dbghelp/module.c | 18 +++++++++--------- dlls/dbghelp/pe_module.c | 17 ++++++++++++----- dlls/dbghelp/stabs.c | 27 ++++++++++++++++----------- 6 files changed, 60 insertions(+), 66 deletions(-) diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 4710e6cea60..f22d6af1554 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -296,16 +296,6 @@ extern struct module* extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs); extern BOOL elf_synchronize_module_list(struct process* pcs); -/* memory.c */ -struct memory_access -{ - BOOL (*read_mem)(HANDLE hProcess, DWORD addr, void* buf, DWORD len); - BOOL (*write_mem)(HANDLE hProcess, DWORD addr, void* buf, DWORD len); -}; - -extern struct memory_access mem_access; -#define read_mem(p,a,b,l) (mem_access.read_mem)((p),(a),(b),(l)) -#define write_mem(p,a,b,l) (mem_access.write_mem)((p),(a),(b),(l)) extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr); /* module.c */ @@ -351,10 +341,9 @@ extern unsigned source_new(struct module* module, const char* source); extern const char* source_get(const struct module* module, unsigned idx); /* stabs.c */ -extern BOOL stabs_parse(struct module* module, const char* addr, - unsigned long load_offset, - unsigned int staboff, int stablen, - unsigned int strtaboff, int strtablen); +extern BOOL stabs_parse(struct module* module, unsigned long load_offset, + const void* stabs, int stablen, + const char* strs, int strtablen); /* symbol.c */ extern const char* symt_get_name(const struct symt* sym); diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 58f678b5823..9954ed7e405 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -158,6 +158,12 @@ static void elf_hash_symtab(const struct module* module, struct pool* pool, } if (j < num_areas) continue; + /* FIXME: we don't need to handle them (GCC internals) + * Moreover, they screw up our symbol lookup :-/ + */ + if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2])) + continue; + ste = pool_alloc(pool, sizeof(*ste)); /* GCC seems to emit, in some cases, a .+ suffix. * This is used for static variable inside functions, so @@ -286,7 +292,7 @@ static void elf_finish_stabs_info(struct module* module, struct hash_table* symt ((struct symt_function*)sym)->address = module->elf_info->elf_addr + symp->st_value; ((struct symt_function*)sym)->size = symp->st_size; - } + } else FIXME("Couldn't find %s\n", sym->hash_elt.name); break; case SymTagData: switch (((struct symt_data*)sym)->kind) @@ -694,9 +700,10 @@ static BOOL elf_load_debug_info_from_file( if (stab_sect != -1 && stabstr_sect != -1) { /* OK, now just parse all of the stabs. */ - ret = stabs_parse(module, addr, module->elf_info->elf_addr, - spnt[stab_sect].sh_offset, spnt[stab_sect].sh_size, - spnt[stabstr_sect].sh_offset, + ret = stabs_parse(module, module->elf_info->elf_addr, + addr + spnt[stab_sect].sh_offset, + spnt[stab_sect].sh_size, + addr + spnt[stabstr_sect].sh_offset, spnt[stabstr_sect].sh_size); if (!ret) { @@ -1010,8 +1017,9 @@ BOOL elf_synchronize_module_list(struct process* pcs) struct elf_info elf_info; struct module* module; - if (!pcs->dbg_hdr_addr) return FALSE; - if (!read_mem(pcs->handle, pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr))) + if (!pcs->dbg_hdr_addr || + !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr, + &dbg_hdr, sizeof(dbg_hdr), NULL)) return FALSE; for (module = pcs->lmodules; module; module = module->next) @@ -1027,12 +1035,12 @@ BOOL elf_synchronize_module_list(struct process* pcs) */ for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next) { - if (!read_mem(pcs->handle, (ULONG)lm_addr, &lm, sizeof(lm))) + if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL)) return FALSE; if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */ lm.l_name != NULL && - read_mem(pcs->handle, (ULONG)lm.l_name, bufstr, sizeof(bufstr))) + ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL)) { bufstr[sizeof(bufstr) - 1] = '\0'; elf_search_and_load_file(pcs, bufstr, (unsigned long)lm.l_addr, @@ -1087,7 +1095,7 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs) * elf_load_module * * loads an ELF module and stores it in process' module list - * if 'sync' is TRUE, let's find module real name and load address from + * Also, find module real name and load address from * the real loaded modules list in pcs address space */ struct module* elf_load_module(struct process* pcs, const char* name) @@ -1111,17 +1119,17 @@ struct module* elf_load_module(struct process* pcs, const char* name) xname = strrchr(name, '/'); if (!xname++) xname = name; - if (!read_mem(pcs->handle, pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr))) + if (!ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr), NULL)) return NULL; for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next) { - if (!read_mem(pcs->handle, (ULONG)lm_addr, &lm, sizeof(lm))) + if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL)) return NULL; if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */ lm.l_name != NULL && - read_mem(pcs->handle, (ULONG)lm.l_name, bufstr, sizeof(bufstr))) + ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL)) { bufstr[sizeof(bufstr) - 1] = '\0'; /* memcmp is needed for matches when bufstr contains also version information diff --git a/dlls/dbghelp/memory.c b/dlls/dbghelp/memory.c index 6d7443007de..f20d9188791 100644 --- a/dlls/dbghelp/memory.c +++ b/dlls/dbghelp/memory.c @@ -26,21 +26,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); -BOOL win32_read_mem(HANDLE hProcess, DWORD addr, void* buf, DWORD len) -{ - return ReadProcessMemory(hProcess, (void*)addr, buf, len, NULL); -} - -BOOL win32_write_mem(HANDLE hProcess, DWORD addr, void* buf, DWORD len) -{ - return WriteProcessMemory(hProcess, (void*)addr, buf, len, NULL); -} - -/* standard routines for reading / writing memory. Can be overriden for some - * minidump usage - */ -struct memory_access mem_access = {win32_read_mem, win32_write_mem}; - /****************************************************************** * addr_to_linear * diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 9109e211763..ea5a955d93f 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -201,16 +201,17 @@ struct module* module_get_containee(const struct process* pcs, */ struct module* module_get_debug(const struct process* pcs, struct module* module) { - BOOL ret; + struct module* parent; if (!module) return NULL; - switch (module->module.SymType) + /* for a PE builtin, always get info from parent */ + if ((parent = module_get_container(pcs, module))) + module = parent; + /* if deferred, force loading */ + if (module->module.SymType == SymDeferred) { - case SymNone: - module = module_get_container(pcs, module); - if (!module || module->module.SymType != SymDeferred) break; - /* fall through */ - case SymDeferred: + BOOL ret; + switch (module->type) { case DMT_ELF: ret = elf_load_debug_info(module); break; @@ -218,8 +219,7 @@ struct module* module_get_debug(const struct process* pcs, struct module* module default: ret = FALSE; break; } if (!ret) module->module.SymType = SymNone; - break; - default: break; + assert(module->module.SymType != SymDeferred); } return (module && module->module.SymType != SymNone) ? module : NULL; } diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c index 24bbb9c42cd..a826acb9dae 100644 --- a/dlls/dbghelp/pe_module.c +++ b/dlls/dbghelp/pe_module.c @@ -66,8 +66,12 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module, if (stabstrsize && stabsize) { - ret = stabs_parse(module, mapping, module->module.BaseOfImage, - stabs, stabsize, stabstr, stabstrsize); + ret = stabs_parse(module, + module->module.BaseOfImage - nth->OptionalHeader.ImageBase, + RtlImageRvaToVa(nth, (void*)mapping, stabs, NULL), + stabsize, + RtlImageRvaToVa(nth, (void*)mapping, stabstr, NULL), + stabstrsize); } return ret; } @@ -269,7 +273,8 @@ static BOOL pe_load_export_debug_info(const struct process* pcs, } } /* no real debug info, only entry points */ - module->module.SymType = SymExport; + if (module->module.SymType == SymDeferred) + module->module.SymType = SymExport; return TRUE; } @@ -303,6 +308,7 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module) * in which case we'll rely on the export's on the ELF side */ } +// FIXME shouldn't we check that? if (!module_get_debug(pcs, module))l if (pe_load_export_debug_info(pcs, module, mapping, nth) && !ret) ret = TRUE; UnmapViewOfFile(mapping); @@ -403,9 +409,10 @@ struct module* pe_load_module_from_pcs(struct process* pcs, const char* name, IMAGE_DOS_HEADER dos; IMAGE_NT_HEADERS nth; - if (read_mem(pcs->handle, base, &dos, sizeof(dos)) && + if (ReadProcessMemory(pcs->handle, (char*)base, &dos, sizeof(dos), NULL) && dos.e_magic == IMAGE_DOS_SIGNATURE && - read_mem(pcs->handle, base + dos.e_lfanew, &nth, sizeof(nth)) && + ReadProcessMemory(pcs->handle, (char*)(base + dos.e_lfanew), + &nth, sizeof(nth), NULL) && nth.Signature == IMAGE_NT_SIGNATURE) { if (!size) size = nth.OptionalHeader.SizeOfImage; diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c index dd0356732d7..0104fdd9829 100644 --- a/dlls/dbghelp/stabs.c +++ b/dlls/dbghelp/stabs.c @@ -1060,8 +1060,11 @@ struct pending_loc_var * Ends function creation: mainly: * - cleans up line number information * - tries to set up a debug-start tag (FIXME: heuristic to be enhanced) + * - for stabs which have abolute address in them, initializes the size of the + * function (assuming that current function ends where next function starts) */ -static void stabs_finalize_function(struct module* module, struct symt_function* func) +static void stabs_finalize_function(struct module* module, struct symt_function* func, + unsigned long end) { IMAGEHLP_LINE il; @@ -1076,11 +1079,12 @@ static void stabs_finalize_function(struct module* module, struct symt_function* symt_add_function_point(module, func, SymTagFuncDebugStart, il.Address - func->address, NULL); } + if (end) func->size = end - func->address; } -BOOL stabs_parse(struct module* module, const char* addr, - unsigned long load_offset, unsigned int staboff, int stablen, - unsigned int strtaboff, int strtablen) +BOOL stabs_parse(struct module* module, unsigned long load_offset, + const void* pv_stab_ptr, int stablen, + const char* strs, int strtablen) { struct symt_function* curr_func = NULL; struct symt_block* block = NULL; @@ -1092,8 +1096,7 @@ BOOL stabs_parse(struct module* module, const char* addr, const char* ptr; char* stabbuff; unsigned int stabbufflen; - const struct stab_nlist* stab_ptr; - const char* strs; + const struct stab_nlist* stab_ptr = pv_stab_ptr; const char* strs_end; int strtabinc; char symname[4096]; @@ -1106,8 +1109,6 @@ BOOL stabs_parse(struct module* module, const char* addr, BOOL ret = TRUE; nstab = stablen / sizeof(struct stab_nlist); - stab_ptr = (const struct stab_nlist*)(addr + staboff); - strs = (const char*)(addr + strtaboff); strs_end = strs + strtablen; memset(srcpath, 0, sizeof(srcpath)); @@ -1355,7 +1356,8 @@ BOOL stabs_parse(struct module* module, const char* addr, break; case N_FUN: /* First, clean up the previous function we were working on. */ - stabs_finalize_function(module, curr_func); + stabs_finalize_function(module, curr_func, + stab_ptr->n_value ? load_offset + stab_ptr->n_value : 0); /* * For now, just declare the various functions. Later @@ -1394,7 +1396,8 @@ BOOL stabs_parse(struct module* module, const char* addr, { /* Nuke old path. */ srcpath[0] = '\0'; - stabs_finalize_function(module, curr_func); + stabs_finalize_function(module, curr_func, + stab_ptr->n_value ? load_offset + stab_ptr->n_value : 0); curr_func = NULL; source_idx = -1; incl_stk = -1; @@ -1429,7 +1432,9 @@ BOOL stabs_parse(struct module* module, const char* addr, case N_UNDF: strs += strtabinc; strtabinc = stab_ptr->n_value; - stabs_finalize_function(module, curr_func); + /* I'm not sure this is needed, so trace it before we obsolete it */ + if (curr_func) FIXME("UNDF: curr_func %s\n", curr_func->hash_elt.name); + stabs_finalize_function(module, curr_func, 0); /* FIXME */ curr_func = NULL; break; case N_OPT: -- 2.11.4.GIT