Authors: Robert Shearman <rob@codeweavers.com>, Eric Pouech <pouech-eric@wanadoo.fr>

- 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).
This commit is contained in:
Alexandre Julliard 2004-08-30 19:31:13 +00:00
parent b1bb722088
commit 65c3765739
8 changed files with 231 additions and 233 deletions

View File

@ -33,8 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
* + funcargtype:s are (partly) wrong: they should be a specific struct (like * + funcargtype:s are (partly) wrong: they should be a specific struct (like
* typedef) pointing to the actual type (and not a direct access) * 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 * + we should store the underlying type for an enum in the symt_enum struct
* - most options (dbghelp_options) are not used (loading lines, decoration, * - most options (dbghelp_options) are not used (loading lines, decoration...)
* deferring reading of module symbols, public symbols...)
* - in symbol lookup by name, we don't use RE everywhere we should. Moreover, when * - 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'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 * 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 * + we should add parameters' types to the function's signature
* while processing a function's parameters * while processing a function's parameters
* + get rid of MSC reading FIXME:s (lots of types are not defined) * + 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 * + C++ management
* - stabs: * - 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 * + C++ management
* - implement the callback notification mechanism * - implement the callback notification mechanism
*/ */

View File

@ -287,7 +287,7 @@ struct process
extern struct process* process_find_by_handle(HANDLE hProcess); extern struct process* process_find_by_handle(HANDLE hProcess);
/* elf_module.c */ /* 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* extern struct module*
elf_load_module(struct process* pcs, const char* name); elf_load_module(struct process* pcs, const char* name);
extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs); 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, extern BOOL module_remove(struct process* pcs,
struct module* module); struct module* module);
/* msc.c */ /* 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, struct module* module,
const BYTE* file_map, const BYTE* file_map,
const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg); const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg);
@ -340,14 +340,14 @@ extern struct module*
extern struct module* extern struct module*
pe_load_module_from_pcs(struct process* pcs, const char* name, pe_load_module_from_pcs(struct process* pcs, const char* name,
const char* mod_name, DWORD base, DWORD size); 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); struct module* module);
/* source.c */ /* source.c */
extern unsigned source_new(struct module* module, const char* source); extern unsigned source_new(struct module* module, const char* source);
extern const char* source_get(const struct module* module, unsigned idx); extern const char* source_get(const struct module* module, unsigned idx);
/* stabs.c */ /* 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 long load_offset,
unsigned int staboff, int stablen, unsigned int staboff, int stablen,
unsigned int strtaboff, int strtablen); unsigned int strtaboff, int strtablen);

View File

@ -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)) 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_ADDRESS, &xaddr);
symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_LENGTH, &xsize); 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 * 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", FIXME("Duplicate in %s: %s<%08lx-%08x> %s<%08lx-%08lx>\n",
module->module.ModuleName, module->module.ModuleName,
ste->ht_elt.name, addr, ste->symp->st_size, 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 * Creates a set of public symbols from an ELF symtab
*/ */
static int elf_new_public_symbols(struct module* module, struct hash_table* symtab, static int elf_new_public_symbols(struct module* module, struct hash_table* symtab)
BOOL dont_check)
{ {
struct symt_compiland* compiland = NULL; struct symt_compiland* compiland = NULL;
const char* compiland_name = 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; if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
/* FIXME: we're missing the ELF entry point here */
hash_table_iter_init(symtab, &hti, NULL); hash_table_iter_init(symtab, &hti, NULL);
while ((ste = hash_table_iter_up(&hti))) 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 = symt_new_compiland(module,
compiland_name = ste->filename); compiland_name = ste->filename);
if (dont_check || !(dbghelp_options & SYMOPT_AUTO_PUBLICS) || symt_new_public(module, compiland, ste->ht_elt.name,
symt_find_nearest(module, module->elf_info->elf_addr + ste->symp->st_value) == -1) module->elf_info->elf_addr + ste->symp->st_value,
{ ste->symp->st_size, TRUE /* FIXME */,
symt_new_public(module, compiland, ste->ht_elt.name, ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC);
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; return TRUE;
} }
@ -470,9 +471,9 @@ static int elf_new_public_symbols(struct module* module, struct hash_table* symt
* read or parsed) * read or parsed)
* 1 on success * 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; char* addr = (char*)0xffffffff;
int fd = -1; int fd = -1;
struct stat statbuf; struct stat statbuf;
@ -498,7 +499,7 @@ SYM_TYPE elf_load_debug_info(struct module* module)
if (module->type != DMT_ELF || !module->elf_info) if (module->type != DMT_ELF || !module->elf_info)
{ {
ERR("Bad elf module '%s'\n", module->module.LoadedImageName); ERR("Bad elf module '%s'\n", module->module.LoadedImageName);
return sym_type; return FALSE;
} }
TRACE("%s\n", module->module.LoadedImageName); 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); addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == (char*)0xffffffff) goto leave; if (addr == (char*)0xffffffff) goto leave;
sym_type = SymNone;
/* /*
* Next, we need to find a few of the internal ELF headers within * Next, we need to find a few of the internal ELF headers within
* this thing. We need the main executable header, and the section * 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; dynsym_sect = i;
} }
sym_type = SymExport;
if (symtab_sect == -1) if (symtab_sect == -1)
{ {
/* if we don't have a symtab but a dynsym, process the dynsym /* 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; symtab_sect = dynsym_sect;
} }
module->module.SymType = SymExport;
/* FIXME: guess a better size from ELF info */ /* FIXME: guess a better size from ELF info */
pool_init(&pool, 65536); pool_init(&pool, 65536);
hash_table_init(&pool, &ht_symtab, 256); 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) if (stab_sect != -1 && stabstr_sect != -1)
{ {
/* OK, now just parse all of the stabs. */ /* OK, now just parse all of the stabs. */
sym_type = stabs_parse(module, addr, module->elf_info->elf_addr, ret = stabs_parse(module, addr, module->elf_info->elf_addr,
spnt[stab_sect].sh_offset, spnt[stab_sect].sh_size, spnt[stab_sect].sh_offset, spnt[stab_sect].sh_size,
spnt[stabstr_sect].sh_offset, spnt[stabstr_sect].sh_offset,
spnt[stabstr_sect].sh_size); spnt[stabstr_sect].sh_size);
if (sym_type == -1) if (!ret)
{ {
WARN("Couldn't read correctly read stabs\n"); WARN("Couldn't read correctly read stabs\n");
goto leave; goto leave;
@ -586,8 +585,7 @@ SYM_TYPE elf_load_debug_info(struct module* module)
else if (debug_sect != -1) else if (debug_sect != -1)
{ {
/* Dwarf 2 debug information */ /* Dwarf 2 debug information */
FIXME("Unsupported Dwarf2 information\n"); FIXME("Unsupported Dwarf2 information for %s\n", module->module.ModuleName);
sym_type = SymNone;
} }
} }
if (strstr(module->module.ModuleName, "<elf>") || if (strstr(module->module.ModuleName, "<elf>") ||
@ -597,16 +595,9 @@ SYM_TYPE elf_load_debug_info(struct module* module)
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY)) if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
elf_new_wine_thunks(module, &ht_symtab, elf_new_wine_thunks(module, &ht_symtab,
sizeof(thunks) / sizeof(thunks[0]), thunks); 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); pool_destroy(&pool);
@ -614,7 +605,7 @@ leave:
if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size); if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
if (fd != -1) close(fd); 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) * read or parsed)
* 1 on success * 1 on success
*/ */
static SYM_TYPE elf_load_file(struct process* pcs, const char* filename, static BOOL elf_load_file(struct process* pcs, const char* filename,
unsigned long load_offset, struct elf_info* elf_info) unsigned long load_offset, struct elf_info* elf_info)
{ {
static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 }; static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
const char* addr = (char*)0xffffffff; const char* addr = (char*)0xffffffff;
int fd = -1; int fd = -1;
struct stat statbuf; struct stat statbuf;
@ -663,7 +654,7 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename,
const Elf32_Phdr* ppnt; const Elf32_Phdr* ppnt;
const char* shstrtab; const char* shstrtab;
int i; int i;
DWORD delta, size; DWORD size, start;
unsigned tmp, page_mask = getpagesize() - 1; unsigned tmp, page_mask = getpagesize() - 1;
TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset); 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); addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == (char*)-1) goto leave; if (addr == (char*)-1) goto leave;
sym_type = SymNone;
/* Next, we need to find a few of the internal ELF headers within /* Next, we need to find a few of the internal ELF headers within
* this thing. We need the main executable header, and the section * this thing. We need the main executable header, and the section
* table. * 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); spnt = (const Elf32_Shdr*)(addr + ehptr->e_shoff);
shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset); 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 */ /* grab size of module once loaded in memory */
ppnt = (const Elf32_Phdr*)(addr + ehptr->e_phoff); ppnt = (const Elf32_Phdr*)(addr + ehptr->e_phoff);
size = 0; size = 0; start = ~0L;
for (i = 0; i < ehptr->e_phnum; i++) for (i = 0; i < ehptr->e_phnum; i++)
{ {
if (ppnt[i].p_type == PT_LOAD) if (ppnt[i].p_type == PT_LOAD)
{ {
tmp = (ppnt[i].p_vaddr + ppnt[i].p_memsz + page_mask) & ~page_mask; tmp = (ppnt[i].p_vaddr + ppnt[i].p_memsz + page_mask) & ~page_mask;
if (size < tmp) size = tmp; 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) if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
{ {
for (i = 0; i < ehptr->e_shnum; i++) 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; dyn.d_tag = DT_NULL;
ptr += sizeof(dyn); ptr += sizeof(dyn);
} while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL); } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
if (dyn.d_tag == DT_NULL) if (dyn.d_tag == DT_NULL) goto leave;
{
sym_type = -1;
goto leave;
}
elf_info->dbg_hdr_addr = dyn.d_un.d_ptr; 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) if (elf_info->flags & ELF_INFO_MODULE)
{ {
elf_info->module = module_new(pcs, filename, DMT_ELF, elf_info->module = module_new(pcs, filename, DMT_ELF,
(load_offset) ? load_offset : ehptr->e_entry, (load_offset) ? load_offset : start,
size, 0, 0); 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(), ERR("OOM\n");
0, sizeof(struct elf_module_info)); exit(0); /* FIXME */
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;
} }
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: leave:
if (addr != (char*)0xffffffff) munmap((void*)addr, statbuf.st_size); if (addr != (char*)0xffffffff) munmap((void*)addr, statbuf.st_size);
if (fd != -1) close(fd); if (fd != -1) close(fd);
return sym_type; return ret;
} }
/****************************************************************** /******************************************************************
* elf_load_file_from_path * elf_load_file_from_path
* tries to load an ELF file from a set of paths (separated by ':') * tries to load an ELF file from a set of paths (separated by ':')
*/ */
static SYM_TYPE elf_load_file_from_path(HANDLE hProcess, static BOOL elf_load_file_from_path(HANDLE hProcess,
const char* filename, const char* filename,
unsigned long load_offset, unsigned long load_offset,
const char* path, const char* path,
struct elf_info* elf_info) struct elf_info* elf_info)
{ {
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
char *s, *t, *fn; char *s, *t, *fn;
char* paths = NULL; char* paths = NULL;
if (!path) return sym_type; if (!path) return FALSE;
paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path); paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path);
for (s = paths; s && *s; s = (t) ? (t+1) : NULL) 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); strcpy(fn, s);
strcat(fn, "/"); strcat(fn, "/");
strcat(fn, filename); 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); HeapFree(GetProcessHeap(), 0, fn);
if (sym_type != -1) break; if (ret) break;
s = (t) ? (t+1) : NULL; s = (t) ? (t+1) : NULL;
} }
HeapFree(GetProcessHeap(), 0, paths); 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 * 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, static BOOL elf_search_and_load_file(struct process* pcs, const char* filename,
unsigned long load_offset, struct elf_info* elf_info) unsigned long load_offset,
struct elf_info* elf_info)
{ {
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
struct module* module; 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))) if ((module = module_find_by_name(pcs, filename, DMT_ELF)))
{ {
elf_info->module = module; 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; return module->module.SymType;
} }
if (strstr(filename, "libstdc++")) return -1; /* We know we can't do it */ if (strstr(filename, "libstdc++")) return FALSE; /* We know we can't do it */
sym_type = elf_load_file(pcs, filename, load_offset, elf_info); ret = elf_load_file(pcs, filename, load_offset, elf_info);
/* if relative pathname, try some absolute base dirs */ /* 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, ret = elf_load_file_from_path(pcs, filename, load_offset,
getenv("PATH"), elf_info); getenv("PATH"), elf_info) ||
if (sym_type == -1) elf_load_file_from_path(pcs, filename, load_offset,
sym_type = elf_load_file_from_path(pcs, filename, load_offset, getenv("LD_LIBRARY_PATH"), elf_info) ||
getenv("LD_LIBRARY_PATH"), elf_info); elf_load_file_from_path(pcs, filename, load_offset,
if (sym_type == -1) getenv("WINEDLLPATH"), elf_info);
sym_type = 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) BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
{ {
const char* ptr; const char* ptr;
SYM_TYPE sym_type;
struct elf_info elf_info; struct elf_info elf_info;
BOOL ret;
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE; elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
/* All binaries are loaded with WINELOADER (if run from tree) or by the /* 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 * wine-kthread is not 100% safe
*/ */
if ((ptr = getenv("WINELOADER"))) 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 else
{ {
if ((sym_type = elf_search_and_load_file(pcs, "wine-kthread", 0, &elf_info)) == -1) ret = elf_search_and_load_file(pcs, "wine-kthread", 0, &elf_info) ||
sym_type = elf_search_and_load_file(pcs, "wine-pthread", 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; elf_info.module->elf_info->elf_loader = 1;
strcpy(elf_info.module->module.ModuleName, "<wine-loader>"); strcpy(elf_info.module->module.ModuleName, "<wine-loader>");
return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0; 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 module* elf_load_module(struct process* pcs, const char* name)
{ {
struct elf_info elf_info; struct elf_info elf_info;
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
const char* p; const char* p;
const char* xname; const char* xname;
struct r_debug dbg_hdr; 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 (!p++) p = bufstr;
if (!memcmp(p, xname, strlen(xname))) if (!memcmp(p, xname, strlen(xname)))
{ {
sym_type = elf_search_and_load_file(pcs, bufstr, ret = elf_search_and_load_file(pcs, bufstr,
(unsigned long)lm.l_addr, &elf_info); (unsigned long)lm.l_addr, &elf_info);
break; break;
} }
} }
} }
if (!lm_addr || sym_type == -1) return NULL; if (!lm_addr || !ret) return NULL;
assert(elf_info.module); assert(elf_info.module);
return elf_info.module; return elf_info.module;
} }
@ -1005,8 +1002,8 @@ struct module* elf_load_module(struct process* pcs, const char* name)
return NULL; 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__ */ #endif /* __ELF__ */

