1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-01 07:14:31 +00:00

dbghelp: Expose some internal information about modules to winedbg.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
Eric Pouech 2023-11-16 18:38:02 +01:00 committed by Alexandre Julliard
parent 416d29e26c
commit c50e02ec9c
10 changed files with 131 additions and 61 deletions

View File

@ -67,6 +67,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
unsigned dbghelp_options = SYMOPT_UNDNAME;
BOOL dbghelp_opt_native = FALSE;
BOOL dbghelp_opt_extension_api = FALSE;
BOOL dbghelp_opt_real_path = FALSE;
BOOL dbghelp_opt_source_actual_path = FALSE;
SYSTEM_INFO sysinfo;
@ -612,6 +613,10 @@ BOOL WINAPI SymSetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option, BOOL value)
old = dbghelp_opt_native;
dbghelp_opt_native = value;
break;
case SYMOPT_EX_WINE_EXTENSION_API:
old = dbghelp_opt_extension_api;
dbghelp_opt_extension_api = value;
break;
case SYMOPT_EX_WINE_MODULE_REAL_PATH:
old = dbghelp_opt_real_path;
dbghelp_opt_real_path = value;
@ -637,6 +642,8 @@ BOOL WINAPI SymGetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option)
{
case SYMOPT_EX_WINE_NATIVE_MODULES:
return dbghelp_opt_native;
case SYMOPT_EX_WINE_EXTENSION_API:
return dbghelp_opt_extension_api;
case SYMOPT_EX_WINE_MODULE_REAL_PATH:
return dbghelp_opt_real_path;
case SYMOPT_EX_WINE_SOURCE_ACTUAL_PATH:

View File

@ -215,3 +215,6 @@
#@ stub sym
#@ stub symsrv
#@ stub vc7fpo
# wine extensions
@ stdcall wine_get_module_information(long int64 ptr long)

View File

@ -112,6 +112,7 @@ void* hash_table_iter_up(struct hash_table_iter* hti);
extern unsigned dbghelp_options;
extern BOOL dbghelp_opt_native;
extern BOOL dbghelp_opt_extension_api;
extern BOOL dbghelp_opt_real_path;
extern BOOL dbghelp_opt_source_actual_path;
extern SYSTEM_INFO sysinfo;
@ -396,13 +397,6 @@ struct symt_udt
struct vector vchildren;
};
enum module_type
{
DMT_ELF, /* a real ELF shared module */
DMT_PE, /* a native or builtin PE module */
DMT_MACHO, /* a real Mach-O shared module */
};
struct process;
struct module;
@ -445,7 +439,7 @@ struct module
IMAGEHLP_MODULEW64 module;
WCHAR modulename[64]; /* used for enumeration */
struct module* next;
enum module_type type : 16;
enum dhext_module_type type : 16;
unsigned short is_virtual : 1;
struct cpu* cpu;
DWORD64 reloc_delta;
@ -453,6 +447,7 @@ struct module
/* specific information for debug types */
struct module_format* format_info[DFI_LAST];
unsigned debug_format_bitmask;
/* memory allocation pool */
struct pool pool;
@ -742,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 module_type type, BOOL virtual,
enum dhext_module_type type, BOOL virtual,
DWORD64 addr, DWORD64 size,
ULONG_PTR stamp, ULONG_PTR checksum, WORD machine);
extern struct module*

View File

