Commit 65c37657 authored by Alexandre Julliard's avatar Alexandre Julliard

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).
parent b1bb7220
......@@ -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
*/
......
......@@ -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);
......
......@@ -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, "<elf>") ||
......@@ -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 */
}
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;
if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
{
elf_info->module->module.SymType = SymDeferred;
ret = TRUE;
}
else sym_type = -1;
}
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, "<wine-loader>");
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__ */
......@@ -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;
}
......
......@@ -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;
}
......@@ -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)))
if ((exports = RtlImageDirectoryEntryToData((void*)mapping, FALSE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &size)))
{
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);
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);
......
......@@ -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();
......
......@@ -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)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment