dbghelp: Move loader search functions to the end of module files.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2020-03-24 01:53:37 +01:00 committed by Alexandre Julliard
parent 724f433f39
commit f30fdd1822
2 changed files with 148 additions and 149 deletions

View File

@ -1483,64 +1483,6 @@ static BOOL elf_enum_modules_internal(const struct process* pcs,
return TRUE; return TRUE;
} }
/******************************************************************
* elf_search_loader
*
* Lookup in a running ELF process the loader, and sets its ELF link
* address (for accessing the list of loaded .so libs) in pcs.
* If flags is ELF_INFO_MODULE, the module for the loader is also
* added as a module into pcs.
*/
static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
{
WCHAR *loader = get_wine_loader_name(pcs);
PROCESS_BASIC_INFORMATION pbi;
ULONG_PTR base = 0;
BOOL ret;
if (NtQueryInformationProcess( pcs->handle, ProcessBasicInformation,
&pbi, sizeof(pbi), NULL ))
return FALSE;
if (!pcs->is_64bit)
{
PEB32 *peb32 = (PEB32 *)pbi.PebBaseAddress;
DWORD base32;
if (!ReadProcessMemory( pcs->handle, &peb32->Reserved[0], &base32,
sizeof(base32), NULL ))
return FALSE;
base = base32;
}
else
{
if (!ReadProcessMemory( pcs->handle, &pbi.PebBaseAddress->Reserved[0],
&base, sizeof(base), NULL ))
return FALSE;
}
ret = elf_search_and_load_file(pcs, loader, base, 0, elf_info);
heap_free(loader);
return ret;
}
/******************************************************************
* elf_read_wine_loader_dbg_info
*
* Try to find a decent wine executable which could have loaded the debuggee
*/
BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
{
struct elf_info elf_info;
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
if (!elf_search_loader(pcs, &elf_info)) return FALSE;
elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1;
module_set_module(elf_info.module, S_WineLoaderW);
return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
}
struct elf_enum_user struct elf_enum_user
{ {
enum_modules_cb cb; enum_modules_cb cb;
@ -1720,6 +1662,64 @@ BOOL elf_synchronize_module_list(struct process* pcs)
return TRUE; return TRUE;
} }
/******************************************************************
* elf_search_loader
*
* Lookup in a running ELF process the loader, and sets its ELF link
* address (for accessing the list of loaded .so libs) in pcs.
* If flags is ELF_INFO_MODULE, the module for the loader is also
* added as a module into pcs.
*/
static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
{
WCHAR *loader = get_wine_loader_name(pcs);
PROCESS_BASIC_INFORMATION pbi;
ULONG_PTR base = 0;
BOOL ret;
if (NtQueryInformationProcess( pcs->handle, ProcessBasicInformation,
&pbi, sizeof(pbi), NULL ))
return FALSE;
if (!pcs->is_64bit)
{
PEB32 *peb32 = (PEB32 *)pbi.PebBaseAddress;
DWORD base32;
if (!ReadProcessMemory( pcs->handle, &peb32->Reserved[0], &base32,
sizeof(base32), NULL ))
return FALSE;
base = base32;
}
else
{
if (!ReadProcessMemory( pcs->handle, &pbi.PebBaseAddress->Reserved[0],
&base, sizeof(base), NULL ))
return FALSE;
}
ret = elf_search_and_load_file(pcs, loader, base, 0, elf_info);
heap_free(loader);
return ret;
}
/******************************************************************
* elf_read_wine_loader_dbg_info
*
* Try to find a decent wine executable which could have loaded the debuggee
*/
BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
{
struct elf_info elf_info;
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
if (!elf_search_loader(pcs, &elf_info)) return FALSE;
elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1;
module_set_module(elf_info.module, S_WineLoaderW);
return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
}
#else /* !__ELF__ */ #else /* !__ELF__ */
BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap)

View File

