Commit 01c98c5e authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Expose PE native vs builtin information to winedbg.

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