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