@ -1373,7 +1373,6 @@ static void macho_module_remove(struct process* pcs, struct module_format* modfm
HeapFree(GetProcessHeap(), 0, modfmt); HeapFree(GetProcessHeap(), 0, modfmt);
} }
/****************************************************************** /******************************************************************
* get_dyld_image_info_address * get_dyld_image_info_address
*/ */
@ -1729,6 +1728,96 @@ BOOL macho_synchronize_module_list(struct process* pcs)
return TRUE; return TRUE;
} }
/******************************************************************
* macho_enum_modules
*
* Enumerates the Mach-O loaded modules from a running target (hProc)
* This function doesn't require that someone has called SymInitialize
* on this very process.
*/
BOOL macho_enum_modules(struct process* process, enum_modules_cb cb, void* user)
{
struct macho_info macho_info;
BOOL ret;
TRACE("(%p, %p, %p)\n", process->handle, cb, user);
macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_NAME;
ret = macho_enum_modules_internal(process, macho_info.module_name, cb, user);
HeapFree(GetProcessHeap(), 0, (char*)macho_info.module_name);
return ret;
}
struct macho_load
{
struct process* pcs;
struct macho_info macho_info;
const WCHAR* name;
BOOL ret;
};
/******************************************************************
* macho_load_cb
*
* Callback for macho_load_module, used to walk the list of loaded
* modules.
*/
static BOOL macho_load_cb(const WCHAR* name, unsigned long addr, void* user)
{
struct macho_load* ml = user;
const WCHAR* p;
TRACE("(%s, 0x%08lx, %p)\n", debugstr_w(name), addr, user);
/* memcmp is needed for matches when bufstr contains also version information
* ml->name: libc.so, name: libc.so.6.0
*/
p = file_name(name);
if (!memcmp(p, ml->name, lstrlenW(ml->name) * sizeof(WCHAR)))
{
ml->ret = macho_search_and_load_file(ml->pcs, name, addr, &ml->macho_info);
return FALSE;
}
return TRUE;
}
/******************************************************************
* macho_load_module
*
* Loads a Mach-O module and stores it in process' module list.
* Also, find module real name and load address from
* the real loaded modules list in pcs address space.
*/
struct module* macho_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
{
struct macho_load ml;
TRACE("(%p/%p, %s, 0x%08lx)\n", pcs, pcs->handle, debugstr_w(name), addr);
ml.macho_info.flags = MACHO_INFO_MODULE;
ml.ret = FALSE;
if (pcs->dbg_hdr_addr) /* we're debugging a live target */
{
ml.pcs = pcs;
/* do only the lookup from the filename, not the path (as we lookup module
* name in the process' loaded module list)
*/
ml.name = file_name(name);
ml.ret = FALSE;
if (!macho_enum_modules_internal(pcs, NULL, macho_load_cb, &ml))
return NULL;
}
else if (addr)
{
ml.name = name;
ml.ret = macho_search_and_load_file(pcs, ml.name, addr, &ml.macho_info);
}
if (!ml.ret) return NULL;
assert(ml.macho_info.module);
return ml.macho_info.module;
}
/****************************************************************** /******************************************************************
* macho_search_loader * macho_search_loader
* *
@ -1836,96 +1925,6 @@ BOOL macho_read_wine_loader_dbg_info(struct process* pcs)
return (pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr) != 0; return (pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr) != 0;
} }
/******************************************************************
* macho_enum_modules
*
* Enumerates the Mach-O loaded modules from a running target (hProc)
* This function doesn't require that someone has called SymInitialize
* on this very process.
*/
BOOL macho_enum_modules(struct process* process, enum_modules_cb cb, void* user)
{
struct macho_info macho_info;
BOOL ret;
TRACE("(%p, %p, %p)\n", process->handle, cb, user);
macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_NAME;
ret = macho_enum_modules_internal(process, macho_info.module_name, cb, user);
HeapFree(GetProcessHeap(), 0, (char*)macho_info.module_name);
return ret;
}
struct macho_load
{
struct process* pcs;
struct macho_info macho_info;
const WCHAR* name;
BOOL ret;
};
/******************************************************************
* macho_load_cb
*
* Callback for macho_load_module, used to walk the list of loaded
* modules.
*/
static BOOL macho_load_cb(const WCHAR* name, unsigned long addr, void* user)
{
struct macho_load* ml = user;
const WCHAR* p;
TRACE("(%s, 0x%08lx, %p)\n", debugstr_w(name), addr, user);
/* memcmp is needed for matches when bufstr contains also version information
* ml->name: libc.so, name: libc.so.6.0
*/
p = file_name(name);
if (!memcmp(p, ml->name, lstrlenW(ml->name) * sizeof(WCHAR)))
{
ml->ret = macho_search_and_load_file(ml->pcs, name, addr, &ml->macho_info);
return FALSE;
}
return TRUE;
}
/******************************************************************
* macho_load_module
*
* Loads a Mach-O module and stores it in process' module list.
* Also, find module real name and load address from
* the real loaded modules list in pcs address space.
*/
struct module* macho_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
{
struct macho_load ml;
TRACE("(%p/%p, %s, 0x%08lx)\n", pcs, pcs->handle, debugstr_w(name), addr);
ml.macho_info.flags = MACHO_INFO_MODULE;
ml.ret = FALSE;
if (pcs->dbg_hdr_addr) /* we're debugging a live target */
{
ml.pcs = pcs;
/* do only the lookup from the filename, not the path (as we lookup module
* name in the process' loaded module list)
*/
ml.name = file_name(name);
ml.ret = FALSE;
if (!macho_enum_modules_internal(pcs, NULL, macho_load_cb, &ml))
return NULL;
}
else if (addr)
{
ml.name = name;
ml.ret = macho_search_and_load_file(pcs, ml.name, addr, &ml.macho_info);
}
if (!ml.ret) return NULL;
assert(ml.macho_info.module);
return ml.macho_info.module;
}
#else /* HAVE_MACH_O_LOADER_H */ #else /* HAVE_MACH_O_LOADER_H */
BOOL macho_synchronize_module_list(struct process* pcs) BOOL macho_synchronize_module_list(struct process* pcs)