View File

@ -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) struct module* module_get_debug(const struct process* pcs, struct module* module)
{ {
BOOL ret;
if (!module) return NULL; if (!module) return NULL;
switch (module->module.SymType) switch (module->module.SymType)
{ {
case -1: break;
case SymNone: case SymNone:
module = module_get_container(pcs, module); module = module_get_container(pcs, module);
if (!module || module->module.SymType != SymDeferred) break; 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: case SymDeferred:
switch (module->type) switch (module->type)
{ {
case DMT_ELF: case DMT_ELF: ret = elf_load_debug_info(module); break;
elf_load_debug_info(module); case DMT_PE: ret = pe_load_debug_info(pcs, module); break;
break; default: ret = FALSE; break;
case DMT_PE:
pe_load_debug_info(pcs, module);
break;
default: break;
} }
if (!ret) module->module.SymType = SymNone;
break; break;
default: 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; if (!module) return FALSE;
*ModuleInfo = module->module; *ModuleInfo = module->module;
if (module->module.SymType <= SymNone) if (module->module.SymType == SymNone)
{ {
module = module_get_container(pcs, module); module = module_get_container(pcs, module);
if (module && module->module.SymType > SymNone) if (module && module->module.SymType != SymNone)
ModuleInfo->SymType = module->module.SymType; ModuleInfo->SymType = module->module.SymType;
} }

View File

@ -171,7 +171,7 @@ static void coff_add_symbol(struct CoffFile* coff_file, struct symt* sym)
coff_file->entries[coff_file->neps++] = 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_AUX_SYMBOL* aux;
const IMAGE_COFF_SYMBOLS_HEADER* coff; 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; int linetab_indx;
const char* nampnt; const char* nampnt;
int naux; int naux;
SYM_TYPE sym_type = SymNone; BOOL ret = FALSE;
DWORD addr; DWORD addr;
TRACE("Processing COFF symbols...\n"); 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++) for (j = 0; j < coff_files.nfiles; j++)
{ {
if (coff_files.files[j].entries != NULL) 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); 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; return (h == INVALID_HANDLE_VALUE) ? NULL : h;
} }
static SYM_TYPE pdb_process_file(const struct process* pcs, static BOOL pdb_process_file(const struct process* pcs,
const struct msc_debug_info* msc_dbg, const struct msc_debug_info* msc_dbg,
const char* filename, DWORD timestamp) const char* filename, DWORD timestamp)
{ {
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
HANDLE hFile, hMap = NULL; HANDLE hFile, hMap = NULL;
char* image = NULL; char* image = NULL;
PDB_HEADER* pdb = 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); file = (char*)((DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3);
} }
sym_type = SymCv; msc_dbg->module->module.SymType = SymCv;
ret = TRUE;
leave: leave:
@ -2871,7 +2872,7 @@ static SYM_TYPE pdb_process_file(const struct process* pcs,
if (hMap) CloseHandle(hMap); if (hMap) CloseHandle(hMap);
if (hFile) CloseHandle(hFile); if (hFile) CloseHandle(hFile);
return sym_type; return ret;
} }
/*======================================================================== /*========================================================================
@ -2915,11 +2916,12 @@ typedef struct _CV_DIRECTORY_ENTRY
#define sstAlignSym 0x125 #define sstAlignSym 0x125
#define sstSrcModule 0x127 #define sstSrcModule 0x127
static SYM_TYPE codeview_process_info(const struct process* pcs, static BOOL codeview_process_info(const struct process* pcs,
const struct msc_debug_info* msc_dbg) const struct msc_debug_info* msc_dbg)
{ {
const CODEVIEW_HEADER* cv = (const CODEVIEW_HEADER*)msc_dbg->root; const CODEVIEW_HEADER* cv = (const CODEVIEW_HEADER*)msc_dbg->root;
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
switch (cv->dwSignature) 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; 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); const CODEVIEW_PDB_DATA* pdb = (const CODEVIEW_PDB_DATA*)(cv + 1);
codeview_init_basic_types(msc_dbg->module); 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; break;
} }
default: default:
@ -2981,17 +2984,17 @@ static SYM_TYPE codeview_process_info(const struct process* pcs,
break; break;
} }
return sym_type; return ret;
} }
/*======================================================================== /*========================================================================
* Process debug directory. * Process debug directory.
*/ */
SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* module, BOOL pe_load_debug_directory(const struct process* pcs, struct module* module,
const BYTE* mapping, const IMAGE_DEBUG_DIRECTORY* dbg, const BYTE* mapping, const IMAGE_DEBUG_DIRECTORY* dbg,
int nDbg) int nDbg)
{ {
SYM_TYPE sym_type; BOOL ret;
int i; int i;
struct msc_debug_info msc_dbg; struct msc_debug_info msc_dbg;
const IMAGE_NT_HEADERS* nth = RtlImageNtHeader((void*)mapping); 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 __TRY
{ {
sym_type = -1; ret = FALSE;
/* First, watch out for OMAP data */ /* First, watch out for OMAP data */
for (i = 0; i < nDbg; i++) 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) if (dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW)
{ {
msc_dbg.root = mapping + dbg[i].PointerToRawData; msc_dbg.root = mapping + dbg[i].PointerToRawData;
sym_type = codeview_process_info(pcs, &msc_dbg); if ((ret = codeview_process_info(pcs, &msc_dbg))) goto done;
if (sym_type == SymCv) 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) if (dbg[i].Type == IMAGE_DEBUG_TYPE_COFF)
{ {
msc_dbg.root = mapping + dbg[i].PointerToRawData; msc_dbg.root = mapping + dbg[i].PointerToRawData;
sym_type = coff_process_info(&msc_dbg); if ((ret = coff_process_info(&msc_dbg))) goto done;
if (sym_type == SymCoff) goto done;
} }
} }
done: done:
@ -3073,8 +3074,8 @@ typedef struct _FPO_DATA
__EXCEPT(page_fault) __EXCEPT(page_fault)
{ {
ERR("Got a page fault while loading symbols\n"); ERR("Got a page fault while loading symbols\n");
sym_type = -1; ret = FALSE;
} }
__ENDTRY __ENDTRY
return sym_type; return ret;
} }

