dbghelp: Expose PE native vs builtin information to winedbg.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
parent
8d75739b6a
commit
01c98c5eaf
8 changed files with 64 additions and 37 deletions
|
@ -440,7 +440,8 @@ struct module
|
|||
WCHAR modulename[64]; /* used for enumeration */
|
||||
struct module* next;
|
||||
enum dhext_module_type type : 16;
|
||||
unsigned short is_virtual : 1;
|
||||
unsigned short is_virtual : 1,
|
||||
is_wine_builtin : 1;
|
||||
struct cpu* cpu;
|
||||
DWORD64 reloc_delta;
|
||||
WCHAR* real_path;
|
||||
|
@ -736,7 +737,7 @@ extern struct module*
|
|||
extern BOOL module_get_debug(struct module_pair*);
|
||||
extern struct module*
|
||||
module_new(struct process* pcs, const WCHAR* name,
|
||||
enum dhext_module_type type, BOOL virtual,
|
||||
enum dhext_module_type type, BOOL builtin, BOOL virtual,
|
||||
DWORD64 addr, DWORD64 size,
|
||||
ULONG_PTR stamp, ULONG_PTR checksum, WORD machine);
|
||||
extern struct module*
|
||||
|
@ -778,7 +779,7 @@ extern const WCHAR* file_name(const WCHAR* str);
|
|||
extern const char* file_nameA(const char* str);
|
||||
|
||||
/* pe_module.c */
|
||||
extern BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth);
|
||||
extern BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth, BOOL* is_builtin);
|
||||
extern struct module*
|
||||
pe_load_native_module(struct process* pcs, const WCHAR* name,
|
||||
HANDLE hFile, DWORD64 base, DWORD size);
|
||||
|
|
|
@ -1083,7 +1083,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
|
|||
lret = dwarf2_parse(module, module->reloc_delta, thunks, fmap);
|
||||
ret = ret || lret;
|
||||
/* add the thunks for native libraries */
|
||||
if (module_is_wine_host(module->modulename, L".so"))
|
||||
if (module->is_wine_builtin)
|
||||
elf_new_wine_thunks(module, ht_symtab, thunks);
|
||||
}
|
||||
/* add all the public symbols from symtab */
|
||||
|
@ -1238,7 +1238,8 @@ static BOOL elf_load_file_from_fmap(struct process* pcs, const WCHAR* filename,
|
|||
modfmt = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(struct module_format) + sizeof(struct elf_module_info));
|
||||
if (!modfmt) return FALSE;
|
||||
elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE, modbase,
|
||||
elf_info->module = module_new(pcs, filename, DMT_ELF,
|
||||
module_is_wine_host(filename, L".so"), FALSE, modbase,
|
||||
fmap->u.elf.elf_size, 0, calc_crc32(fmap->u.elf.handle),
|
||||
elf_get_machine(fmap->u.elf.elfhdr.e_machine));
|
||||
if (!elf_info->module)
|
||||
|
|
|
@ -1509,7 +1509,8 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename,
|
|||
if (!modfmt) goto leave;
|
||||
if (!load_addr)
|
||||
load_addr = fmap.u.macho.segs_start;
|
||||
macho_info->module = module_new(pcs, filename, DMT_MACHO, FALSE, load_addr,
|
||||
macho_info->module = module_new(pcs, filename, DMT_MACHO, module_is_wine_host(filename, L".so"),
|
||||
FALSE, load_addr,
|
||||
fmap.u.macho.segs_size, 0, calc_crc32(fmap.u.macho.handle),
|
||||
image_get_machine(pcs, load_addr));
|
||||
if (!macho_info->module)
|
||||
|
|
|
@ -235,7 +235,7 @@ static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size
|
|||
|
||||
if (!validate_addr64(base)) return FALSE;
|
||||
|
||||
if (pe_load_nt_header(dc->process->handle, base, &nth))
|
||||
if (pe_load_nt_header(dc->process->handle, base, &nth, NULL))
|
||||
add_module(user, name, base, size,
|
||||
nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum,
|
||||
FALSE);
|
||||
|
|
|
@ -169,13 +169,13 @@ WCHAR *get_wine_loader_name(struct process *pcs)
|
|||
return altname;
|
||||
}
|
||||
|
||||
static const char* get_module_type(enum dhext_module_type type, BOOL virtual)
|
||||
static const char* get_module_type(struct module* module)
|
||||
{
|
||||
switch (type)
|
||||
switch (module->type)
|
||||
{
|
||||
case DMT_ELF: return virtual ? "Virtual ELF" : "ELF";
|
||||
case DMT_PE: return virtual ? "Virtual PE" : "PE";
|
||||
case DMT_MACHO: return virtual ? "Virtual Mach-O" : "Mach-O";
|
||||
case DMT_ELF: return "ELF";
|
||||
case DMT_MACHO: return "Mach-O";
|
||||
case DMT_PE: return module->is_wine_builtin ? "PE (builtin)" : "PE";
|
||||
default: return "---";
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ static const char* get_module_type(enum dhext_module_type type, BOOL virtua
|
|||
* Creates and links a new module to a process
|
||||
*/
|
||||
struct module* module_new(struct process* pcs, const WCHAR* name,
|
||||
enum dhext_module_type type, BOOL virtual,
|
||||
enum dhext_module_type type, BOOL builtin, BOOL virtual,
|
||||
DWORD64 mod_addr, DWORD64 size,
|
||||
ULONG_PTR stamp, ULONG_PTR checksum, WORD machine)
|
||||
{
|
||||
|
@ -200,8 +200,8 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
|
|||
module->next = NULL;
|
||||
*pmodule = module;
|
||||
|
||||
TRACE("=> %s %I64x-%I64x %s\n",
|
||||
get_module_type(type, virtual), mod_addr, mod_addr + size, debugstr_w(name));
|
||||
TRACE("=> %s%s%s %I64x-%I64x %s\n", virtual ? "virtual " : "", builtin ? "built-in " : "",
|
||||
get_module_type(module), mod_addr, mod_addr + size, debugstr_w(name));
|
||||
|
||||
pool_init(&module->pool, 65536);
|
||||
|
||||
|
@ -235,7 +235,8 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
|
|||
|
||||
module->reloc_delta = 0;
|
||||
module->type = type;
|
||||
module->is_virtual = virtual;
|
||||
module->is_virtual = !!virtual;
|
||||
module->is_wine_builtin = !!builtin;
|
||||
for (i = 0; i < DFI_LAST; i++) module->format_info[i] = NULL;
|
||||
module->sortlist_valid = FALSE;
|
||||
module->sorttab_size = 0;
|
||||
|
@ -948,7 +949,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
|
|||
if (Flags & SLMFLAG_VIRTUAL)
|
||||
{
|
||||
if (!wImageName) return 0;
|
||||
module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
|
||||
module = module_new(pcs, wImageName, DMT_PE, FALSE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
|
||||
if (!module) return 0;
|
||||
module->module.SymType = SymVirtual;
|
||||
}
|
||||
|
@ -1684,6 +1685,8 @@ BOOL WINAPI wine_get_module_information(HANDLE proc, DWORD64 base, struct dhext_
|
|||
if (!module) return FALSE;
|
||||
|
||||
dhmi.type = module->type;
|
||||
dhmi.is_virtual = module->is_virtual;
|
||||
dhmi.is_wine_builtin = module->is_wine_builtin;
|
||||
dhmi.debug_format_bitmask = module->debug_format_bitmask;
|
||||
if ((module = module_get_container(pcs, module)))
|
||||
{
|
||||
|
|
|
@ -821,7 +821,8 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
|
|||
if (!base) base = PE_FROM_OPTHDR(&modfmt->u.pe_info->fmap, ImageBase);
|
||||
if (!size) size = PE_FROM_OPTHDR(&modfmt->u.pe_info->fmap, SizeOfImage);
|
||||
|
||||
module = module_new(pcs, loaded_name, DMT_PE, FALSE, base, size,
|
||||
module = module_new(pcs, loaded_name, DMT_PE, modfmt->u.pe_info->fmap.u.pe.builtin, FALSE,
|
||||
base, size,
|
||||
modfmt->u.pe_info->fmap.u.pe.file_header.TimeDateStamp,
|
||||
PE_FROM_OPTHDR(&modfmt->u.pe_info->fmap, CheckSum),
|
||||
modfmt->u.pe_info->fmap.u.pe.file_header.Machine);
|
||||
|
@ -852,15 +853,27 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
|
|||
* pe_load_nt_header
|
||||
*
|
||||
*/
|
||||
BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth)
|
||||
BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth, BOOL* is_builtin)
|
||||
{
|
||||
IMAGE_DOS_HEADER dos;
|
||||
|
||||
return ReadProcessMemory(hProc, (char*)(DWORD_PTR)base, &dos, sizeof(dos), NULL) &&
|
||||
dos.e_magic == IMAGE_DOS_SIGNATURE &&
|
||||
ReadProcessMemory(hProc, (char*)(DWORD_PTR)(base + dos.e_lfanew),
|
||||
nth, sizeof(*nth), NULL) &&
|
||||
nth->Signature == IMAGE_NT_SIGNATURE;
|
||||
if (!ReadProcessMemory(hProc, (char*)(DWORD_PTR)base, &dos, sizeof(dos), NULL) ||
|
||||
dos.e_magic != IMAGE_DOS_SIGNATURE ||
|
||||
!ReadProcessMemory(hProc, (char*)(DWORD_PTR)(base + dos.e_lfanew),
|
||||
nth, sizeof(*nth), NULL) ||
|
||||
nth->Signature != IMAGE_NT_SIGNATURE)
|
||||
return FALSE;
|
||||
if (is_builtin)
|
||||
{
|
||||
if (dos.e_lfanew >= sizeof(dos) + sizeof(builtin_signature))
|
||||
{
|
||||
char sig[sizeof(builtin_signature)];
|
||||
*is_builtin = ReadProcessMemory(hProc, (char*)(DWORD_PTR)base + sizeof(dos), sig, sizeof(sig), NULL) &&
|
||||
!memcmp(sig, builtin_signature, sizeof(builtin_signature));
|
||||
}
|
||||
else *is_builtin = FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
@ -875,11 +888,12 @@ struct module* pe_load_builtin_module(struct process* pcs, const WCHAR* name,
|
|||
if (base && pcs->dbg_hdr_addr)
|
||||
{
|
||||
IMAGE_NT_HEADERS nth;
|
||||
BOOL is_builtin;
|
||||
|
||||
if (pe_load_nt_header(pcs->handle, base, &nth))
|
||||
if (pe_load_nt_header(pcs->handle, base, &nth, &is_builtin))
|
||||
{
|
||||
if (!size) size = nth.OptionalHeader.SizeOfImage;
|
||||
module = module_new(pcs, name, DMT_PE, FALSE, base, size,
|
||||
module = module_new(pcs, name, DMT_PE, is_builtin, FALSE, base, size,
|
||||
nth.FileHeader.TimeDateStamp,
|
||||
nth.OptionalHeader.CheckSum,
|
||||
nth.FileHeader.Machine);
|
||||
|
|
|
@ -1266,6 +1266,8 @@ enum dhext_debug_format
|
|||
struct dhext_module_information
|
||||
{
|
||||
enum dhext_module_type type;
|
||||
unsigned is_wine_builtin : 1,
|
||||
is_virtual : 1;
|
||||
unsigned debug_format_bitmask;
|
||||
};
|
||||
|
||||
|
|
|
@ -130,13 +130,13 @@ struct info_modules
|
|||
unsigned num_used;
|
||||
};
|
||||
|
||||
static const char* get_module_type(const struct info_module* im)
|
||||
static const char* get_module_type(const struct info_module* im, BOOL is_embedded)
|
||||
{
|
||||
switch (im->ext_module_info.type)
|
||||
{
|
||||
case DMT_ELF: return "ELF";
|
||||
case DMT_MACHO: return "Mach-O";
|
||||
case DMT_PE: return "PE";
|
||||
case DMT_PE: return !is_embedded && im->ext_module_info.is_wine_builtin ? "PE-Wine" : "PE";
|
||||
default: return "----";
|
||||
}
|
||||
}
|
||||
|
@ -190,18 +190,23 @@ static const char* get_machine_str(DWORD machine)
|
|||
|
||||
static void module_print_info(const struct info_module *module, BOOL is_embedded, BOOL multi_machine)
|
||||
{
|
||||
char buffer[9];
|
||||
snprintf(buffer, sizeof(buffer), "%s%s",
|
||||
is_embedded ? " \\-" : "",
|
||||
get_module_type(module, is_embedded));
|
||||
|
||||
if (multi_machine)
|
||||
dbg_printf("%s%s\t%16I64x-%16I64x\t%s\t%-16s%s\n",
|
||||
is_embedded ? " \\-" : "", get_module_type(module),
|
||||
dbg_printf("%-8s%16I64x-%16I64x %-16s%-16s%s\n",
|
||||
buffer,
|
||||
module->mi.BaseOfImage,
|
||||
module->mi.BaseOfImage + module->mi.ImageSize,
|
||||
get_machine_str(module->mi.MachineType),
|
||||
is_embedded ? "\\" : get_symtype_str(module), module->name);
|
||||
else
|
||||
dbg_printf("%s%s\t%*.*I64x-%*.*I64x\t%-16s%s\n",
|
||||
is_embedded ? " \\-" : "", get_module_type(module),
|
||||
ADDRWIDTH, ADDRWIDTH, module->mi.BaseOfImage,
|
||||
ADDRWIDTH, ADDRWIDTH, module->mi.BaseOfImage + module->mi.ImageSize,
|
||||
dbg_printf("%-8s%*I64x-%*I64x %-16s%s\n",
|
||||
buffer,
|
||||
ADDRWIDTH, module->mi.BaseOfImage,
|
||||
ADDRWIDTH, module->mi.BaseOfImage + module->mi.ImageSize,
|
||||
is_embedded ? "\\" : get_symtype_str(module), module->name);
|
||||
}
|
||||
|
||||
|
@ -284,14 +289,14 @@ void info_win32_module(DWORD64 base, BOOL multi_machine)
|
|||
machine = im.modules[0].mi.MachineType;
|
||||
|
||||
if (multi_machine)
|
||||
dbg_printf("Module\tAddress\t\t\t\t\tMachine\tDebug info\tName (%d modules)\n", im.num_used);
|
||||
dbg_printf("%-8s%-40s%-16s%-16sName (%d modules)\n", "Module", "Address", "Machine", "Debug info", im.num_used);
|
||||
else
|
||||
{
|
||||
unsigned same_machine = 0;
|
||||
for (i = 0; i < im.num_used; i++)
|
||||
if (machine == im.modules[i].mi.MachineType) same_machine++;
|
||||
dbg_printf("Module\tAddress\t\t\t%sDebug info\tName (%d modules",
|
||||
ADDRWIDTH == 16 ? "\t\t" : "", same_machine);
|
||||
dbg_printf("%-8s%-*s%-16sName (%d modules",
|
||||
"Module", ADDRWIDTH == 16 ? 40 : 24, "Address", "Debug info", same_machine);
|
||||
if (same_machine != im.num_used)
|
||||
dbg_printf(", %u for wow64 not listed", im.num_used - same_machine);
|
||||
dbg_printf(")\n");
|
||||
|
|
Loading…
Add table
Reference in a new issue