Commit a49adbc4 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Base and symbols.

- report the correct image base for a symbol which is seen as being in a builtin PE module, whilst its debug information is gotten from an ELF module - module_get_debug now returns a pair of modules (the requested that has to be presented back to the client and the effective one, which contains the debug info) - reworked SymFromName in order to provide also the revelant module base address
parent bc31b388
...@@ -315,6 +315,12 @@ struct line_info ...@@ -315,6 +315,12 @@ struct line_info
} u; } u;
}; };
struct module_pair
{
struct module* requested; /* in: to module_get_debug() */
struct module* effective; /* out: module with debug info */
};
/* dbghelp.c */ /* dbghelp.c */
extern struct process* process_find_by_handle(HANDLE hProcess); extern struct process* process_find_by_handle(HANDLE hProcess);
extern HANDLE hMsvcrt; extern HANDLE hMsvcrt;
...@@ -342,8 +348,7 @@ extern struct module* ...@@ -342,8 +348,7 @@ extern struct module*
extern struct module* extern struct module*
module_find_by_name(const struct process* pcs, module_find_by_name(const struct process* pcs,
const char* name, enum module_type type); const char* name, enum module_type type);
extern struct module* extern BOOL module_get_debug(const struct process* pcs, struct module_pair*);
module_get_debug(const struct process* pcs, struct module*);
extern struct module* extern struct module*
module_new(struct process* pcs, const char* name, module_new(struct process* pcs, const char* name,
enum module_type type, BOOL virtual, enum module_type type, BOOL virtual,
......
...@@ -229,37 +229,36 @@ struct module* module_get_containee(const struct process* pcs, ...@@ -229,37 +229,36 @@ struct module* module_get_containee(const struct process* pcs,
* container (and also force the ELF container's debug info loading if deferred) * container (and also force the ELF container's debug info loading if deferred)
* - otherwise return the module itself if it has some debug info * - otherwise return the module itself if it has some debug info
*/ */
struct module* module_get_debug(const struct process* pcs, struct module* module) BOOL module_get_debug(const struct process* pcs, struct module_pair* pair)
{ {
struct module* parent;
IMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl64; IMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl64;
if (!module) return NULL; if (!pair->requested) return FALSE;
/* for a PE builtin, always get info from parent */ /* for a PE builtin, always get info from container */
if ((parent = module_get_container(pcs, module))) if (!(pair->effective = module_get_container(pcs, pair->requested)))
module = parent; pair->effective = pair->requested;
/* if deferred, force loading */ /* if deferred, force loading */
if (module->module.SymType == SymDeferred) if (pair->effective->module.SymType == SymDeferred)
{ {
BOOL ret; BOOL ret;
if (module->is_virtual) ret = FALSE; if (pair->effective->is_virtual) ret = FALSE;
else switch (module->type) else switch (pair->effective->type)
{ {
case DMT_ELF: case DMT_ELF:
ret = elf_load_debug_info(module, NULL); ret = elf_load_debug_info(pair->effective, NULL);
break; break;
case DMT_PE: case DMT_PE:
idsl64.SizeOfStruct = sizeof(idsl64); idsl64.SizeOfStruct = sizeof(idsl64);
idsl64.BaseOfImage = module->module.BaseOfImage; idsl64.BaseOfImage = pair->effective->module.BaseOfImage;
idsl64.CheckSum = module->module.CheckSum; idsl64.CheckSum = pair->effective->module.CheckSum;
idsl64.TimeDateStamp = module->module.TimeDateStamp; idsl64.TimeDateStamp = pair->effective->module.TimeDateStamp;
strcpy(idsl64.FileName, module->module.ImageName); strcpy(idsl64.FileName, pair->effective->module.ImageName);
idsl64.Reparse = FALSE; idsl64.Reparse = FALSE;
idsl64.hFile = INVALID_HANDLE_VALUE; idsl64.hFile = INVALID_HANDLE_VALUE;
pcs_callback(pcs, CBA_DEFERRED_SYMBOL_LOAD_START, &idsl64); pcs_callback(pcs, CBA_DEFERRED_SYMBOL_LOAD_START, &idsl64);
ret = pe_load_debug_info(pcs, module); ret = pe_load_debug_info(pcs, pair->effective);
pcs_callback(pcs, pcs_callback(pcs,
ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE, ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE,
&idsl64); &idsl64);
...@@ -268,11 +267,11 @@ struct module* module_get_debug(const struct process* pcs, struct module* module ...@@ -268,11 +267,11 @@ struct module* module_get_debug(const struct process* pcs, struct module* module
ret = FALSE; ret = FALSE;
break; break;
} }
if (!ret) module->module.SymType = SymNone; if (!ret) pair->effective->module.SymType = SymNone;
assert(module->module.SymType != SymDeferred); assert(pair->effective->module.SymType != SymDeferred);
module_compute_num_syms(module); module_compute_num_syms(pair->effective);
} }
return (module && module->module.SymType != SymNone) ? module : NULL; return pair->effective->module.SymType != SymNone;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -102,7 +102,7 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask, ...@@ -102,7 +102,7 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
PVOID UserContext) PVOID UserContext)
{ {
struct process* pcs; struct process* pcs;
struct module* module; struct module_pair pair;
SOURCEFILE sf; SOURCEFILE sf;
char* ptr; char* ptr;
...@@ -112,15 +112,15 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask, ...@@ -112,15 +112,15 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
if (ModBase) if (ModBase)
{ {
module = module_find_by_addr(pcs, ModBase, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, ModBase, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
} }
else else
{ {
if (Mask[0] == '!') if (Mask[0] == '!')
{ {
module = module_find_by_name(pcs, Mask + 1, DMT_UNKNOWN); pair.requested = module_find_by_name(pcs, Mask + 1, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
} }
else else
{ {
...@@ -128,8 +128,8 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask, ...@@ -128,8 +128,8 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
return FALSE; return FALSE;
} }
} }
if (!module->sources) return FALSE; if (!pair.effective->sources) return FALSE;
for (ptr = module->sources; *ptr; ptr += strlen(ptr) + 1) for (ptr = pair.effective->sources; *ptr; ptr += strlen(ptr) + 1)
{ {
/* FIXME: not using Mask */ /* FIXME: not using Mask */
sf.ModBase = ModBase; sf.ModBase = ModBase;
...@@ -148,7 +148,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, ...@@ -148,7 +148,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user) PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
{ {
struct process* pcs; struct process* pcs;
struct module* module; struct module_pair pair;
struct hash_table_iter hti; struct hash_table_iter hti;
struct symt_ht* sym; struct symt_ht* sym;
regex_t re; regex_t re;
...@@ -168,13 +168,13 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, ...@@ -168,13 +168,13 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
return FALSE; return FALSE;
} }
if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland); if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland);
module = module_find_by_addr(pcs, base, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, base, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
sci.SizeOfStruct = sizeof(sci); sci.SizeOfStruct = sizeof(sci);
sci.ModBase = base; sci.ModBase = base;
hash_table_iter_init(&module->ht_symbols, &hti, NULL); hash_table_iter_init(&pair.effective->ht_symbols, &hti, NULL);
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);
...@@ -186,7 +186,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, ...@@ -186,7 +186,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
{ {
if (dli->is_source_file) if (dli->is_source_file)
{ {
file = (char*)source_get(module, dli->u.source_file); file = (char*)source_get(pair.effective, dli->u.source_file);
if (regexec(&re, file, 0, NULL, 0) != 0) file = ""; if (regexec(&re, file, 0, NULL, 0) != 0) file = "";
strcpy(sci.FileName, file); strcpy(sci.FileName, file);
} }
......
...@@ -452,7 +452,7 @@ struct symt_thunk* symt_new_thunk(struct module* module, ...@@ -452,7 +452,7 @@ struct symt_thunk* symt_new_thunk(struct module* module,
} }
/* expect sym_info->MaxNameLen to be set before being called */ /* expect sym_info->MaxNameLen to be set before being called */
static void symt_fill_sym_info(const struct module* module, static void symt_fill_sym_info(const struct module_pair* pair,
const struct symt* sym, SYMBOL_INFO* sym_info) const struct symt* sym, SYMBOL_INFO* sym_info)
{ {
const char* name; const char* name;
...@@ -467,7 +467,7 @@ static void symt_fill_sym_info(const struct module* module, ...@@ -467,7 +467,7 @@ static void symt_fill_sym_info(const struct module* module,
!symt_get_info((struct symt*)sym_info->TypeIndex, TI_GET_LENGTH, &size))) !symt_get_info((struct symt*)sym_info->TypeIndex, TI_GET_LENGTH, &size)))
size = 0; size = 0;
sym_info->Size = (DWORD)size; sym_info->Size = (DWORD)size;
sym_info->ModBase = module->module.BaseOfImage; sym_info->ModBase = pair->requested->module.BaseOfImage;
sym_info->Flags = 0; sym_info->Flags = 0;
sym_info->Value = 0; sym_info->Value = 0;
...@@ -556,7 +556,7 @@ static void symt_fill_sym_info(const struct module* module, ...@@ -556,7 +556,7 @@ static void symt_fill_sym_info(const struct module* module,
wine_dbgstr_longlong(sym_info->Address)); wine_dbgstr_longlong(sym_info->Address));
} }
static BOOL symt_enum_module(struct module* module, regex_t* regex, static BOOL symt_enum_module(struct module_pair* pair, regex_t* regex,
PSYM_ENUMERATESYMBOLS_CALLBACK cb, PVOID user) PSYM_ENUMERATESYMBOLS_CALLBACK cb, PVOID user)
{ {
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
...@@ -565,7 +565,7 @@ static BOOL symt_enum_module(struct module* module, regex_t* regex, ...@@ -565,7 +565,7 @@ static BOOL symt_enum_module(struct module* module, regex_t* regex,
struct symt_ht* sym = NULL; struct symt_ht* sym = NULL;
struct hash_table_iter hti; struct hash_table_iter hti;
hash_table_iter_init(&module->ht_symbols, &hti, NULL); hash_table_iter_init(&pair->effective->ht_symbols, &hti, NULL);
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);
...@@ -574,7 +574,7 @@ static BOOL symt_enum_module(struct module* module, regex_t* regex, ...@@ -574,7 +574,7 @@ static BOOL symt_enum_module(struct module* module, regex_t* regex,
{ {
sym_info->SizeOfStruct = sizeof(SYMBOL_INFO); sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO); sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
symt_fill_sym_info(module, &sym->symt, sym_info); symt_fill_sym_info(pair, &sym->symt, sym_info);
if (!cb(sym_info, sym_info->Size, user)) return TRUE; if (!cb(sym_info, sym_info->Size, user)) return TRUE;
} }
} }
...@@ -681,7 +681,7 @@ int symt_find_nearest(struct module* module, DWORD addr) ...@@ -681,7 +681,7 @@ int symt_find_nearest(struct module* module, DWORD addr)
return low; return low;
} }
static BOOL symt_enum_locals_helper(struct process* pcs, struct module* module, static BOOL symt_enum_locals_helper(struct process* pcs, struct module_pair* pair,
regex_t* preg, PSYM_ENUMERATESYMBOLS_CALLBACK cb, regex_t* preg, PSYM_ENUMERATESYMBOLS_CALLBACK cb,
PVOID user, SYMBOL_INFO* sym_info, PVOID user, SYMBOL_INFO* sym_info,
struct vector* v) struct vector* v)
...@@ -700,7 +700,7 @@ static BOOL symt_enum_locals_helper(struct process* pcs, struct module* module, ...@@ -700,7 +700,7 @@ static BOOL symt_enum_locals_helper(struct process* pcs, struct module* module,
struct symt_block* block = (struct symt_block*)lsym; struct symt_block* block = (struct symt_block*)lsym;
if (pc < block->address || block->address + block->size <= pc) if (pc < block->address || block->address + block->size <= pc)
continue; continue;
if (!symt_enum_locals_helper(pcs, module, preg, cb, user, if (!symt_enum_locals_helper(pcs, pair, preg, cb, user,
sym_info, &block->vchildren)) sym_info, &block->vchildren))
return FALSE; return FALSE;
} }
...@@ -708,7 +708,7 @@ static BOOL symt_enum_locals_helper(struct process* pcs, struct module* module, ...@@ -708,7 +708,7 @@ static BOOL symt_enum_locals_helper(struct process* pcs, struct module* module,
case SymTagData: case SymTagData:
if (regexec(preg, symt_get_name(lsym), 0, NULL, 0) == 0) if (regexec(preg, symt_get_name(lsym), 0, NULL, 0) == 0)
{ {
symt_fill_sym_info(module, lsym, sym_info); symt_fill_sym_info(pair, lsym, sym_info);
if (!cb(sym_info, sym_info->Size, user)) if (!cb(sym_info, sym_info->Size, user))
return FALSE; return FALSE;
} }
...@@ -729,7 +729,7 @@ static BOOL symt_enum_locals(struct process* pcs, const char* mask, ...@@ -729,7 +729,7 @@ static BOOL symt_enum_locals(struct process* pcs, const char* mask,
PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
PVOID UserContext) PVOID UserContext)
{ {
struct module* module; struct module_pair pair;
struct symt_ht* sym; struct symt_ht* sym;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer; SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
...@@ -739,11 +739,11 @@ static BOOL symt_enum_locals(struct process* pcs, const char* mask, ...@@ -739,11 +739,11 @@ static BOOL symt_enum_locals(struct process* pcs, const char* mask,
sym_info->SizeOfStruct = sizeof(*sym_info); sym_info->SizeOfStruct = sizeof(*sym_info);
sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO); sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
module = module_find_by_addr(pcs, pc, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, pc, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
if ((idx = symt_find_nearest(module, pc)) == -1) return FALSE; if ((idx = symt_find_nearest(pair.effective, pc)) == -1) return FALSE;
sym = module->addr_sorttab[idx]; sym = pair.effective->addr_sorttab[idx];
if (sym->symt.tag == SymTagFunction) if (sym->symt.tag == SymTagFunction)
{ {
BOOL ret; BOOL ret;
...@@ -751,14 +751,14 @@ static BOOL symt_enum_locals(struct process* pcs, const char* mask, ...@@ -751,14 +751,14 @@ static BOOL symt_enum_locals(struct process* pcs, const char* mask,
compile_regex(mask ? mask : "*", -1, &preg, compile_regex(mask ? mask : "*", -1, &preg,
dbghelp_options & SYMOPT_CASE_INSENSITIVE); dbghelp_options & SYMOPT_CASE_INSENSITIVE);
ret = symt_enum_locals_helper(pcs, module, &preg, EnumSymbolsCallback, ret = symt_enum_locals_helper(pcs, &pair, &preg, EnumSymbolsCallback,
UserContext, sym_info, UserContext, sym_info,
&((struct symt_function*)sym)->vchildren); &((struct symt_function*)sym)->vchildren);
regfree(&preg); regfree(&preg);
return ret; return ret;
} }
symt_fill_sym_info(module, &sym->symt, sym_info); symt_fill_sym_info(&pair, &sym->symt, sym_info);
return EnumSymbolsCallback(sym_info, sym_info->Size, UserContext); return EnumSymbolsCallback(sym_info, sym_info->Size, UserContext);
} }
...@@ -778,8 +778,7 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, ...@@ -778,8 +778,7 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask,
PVOID UserContext) PVOID UserContext)
{ {
struct process* pcs = process_find_by_handle(hProcess); struct process* pcs = process_find_by_handle(hProcess);
struct module* module; struct module_pair pair;
struct module* dbg_module;
const char* bang; const char* bang;
regex_t mod_regex, sym_regex; regex_t mod_regex, sym_regex;
...@@ -801,28 +800,28 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, ...@@ -801,28 +800,28 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask,
compile_regex(bang + 1, -1, &sym_regex, compile_regex(bang + 1, -1, &sym_regex,
dbghelp_options & SYMOPT_CASE_INSENSITIVE); dbghelp_options & SYMOPT_CASE_INSENSITIVE);
for (module = pcs->lmodules; module; module = module->next) for (pair.requested = pcs->lmodules; pair.requested; pair.requested = pair.requested->next)
{ {
if (module->type == DMT_PE && (dbg_module = module_get_debug(pcs, module))) if (pair.requested->type == DMT_PE && module_get_debug(pcs, &pair))
{ {
if (regexec(&mod_regex, module->module.ModuleName, 0, NULL, 0) == 0 && if (regexec(&mod_regex, pair.requested->module.ModuleName, 0, NULL, 0) == 0 &&
symt_enum_module(dbg_module, &sym_regex, symt_enum_module(&pair, &sym_regex,
EnumSymbolsCallback, UserContext)) EnumSymbolsCallback, UserContext))
break; break;
} }
} }
/* not found in PE modules, retry on the ELF ones /* not found in PE modules, retry on the ELF ones
*/ */
if (!module && (dbghelp_options & SYMOPT_WINE_WITH_ELF_MODULES)) if (!pair.requested && (dbghelp_options & SYMOPT_WINE_WITH_ELF_MODULES))
{ {
for (module = pcs->lmodules; module; module = module->next) for (pair.requested = pcs->lmodules; pair.requested; pair.requested = pair.requested->next)
{ {
if (module->type == DMT_ELF && if (pair.requested->type == DMT_ELF &&
!module_get_containee(pcs, module) && !module_get_containee(pcs, pair.requested) &&
(dbg_module = module_get_debug(pcs, module))) module_get_debug(pcs, &pair))
{ {
if (regexec(&mod_regex, module->module.ModuleName, 0, NULL, 0) == 0 && if (regexec(&mod_regex, pair.requested->module.ModuleName, 0, NULL, 0) == 0 &&
symt_enum_module(dbg_module, &sym_regex, EnumSymbolsCallback, UserContext)) symt_enum_module(&pair, &sym_regex, EnumSymbolsCallback, UserContext))
break; break;
} }
} }
...@@ -831,8 +830,8 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, ...@@ -831,8 +830,8 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask,
regfree(&sym_regex); regfree(&sym_regex);
return TRUE; return TRUE;
} }
module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) if (!module_get_debug(pcs, &pair))
return FALSE; return FALSE;
/* we always ignore module name from Mask when BaseOfDll is defined */ /* we always ignore module name from Mask when BaseOfDll is defined */
...@@ -843,8 +842,8 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, ...@@ -843,8 +842,8 @@ BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask,
} }
compile_regex(Mask ? Mask : "*", -1, &sym_regex, compile_regex(Mask ? Mask : "*", -1, &sym_regex,
dbghelp_options & SYMOPT_CASE_INSENSITIVE); dbghelp_options & SYMOPT_CASE_INSENSITIVE);
symt_enum_module(module, &sym_regex, EnumSymbolsCallback, UserContext); symt_enum_module(&pair, &sym_regex, EnumSymbolsCallback, UserContext);
regfree(&sym_regex); regfree(&sym_regex);
return TRUE; return TRUE;
...@@ -885,18 +884,18 @@ BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, ...@@ -885,18 +884,18 @@ BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address,
DWORD64* Displacement, PSYMBOL_INFO Symbol) DWORD64* Displacement, PSYMBOL_INFO Symbol)
{ {
struct process* pcs = process_find_by_handle(hProcess); struct process* pcs = process_find_by_handle(hProcess);
struct module* module; struct module_pair pair;
struct symt_ht* sym; struct symt_ht* sym;
int idx; int idx;
if (!pcs) return FALSE; if (!pcs) return FALSE;
module = module_find_by_addr(pcs, Address, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, Address, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
if ((idx = symt_find_nearest(module, Address)) == -1) return FALSE; if ((idx = symt_find_nearest(pair.effective, Address)) == -1) return FALSE;
sym = module->addr_sorttab[idx]; sym = pair.effective->addr_sorttab[idx];
symt_fill_sym_info(module, &sym->symt, Symbol); symt_fill_sym_info(&pair, &sym->symt, Symbol);
*Displacement = Address - Symbol->Address; *Displacement = Address - Symbol->Address;
return TRUE; return TRUE;
} }
...@@ -929,6 +928,31 @@ BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address, ...@@ -929,6 +928,31 @@ BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address,
return TRUE; return TRUE;
} }
static BOOL find_name(struct process* pcs, struct module* module, const char* name,
SYMBOL_INFO* symbol)
{
struct hash_table_iter hti;
void* ptr;
struct symt_ht* sym = NULL;
struct module_pair pair;
if (!(pair.requested = module)) return FALSE;
if (!module_get_debug(pcs, &pair)) return FALSE;
hash_table_iter_init(&pair.effective->ht_symbols, &hti, name);
while ((ptr = hash_table_iter_up(&hti)))
{
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
if (!strcmp(sym->hash_elt.name, name))
{
symt_fill_sym_info(&pair, &sym->symt, symbol);
return TRUE;
}
}
return FALSE;
}
/****************************************************************** /******************************************************************
* SymFromName (DBGHELP.@) * SymFromName (DBGHELP.@)
* *
...@@ -937,9 +961,6 @@ BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol) ...@@ -937,9 +961,6 @@ BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
{ {
struct process* pcs = process_find_by_handle(hProcess); struct process* pcs = process_find_by_handle(hProcess);
struct module* module; struct module* module;
struct hash_table_iter hti;
void* ptr;
struct symt_ht* sym = NULL;
const char* name; const char* name;
TRACE("(%p, %s, %p)\n", hProcess, Name, Symbol); TRACE("(%p, %s, %p)\n", hProcess, Name, Symbol);
...@@ -953,30 +974,22 @@ BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol) ...@@ -953,30 +974,22 @@ BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
memcpy(tmp, Name, name - Name); memcpy(tmp, Name, name - Name);
tmp[name - Name] = '\0'; tmp[name - Name] = '\0';
module = module_find_by_name(pcs, tmp, DMT_UNKNOWN); module = module_find_by_name(pcs, tmp, DMT_UNKNOWN);
if (!module) return FALSE; return find_name(pcs, module, (char*)(name + 1), Symbol);
Name = (char*)(name + 1);
} }
else module = pcs->lmodules; for (module = pcs->lmodules; module; module = module->next)
/* FIXME: Name could be made out of a regular expression */
for (; module; module = (name) ? NULL : module->next)
{ {
if (module->module.SymType == SymNone) continue; if (module->type == DMT_PE && find_name(pcs, module, Name, Symbol))
if (module->module.SymType == SymDeferred) return TRUE;
{ }
struct module* xmodule = module_get_debug(pcs, module); /* not found in PE modules, retry on the ELF ones
if (!xmodule || xmodule != module) continue; */
} if (dbghelp_options & SYMOPT_WINE_WITH_ELF_MODULES)
hash_table_iter_init(&module->ht_symbols, &hti, Name); {
while ((ptr = hash_table_iter_up(&hti))) for (module = pcs->lmodules; module; module = module->next)
{ {
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt); if (module->type == DMT_ELF && !module_get_containee(pcs, module) &&
find_name(pcs, module, Name, Symbol))
if (!strcmp(sym->hash_elt.name, Name))
{
symt_fill_sym_info(module, &sym->symt, Symbol);
return TRUE; return TRUE;
}
} }
} }
return FALSE; return FALSE;
...@@ -1072,7 +1085,7 @@ BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, ...@@ -1072,7 +1085,7 @@ BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr,
PDWORD pdwDisplacement, PIMAGEHLP_LINE Line) PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
{ {
struct process* pcs = process_find_by_handle(hProcess); struct process* pcs = process_find_by_handle(hProcess);
struct module* module; struct module_pair pair;
int idx; int idx;
TRACE("%p %08lx %p %p\n", hProcess, dwAddr, pdwDisplacement, Line); TRACE("%p %08lx %p %p\n", hProcess, dwAddr, pdwDisplacement, Line);
...@@ -1080,13 +1093,13 @@ BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, ...@@ -1080,13 +1093,13 @@ BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr,
if (Line->SizeOfStruct < sizeof(*Line)) return FALSE; if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
if (!pcs) return FALSE; if (!pcs) return FALSE;
module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
if ((idx = symt_find_nearest(module, dwAddr)) == -1) return FALSE; if ((idx = symt_find_nearest(pair.effective, dwAddr)) == -1) return FALSE;
if (module->addr_sorttab[idx]->symt.tag != SymTagFunction) return FALSE; if (pair.effective->addr_sorttab[idx]->symt.tag != SymTagFunction) return FALSE;
if (!symt_fill_func_line_info(module, if (!symt_fill_func_line_info(pair.effective,
(struct symt_function*)module->addr_sorttab[idx], (struct symt_function*)pair.effective->addr_sorttab[idx],
dwAddr, Line)) return FALSE; dwAddr, Line)) return FALSE;
*pdwDisplacement = dwAddr - Line->Address; *pdwDisplacement = dwAddr - Line->Address;
return TRUE; return TRUE;
...@@ -1143,7 +1156,7 @@ BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr, ...@@ -1143,7 +1156,7 @@ BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr,
BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line) BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
{ {
struct process* pcs = process_find_by_handle(hProcess); struct process* pcs = process_find_by_handle(hProcess);
struct module* module; struct module_pair pair;
struct line_info* li; struct line_info* li;
BOOL in_search = FALSE; BOOL in_search = FALSE;
...@@ -1152,8 +1165,8 @@ BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line) ...@@ -1152,8 +1165,8 @@ BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
if (Line->SizeOfStruct < sizeof(*Line)) return FALSE; if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
if (!pcs) return FALSE; if (!pcs) return FALSE;
module = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
if (Line->Key == 0) return FALSE; if (Line->Key == 0) return FALSE;
li = (struct line_info*)Line->Key; li = (struct line_info*)Line->Key;
...@@ -1176,7 +1189,7 @@ BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line) ...@@ -1176,7 +1189,7 @@ BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
{ {
if (in_search) if (in_search)
{ {
Line->FileName = (char*)source_get(module, li->u.source_file); Line->FileName = (char*)source_get(pair.effective, li->u.source_file);
return TRUE; return TRUE;
} }
in_search = TRUE; in_search = TRUE;
...@@ -1229,16 +1242,16 @@ BOOL symt_get_func_line_next(struct module* module, PIMAGEHLP_LINE line) ...@@ -1229,16 +1242,16 @@ BOOL symt_get_func_line_next(struct module* module, PIMAGEHLP_LINE line)
BOOL WINAPI SymGetLineNext(HANDLE hProcess, PIMAGEHLP_LINE Line) BOOL WINAPI SymGetLineNext(HANDLE hProcess, PIMAGEHLP_LINE Line)
{ {
struct process* pcs = process_find_by_handle(hProcess); struct process* pcs = process_find_by_handle(hProcess);
struct module* module; struct module_pair pair;
TRACE("(%p %p)\n", hProcess, Line); TRACE("(%p %p)\n", hProcess, Line);
if (Line->SizeOfStruct < sizeof(*Line)) return FALSE; if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
if (!pcs) return FALSE; if (!pcs) return FALSE;
module = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
if (symt_get_func_line_next(module, Line)) return TRUE; if (symt_get_func_line_next(pair.effective, Line)) return TRUE;
SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */ SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
return FALSE; return FALSE;
} }
......
...@@ -373,7 +373,7 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll, ...@@ -373,7 +373,7 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
PVOID UserContext) PVOID UserContext)
{ {
struct process* pcs; struct process* pcs;
struct module* module; struct module_pair pair;
char buffer[sizeof(SYMBOL_INFO) + 256]; char buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer; SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
const char* tmp; const char* tmp;
...@@ -386,20 +386,20 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll, ...@@ -386,20 +386,20 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
UserContext); UserContext);
if (!(pcs = process_find_by_handle(hProcess))) return FALSE; if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE; if (!module_get_debug(pcs, &pair)) return FALSE;
sym_info->SizeOfStruct = sizeof(SYMBOL_INFO); sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO); sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
while ((pos = vector_iter_up(&module->vtypes, pos))) while ((pos = vector_iter_up(&pair.effective->vtypes, pos)))
{ {
type = *(struct symt**)pos; type = *(struct symt**)pos;
sym_info->TypeIndex = (DWORD)type; sym_info->TypeIndex = (DWORD)type;
sym_info->info = 0; /* FIXME */ sym_info->info = 0; /* FIXME */
symt_get_info(type, TI_GET_LENGTH, &size); symt_get_info(type, TI_GET_LENGTH, &size);
sym_info->Size = size; sym_info->Size = size;
sym_info->ModBase = module->module.BaseOfImage; sym_info->ModBase = pair.requested->module.BaseOfImage;
sym_info->Flags = 0; /* FIXME */ sym_info->Flags = 0; /* FIXME */
sym_info->Value = 0; /* FIXME */ sym_info->Value = 0; /* FIXME */
sym_info->Address = 0; /* FIXME */ sym_info->Address = 0; /* FIXME */
...@@ -788,12 +788,12 @@ BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase, ...@@ -788,12 +788,12 @@ BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase,
PVOID pInfo) PVOID pInfo)
{ {
struct process* pcs = process_find_by_handle(hProcess); struct process* pcs = process_find_by_handle(hProcess);
struct module* module; struct module_pair pair;
if (!pcs) return FALSE; if (!pcs) return FALSE;
module = module_find_by_addr(pcs, ModBase, DMT_UNKNOWN); pair.requested = module_find_by_addr(pcs, ModBase, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) if (!module_get_debug(pcs, &pair))
{ {
FIXME("Someone didn't properly set ModBase (%s)\n", wine_dbgstr_longlong(ModBase)); FIXME("Someone didn't properly set ModBase (%s)\n", wine_dbgstr_longlong(ModBase));
return FALSE; return FALSE;
......
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