@ -2892,8 +2892,8 @@ static BOOL dwarf2_parse_compilation_unit_head(dwarf2_parse_context_t* ctx,
TRACE("- word_size: %u\n", ctx->head.word_size);
TRACE("- offset_size: %u\n", ctx->head.offset_size);
if (ctx->head.version >= 2)
ctx->module_ctx->cu_versions |= 1 << (ctx->head.version - 2);
if (ctx->head.version >= 2 && ctx->head.version <= 5)
ctx->module_ctx->cu_versions |= DHEXT_FORMAT_DWARF2 << (ctx->head.version - 2);
if (max_supported_dwarf_version == 0)
{
char* env = getenv("DBGHELP_DWARF_VERSION");
@ -4259,17 +4259,16 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset,
module_ctx.dwz = dwarf2_load_dwz(fmap, module);
dwarf2_load_CU_module(&module_ctx, module, section, load_offset, thunks, FALSE);
dwarf2_modfmt->module->module.SymType = SymDia;
/* hide dwarf versions in CVSig
* bits 24-31 will be set according to found dwarf version
* different CU can have different dwarf version, so use a bit per version (version 2 => b24)
*/
dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('F' << 16) | ((module_ctx.cu_versions & 0xFF) << 24);
/* FIXME: we could have a finer grain here */
dwarf2_modfmt->module->module.GlobalSymbols = TRUE;
dwarf2_modfmt->module->module.TypeInfo = TRUE;
dwarf2_modfmt->module->module.SourceIndexed = TRUE;
dwarf2_modfmt->module->module.Publics = TRUE;
if (module_ctx.cu_versions)
{
dwarf2_modfmt->module->module.SymType = SymDia;
module->debug_format_bitmask |= module_ctx.cu_versions;
/* FIXME: we could have a finer grain here */
dwarf2_modfmt->module->module.GlobalSymbols = TRUE;
dwarf2_modfmt->module->module.TypeInfo = TRUE;
dwarf2_modfmt->module->module.SourceIndexed = TRUE;
dwarf2_modfmt->module->module.Publics = TRUE;
}
dwarf2_unload_CU_module(&module_ctx);
leave:

View File

@ -102,7 +102,7 @@ struct macho_section32
*/
struct image_file_map
{
enum module_type modtype;
enum dhext_module_type modtype;
const struct image_file_map_ops *ops;
unsigned addr_size; /* either 16 (not used), 32 or 64 */
struct image_file_map* alternate; /* another file linked to this one */

View File

@ -162,7 +162,7 @@ WCHAR *get_wine_loader_name(struct process *pcs)
return altname;
}
static const char* get_module_type(enum module_type type, BOOL virtual)
static const char* get_module_type(enum dhext_module_type type, BOOL virtual)
{
switch (type)
{
@ -177,7 +177,7 @@ static const char* get_module_type(enum module_type type, BOOL virtual)
* Creates and links a new module to a process
*/
struct module* module_new(struct process* pcs, const WCHAR* name,
enum module_type type, BOOL virtual,
enum dhext_module_type type, BOOL virtual,
DWORD64 mod_addr, DWORD64 size,
ULONG_PTR stamp, ULONG_PTR checksum, WORD machine)
{
@ -238,6 +238,7 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
module->cpu = cpu_find(machine);
if (!module->cpu)
module->cpu = dbghelp_current_cpu;
module->debug_format_bitmask = 0;
vector_init(&module->vsymt, sizeof(struct symt*), 128);
vector_init(&module->vcustom_symt, sizeof(struct symt*), 16);
@ -1653,3 +1654,35 @@ const struct loader_ops empty_loader_ops =
empty_enum_modules,
native_fetch_file_info,
};
BOOL WINAPI wine_get_module_information(HANDLE proc, DWORD64 base, struct dhext_module_information* wmi, unsigned len)
{
struct process* pcs;
struct module* module;
struct dhext_module_information dhmi;
/* could be interpreted as a WinDbg extension */
if (!dbghelp_opt_extension_api)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
TRACE("(%p %I64x %p %u\n", proc, base, wmi, len);
if (!(pcs = process_find_by_handle(proc))) return FALSE;
if (len > sizeof(*wmi)) return FALSE;
module = module_find_by_addr(pcs, base);
if (!module) return FALSE;
dhmi.type = module->type;
dhmi.debug_format_bitmask = module->debug_format_bitmask;
if ((module = module_get_container(pcs, module)))
{
dhmi.debug_format_bitmask |= module->debug_format_bitmask;
}
memcpy(wmi, &dhmi, len);
return TRUE;
}

View File

@ -1664,7 +1664,7 @@ BOOL stabs_parse(struct module* module, ULONG_PTR load_offset,
stab_ptr->n_type, (ULONG_PTR)n_value, debugstr_a(strs + stab_ptr->n_strx));
}
module->module.SymType = SymDia;
module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24);
module->debug_format_bitmask |= DHEXT_FORMAT_STABS;
/* FIXME: we could have a finer grain here */
module->module.LineNumbers = TRUE;
module->module.GlobalSymbols = TRUE;

View File

@ -1098,6 +1098,8 @@ typedef enum
#ifdef __WINESRC__
/* Include ELF/Mach-O modules in module operations */
SYMOPT_EX_WINE_NATIVE_MODULES = 1000,
/* Enable Wine's extension APIs */
SYMOPT_EX_WINE_EXTENSION_API,
/* Return the Unix actual path of loaded module */
SYMOPT_EX_WINE_MODULE_REAL_PATH,
/* Return the raw source file path from debug info (not always mapped to DOS) */
@ -1240,6 +1242,37 @@ BOOL IMAGEAPI SymUnloadModule(HANDLE, DWORD);
#endif
#ifdef __WINESRC__
/* Wine extensions to dbghelp */
enum dhext_module_type
{
DMT_UNKNOWN, /* for lookup, not actually used for a module */
DMT_ELF, /* a real ELF shared module */
DMT_MACHO, /* a real Mach-O shared module */
DMT_PE, /* a native or builtin PE module */
};
/* only reporting the formats not exposed in regular IMAGHELP_MODULE_INFO */
enum dhext_debug_format
{
DHEXT_FORMAT_DWARF2 = 0x0001,
DHEXT_FORMAT_DWARF3 = 0x0002,
DHEXT_FORMAT_DWARF4 = 0x0004,
DHEXT_FORMAT_DWARF5 = 0x0008,
DHEXT_FORMAT_STABS = 0x0010,
};
struct dhext_module_information
{
enum dhext_module_type type;
unsigned debug_format_bitmask;
};
extern BOOL WINAPI wine_get_module_information(HANDLE, DWORD64 base, struct dhext_module_information*, unsigned len);
#endif /* __WINESRC__ */
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */

View File

@ -116,9 +116,23 @@ void info_help(void)
while (infotext[i]) dbg_printf("%s\n", infotext[i++]);
}
static const char* get_symtype_str(const IMAGEHLP_MODULE64* mi)
struct info_module
{
switch (mi->SymType)
IMAGEHLP_MODULEW64 mi;
struct dhext_module_information ext_module_info;
char name[64];
};
struct info_modules
{
struct info_module *modules;
unsigned num_alloc;
unsigned num_used;
};
static const char* get_symtype_str(const struct info_module* im)
{
switch (im->mi.SymType)
{
default:
case SymNone: return "--none--";
@ -129,43 +143,26 @@ static const char* get_symtype_str(const IMAGEHLP_MODULE64* mi)
case SymDeferred: return "Deferred";
case SymSym: return "Sym";
case SymDia:
switch (mi->CVSig)
if (im->ext_module_info.debug_format_bitmask)
{
case 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24):
return "Stabs";
case 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24):
/* previous versions of dbghelp used to report this... */
return "Dwarf";
default:
if ((mi->CVSig & 0x00FFFFFF) == ('D' | ('W' << 8) | ('F' << 16)))
static char tmp[64];
tmp[0] = '\0';
if (im->ext_module_info.debug_format_bitmask & DHEXT_FORMAT_STABS) strcpy(tmp, "stabs");
if (im->ext_module_info.debug_format_bitmask & (DHEXT_FORMAT_DWARF2 | DHEXT_FORMAT_DWARF3 | DHEXT_FORMAT_DWARF4 | DHEXT_FORMAT_DWARF5))
{
static char tmp[64];
DWORD versbit = mi->CVSig >> 24;
strcpy(tmp, "Dwarf");
if (versbit & 1) strcat(tmp, "-2");
if (versbit & 2) strcat(tmp, "-3");
if (versbit & 4) strcat(tmp, "-4");
if (versbit & 8) strcat(tmp, "-5");
return tmp;
if (tmp[0]) strcat(tmp, ", ");
strcat(tmp, "Dwarf");
if (im->ext_module_info.debug_format_bitmask & DHEXT_FORMAT_DWARF2) strcat(tmp, "-2");
if (im->ext_module_info.debug_format_bitmask & DHEXT_FORMAT_DWARF3) strcat(tmp, "-3");
if (im->ext_module_info.debug_format_bitmask & DHEXT_FORMAT_DWARF4) strcat(tmp, "-4");
if (im->ext_module_info.debug_format_bitmask & DHEXT_FORMAT_DWARF5) strcat(tmp, "-5");
}
return "DIA";
return tmp;
}
return "DIA";
}
}
struct info_module
{
IMAGEHLP_MODULE64 mi;
char name[64];
};
struct info_modules
{
struct info_module *modules;
unsigned num_alloc;
unsigned num_used;
};
static const char* get_machine_str(DWORD machine)
{
static char tmp[32];
@ -187,12 +184,12 @@ static void module_print_info(const struct info_module *module, BOOL is_embedded
module->mi.BaseOfImage,
module->mi.BaseOfImage + module->mi.ImageSize,
get_machine_str(module->mi.MachineType),
is_embedded ? "\\" : get_symtype_str(&module->mi), module->name);
is_embedded ? "\\" : get_symtype_str(module), module->name);
else
dbg_printf("%*.*I64x-%*.*I64x\t%-16s%s\n",
ADDRWIDTH, ADDRWIDTH, module->mi.BaseOfImage,
ADDRWIDTH, ADDRWIDTH, module->mi.BaseOfImage + module->mi.ImageSize,
is_embedded ? "\\" : get_symtype_str(&module->mi), module->name);
is_embedded ? "\\" : get_symtype_str(module), module->name);
}
static int __cdecl module_compare(const void* p1, const void* p2)
@ -226,7 +223,9 @@ static BOOL CALLBACK info_mod_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
im->modules = new;
}
im->modules[im->num_used].mi.SizeOfStruct = sizeof(im->modules[im->num_used].mi);
if (SymGetModuleInfo64(dbg_curr_process->handle, base, &im->modules[im->num_used].mi))
if (SymGetModuleInfoW64(dbg_curr_process->handle, base, &im->modules[im->num_used].mi) &&
wine_get_module_information(dbg_curr_process->handle, base, &im->modules[im->num_used].ext_module_info,
sizeof(im->modules[im->num_used].ext_module_info)))
{
const int dst_len = sizeof(im->modules[im->num_used].name);
lstrcpynA(im->modules[im->num_used].name, mod_name, dst_len - 1);

View File

@ -723,6 +723,7 @@ int main(int argc, char** argv)
SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_AUTO_PUBLICS |
SYMOPT_INCLUDE_32BIT_MODULES);
SymSetExtendedOption(SYMOPT_EX_WINE_EXTENSION_API, TRUE);
SymSetExtendedOption(SYMOPT_EX_WINE_SOURCE_ACTUAL_PATH, TRUE);
if (argc && !strcmp(argv[0], "--auto"))