From 65c37657398119d4b777e3e1f97481edf907a949 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 30 Aug 2004 19:31:13 +0000 Subject: [PATCH] Authors: Robert Shearman , Eric Pouech - Fix debug info look-up (bug in translating the RVA of the debug directory). - Fix code for adding PE export table as debug info (crash with NULL passed to RtlImageDirectoryEntryToData). - Fix computation of non-relocatable ELF shared objects size. - Fix loading (while parsing the link map) of new non-relocatable ELF shared objects (no longer take account load-address of link-map). - Finished the AUTO_PUBLIC, NO_PUBLICS and PUBLICS_ONLY support for PE and ELF. - Cleaned up public symbol management (which should now properly work). --- dlls/dbghelp/dbghelp.c | 11 +- dlls/dbghelp/dbghelp_private.h | 8 +- dlls/dbghelp/elf_module.c | 217 ++++++++++++++++----------------- dlls/dbghelp/module.c | 20 ++- dlls/dbghelp/msc.c | 57 ++++----- dlls/dbghelp/pe_module.c | 131 ++++++++++---------- dlls/dbghelp/stabs.c | 11 +- dlls/dbghelp/symbol.c | 9 +- 8 files changed, 231 insertions(+), 233 deletions(-) diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c index ce7681b078c..d95e6282742 100644 --- a/dlls/dbghelp/dbghelp.c +++ b/dlls/dbghelp/dbghelp.c @@ -33,8 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); * + funcargtype:s are (partly) wrong: they should be a specific struct (like * typedef) pointing to the actual type (and not a direct access) * + we should store the underlying type for an enum in the symt_enum struct - * - most options (dbghelp_options) are not used (loading lines, decoration, - * deferring reading of module symbols, public symbols...) + * - most options (dbghelp_options) are not used (loading lines, decoration...) * - in symbol lookup by name, we don't use RE everywhere we should. Moreover, when * we're supposed to use RE, it doesn't make use of our hash tables. Therefore, * we could use hash if name isn't a RE, and fall back to a full search when we @@ -46,9 +45,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); * + we should add parameters' types to the function's signature * while processing a function's parameters * + get rid of MSC reading FIXME:s (lots of types are not defined) - * + support the PUBLICS_ONLY, NO_PUBLICS and AUTO_PUBLICS options * + C++ management * - stabs: + * + when, in a same module, the same definition is used in several compilation + * units, we get several definitions of the same object (especially + * struct/union). we should find a way not to duplicate them + * + in some cases (dlls/user/dialog16.c DIALOG_GetControl16), the same static + * global variable is defined several times (at different scopes). We are + * getting several of those while looking for a unique symbol. Part of the + * issue is that we don't give a scope to a static variable inside a function * + C++ management * - implement the callback notification mechanism */ diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index ab8af1730c5..f8caf6e2245 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -287,7 +287,7 @@ struct process extern struct process* process_find_by_handle(HANDLE hProcess); /* elf_module.c */ -extern SYM_TYPE elf_load_debug_info(struct module* module); +extern BOOL elf_load_debug_info(struct module* module); extern struct module* elf_load_module(struct process* pcs, const char* name); extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs); @@ -329,7 +329,7 @@ extern void module_reset_debug_info(struct module* module); extern BOOL module_remove(struct process* pcs, struct module* module); /* msc.c */ -extern SYM_TYPE pe_load_debug_directory(const struct process* pcs, +extern BOOL pe_load_debug_directory(const struct process* pcs, struct module* module, const BYTE* file_map, const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg); @@ -340,14 +340,14 @@ extern struct module* extern struct module* pe_load_module_from_pcs(struct process* pcs, const char* name, const char* mod_name, DWORD base, DWORD size); -extern SYM_TYPE pe_load_debug_info(const struct process* pcs, +extern BOOL pe_load_debug_info(const struct process* pcs, struct module* module); /* source.c */ extern unsigned source_new(struct module* module, const char* source); extern const char* source_get(const struct module* module, unsigned idx); /* stabs.c */ -extern SYM_TYPE stabs_parse(struct module* module, const char* addr, +extern BOOL stabs_parse(struct module* module, const char* addr, unsigned long load_offset, unsigned int staboff, int stablen, unsigned int strtaboff, int strtablen); diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index e90e96d289f..5d7c9936ceb 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -397,15 +397,19 @@ static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symt } else if (strcmp(ste->ht_elt.name, module->addr_sorttab[idx]->hash_elt.name)) { - DWORD xaddr = 0, xsize = 0; + DWORD xaddr = 0, xsize = 0, kind = -1; - symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_ADDRESS, &xaddr); - symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_LENGTH, &xsize); + symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_ADDRESS, &xaddr); + symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_LENGTH, &xsize); + symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_DATAKIND, &kind); - /* if none of symbols has a correct size, we consider they are both markers + /* If none of symbols has a correct size, we consider they are both markers * Hence, we can silence this warning + * Also, we check that we don't have two symbols, one local, the other + * global which is legal */ - if (xsize || ste->symp->st_size) + if ((xsize || ste->symp->st_size) && + (kind == (ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL) ? DataIsFileStatic : DataIsGlobal)) FIXME("Duplicate in %s: %s<%08lx-%08x> %s<%08lx-%08lx>\n", module->module.ModuleName, ste->ht_elt.name, addr, ste->symp->st_size, @@ -423,8 +427,7 @@ static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symt * * Creates a set of public symbols from an ELF symtab */ -static int elf_new_public_symbols(struct module* module, struct hash_table* symtab, - BOOL dont_check) +static int elf_new_public_symbols(struct module* module, struct hash_table* symtab) { struct symt_compiland* compiland = NULL; const char* compiland_name = NULL; @@ -433,6 +436,8 @@ static int elf_new_public_symbols(struct module* module, struct hash_table* symt if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE; + /* FIXME: we're missing the ELF entry point here */ + hash_table_iter_init(symtab, &hti, NULL); while ((ste = hash_table_iter_up(&hti))) { @@ -446,14 +451,10 @@ static int elf_new_public_symbols(struct module* module, struct hash_table* symt compiland = symt_new_compiland(module, compiland_name = ste->filename); - if (dont_check || !(dbghelp_options & SYMOPT_AUTO_PUBLICS) || - symt_find_nearest(module, module->elf_info->elf_addr + ste->symp->st_value) == -1) - { - symt_new_public(module, compiland, ste->ht_elt.name, - module->elf_info->elf_addr + ste->symp->st_value, - ste->symp->st_size, TRUE /* FIXME */, - ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC); - } + symt_new_public(module, compiland, ste->ht_elt.name, + module->elf_info->elf_addr + ste->symp->st_value, + ste->symp->st_size, TRUE /* FIXME */, + ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC); } return TRUE; } @@ -470,9 +471,9 @@ static int elf_new_public_symbols(struct module* module, struct hash_table* symt * read or parsed) * 1 on success */ -SYM_TYPE elf_load_debug_info(struct module* module) +BOOL elf_load_debug_info(struct module* module) { - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; char* addr = (char*)0xffffffff; int fd = -1; struct stat statbuf; @@ -498,7 +499,7 @@ SYM_TYPE elf_load_debug_info(struct module* module) if (module->type != DMT_ELF || !module->elf_info) { ERR("Bad elf module '%s'\n", module->module.LoadedImageName); - return sym_type; + return FALSE; } TRACE("%s\n", module->module.LoadedImageName); @@ -517,7 +518,6 @@ SYM_TYPE elf_load_debug_info(struct module* module) addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == (char*)0xffffffff) goto leave; - sym_type = SymNone; /* * Next, we need to find a few of the internal ELF headers within * this thing. We need the main executable header, and the section @@ -545,8 +545,6 @@ SYM_TYPE elf_load_debug_info(struct module* module) dynsym_sect = i; } - sym_type = SymExport; - if (symtab_sect == -1) { /* if we don't have a symtab but a dynsym, process the dynsym @@ -557,6 +555,7 @@ SYM_TYPE elf_load_debug_info(struct module* module) symtab_sect = dynsym_sect; } + module->module.SymType = SymExport; /* FIXME: guess a better size from ELF info */ pool_init(&pool, 65536); hash_table_init(&pool, &ht_symtab, 256); @@ -571,11 +570,11 @@ SYM_TYPE elf_load_debug_info(struct module* module) if (stab_sect != -1 && stabstr_sect != -1) { /* OK, now just parse all of the stabs. */ - sym_type = stabs_parse(module, addr, module->elf_info->elf_addr, - spnt[stab_sect].sh_offset, spnt[stab_sect].sh_size, - spnt[stabstr_sect].sh_offset, - spnt[stabstr_sect].sh_size); - if (sym_type == -1) + 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, + spnt[stabstr_sect].sh_size); + if (!ret) { WARN("Couldn't read correctly read stabs\n"); goto leave; @@ -586,8 +585,7 @@ SYM_TYPE elf_load_debug_info(struct module* module) else if (debug_sect != -1) { /* Dwarf 2 debug information */ - FIXME("Unsupported Dwarf2 information\n"); - sym_type = SymNone; + FIXME("Unsupported Dwarf2 information for %s\n", module->module.ModuleName); } } if (strstr(module->module.ModuleName, "") || @@ -597,16 +595,9 @@ SYM_TYPE elf_load_debug_info(struct module* module) if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY)) elf_new_wine_thunks(module, &ht_symtab, sizeof(thunks) / sizeof(thunks[0]), thunks); - /* add the public symbols from symtab - * (only if they haven't been defined yet) - */ - elf_new_public_symbols(module, &ht_symtab, FALSE); - } - else - { - /* add all the public symbols from symtab */ - elf_new_public_symbols(module, &ht_symtab, TRUE); } + /* add all the public symbols from symtab */ + if (elf_new_public_symbols(module, &ht_symtab) && !ret) ret = TRUE; pool_destroy(&pool); @@ -614,7 +605,7 @@ leave: if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size); if (fd != -1) close(fd); - return module->module.SymType = sym_type; + return ret; } /****************************************************************** @@ -650,11 +641,11 @@ static unsigned is_dt_flag_valid(unsigned d_tag) * read or parsed) * 1 on success */ -static SYM_TYPE elf_load_file(struct process* pcs, const char* filename, - unsigned long load_offset, struct elf_info* elf_info) +static BOOL elf_load_file(struct process* pcs, const char* filename, + unsigned long load_offset, struct elf_info* elf_info) { static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 }; - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; const char* addr = (char*)0xffffffff; int fd = -1; struct stat statbuf; @@ -663,7 +654,7 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename, const Elf32_Phdr* ppnt; const char* shstrtab; int i; - DWORD delta, size; + DWORD size, start; unsigned tmp, page_mask = getpagesize() - 1; TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset); @@ -678,8 +669,6 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename, addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == (char*)-1) goto leave; - sym_type = SymNone; - /* Next, we need to find a few of the internal ELF headers within * this thing. We need the main executable header, and the section * table. @@ -690,23 +679,34 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename, spnt = (const Elf32_Shdr*)(addr + ehptr->e_shoff); shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset); - /* if non relocatable ELF, then remove fixed address from computation - * otherwise, all addresses are zero based - */ - delta = (load_offset == 0) ? ehptr->e_entry : 0; - /* grab size of module once loaded in memory */ ppnt = (const Elf32_Phdr*)(addr + ehptr->e_phoff); - size = 0; + size = 0; start = ~0L; + for (i = 0; i < ehptr->e_phnum; i++) { if (ppnt[i].p_type == PT_LOAD) { tmp = (ppnt[i].p_vaddr + ppnt[i].p_memsz + page_mask) & ~page_mask; if (size < tmp) size = tmp; + if (ppnt[i].p_vaddr < start) start = ppnt[i].p_vaddr; } } + /* if non relocatable ELF, then remove fixed address from computation + * otherwise, all addresses are zero based and start has no effect + */ + size -= start; + if (!start && !load_offset) + ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n", + filename); + if (start && load_offset) + { + WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. " + "Assuming load address is corrupt\n", filename, load_offset); + load_offset = 0; + } + if (elf_info->flags & ELF_INFO_DEBUG_HEADER) { for (i = 0; i < ehptr->e_shnum; i++) @@ -725,11 +725,7 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename, dyn.d_tag = DT_NULL; ptr += sizeof(dyn); } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL); - if (dyn.d_tag == DT_NULL) - { - sym_type = -1; - goto leave; - } + if (dyn.d_tag == DT_NULL) goto leave; elf_info->dbg_hdr_addr = dyn.d_un.d_ptr; } } @@ -738,49 +734,51 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename, if (elf_info->flags & ELF_INFO_MODULE) { elf_info->module = module_new(pcs, filename, DMT_ELF, - (load_offset) ? load_offset : ehptr->e_entry, + (load_offset) ? load_offset : start, size, 0, 0); - if (elf_info->module) + if (!elf_info->module) goto leave; + elf_info->module->elf_info = HeapAlloc(GetProcessHeap(), + 0, sizeof(struct elf_module_info)); + if (elf_info->module->elf_info == NULL) { - elf_info->module->elf_info = HeapAlloc(GetProcessHeap(), - 0, sizeof(struct elf_module_info)); - if (elf_info->module->elf_info == NULL) - { - ERR("OOM\n"); - exit(0); /* FIXME */ - } - elf_info->module->elf_info->elf_addr = load_offset; - elf_info->module->module.SymType = sym_type = - (dbghelp_options & SYMOPT_DEFERRED_LOADS) ? SymDeferred : - elf_load_debug_info(elf_info->module); - elf_info->module->elf_info->elf_mark = 1; - elf_info->module->elf_info->elf_loader = 0; + ERR("OOM\n"); + exit(0); /* FIXME */ } - else sym_type = -1; - } + elf_info->module->elf_info->elf_addr = load_offset; + + if (dbghelp_options & SYMOPT_DEFERRED_LOADS) + { + elf_info->module->module.SymType = SymDeferred; + ret = TRUE; + } + else ret = elf_load_debug_info(elf_info->module); + + elf_info->module->elf_info->elf_mark = 1; + elf_info->module->elf_info->elf_loader = 0; + } else ret = TRUE; leave: if (addr != (char*)0xffffffff) munmap((void*)addr, statbuf.st_size); if (fd != -1) close(fd); - return sym_type; + return ret; } /****************************************************************** * elf_load_file_from_path * tries to load an ELF file from a set of paths (separated by ':') */ -static SYM_TYPE elf_load_file_from_path(HANDLE hProcess, - const char* filename, - unsigned long load_offset, - const char* path, - struct elf_info* elf_info) +static BOOL elf_load_file_from_path(HANDLE hProcess, + const char* filename, + unsigned long load_offset, + const char* path, + struct elf_info* elf_info) { - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; char *s, *t, *fn; char* paths = NULL; - if (!path) return sym_type; + if (!path) return FALSE; paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path); for (s = paths; s && *s; s = (t) ? (t+1) : NULL) @@ -792,14 +790,14 @@ static SYM_TYPE elf_load_file_from_path(HANDLE hProcess, strcpy(fn, s); strcat(fn, "/"); strcat(fn, filename); - sym_type = elf_load_file(hProcess, fn, load_offset, elf_info); + ret = elf_load_file(hProcess, fn, load_offset, elf_info); HeapFree(GetProcessHeap(), 0, fn); - if (sym_type != -1) break; + if (ret) break; s = (t) ? (t+1) : NULL; } HeapFree(GetProcessHeap(), 0, paths); - return sym_type; + return ret; } /****************************************************************** @@ -807,13 +805,14 @@ static SYM_TYPE elf_load_file_from_path(HANDLE hProcess, * * lookup a file in standard ELF locations, and if found, load it */ -static SYM_TYPE elf_search_and_load_file(struct process* pcs, const char* filename, - unsigned long load_offset, struct elf_info* elf_info) +static BOOL elf_search_and_load_file(struct process* pcs, const char* filename, + unsigned long load_offset, + struct elf_info* elf_info) { - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; struct module* module; - if (filename == NULL || *filename == '\0') return sym_type; + if (filename == NULL || *filename == '\0') return FALSE; if ((module = module_find_by_name(pcs, filename, DMT_ELF))) { elf_info->module = module; @@ -821,22 +820,20 @@ static SYM_TYPE elf_search_and_load_file(struct process* pcs, const char* filena return module->module.SymType; } - if (strstr(filename, "libstdc++")) return -1; /* We know we can't do it */ - sym_type = elf_load_file(pcs, filename, load_offset, elf_info); + if (strstr(filename, "libstdc++")) return FALSE; /* We know we can't do it */ + ret = elf_load_file(pcs, filename, load_offset, elf_info); /* if relative pathname, try some absolute base dirs */ - if (sym_type == -1 && !strchr(filename, '/')) + if (!ret && !strchr(filename, '/')) { - sym_type = elf_load_file_from_path(pcs, filename, load_offset, - getenv("PATH"), elf_info); - if (sym_type == -1) - sym_type = elf_load_file_from_path(pcs, filename, load_offset, - getenv("LD_LIBRARY_PATH"), elf_info); - if (sym_type == -1) - sym_type = elf_load_file_from_path(pcs, filename, load_offset, - getenv("WINEDLLPATH"), elf_info); + ret = elf_load_file_from_path(pcs, filename, load_offset, + getenv("PATH"), elf_info) || + elf_load_file_from_path(pcs, filename, load_offset, + getenv("LD_LIBRARY_PATH"), elf_info) || + elf_load_file_from_path(pcs, filename, load_offset, + getenv("WINEDLLPATH"), elf_info); } - return sym_type; + return ret; } /****************************************************************** @@ -907,8 +904,8 @@ BOOL elf_synchronize_module_list(struct process* pcs) BOOL elf_read_wine_loader_dbg_info(struct process* pcs) { const char* ptr; - SYM_TYPE sym_type; struct elf_info elf_info; + BOOL ret; elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE; /* All binaries are loaded with WINELOADER (if run from tree) or by the @@ -917,13 +914,13 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs) * wine-kthread is not 100% safe */ if ((ptr = getenv("WINELOADER"))) - sym_type = elf_search_and_load_file(pcs, ptr, 0, &elf_info); + ret = elf_search_and_load_file(pcs, ptr, 0, &elf_info); else { - if ((sym_type = elf_search_and_load_file(pcs, "wine-kthread", 0, &elf_info)) == -1) - sym_type = elf_search_and_load_file(pcs, "wine-pthread", 0, &elf_info); + ret = elf_search_and_load_file(pcs, "wine-kthread", 0, &elf_info) || + elf_search_and_load_file(pcs, "wine-pthread", 0, &elf_info); } - if (sym_type < 0) return FALSE; + if (!ret) return FALSE; elf_info.module->elf_info->elf_loader = 1; strcpy(elf_info.module->module.ModuleName, ""); return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0; @@ -939,7 +936,7 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs) struct module* elf_load_module(struct process* pcs, const char* name) { struct elf_info elf_info; - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; const char* p; const char* xname; struct r_debug dbg_hdr; @@ -977,13 +974,13 @@ struct module* elf_load_module(struct process* pcs, const char* name) if (!p++) p = bufstr; if (!memcmp(p, xname, strlen(xname))) { - sym_type = elf_search_and_load_file(pcs, bufstr, - (unsigned long)lm.l_addr, &elf_info); + ret = elf_search_and_load_file(pcs, bufstr, + (unsigned long)lm.l_addr, &elf_info); break; } } } - if (!lm_addr || sym_type == -1) return NULL; + if (!lm_addr || !ret) return NULL; assert(elf_info.module); return elf_info.module; } @@ -1005,8 +1002,8 @@ struct module* elf_load_module(struct process* pcs, const char* name) return NULL; } -SYM_TYPE elf_load_debug_info(struct module* module) +BOOL elf_load_debug_info(struct module* module) { - return -1; + return FALSE; } #endif /* __ELF__ */ diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 22167ae995a..21aa7987b75 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -200,10 +200,11 @@ struct module* module_get_containee(const struct process* pcs, */ struct module* module_get_debug(const struct process* pcs, struct module* module) { + BOOL ret; + if (!module) return NULL; switch (module->module.SymType) { - case -1: break; case SymNone: module = module_get_container(pcs, module); if (!module || module->module.SymType != SymDeferred) break; @@ -211,18 +212,15 @@ struct module* module_get_debug(const struct process* pcs, struct module* module case SymDeferred: switch (module->type) { - case DMT_ELF: - elf_load_debug_info(module); - break; - case DMT_PE: - pe_load_debug_info(pcs, module); - break; - default: break; + case DMT_ELF: ret = elf_load_debug_info(module); break; + case DMT_PE: ret = pe_load_debug_info(pcs, module); break; + default: ret = FALSE; break; } + if (!ret) module->module.SymType = SymNone; break; default: break; } - return (module && module->module.SymType > SymNone) ? module : NULL; + return (module && module->module.SymType != SymNone) ? module : NULL; } /*********************************************************************** @@ -461,10 +459,10 @@ BOOL WINAPI SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, if (!module) return FALSE; *ModuleInfo = module->module; - if (module->module.SymType <= SymNone) + if (module->module.SymType == SymNone) { module = module_get_container(pcs, module); - if (module && module->module.SymType > SymNone) + if (module && module->module.SymType != SymNone) ModuleInfo->SymType = module->module.SymType; } diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 92196c89383..bd43f8f459d 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -171,7 +171,7 @@ static void coff_add_symbol(struct CoffFile* coff_file, struct symt* sym) coff_file->entries[coff_file->neps++] = sym; } -static SYM_TYPE coff_process_info(const struct msc_debug_info* msc_dbg) +static BOOL coff_process_info(const struct msc_debug_info* msc_dbg) { const IMAGE_AUX_SYMBOL* aux; const IMAGE_COFF_SYMBOLS_HEADER* coff; @@ -189,7 +189,7 @@ static SYM_TYPE coff_process_info(const struct msc_debug_info* msc_dbg) int linetab_indx; const char* nampnt; int naux; - SYM_TYPE sym_type = SymNone; + BOOL ret = FALSE; DWORD addr; TRACE("Processing COFF symbols...\n"); @@ -466,8 +466,6 @@ static SYM_TYPE coff_process_info(const struct msc_debug_info* msc_dbg) } } - sym_type = SymCoff; - for (j = 0; j < coff_files.nfiles; j++) { if (coff_files.files[j].entries != NULL) @@ -476,9 +474,11 @@ static SYM_TYPE coff_process_info(const struct msc_debug_info* msc_dbg) } } HeapFree(GetProcessHeap(), 0, coff_files.files); + msc_dbg->module->module.SymType = SymCoff; + ret = TRUE; } - return sym_type; + return ret; } @@ -2701,11 +2701,11 @@ static HANDLE open_pdb_file(const struct process* pcs, struct module* module, return (h == INVALID_HANDLE_VALUE) ? NULL : h; } -static SYM_TYPE pdb_process_file(const struct process* pcs, - const struct msc_debug_info* msc_dbg, - const char* filename, DWORD timestamp) +static BOOL pdb_process_file(const struct process* pcs, + const struct msc_debug_info* msc_dbg, + const char* filename, DWORD timestamp) { - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; HANDLE hFile, hMap = NULL; char* image = NULL; PDB_HEADER* pdb = NULL; @@ -2855,7 +2855,8 @@ static SYM_TYPE pdb_process_file(const struct process* pcs, file = (char*)((DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3); } - sym_type = SymCv; + msc_dbg->module->module.SymType = SymCv; + ret = TRUE; leave: @@ -2871,7 +2872,7 @@ static SYM_TYPE pdb_process_file(const struct process* pcs, if (hMap) CloseHandle(hMap); if (hFile) CloseHandle(hFile); - return sym_type; + return ret; } /*======================================================================== @@ -2915,11 +2916,12 @@ typedef struct _CV_DIRECTORY_ENTRY #define sstAlignSym 0x125 #define sstSrcModule 0x127 -static SYM_TYPE codeview_process_info(const struct process* pcs, - const struct msc_debug_info* msc_dbg) +static BOOL codeview_process_info(const struct process* pcs, + const struct msc_debug_info* msc_dbg) { const CODEVIEW_HEADER* cv = (const CODEVIEW_HEADER*)msc_dbg->root; - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; + switch (cv->dwSignature) { @@ -2963,7 +2965,8 @@ static SYM_TYPE codeview_process_info(const struct process* pcs, } } - sym_type = SymCv; + msc_dbg->module->module.SymType = SymCv; + ret = TRUE; break; } @@ -2972,7 +2975,7 @@ static SYM_TYPE codeview_process_info(const struct process* pcs, const CODEVIEW_PDB_DATA* pdb = (const CODEVIEW_PDB_DATA*)(cv + 1); codeview_init_basic_types(msc_dbg->module); - sym_type = pdb_process_file(pcs, msc_dbg, pdb->name, pdb->timestamp); + ret = pdb_process_file(pcs, msc_dbg, pdb->name, pdb->timestamp); break; } default: @@ -2981,17 +2984,17 @@ static SYM_TYPE codeview_process_info(const struct process* pcs, break; } - return sym_type; + return ret; } /*======================================================================== * Process debug directory. */ -SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* module, - const BYTE* mapping, const IMAGE_DEBUG_DIRECTORY* dbg, - int nDbg) +BOOL pe_load_debug_directory(const struct process* pcs, struct module* module, + const BYTE* mapping, const IMAGE_DEBUG_DIRECTORY* dbg, + int nDbg) { - SYM_TYPE sym_type; + BOOL ret; int i; struct msc_debug_info msc_dbg; const IMAGE_NT_HEADERS* nth = RtlImageNtHeader((void*)mapping); @@ -3004,7 +3007,7 @@ SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* modul __TRY { - sym_type = -1; + ret = FALSE; /* First, watch out for OMAP data */ for (i = 0; i < nDbg; i++) @@ -3023,8 +3026,7 @@ SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* modul if (dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW) { msc_dbg.root = mapping + dbg[i].PointerToRawData; - sym_type = codeview_process_info(pcs, &msc_dbg); - if (sym_type == SymCv) goto done; + if ((ret = codeview_process_info(pcs, &msc_dbg))) goto done; } } @@ -3034,8 +3036,7 @@ SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* modul if (dbg[i].Type == IMAGE_DEBUG_TYPE_COFF) { msc_dbg.root = mapping + dbg[i].PointerToRawData; - sym_type = coff_process_info(&msc_dbg); - if (sym_type == SymCoff) goto done; + if ((ret = coff_process_info(&msc_dbg))) goto done; } } done: @@ -3073,8 +3074,8 @@ typedef struct _FPO_DATA __EXCEPT(page_fault) { ERR("Got a page fault while loading symbols\n"); - sym_type = -1; + ret = FALSE; } __ENDTRY - return sym_type; + return ret; } diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c index cf7ba1193b6..f7bb142d9b8 100644 --- a/dlls/dbghelp/pe_module.c +++ b/dlls/dbghelp/pe_module.c @@ -40,13 +40,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); * look for stabs information in PE header (it's how the mingw compiler provides * its debugging information) */ -static SYM_TYPE pe_load_stabs(const struct process* pcs, struct module* module, - const void* mapping, IMAGE_NT_HEADERS* nth) +static BOOL pe_load_stabs(const struct process* pcs, struct module* module, + const void* mapping, IMAGE_NT_HEADERS* nth) { IMAGE_SECTION_HEADER* section; int i, stabsize = 0, stabstrsize = 0; unsigned int stabs = 0, stabstr = 0; - SYM_TYPE sym_type = SymNone; + BOOL ret = FALSE; section = (IMAGE_SECTION_HEADER*) ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader); @@ -66,10 +66,10 @@ static SYM_TYPE pe_load_stabs(const struct process* pcs, struct module* module, if (stabstrsize && stabsize) { - sym_type = stabs_parse(module, mapping, module->module.BaseOfImage, - stabs, stabsize, stabstr, stabstrsize); + ret = stabs_parse(module, mapping, module->module.BaseOfImage, + stabs, stabsize, stabstr, stabstrsize); } - return sym_type; + return ret; } static BOOL CALLBACK dbg_match(char* file, void* user) @@ -83,15 +83,15 @@ static BOOL CALLBACK dbg_match(char* file, void* user) * * loads a .dbg file */ -static SYM_TYPE pe_load_dbg_file(const struct process* pcs, struct module* module, - const char* dbg_name, DWORD timestamp) +static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module, + const char* dbg_name, DWORD timestamp) { char tmp[MAX_PATH]; HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0; const BYTE* dbg_mapping = NULL; const IMAGE_SEPARATE_DEBUG_HEADER* hdr; const IMAGE_DEBUG_DIRECTORY* dbg; - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; WINE_TRACE("Processing DBG file %s\n", dbg_name); @@ -120,8 +120,8 @@ static SYM_TYPE pe_load_dbg_file(const struct process* pcs, struct module* modul hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + hdr->ExportedNamesSize); - sym_type = pe_load_debug_directory(pcs, module, dbg_mapping, dbg, - hdr->DebugDirectorySize / sizeof(*dbg)); + ret = pe_load_debug_directory(pcs, module, dbg_mapping, dbg, + hdr->DebugDirectorySize / sizeof(*dbg)); } else WINE_ERR("-Unable to peruse .DBG file %s (%s)\n", dbg_name, debugstr_a(tmp)); @@ -129,7 +129,7 @@ static SYM_TYPE pe_load_dbg_file(const struct process* pcs, struct module* modul if (dbg_mapping) UnmapViewOfFile((void*)dbg_mapping); if (hMap) CloseHandle(hMap); if (hFile != NULL) CloseHandle(hFile); - return sym_type; + return ret; } /****************************************************************** @@ -137,11 +137,11 @@ static SYM_TYPE pe_load_dbg_file(const struct process* pcs, struct module* modul * * Process MSC debug information in PE file. */ -static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs, - struct module* module, - const void* mapping, IMAGE_NT_HEADERS* nth) +static BOOL pe_load_msc_debug_info(const struct process* pcs, + struct module* module, + const void* mapping, IMAGE_NT_HEADERS* nth) { - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; const IMAGE_DATA_DIRECTORY* dir; const IMAGE_DEBUG_DIRECTORY*dbg = NULL; int nDbg; @@ -149,9 +149,9 @@ static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs, /* Read in debug directory */ dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG; nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY); - if (!nDbg) return sym_type; + if (!nDbg) return FALSE; - dbg = (const IMAGE_DEBUG_DIRECTORY*)((const char*)mapping + dir->VirtualAddress); + dbg = RtlImageRvaToVa(nth, (void*)mapping, dir->VirtualAddress, NULL); /* Parse debug directory */ if (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) @@ -168,32 +168,31 @@ static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs, } else { - sym_type = pe_load_dbg_file(pcs, module, misc->Data, nth->FileHeader.TimeDateStamp); + ret = pe_load_dbg_file(pcs, module, misc->Data, nth->FileHeader.TimeDateStamp); } } else { /* Debug info is embedded into PE module */ - sym_type = pe_load_debug_directory(pcs, module, mapping, dbg, nDbg); + ret = pe_load_debug_directory(pcs, module, mapping, dbg, nDbg); } - return sym_type; + return ret; } /*********************************************************************** * pe_load_export_debug_info */ -static SYM_TYPE pe_load_export_debug_info(const struct process* pcs, - struct module* module, - const void* mapping, IMAGE_NT_HEADERS* nth) +static BOOL pe_load_export_debug_info(const struct process* pcs, + struct module* module, + const void* mapping, IMAGE_NT_HEADERS* nth) { - unsigned int i; - IMAGE_DATA_DIRECTORY* dir; - DWORD base = module->module.BaseOfImage; - ADDRESS addr; + unsigned int i; + const IMAGE_EXPORT_DIRECTORY* exports; + DWORD base = module->module.BaseOfImage; + DWORD size; - addr.Mode = AddrModeFlat; - addr.Segment = 0; + if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE; #if 0 /* Add start of DLL (better use the (yet unimplemented) Exe SymTag for this) */ @@ -205,8 +204,7 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs, /* Add entry point */ symt_new_public(module, NULL, "EntryPoint", base + nth->OptionalHeader.AddressOfEntryPoint, 0, - TRUE /* FIXME */, TRUE /* FIXME */); - + TRUE, TRUE); #if 0 /* FIXME: we'd better store addresses linked to sections rather than absolute values */ @@ -216,33 +214,33 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs, ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader); for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++) { - symt_new_public(module, NULL, section->Name, base + section->VirtualAddress, 0, - TRUE /* FIXME */, TRUE /* FIXME */); + symt_new_public(module, NULL, section->Name, + RtlImageRvaToVa(nth, (void*)mapping, section->VirtualAddress, NULL), + 0, TRUE /* FIXME */, TRUE /* FIXME */); } #endif - - /* Add exported functions */ - if ((dir = RtlImageDirectoryEntryToData((void*)mapping, TRUE, - IMAGE_DIRECTORY_ENTRY_EXPORT, NULL))) - { - const IMAGE_EXPORT_DIRECTORY* exports; - const WORD* ordinals = NULL; - const void* const* functions = NULL; - const DWORD* names = NULL; - unsigned int j; - char buffer[16]; - exports = (const void*)((const char*)mapping + dir->VirtualAddress); - functions = (const void*)((const char*)mapping + exports->AddressOfFunctions); - ordinals = (const void*)((const char*)mapping + exports->AddressOfNameOrdinals); - names = (const void*)((const char*)mapping + exports->AddressOfNames); - + /* Add exported functions */ + if ((exports = RtlImageDirectoryEntryToData((void*)mapping, FALSE, + IMAGE_DIRECTORY_ENTRY_EXPORT, &size))) + { + const WORD* ordinals = NULL; + const DWORD_PTR* functions = NULL; + const DWORD* names = NULL; + unsigned int j; + char buffer[16]; + + functions = RtlImageRvaToVa(nth, (void*)mapping, exports->AddressOfFunctions, NULL); + ordinals = RtlImageRvaToVa(nth, (void*)mapping, exports->AddressOfNameOrdinals, NULL); + names = RtlImageRvaToVa(nth, (void*)mapping, exports->AddressOfNames, NULL); + for (i = 0; i < exports->NumberOfNames; i++) { if (!names[i]) continue; - symt_new_public(module, NULL, (const char*)base + names[i], - base + (DWORD)functions[ordinals[i]], 0, - TRUE /* FIXME */, TRUE /* FIXME */); + symt_new_public(module, NULL, + RtlImageRvaToVa(nth, (void*)mapping, names[i], NULL), + base + functions[ordinals[i]], + 0, TRUE /* FIXME */, TRUE /* FIXME */); } for (i = 0; i < exports->NumberOfFunctions; i++) @@ -258,16 +256,17 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs, } } /* no real debug info, only entry points */ - return module->module.SymType = SymExport; + module->module.SymType = SymExport; + return TRUE; } /****************************************************************** * pe_load_debug_info * */ -SYM_TYPE pe_load_debug_info(const struct process* pcs, struct module* module) +BOOL pe_load_debug_info(const struct process* pcs, struct module* module) { - SYM_TYPE sym_type = -1; + BOOL ret = FALSE; HANDLE hFile; HANDLE hMap; void* mapping; @@ -275,7 +274,7 @@ SYM_TYPE pe_load_debug_info(const struct process* pcs, struct module* module) hFile = CreateFileA(module->module.LoadedImageName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) return -1; + if (hFile == INVALID_HANDLE_VALUE) return ret; if ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) { if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) @@ -284,24 +283,22 @@ SYM_TYPE pe_load_debug_info(const struct process* pcs, struct module* module) if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY)) { - sym_type = pe_load_stabs(pcs, module, mapping, nth); - if (sym_type <= SymNone) - sym_type = pe_load_msc_debug_info(pcs, module, mapping, nth); + ret = pe_load_stabs(pcs, module, mapping, nth) || + pe_load_msc_debug_info(pcs, module, mapping, nth); /* if we still have no debug info (we could only get SymExport at this * point), then do the SymExport except if we have an ELF container, * in which case we'll rely on the export's on the ELF side */ } - if (sym_type <= SymNone && !module_get_debug(pcs, module)) - sym_type = pe_load_export_debug_info(pcs, module, mapping, nth); + if (pe_load_export_debug_info(pcs, module, mapping, nth) && !ret) + ret = TRUE; UnmapViewOfFile(mapping); } CloseHandle(hMap); } CloseHandle(hFile); - module->module.SymType = (sym_type >= SymNone) ? sym_type : SymNone; - return sym_type; + return ret; } /****************************************************************** @@ -349,8 +346,10 @@ struct module* pe_load_module(struct process* pcs, char* name, nth->OptionalHeader.CheckSum); if (module) { - module->module.SymType = (dbghelp_options & SYMOPT_DEFERRED_LOADS) ? - SymDeferred : pe_load_debug_info(pcs, module); + if (dbghelp_options & SYMOPT_DEFERRED_LOADS) + module->module.SymType = SymDeferred; + else + pe_load_debug_info(pcs, module); } } UnmapViewOfFile(mapping); diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c index 95b90fa2a0d..da0df42120c 100644 --- a/dlls/dbghelp/stabs.c +++ b/dlls/dbghelp/stabs.c @@ -1078,9 +1078,9 @@ static void stabs_finalize_function(struct module* module, struct symt_function* } } -SYM_TYPE 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, const char* addr, + unsigned long load_offset, unsigned int staboff, int stablen, + unsigned int strtaboff, int strtablen) { struct symt_function* curr_func = NULL; struct symt_block* block = NULL; @@ -1102,7 +1102,7 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr, struct pending_loc_var* pending_vars = NULL; unsigned num_pending_vars = 0; unsigned num_allocated_pending_vars = 0; - SYM_TYPE ret = SymDia; + BOOL ret = TRUE; nstab = stablen / sizeof(struct stab_nlist); stab_ptr = (const struct stab_nlist*)(addr + staboff); @@ -1437,7 +1437,7 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr, { ERR("Excluded header not found (%s,%ld)\n", ptr, stab_ptr->n_value); module_reset_debug_info(module); - ret = SymNone; + ret = FALSE; goto done; } break; @@ -1452,6 +1452,7 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr, TRACE("0x%02x %lx %s\n", stab_ptr->n_type, stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_un.n_strx)); } + module->module.SymType = SymDia; done: HeapFree(GetProcessHeap(), 0, stabbuff); stabs_free_includes(); diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index e94afc9ae4a..aa226b599da 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -161,6 +161,9 @@ struct symt_public* symt_new_public(struct module* module, TRACE_(dbghelp_symt)("Adding public symbol %s:%s @%lx\n", module->module.ModuleName, name, address); + if ((dbghelp_options & SYMOPT_AUTO_PUBLICS) && + symt_find_nearest(module, address) != -1) + return NULL; if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) { sym->symt.tag = SymTagPublicSymbol; @@ -548,12 +551,6 @@ static BOOL symt_enum_module(struct module* module, regex_t* regex, while ((ptr = hash_table_iter_up(&hti))) { sym = GET_ENTRY(ptr, struct symt_ht, hash_elt); - /* FIXME: this is not true, we should only drop the public - * symbol iff no other one is found - */ - if ((dbghelp_options & SYMOPT_AUTO_PUBLICS) && - sym->symt.tag == SymTagPublicSymbol) continue; - if (sym->hash_elt.name && regexec(regex, sym->hash_elt.name, 0, NULL, 0) == 0) {