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); ...@@ -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); ...@@ -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
*/ */
......
...@@ -287,7 +287,7 @@ struct process ...@@ -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); ...@@ -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* ...@@ -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);
......
...@@ -200,10 +200,11 @@ struct module* module_get_containee(const struct process* pcs, ...@@ -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 ...@@ -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, ...@@ -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;
} }
......
...@@ -171,7 +171,7 @@ static void coff_add_symbol(struct CoffFile* coff_file, struct symt* sym) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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;
} }
...@@ -1078,7 +1078,7 @@ static void stabs_finalize_function(struct module* module, struct symt_function* ...@@ -1078,7 +1078,7 @@ 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)
{ {
...@@ -1102,7 +1102,7 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr, ...@@ -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, ...@@ -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, ...@@ -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();
......
...@@ -161,6 +161,9 @@ struct symt_public* symt_new_public(struct module* module, ...@@ -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, ...@@ -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)
{ {
......
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