Commit fec01575 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

dbghelp: Introduce loader_ops to abstract platform-specific loader and use it to…

dbghelp: Introduce loader_ops to abstract platform-specific loader and use it to synchronize module list. Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent f30fdd18
...@@ -334,6 +334,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP ...@@ -334,6 +334,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP
pcs->handle = hProcess; pcs->handle = hProcess;
pcs->is_64bit = (sizeof(void *) == 8 || wow64) && !child_wow64; pcs->is_64bit = (sizeof(void *) == 8 || wow64) && !child_wow64;
pcs->loader = &no_loader_ops; /* platform-specific initialization will override it if loader debug info can be found */
if (UserSearchPath) if (UserSearchPath)
{ {
...@@ -379,8 +380,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP ...@@ -379,8 +380,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP
{ {
if (fInvadeProcess) if (fInvadeProcess)
EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess); EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess);
elf_synchronize_module_list(pcs); pcs->loader->synchronize_module_list(pcs);
macho_synchronize_module_list(pcs);
} }
else if (fInvadeProcess) else if (fInvadeProcess)
{ {
......
...@@ -387,10 +387,16 @@ struct module ...@@ -387,10 +387,16 @@ struct module
struct wine_rb_tree sources_offsets_tree; struct wine_rb_tree sources_offsets_tree;
}; };
struct loader_ops
{
BOOL (*synchronize_module_list)(struct process* process);
};
struct process struct process
{ {
struct process* next; struct process* next;
HANDLE handle; HANDLE handle;
const struct loader_ops* loader;
WCHAR* search_path; WCHAR* search_path;
PSYMBOL_REGISTERED_CALLBACK64 reg_cb; PSYMBOL_REGISTERED_CALLBACK64 reg_cb;
...@@ -601,7 +607,6 @@ extern BOOL elf_load_debug_info(struct module* module) DECLSPEC_HIDDEN; ...@@ -601,7 +607,6 @@ extern BOOL elf_load_debug_info(struct module* module) DECLSPEC_HIDDEN;
extern struct module* extern struct module*
elf_load_module(struct process* pcs, const WCHAR* name, unsigned long) DECLSPEC_HIDDEN; elf_load_module(struct process* pcs, const WCHAR* name, unsigned long) DECLSPEC_HIDDEN;
extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN; extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN;
extern BOOL elf_synchronize_module_list(struct process* pcs) DECLSPEC_HIDDEN;
struct elf_thunk_area; struct elf_thunk_area;
extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks) DECLSPEC_HIDDEN; extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks) DECLSPEC_HIDDEN;
...@@ -612,7 +617,6 @@ extern BOOL macho_load_debug_info(struct process *pcs, struct module* mo ...@@ -612,7 +617,6 @@ extern BOOL macho_load_debug_info(struct process *pcs, struct module* mo
extern struct module* extern struct module*
macho_load_module(struct process* pcs, const WCHAR* name, unsigned long) DECLSPEC_HIDDEN; macho_load_module(struct process* pcs, const WCHAR* name, unsigned long) DECLSPEC_HIDDEN;
extern BOOL macho_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN; extern BOOL macho_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN;
extern BOOL macho_synchronize_module_list(struct process* pcs) DECLSPEC_HIDDEN;
/* minidump.c */ /* minidump.c */
void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva) DECLSPEC_HIDDEN; void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva) DECLSPEC_HIDDEN;
...@@ -621,6 +625,7 @@ void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size ...@@ -621,6 +625,7 @@ void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size
extern const WCHAR S_ElfW[] DECLSPEC_HIDDEN; extern const WCHAR S_ElfW[] DECLSPEC_HIDDEN;
extern const WCHAR S_WineLoaderW[] DECLSPEC_HIDDEN; extern const WCHAR S_WineLoaderW[] DECLSPEC_HIDDEN;
extern const WCHAR S_SlashW[] DECLSPEC_HIDDEN; extern const WCHAR S_SlashW[] DECLSPEC_HIDDEN;
extern const struct loader_ops no_loader_ops DECLSPEC_HIDDEN;
extern struct module* extern struct module*
module_find_by_addr(const struct process* pcs, DWORD64 addr, module_find_by_addr(const struct process* pcs, DWORD64 addr,
......
...@@ -1623,7 +1623,7 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned ...@@ -1623,7 +1623,7 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned
* - if a module is in debuggee and not in pcs, it's loaded into pcs * - if a module is in debuggee and not in pcs, it's loaded into pcs
* - if a module is in pcs and not in debuggee, it's unloaded from pcs * - if a module is in pcs and not in debuggee, it's unloaded from pcs
*/ */
BOOL elf_synchronize_module_list(struct process* pcs) static BOOL elf_synchronize_module_list(struct process* pcs)
{ {
struct module* module; struct module* module;
struct elf_load el; struct elf_load el;
...@@ -1704,6 +1704,11 @@ static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info) ...@@ -1704,6 +1704,11 @@ static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
return ret; return ret;
} }
static const struct loader_ops elf_loader_ops =
{
elf_synchronize_module_list,
};
/****************************************************************** /******************************************************************
* elf_read_wine_loader_dbg_info * elf_read_wine_loader_dbg_info
* *
...@@ -1714,10 +1719,12 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs) ...@@ -1714,10 +1719,12 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
struct elf_info elf_info; struct elf_info elf_info;
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE; elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
if (!elf_search_loader(pcs, &elf_info)) return FALSE; if (!elf_search_loader(pcs, &elf_info) || !elf_info.dbg_hdr_addr) return FALSE;
elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1; elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1;
module_set_module(elf_info.module, S_WineLoaderW); module_set_module(elf_info.module, S_WineLoaderW);
return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0; pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr;
pcs->loader = &elf_loader_ops;
return TRUE;
} }
#else /* !__ELF__ */ #else /* !__ELF__ */
...@@ -1727,11 +1734,6 @@ BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) ...@@ -1727,11 +1734,6 @@ BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap)
return FALSE; return FALSE;
} }
BOOL elf_synchronize_module_list(struct process* pcs)
{
return FALSE;
}
BOOL elf_fetch_file_info(const WCHAR* name, DWORD_PTR* base, BOOL elf_fetch_file_info(const WCHAR* name, DWORD_PTR* base,
DWORD* size, DWORD* checksum) DWORD* size, DWORD* checksum)
{ {
......
...@@ -1694,7 +1694,7 @@ static BOOL macho_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user ...@@ -1694,7 +1694,7 @@ static BOOL macho_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user
* - if a module is in debuggee and not in pcs, it's loaded into pcs * - if a module is in debuggee and not in pcs, it's loaded into pcs
* - if a module is in pcs and not in debuggee, it's unloaded from pcs * - if a module is in pcs and not in debuggee, it's unloaded from pcs
*/ */
BOOL macho_synchronize_module_list(struct process* pcs) static BOOL macho_synchronize_module_list(struct process* pcs)
{ {
struct module* module; struct module* module;
struct macho_sync ms; struct macho_sync ms;
...@@ -1908,6 +1908,11 @@ static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_in ...@@ -1908,6 +1908,11 @@ static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_in
return ret; return ret;
} }
static const struct loader_ops macho_loader_ops =
{
macho_synchronize_module_list,
};
/****************************************************************** /******************************************************************
* macho_read_wine_loader_dbg_info * macho_read_wine_loader_dbg_info
* *
...@@ -1919,19 +1924,16 @@ BOOL macho_read_wine_loader_dbg_info(struct process* pcs) ...@@ -1919,19 +1924,16 @@ BOOL macho_read_wine_loader_dbg_info(struct process* pcs)
TRACE("(%p/%p)\n", pcs, pcs->handle); TRACE("(%p/%p)\n", pcs, pcs->handle);
macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_MODULE; macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_MODULE;
if (!macho_search_loader(pcs, &macho_info)) return FALSE; if (!macho_search_loader(pcs, &macho_info) || !macho_info.dbg_hdr_addr) return FALSE;
macho_info.module->format_info[DFI_MACHO]->u.macho_info->is_loader = 1; macho_info.module->format_info[DFI_MACHO]->u.macho_info->is_loader = 1;
module_set_module(macho_info.module, S_WineLoaderW); module_set_module(macho_info.module, S_WineLoaderW);
return (pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr) != 0; pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr;
pcs->loader = &macho_loader_ops;
return TRUE;
} }
#else /* HAVE_MACH_O_LOADER_H */ #else /* HAVE_MACH_O_LOADER_H */
BOOL macho_synchronize_module_list(struct process* pcs)
{
return FALSE;
}
BOOL macho_fetch_file_info(HANDLE process, const WCHAR* name, unsigned long load_addr, DWORD_PTR* base, BOOL macho_fetch_file_info(HANDLE process, const WCHAR* name, unsigned long load_addr, DWORD_PTR* base,
DWORD* size, DWORD* checksum) DWORD* size, DWORD* checksum)
{ {
......
...@@ -529,15 +529,6 @@ enum module_type module_get_type_by_name(const WCHAR* name) ...@@ -529,15 +529,6 @@ enum module_type module_get_type_by_name(const WCHAR* name)
return DMT_PE; return DMT_PE;
} }
/******************************************************************
* refresh_module_list
*/
static BOOL refresh_module_list(struct process* pcs)
{
/* force transparent ELF and Mach-O loading / unloading */
return elf_synchronize_module_list(pcs) || macho_synchronize_module_list(pcs);
}
static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc) static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc)
{ {
DWORD read_bytes; DWORD read_bytes;
...@@ -875,7 +866,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam ...@@ -875,7 +866,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
if (Flags & ~(SLMFLAG_VIRTUAL)) if (Flags & ~(SLMFLAG_VIRTUAL))
FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName)); FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName));
refresh_module_list(pcs); pcs->loader->synchronize_module_list(pcs);
/* this is a Wine extension to the API just to redo the synchronisation */ /* this is a Wine extension to the API just to redo the synchronisation */
if (!wImageName && !hFile) return 0; if (!wImageName && !hFile) return 0;
...@@ -1409,7 +1400,7 @@ BOOL WINAPI SymRefreshModuleList(HANDLE hProcess) ...@@ -1409,7 +1400,7 @@ BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
if (!(pcs = process_find_by_handle(hProcess))) return FALSE; if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
return refresh_module_list(pcs); return pcs->loader->synchronize_module_list(pcs);
} }
/*********************************************************************** /***********************************************************************
...@@ -1434,3 +1425,13 @@ PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) ...@@ -1434,3 +1425,13 @@ PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase)
return dbghelp_current_cpu->find_runtime_function(module, AddrBase); return dbghelp_current_cpu->find_runtime_function(module, AddrBase);
} }
static BOOL native_synchronize_module_list(struct process* pcs)
{
return FALSE;
}
const struct loader_ops no_loader_ops =
{
native_synchronize_module_list,
};
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