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:
parent
b1bb722088
commit
65c3765739
|
@ -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 */
|
||||
}
|
||||
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, "<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)))
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue