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
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");
......
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