View File

@ -40,13 +40,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
* look for stabs information in PE header (it's how the mingw compiler provides * look for stabs information in PE header (it's how the mingw compiler provides
* its debugging information) * its debugging information)
*/ */
static SYM_TYPE pe_load_stabs(const struct process* pcs, struct module* module, static BOOL pe_load_stabs(const struct process* pcs, struct module* module,
const void* mapping, IMAGE_NT_HEADERS* nth) const void* mapping, IMAGE_NT_HEADERS* nth)
{ {
IMAGE_SECTION_HEADER* section; IMAGE_SECTION_HEADER* section;
int i, stabsize = 0, stabstrsize = 0; int i, stabsize = 0, stabstrsize = 0;
unsigned int stabs = 0, stabstr = 0; unsigned int stabs = 0, stabstr = 0;
SYM_TYPE sym_type = SymNone; BOOL ret = FALSE;
section = (IMAGE_SECTION_HEADER*) section = (IMAGE_SECTION_HEADER*)
((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader); ((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) if (stabstrsize && stabsize)
{ {
sym_type = stabs_parse(module, mapping, module->module.BaseOfImage, ret = stabs_parse(module, mapping, module->module.BaseOfImage,
stabs, stabsize, stabstr, stabstrsize); stabs, stabsize, stabstr, stabstrsize);
} }
return sym_type; return ret;
} }
static BOOL CALLBACK dbg_match(char* file, void* user) 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 * loads a .dbg file
*/ */
static SYM_TYPE pe_load_dbg_file(const struct process* pcs, struct module* module, static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
const char* dbg_name, DWORD timestamp) const char* dbg_name, DWORD timestamp)
{ {
char tmp[MAX_PATH]; char tmp[MAX_PATH];
HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0; HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
const BYTE* dbg_mapping = NULL; const BYTE* dbg_mapping = NULL;
const IMAGE_SEPARATE_DEBUG_HEADER* hdr; const IMAGE_SEPARATE_DEBUG_HEADER* hdr;
const IMAGE_DEBUG_DIRECTORY* dbg; const IMAGE_DEBUG_DIRECTORY* dbg;
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
WINE_TRACE("Processing DBG file %s\n", dbg_name); 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->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
hdr->ExportedNamesSize); hdr->ExportedNamesSize);
sym_type = pe_load_debug_directory(pcs, module, dbg_mapping, dbg, ret = pe_load_debug_directory(pcs, module, dbg_mapping, dbg,
hdr->DebugDirectorySize / sizeof(*dbg)); hdr->DebugDirectorySize / sizeof(*dbg));
} }
else else
WINE_ERR("-Unable to peruse .DBG file %s (%s)\n", dbg_name, debugstr_a(tmp)); 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 (dbg_mapping) UnmapViewOfFile((void*)dbg_mapping);
if (hMap) CloseHandle(hMap); if (hMap) CloseHandle(hMap);
if (hFile != NULL) CloseHandle(hFile); 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. * Process MSC debug information in PE file.
*/ */
static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs, static BOOL pe_load_msc_debug_info(const struct process* pcs,
struct module* module, struct module* module,
const void* mapping, IMAGE_NT_HEADERS* nth) const void* mapping, IMAGE_NT_HEADERS* nth)
{ {
SYM_TYPE sym_type = -1; BOOL ret = FALSE;
const IMAGE_DATA_DIRECTORY* dir; const IMAGE_DATA_DIRECTORY* dir;
const IMAGE_DEBUG_DIRECTORY*dbg = NULL; const IMAGE_DEBUG_DIRECTORY*dbg = NULL;
int nDbg; int nDbg;
@ -149,9 +149,9 @@ static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs,
/* Read in debug directory */ /* Read in debug directory */
dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG; dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY); 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 */ /* Parse debug directory */
if (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) 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 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 else
{ {
/* Debug info is embedded into PE module */ /* 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 * pe_load_export_debug_info
*/ */
static SYM_TYPE pe_load_export_debug_info(const struct process* pcs, static BOOL pe_load_export_debug_info(const struct process* pcs,
struct module* module, struct module* module,
const void* mapping, IMAGE_NT_HEADERS* nth) const void* mapping, IMAGE_NT_HEADERS* nth)
{ {
unsigned int i; unsigned int i;
IMAGE_DATA_DIRECTORY* dir; const IMAGE_EXPORT_DIRECTORY* exports;
DWORD base = module->module.BaseOfImage; DWORD base = module->module.BaseOfImage;
ADDRESS addr; DWORD size;
addr.Mode = AddrModeFlat; if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
addr.Segment = 0;
#if 0 #if 0
/* Add start of DLL (better use the (yet unimplemented) Exe SymTag for this) */ /* 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 */ /* Add entry point */
symt_new_public(module, NULL, "EntryPoint", symt_new_public(module, NULL, "EntryPoint",
base + nth->OptionalHeader.AddressOfEntryPoint, 0, base + nth->OptionalHeader.AddressOfEntryPoint, 0,
TRUE /* FIXME */, TRUE /* FIXME */); TRUE, TRUE);
#if 0 #if 0
/* FIXME: we'd better store addresses linked to sections rather than /* FIXME: we'd better store addresses linked to sections rather than
absolute values */ absolute values */
@ -216,33 +214,33 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs,
((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader); ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++) for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
{ {
symt_new_public(module, NULL, section->Name, base + section->VirtualAddress, 0, symt_new_public(module, NULL, section->Name,
TRUE /* FIXME */, TRUE /* FIXME */); RtlImageRvaToVa(nth, (void*)mapping, section->VirtualAddress, NULL),
0, TRUE /* FIXME */, TRUE /* FIXME */);
} }
#endif #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); /* Add exported functions */
functions = (const void*)((const char*)mapping + exports->AddressOfFunctions); if ((exports = RtlImageDirectoryEntryToData((void*)mapping, FALSE,
ordinals = (const void*)((const char*)mapping + exports->AddressOfNameOrdinals); IMAGE_DIRECTORY_ENTRY_EXPORT, &size)))
names = (const void*)((const char*)mapping + exports->AddressOfNames); {
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++) for (i = 0; i < exports->NumberOfNames; i++)
{ {
if (!names[i]) continue; if (!names[i]) continue;
symt_new_public(module, NULL, (const char*)base + names[i], symt_new_public(module, NULL,
base + (DWORD)functions[ordinals[i]], 0, RtlImageRvaToVa(nth, (void*)mapping, names[i], NULL),
TRUE /* FIXME */, TRUE /* FIXME */); base + functions[ordinals[i]],
0, TRUE /* FIXME */, TRUE /* FIXME */);
} }
for (i = 0; i < exports->NumberOfFunctions; i++) 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 */ /* no real debug info, only entry points */
return module->module.SymType = SymExport; module->module.SymType = SymExport;
return TRUE;
} }
/****************************************************************** /******************************************************************
* pe_load_debug_info * 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 hFile;
HANDLE hMap; HANDLE hMap;
void* mapping; 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, hFile = CreateFileA(module->module.LoadedImageName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 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 ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0)
{ {
if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) 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)) if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
{ {
sym_type = pe_load_stabs(pcs, module, mapping, nth); ret = pe_load_stabs(pcs, module, mapping, nth) ||
if (sym_type <= SymNone) pe_load_msc_debug_info(pcs, module, mapping, nth);
sym_type = pe_load_msc_debug_info(pcs, module, mapping, nth);
/* if we still have no debug info (we could only get SymExport at this /* 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, * 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 * in which case we'll rely on the export's on the ELF side
*/ */
} }
if (sym_type <= SymNone && !module_get_debug(pcs, module)) if (pe_load_export_debug_info(pcs, module, mapping, nth) && !ret)
sym_type = pe_load_export_debug_info(pcs, module, mapping, nth); ret = TRUE;
UnmapViewOfFile(mapping); UnmapViewOfFile(mapping);
} }
CloseHandle(hMap); CloseHandle(hMap);
} }
CloseHandle(hFile); CloseHandle(hFile);
module->module.SymType = (sym_type >= SymNone) ? sym_type : SymNone; return ret;
return sym_type;
} }
/****************************************************************** /******************************************************************
@ -349,8 +346,10 @@ struct module* pe_load_module(struct process* pcs, char* name,
nth->OptionalHeader.CheckSum); nth->OptionalHeader.CheckSum);
if (module) if (module)
{ {
module->module.SymType = (dbghelp_options & SYMOPT_DEFERRED_LOADS) ? if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
SymDeferred : pe_load_debug_info(pcs, module); module->module.SymType = SymDeferred;
else
pe_load_debug_info(pcs, module);
} }
} }
UnmapViewOfFile(mapping); UnmapViewOfFile(mapping);

View File

@ -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, BOOL stabs_parse(struct module* module, const char* addr,
unsigned long load_offset, unsigned int staboff, int stablen, unsigned long load_offset, unsigned int staboff, int stablen,
unsigned int strtaboff, int strtablen) unsigned int strtaboff, int strtablen)
{ {
struct symt_function* curr_func = NULL; struct symt_function* curr_func = NULL;
struct symt_block* block = 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; struct pending_loc_var* pending_vars = NULL;
unsigned num_pending_vars = 0; unsigned num_pending_vars = 0;
unsigned num_allocated_pending_vars = 0; unsigned num_allocated_pending_vars = 0;
SYM_TYPE ret = SymDia; BOOL ret = TRUE;
nstab = stablen / sizeof(struct stab_nlist); nstab = stablen / sizeof(struct stab_nlist);
stab_ptr = (const struct stab_nlist*)(addr + staboff); 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); ERR("Excluded header not found (%s,%ld)\n", ptr, stab_ptr->n_value);
module_reset_debug_info(module); module_reset_debug_info(module);
ret = SymNone; ret = FALSE;
goto done; goto done;
} }
break; break;
@ -1452,6 +1452,7 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr,
TRACE("0x%02x %lx %s\n", TRACE("0x%02x %lx %s\n",
stab_ptr->n_type, stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_un.n_strx)); stab_ptr->n_type, stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_un.n_strx));
} }
module->module.SymType = SymDia;
done: done:
HeapFree(GetProcessHeap(), 0, stabbuff); HeapFree(GetProcessHeap(), 0, stabbuff);
stabs_free_includes(); stabs_free_includes();

View File

@ -161,6 +161,9 @@ struct symt_public* symt_new_public(struct module* module,
TRACE_(dbghelp_symt)("Adding public symbol %s:%s @%lx\n", TRACE_(dbghelp_symt)("Adding public symbol %s:%s @%lx\n",
module->module.ModuleName, name, address); 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)))) if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{ {
sym->symt.tag = SymTagPublicSymbol; 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))) while ((ptr = hash_table_iter_up(&hti)))
{ {
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt); 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 && if (sym->hash_elt.name &&
regexec(regex, sym->hash_elt.name, 0, NULL, 0) == 0) regexec(regex, sym->hash_elt.name, 0, NULL, 0) == 0)
{ {