[PATCH 0/4] MR10020: Winedump improvements for PDB files.
This MR: - improves the dump of existing records (mostly expanding flags meaning), - adds support for dumping ARM switch table and annotation-ref records, - adds the ability to restrict the contents dumped (abusing the -j option), allowing to: - scope the types (TPI and IPI streams), and global symbols (DBI) dumped (by index), - scope the compilands dumped (by name / substring for now). This is useful when analysing very large PDB files, where dumping the whole file takes hours and tens of on drive, not counting the time to grep/search inside the generated dump. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10020
From: Eric Pouech <epouech@codeweavers.com> Signed-off-by: Eric Pouech <epouech@codeweavers.com> --- tools/winedump/msc.c | 17 +++++++++++++---- tools/winedump/pdb.c | 5 ++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index ff8d7b4ff1a..febee0d4a8a 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1009,13 +1009,19 @@ static void codeview_dump_one_type(unsigned curr_type, const union codeview_type break; case LF_MODIFIER_V1: - printf("\t%x => Modifier V1 type:%x modif:%x\n", - curr_type, type->modifier_v1.type, type->modifier_v1.attribute); + printf("\t%x => Modifier V1 type:%x modif:%x%s%s%s\n", + curr_type, type->modifier_v1.type, type->modifier_v1.attribute, + (type->modifier_v1.attribute & 1) ? "-const" : "", + (type->modifier_v1.attribute & 2) ? "-volatile" : "", + (type->modifier_v1.attribute & 4) ? "-unaligned" : ""); break; case LF_MODIFIER_V2: - printf("\t%x => Modifier V2 type:%x modif:%x\n", - curr_type, type->modifier_v2.type, type->modifier_v2.attribute); + printf("\t%x => Modifier V2 type:%x modif:%x%s%s%s\n", + curr_type, type->modifier_v2.type, type->modifier_v2.attribute, + (type->modifier_v2.attribute & 1) ? "-const" : "", + (type->modifier_v2.attribute & 2) ? "-volatile" : "", + (type->modifier_v2.attribute & 4) ? "-unaligned" : ""); break; case LF_METHODLIST_V1: @@ -1356,6 +1362,9 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long int length; struct symbol_dumper sd; + if (start == sizeof(unsigned)) + printf(" [header: %x]\n", *((unsigned*)root)); + init_symbol_dumper(&sd); /* * Loop over the different types of records and whenever we diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 275c5397f63..9bfbb05449a 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -463,7 +463,7 @@ static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMB "\t\t\tunknown: %08x\n", sym_file->range.timestamp, sym_file->range.unknown); - printf("\t\tflag: %04x\n" + printf("\t\tflag: %04x (%x%s%s)\n" "\t\tstream: %04x\n" "\t\tsymb size: %08x\n" "\t\tline size: %08x\n" @@ -471,6 +471,9 @@ static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMB "\t\tnSrcFiles: %08x\n" "\t\tattribute: %08x\n", sym_file->flag, + HIBYTE(sym_file->flag), + sym_file->flag & 0x01 ? ";Dirty" : "", + sym_file->flag & 0x02 ? ";EC" : "", sym_file->stream, sym_file->symbol_size, sym_file->lineno_size, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10020
From: Eric Pouech <epouech@codeweavers.com> Signed-off-by: Eric Pouech <epouech@codeweavers.com> (imported from commit 2e55986ca4a61c952260cde0d6e50b71f2ceaa70) --- tools/winedump/main.c | 37 +++++++++++++++++++++++++++++++++++++ tools/winedump/msc.c | 5 +++-- tools/winedump/pdb.c | 19 +++++++++++++------ tools/winedump/winedump.h | 3 ++- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/tools/winedump/main.c b/tools/winedump/main.c index 99b1221fdac..4465eb5374d 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -402,6 +402,43 @@ BOOL globals_dump_sect(const char* s) return FALSE; } +BOOL globals_dump_sect_with_range(const char* s, unsigned *from, unsigned *to) +{ + const char** sect; + size_t slen; + + if (!s || !globals.dumpsect) return FALSE; + if (globals_dump_sect(s)) return TRUE; + slen = strlen(s); + for (sect = globals.dumpsect; *sect; sect++) + { + if (!memcmp(*sect, s, slen)) + { + if (sscanf(*sect + slen, ":%i-%i", from, to) == 2) + { + if (*from > *to) + { + printf("Invalid range %x-%x\n", *from, *to); + return FALSE; + } + return TRUE; + } + if (sscanf(*sect + slen, ":%i+%i", from, to) == 2) + { + *to += *from; + return TRUE; + } + if (sscanf(*sect + slen, ":%i", from) == 1) + { + *to = *from + 1; + return TRUE; + } + } + } + + return FALSE; +} + /******************************************************************* * main */ diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index febee0d4a8a..7dd89e3b6da 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1186,7 +1186,7 @@ BOOL codeview_dump_types_from_offsets(const void* table, const DWORD* offsets, u return TRUE; } -BOOL codeview_dump_types_from_block(const void* table, unsigned long len) +BOOL codeview_dump_types_from_block(const void* table, unsigned long len, unsigned int from, unsigned int to) { unsigned int curr_type = 0x1000; const unsigned char*ptr = table; @@ -1195,7 +1195,8 @@ BOOL codeview_dump_types_from_block(const void* table, unsigned long len) { const union codeview_type* type = (const union codeview_type*)ptr; - codeview_dump_one_type(curr_type, type); + if (from <= curr_type && curr_type < to) + codeview_dump_one_type(curr_type, type); curr_type++; ptr += type->generic.len + 2; } diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 9bfbb05449a..1f5f5629257 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -786,11 +786,16 @@ static void pdb_dump_symbols(struct pdb_reader* reader) /* Read global symbol table */ modimage = reader->read_stream(reader, symbols->gsym_stream); - if (modimage && globals_dump_sect("DBI")) + if (modimage) { - printf("\t------------globals-------------\n"); - codeview_dump_symbols(modimage, 0, pdb_get_stream_size(reader, symbols->gsym_stream)); - free(modimage); + unsigned from = 0, to = pdb_get_stream_size(reader, symbols->gsym_stream); + + if (globals_dump_sect_with_range("DBI", &from, &to)) + { + printf("\t------------globals-------------\n"); + codeview_dump_symbols(modimage, from, to); + free(modimage); + } } /* Read per-module symbol / linenumber tables */ @@ -1003,8 +1008,10 @@ static void pdb_dump_types(struct pdb_reader* reader, unsigned strmidx, const ch { PDB_TYPES* types = NULL; BOOL used = has_stream_been_read(reader, strmidx); + unsigned from = 0x1000, to = ~0u; + + if (!globals_dump_sect_with_range(strmidx == 2 ? "TPI" : "IPI", &from, &to)) return; - if (!globals_dump_sect(strmidx == 2 ? "TPI" : "IPI")) return; if (pdb_get_stream_size(reader, strmidx) < sizeof(*types)) { if (strmidx == 2) @@ -1064,7 +1071,7 @@ static void pdb_dump_types(struct pdb_reader* reader, unsigned strmidx, const ch types->search_size, types->type_remap_offset, types->type_remap_size); - codeview_dump_types_from_block((const char*)types + types->type_offset, types->type_size); + codeview_dump_types_from_block((const char*)types + types->type_offset, types->type_size, from, to); pdb_dump_types_hash(reader, types, strmname); free(types); } diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index 61a3e55e67d..e6883859f94 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -143,6 +143,7 @@ extern void *dump_base; extern size_t dump_total_len; BOOL globals_dump_sect(const char*); +BOOL globals_dump_sect_with_range(const char *, unsigned *, unsigned *); /* Names to use for output DLL */ #define OUTPUT_DLL_NAME \ @@ -276,7 +277,7 @@ extern void tlb_dump_resource( void *ptr, size_t size, const char *prefix ); BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long size); BOOL codeview_dump_types_from_offsets(const void* table, const DWORD* offsets, unsigned num_types); -BOOL codeview_dump_types_from_block(const void* table, unsigned long len); +BOOL codeview_dump_types_from_block(const void* table, unsigned long len, unsigned int cvtyp_from, unsigned int cvtyp_to); void codeview_dump_linetab(const char* linetab, BOOL pascal_str, const char* pfx); void codeview_dump_linetab2(const char* linetab, DWORD size, const PDB_STRING_TABLE*, const char* pfx); const char* pdb_get_string_table_entry(const PDB_STRING_TABLE* table, unsigned ofs); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10020
From: Eric Pouech <epouech@codeweavers.com> Signed-off-by: Eric Pouech <epouech@codeweavers.com> (imported from commit 558ceb58780fe5f33d46f74cfe3f59ff22997f3b) --- tools/winedump/main.c | 24 ++++++++++++++++++++++++ tools/winedump/pdb.c | 37 +++++++++++++++++++++++++------------ tools/winedump/winedump.h | 1 + 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/tools/winedump/main.c b/tools/winedump/main.c index 4465eb5374d..ba2cbd49f81 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -402,6 +402,30 @@ BOOL globals_dump_sect(const char* s) return FALSE; } +BOOL globals_dump_sect_with_option(const char* s, const char *opt, const char **value) +{ + const char** sect; + size_t slen, olen; + + if (!s || !globals.dumpsect) return FALSE; + if (globals_dump_sect(s)) return TRUE; + slen = strlen(s); + olen = strlen(opt); + for (sect = globals.dumpsect; *sect; sect++) + { + if (!memcmp(*sect, s, slen) && + (*sect)[slen] == ':' && + !memcmp(*sect + slen + 1, opt, olen) && + (*sect)[slen + 1 + olen] == '=') + { + if (value) *value = (*sect) + slen + 1 + olen + 1; + return TRUE; + } + } + + return FALSE; +} + BOOL globals_dump_sect_with_range(const char* s, unsigned *from, unsigned *to) { const char** sect; diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 1f5f5629257..60a1528948e 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -427,17 +427,14 @@ static void dump_public_symbol(struct pdb_reader* reader, unsigned stream) free(hdr); } -static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMBOL_FILE_EX* sym_file, - const char* file_name) +static void pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMBOL_FILE_EX* sym_file, + const char* file_name, const char* lib_name, unsigned index) { - const char* lib_name; + BOOL new_format = file_name == sym_file->filename; unsigned char* modimage; - BOOL new_format = !file_name; - if (new_format) file_name = sym_file->filename; - printf("\t--------symbol file-----------\n"); + printf("\t--------compilation unit #%u-----------\n", index); printf("\tName: %s\n", file_name); - lib_name = file_name + strlen(file_name) + 1; if (strcmp(file_name, lib_name)) printf("\tLibrary: %s\n", lib_name); printf("\t\tunknown1: %08x\n" "\t\trange\n" @@ -491,6 +488,7 @@ static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMB { int total_size = pdb_get_stream_size(reader, sym_file->stream); + /* first (skipped) DWORD is always 4... */ if (sym_file->symbol_size) codeview_dump_symbols((const char*)modimage, sizeof(DWORD), sym_file->symbol_size); @@ -506,7 +504,6 @@ static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMB total_size - (sym_file->symbol_size + sym_file->lineno_size + sym_file->lineno2_size), " "); free(modimage); } - return (const void*)((DWORD_PTR)(lib_name + strlen(lib_name) + 1 + 3) & ~3); } static void pdb_dump_symbols(struct pdb_reader* reader) @@ -517,6 +514,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader) char tcver[32]; const unsigned short* sub_streams = NULL; unsigned num_sub_streams = 0; + const char* section_filter; symbols = reader->read_stream(reader, 3); if (!symbols) return; @@ -799,16 +797,22 @@ static void pdb_dump_symbols(struct pdb_reader* reader) } /* Read per-module symbol / linenumber tables */ - if (symbols->module_size && globals_dump_sect("DBI")) + section_filter = NULL; + if (symbols->module_size && globals_dump_sect_with_option("DBI", "compiland", §ion_filter)) { SIZE_T module_header_size = symbols->version < 19970000 ? sizeof(PDB_SYMBOL_FILE) : sizeof(PDB_SYMBOL_FILE_EX); + unsigned compiland_index = 0; file = (const char*)symbols + sizeof(PDB_SYMBOLS); while (file + module_header_size <= (const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size) { + PDB_SYMBOL_FILE_EX copy; + const PDB_SYMBOL_FILE_EX *sym_file_ex; + const char *file_name; + const char *lib_name; + if (symbols->version < 19970000) { - PDB_SYMBOL_FILE_EX copy; const PDB_SYMBOL_FILE* sym_file = (const PDB_SYMBOL_FILE*)file; copy.unknown1 = sym_file->unknown1; @@ -830,10 +834,19 @@ static void pdb_dump_symbols(struct pdb_reader* reader) copy.attribute = sym_file->attribute; copy.reserved[0] = 0; copy.reserved[1] = 0; - file = pdb_dump_dbi_module(reader, ©, sym_file->filename); + file_name = sym_file->filename; + sym_file_ex = © } else - file = pdb_dump_dbi_module(reader, (const PDB_SYMBOL_FILE_EX*)file, NULL); + { + sym_file_ex = (const void*)file; + file_name = sym_file_ex->filename; + } + lib_name = file_name + strlen(file_name) + 1; + if (!section_filter || strstr(file_name, section_filter) != NULL) + pdb_dump_dbi_module(reader, sym_file_ex, file_name, lib_name, compiland_index); + compiland_index++; + file = (const void*)((DWORD_PTR)(lib_name + strlen(lib_name) + 1 + 3) & ~3); } } dump_global_symbol(reader, symbols->global_hash_stream); diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index e6883859f94..70e2ad4ffa4 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -143,6 +143,7 @@ extern void *dump_base; extern size_t dump_total_len; BOOL globals_dump_sect(const char*); +BOOL globals_dump_sect_with_option(const char *, const char *, const char **); BOOL globals_dump_sect_with_range(const char *, unsigned *, unsigned *); /* Names to use for output DLL */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10020
From: Eric Pouech <epouech@codeweavers.com> Signed-off-by: Eric Pouech <epouech@codeweavers.com> --- include/wine/mscvpdb.h | 14 ++++++++++++++ tools/winedump/msc.c | 29 +++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 34752d9526b..56c2be41796 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -2127,6 +2127,20 @@ union codeview_symbol cv_typ_t typeid; unsigned int rgl[]; } oem_v3; + + struct + { + unsigned short len; + unsigned short id; + unsigned int base_offset; + unsigned short base_section; + unsigned short switch_type; + unsigned int branch_offset; + unsigned int table_offset; + unsigned short branch_section; + unsigned short table_section; + unsigned int number_entries; + } armswitchtable; }; enum BinaryAnnotationOpcode diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 7dd89e3b6da..fe79b964859 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1440,12 +1440,21 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long case S_PROCREF: case S_LPROCREF: case S_TOKENREF: - printf("%sref V3 '%s' %04x:%08x name:%08x\n", - sym->generic.id == S_DATAREF ? "Data" : - (sym->generic.id == S_PROCREF ? "Proc" : - (sym->generic.id == S_LPROCREF ? "Lproc" : "Token")), - get_symbol_str(sym->refsym2_v3.name), - sym->refsym2_v3.imod, sym->refsym2_v3.ibSym, sym->refsym2_v3.sumName); + case S_ANNOTATIONREF: + { + const char *kind; + switch (sym->generic.id) + { + case S_DATAREF: kind = "Data"; break; + case S_PROCREF: kind = "Proc"; break; + case S_LPROCREF: kind = "LProc"; break; + case S_TOKENREF: kind = "Token"; break; + case S_ANNOTATIONREF: kind = "Annotation"; break; + default: kind = "----"; break; + } + printf("%sref V3 '%s' %04x:%08x name:%08x\n", kind, get_symbol_str(sym->refsym2_v3.name), + sym->refsym2_v3.imod, sym->refsym2_v3.ibSym, sym->refsym2_v3.sumName); + } break; /* @@ -2004,6 +2013,14 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long } break; + case S_ARMSWITCHTABLE: + printf("ARM switch table type=%u base=%04x:%08x branch=%04x:%08x table=%04x:%08x entries=#%u\n", + sym->armswitchtable.switch_type, + sym->armswitchtable.base_section, sym->armswitchtable.base_offset, + sym->armswitchtable.branch_section, sym->armswitchtable.branch_offset, + sym->armswitchtable.table_section, sym->armswitchtable.table_offset, + sym->armswitchtable.number_entries); + break; default: printf("\n\t\t>>> Unsupported symbol-id %x sz=%d\n", sym->generic.id, sym->generic.len + 2); dump_data((const void*)sym, sym->generic.len + 2, " "); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10020
participants (2)
-
Eric Pouech -
eric pouech (@epo)