This series: - complements PDB dumping in a few areas (internals of MSF, string tables, public stream) - allow to opt in for only a portion of PDB file
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- tools/winedump/main.c | 36 +++++++++++++++++++++++++---- tools/winedump/ne.c | 12 ++++------ tools/winedump/pe.c | 48 ++++++++++++++++++--------------------- tools/winedump/winedump.h | 4 +++- 4 files changed, 61 insertions(+), 39 deletions(-)
diff --git a/tools/winedump/main.c b/tools/winedump/main.c index f9557983465..15b1813de5e 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -169,7 +169,23 @@ static void do_dumphead (const char *arg)
static void do_dumpsect (const char* arg) { - globals.dumpsect = arg; + unsigned count = 2; + char* p; + const char** out; + + for (p = (char*)arg; (p = strchr(p, ',')) != NULL; p++, count++); + out = malloc(count * sizeof(char*)); + globals.dumpsect = out; + count = 0; + p = strdup(arg); + for (;;) + { + out[count++] = p; + p = strchr(p, ','); + if (!p) break; + *p++ = '\0'; + } + out[count] = NULL; }
static void do_rawdebug (const char *arg) @@ -182,7 +198,7 @@ static void do_dumpall(const char *arg) globals.do_dumpheader = TRUE; globals.do_dump_rawdata = TRUE; globals.do_symbol_table = TRUE; - globals.dumpsect = "ALL"; + do_dumpsect ("ALL"); }
static void do_symtable(const char* arg) @@ -207,8 +223,10 @@ static const struct my_option option_table[] = { {"-C", DUMP, 0, do_symdmngl, "-C Turn on symbol demangling"}, {"-f", DUMP, 0, do_dumphead, "-f Dump file header information"}, {"-G", DUMP, 0, do_rawdebug, "-G Dump raw debug information"}, - {"-j", DUMP, 1, do_dumpsect, "-j <sect_name> Dump only the content of section 'sect_name'\n" - " (import, export, debug, resource, tls, loadcfg, clr, reloc, except, apiset)"}, + {"-j", DUMP, 1, do_dumpsect, "-j <sect_name> Dump the content of section 'sect_name'\n" + " (use '-j sect_name,sect_name2' to dump several sections)\n" + " for NE: export, resource\n" + " for PE: import, export, debug, resource, tls, loadcfg, clr, reloc, except, apiset"}, {"-t", DUMP, 0, do_symtable, "-t Dump symbol table"}, {"-x", DUMP, 0, do_dumpall, "-x Dump everything"}, {"sym", DMGL, 0, do_demangle, "sym <sym> Demangle C++ symbol <sym> and exit"}, @@ -370,6 +388,16 @@ static BOOL symbol_finish(void) return started; }
+BOOL globals_dump_sect(const char* s) +{ + const char** sect; + + if (!s || !globals.dumpsect) return FALSE; + for (sect = globals.dumpsect; *sect; sect++) + if (!strcmp(*sect, s) || !strcmp(*sect, "ALL")) return TRUE; + return FALSE; +} + /******************************************************************* * main */ diff --git a/tools/winedump/ne.c b/tools/winedump/ne.c index 9b4ede6c86e..c27d7d6a9b7 100644 --- a/tools/winedump/ne.c +++ b/tools/winedump/ne.c @@ -429,15 +429,11 @@ void ne_dump( void ) dump_ne_header( ne ); if (globals.do_dumpheader) dump_ne_names( ne ); - if (globals.dumpsect) - { - BOOL all = strcmp(globals.dumpsect, "ALL") == 0;
- if (all || !strcmp(globals.dumpsect, "resource")) - dump_ne_resources( ne ); - if (all || !strcmp(globals.dumpsect, "export")) - dump_ne_exports( ne ); - } + if (globals_dump_sect("resource")) + dump_ne_resources( ne ); + if (globals_dump_sect("export")) + dump_ne_exports( ne ); if (globals.do_dumpheader) for (i = 1; i <= ne->ne_cseg; i++) dump_ne_segment( ne, i ); } diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c index ed30d54cece..70961ad5b94 100644 --- a/tools/winedump/pe.c +++ b/tools/winedump/pe.c @@ -2401,8 +2401,6 @@ enum FileSig get_kind_exec(void)
void pe_dump(void) { - int all = (globals.dumpsect != NULL) && strcmp(globals.dumpsect, "ALL") == 0; - PE_nt_headers = get_nt_header(); print_fake_dll();
@@ -2419,32 +2417,30 @@ void pe_dump(void) dump_pe_header(); }
- if (globals.dumpsect) + if (globals_dump_sect("import")) { - if (all || !strcmp(globals.dumpsect, "import")) - { - dump_dir_imported_functions(); - dump_dir_delay_imported_functions(); - } - if (all || !strcmp(globals.dumpsect, "export")) - dump_dir_exported_functions(); - if (all || !strcmp(globals.dumpsect, "debug")) - dump_dir_debug(); - if (all || !strcmp(globals.dumpsect, "resource")) - dump_dir_resource(); - if (all || !strcmp(globals.dumpsect, "tls")) - dump_dir_tls(); - if (all || !strcmp(globals.dumpsect, "loadcfg")) - dump_dir_loadconfig(); - if (all || !strcmp(globals.dumpsect, "clr")) - dump_dir_clr_header(); - if (all || !strcmp(globals.dumpsect, "reloc")) - dump_dir_reloc(); - if (all || !strcmp(globals.dumpsect, "except")) - dump_dir_exceptions(); - if (all || !strcmp(globals.dumpsect, "apiset")) - dump_section_apiset(); + dump_dir_imported_functions(); + dump_dir_delay_imported_functions(); } + if (globals_dump_sect("export")) + dump_dir_exported_functions(); + if (globals_dump_sect("debug")) + dump_dir_debug(); + if (globals_dump_sect("resource")) + dump_dir_resource(); + if (globals_dump_sect("tls")) + dump_dir_tls(); + if (globals_dump_sect("loadcfg")) + dump_dir_loadconfig(); + if (globals_dump_sect("clr")) + dump_dir_clr_header(); + if (globals_dump_sect("reloc")) + dump_dir_reloc(); + if (globals_dump_sect("except")) + dump_dir_exceptions(); + if (globals_dump_sect("apiset")) + dump_section_apiset(); + if (globals.do_symbol_table) dump_symbol_table(); if (globals.do_debug) diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index 84694f21b0b..dec7bc42c9f 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -135,13 +135,15 @@ typedef struct __globals const char *uc_dll_name; /* -o */
/* Option arguments: dump mode */ - const char *dumpsect; /* -j */ + const char **dumpsect; /* -j */ } _globals;
extern _globals globals; extern void *dump_base; extern size_t dump_total_len;
+BOOL globals_dump_sect(const char*); + /* Names to use for output DLL */ #define OUTPUT_DLL_NAME \ (globals.dll_name ? globals.dll_name : (globals.input_module ? globals.input_module : globals.input_name))
From: Eric Pouech eric.pouech@gmail.com
Also better taking care of various PDB_SYMBOL_FILE formats.
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- tools/winedump/pdb.c | 240 ++++++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 129 deletions(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index b13161c6c7a..21982c32477 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -331,6 +331,85 @@ 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, PDB_STRING_TABLE* filesimage) +{ + const char* lib_name; + unsigned char* modimage; + BOOL new_format = !file_name; + + if (new_format) file_name = sym_file->filename; + printf("\t--------symbol file-----------\n"); + 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" + "\t\t\tsegment: %04x\n" + "\t\t\tpad1: %04x\n" + "\t\t\toffset: %08x\n" + "\t\t\tsize: %08x\n" + "\t\t\tcharacteristics: %08x", + sym_file->unknown1, + sym_file->range.segment, + sym_file->range.pad1, + sym_file->range.offset, + sym_file->range.size, + sym_file->range.characteristics); + dump_section_characteristics(sym_file->range.characteristics, " "); + printf("\n" + "\t\t\tindex: %04x\n" + "\t\t\tpad2: %04x\n", + sym_file->range.index, + sym_file->range.pad2); + if (new_format) + printf("\t\t\ttimestamp: %08x\n" + "\t\t\tunknown: %08x\n", + sym_file->range.timestamp, + sym_file->range.unknown); + printf("\t\tflag: %04x\n" + "\t\tstream: %04x\n" + "\t\tsymb size: %08x\n" + "\t\tline size: %08x\n" + "\t\tline2 size: %08x\n" + "\t\tnSrcFiles: %08x\n" + "\t\tattribute: %08x\n", + sym_file->flag, + sym_file->stream, + sym_file->symbol_size, + sym_file->lineno_size, + sym_file->lineno2_size, + sym_file->nSrcFiles, + sym_file->attribute); + if (new_format) + printf("\t\treserved/0: %08x\n" + "\t\treserved/1: %08x\n", + sym_file->reserved[0], + sym_file->reserved[1]); + + modimage = reader->read_stream(reader, sym_file->stream); + if (modimage) + { + int total_size = pdb_get_stream_size(reader, sym_file->stream); + + if (sym_file->symbol_size) + codeview_dump_symbols((const char*)modimage, sizeof(DWORD), sym_file->symbol_size); + + /* line number info */ + if (sym_file->lineno_size) + codeview_dump_linetab((const char*)modimage + sym_file->symbol_size, TRUE, " "); + else if (sym_file->lineno2_size) /* actually, only one of the 2 lineno should be present */ + codeview_dump_linetab2((const char*)modimage + sym_file->symbol_size, sym_file->lineno2_size, + filesimage, " "); + /* what's that part ??? */ + if (0) + dump_data(modimage + sym_file->symbol_size + sym_file->lineno_size + sym_file->lineno2_size, + 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, PDB_STREAM_INDEXES* sidx) { PDB_SYMBOLS* symbols; @@ -635,139 +714,42 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx }
/* Read per-module symbol / linenumber tables */ - file = (const char*)symbols + sizeof(PDB_SYMBOLS); - while (file - (const char*)symbols < sizeof(PDB_SYMBOLS) + symbols->module_size) - while ((file - (const char*)symbols + sizeof(symbols->version) < sizeof(PDB_SYMBOLS) + symbols->module_size) && - (file - (const char*)symbols + - symbols->version < 19970000 ? sizeof(PDB_SYMBOL_FILE) : sizeof(PDB_SYMBOL_FILE_EX)) < sizeof(PDB_SYMBOLS) + symbols->module_size) + if (symbols->module_size) { - int stream_nr, symbol_size, lineno_size, lineno2_size; - const char* file_name; - const char* lib_name; + SIZE_T module_header_size = symbols->version < 19970000 ? sizeof(PDB_SYMBOL_FILE) : sizeof(PDB_SYMBOL_FILE_EX);
- if (symbols->version < 19970000) - { - const PDB_SYMBOL_FILE* sym_file = (const PDB_SYMBOL_FILE*) file; - stream_nr = sym_file->stream; - file_name = sym_file->filename; - lib_name = file_name + strlen(file_name) + 1; - symbol_size = sym_file->symbol_size; - lineno_size = sym_file->lineno_size; - lineno2_size = sym_file->lineno2_size; - printf("\t--------symbol file-----------\n"); - printf("\tName: %s\n", file_name); - if (strcmp(file_name, lib_name)) printf("\tLibrary: %s\n", lib_name); - printf("\t\tunknown1: %08x\n" - "\t\trange\n" - "\t\t\tsegment: %04x\n" - "\t\t\tpad1: %04x\n" - "\t\t\toffset: %08x\n" - "\t\t\tsize: %08x\n" - "\t\t\tcharacteristics: %08x", - sym_file->unknown1, - sym_file->range.segment, - sym_file->range.pad1, - sym_file->range.offset, - sym_file->range.size, - sym_file->range.characteristics); - dump_section_characteristics(sym_file->range.characteristics, " "); - printf("\n" - "\t\t\tindex: %04x\n" - "\t\t\tpad2: %04x\n" - "\t\tflag: %04x\n" - "\t\tstream: %04x\n" - "\t\tsymb size: %08x\n" - "\t\tline size: %08x\n" - "\t\tline2 size: %08x\n" - "\t\tnSrcFiles: %08x\n" - "\t\tattribute: %08x\n", - sym_file->range.index, - sym_file->range.pad2, - sym_file->flag, - sym_file->stream, - sym_file->symbol_size, - sym_file->lineno_size, - sym_file->lineno2_size, - sym_file->nSrcFiles, - sym_file->attribute); - } - else - { - const PDB_SYMBOL_FILE_EX* sym_file = (const PDB_SYMBOL_FILE_EX*) file; - - stream_nr = sym_file->stream; - file_name = sym_file->filename; - lib_name = file_name + strlen(file_name) + 1; - symbol_size = sym_file->symbol_size; - lineno_size = sym_file->lineno_size; - lineno2_size = sym_file->lineno2_size; - printf("\t--------symbol file-----------\n"); - printf("\tName: %s\n", file_name); - if (strcmp(file_name, lib_name)) printf("\tLibrary: %s\n", lib_name); - printf("\t\tunknown1: %08x\n" - "\t\trange\n" - "\t\t\tsegment: %04x\n" - "\t\t\tpad1: %04x\n" - "\t\t\toffset: %08x\n" - "\t\t\tsize: %08x\n" - "\t\t\tcharacteristics: %08x", - sym_file->unknown1, - sym_file->range.segment, - sym_file->range.pad1, - sym_file->range.offset, - sym_file->range.size, - sym_file->range.characteristics); - dump_section_characteristics(sym_file->range.characteristics, " "); - printf("\n" - "\t\t\tindex: %04x\n" - "\t\t\tpad2: %04x\n" - "\t\t\ttimestamp: %08x\n" - "\t\t\tunknown: %08x\n" - "\t\tflag: %04x\n" - "\t\tstream: %04x\n" - "\t\tsymb size: %08x\n" - "\t\tline size: %08x\n" - "\t\tline2 size: %08x\n" - "\t\tnSrcFiles: %08x\n" - "\t\tattribute: %08x\n" - "\t\treserved/0: %08x\n" - "\t\treserved/1: %08x\n", - sym_file->range.index, - sym_file->range.pad2, - sym_file->range.timestamp, - sym_file->range.unknown, - sym_file->flag, - sym_file->stream, - sym_file->symbol_size, - sym_file->lineno_size, - sym_file->lineno2_size, - sym_file->nSrcFiles, - sym_file->attribute, - sym_file->reserved[0], - sym_file->reserved[1]); - } - modimage = reader->read_stream(reader, stream_nr); - if (modimage) + file = (const char*)symbols + sizeof(PDB_SYMBOLS); + while (file + module_header_size <= (const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size) { - int total_size = pdb_get_stream_size(reader, stream_nr); - - if (symbol_size) - codeview_dump_symbols((const char*)modimage, sizeof(DWORD), symbol_size); - - /* line number info */ - if (lineno_size) - codeview_dump_linetab((const char*)modimage + symbol_size, TRUE, " "); - else if (lineno2_size) /* actually, only one of the 2 lineno should be present */ - codeview_dump_linetab2((const char*)modimage + symbol_size, lineno2_size, - filesimage, " "); - /* what's that part ??? */ - if (0) - dump_data(modimage + symbol_size + lineno_size + lineno2_size, - total_size - (symbol_size + lineno_size + lineno2_size), " "); - free(modimage); + 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; + copy.range.segment = sym_file->range.segment; + copy.range.pad1 = sym_file->range.pad1; + copy.range.offset = sym_file->range.offset; + copy.range.size = sym_file->range.size; + copy.range.characteristics = sym_file->range.characteristics; + copy.range.index = sym_file->range.index; + copy.range.pad2 = sym_file->range.pad2; + copy.range.timestamp = 0; + copy.range.unknown = 0; + copy.flag = sym_file->flag; + copy.stream = sym_file->stream; + copy.symbol_size = sym_file->symbol_size; + copy.lineno_size = sym_file->lineno_size; + copy.lineno2_size = sym_file->lineno2_size; + copy.nSrcFiles = sym_file->nSrcFiles; + copy.attribute = sym_file->attribute; + copy.reserved[0] = 0; + copy.reserved[1] = 0; + file = pdb_dump_dbi_module(reader, ©, sym_file->filename, filesimage); + } + else + file = pdb_dump_dbi_module(reader, (const PDB_SYMBOL_FILE_EX*)file, NULL, filesimage); } - - file = (char*)((DWORD_PTR)(lib_name + strlen(lib_name) + 1 + 3) & ~3); } dump_global_symbol(reader, symbols->global_hash_stream); dump_public_symbol(reader, symbols->public_stream);
From: Eric Pouech eric.pouech@gmail.com
Allowing section names: DBI, TPI, IPI, hash.
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- tools/winedump/main.c | 4 +- tools/winedump/pdb.c | 197 +++++++++++++++++++++++------------------- 2 files changed, 110 insertions(+), 91 deletions(-)
diff --git a/tools/winedump/main.c b/tools/winedump/main.c index 15b1813de5e..382cfdc3a04 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -226,7 +226,9 @@ static const struct my_option option_table[] = { {"-j", DUMP, 1, do_dumpsect, "-j <sect_name> Dump the content of section 'sect_name'\n" " (use '-j sect_name,sect_name2' to dump several sections)\n" " for NE: export, resource\n" - " for PE: import, export, debug, resource, tls, loadcfg, clr, reloc, except, apiset"}, + " for PE: import, export, debug, resource, tls, loadcfg, clr, reloc, except, apiset\n" + " for PDB: PDB, TPI, DBI, IPI, public, image\n" + " and suboptions: hash (PDB, TPI, TPI, DBI, public) and line (DBI)"}, {"-t", DUMP, 0, do_symtable, "-t Dump symbol table"}, {"-x", DUMP, 0, do_dumpall, "-x Dump everything"}, {"sym", DMGL, 0, do_demangle, "sym <sym> Demangle C++ symbol <sym> and exit"}, diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 21982c32477..07b02057d78 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -134,18 +134,21 @@ static void pdb_exit(struct pdb_reader* reader) unsigned i, size; unsigned char* stream;
- for (i = 0; i < pdb_get_num_streams(reader); i++) + if (globals_dump_sect("ALL")) /* otherwise we won't have loaded all streams */ { - if (has_stream_been_read(reader, i)) continue; + for (i = 0; i < pdb_get_num_streams(reader); i++) + { + if (has_stream_been_read(reader, i)) continue;
- stream = reader->read_stream(reader, i); - if (!stream) continue; + stream = reader->read_stream(reader, i); + if (!stream) continue;
- size = pdb_get_stream_size(reader, i); + size = pdb_get_stream_size(reader, i);
- printf("Stream --unused-- #%d (%x)\n", i, size); - dump_data(stream, size, " "); - free(stream); + printf("Stream --unused-- #%d (%x)\n", i, size); + dump_data(stream, size, " "); + free(stream); + } }
if (reader->read_stream == pdb_jg_read_stream) @@ -160,6 +163,11 @@ static void pdb_exit(struct pdb_reader* reader) } }
+/* forward declarations */ +static void pdb_dump_fpo(struct pdb_reader* reader, unsigned stream_idx); +static void pdb_dump_fpo_ext(struct pdb_reader* reader, unsigned stream_idx); +static void pdb_dump_sections(struct pdb_reader* reader, unsigned stream_idx); + static unsigned get_stream_by_name(struct pdb_reader* reader, const char* name) { DWORD* pdw; @@ -233,6 +241,7 @@ const char* pdb_get_string_table_entry(const PDB_STRING_TABLE* table, unsigned o
static void dump_dbi_hash_table(const BYTE* root, unsigned size, const char* name, const char* pfx) { + if (!globals_dump_sect("hash")) return; if (size >= sizeof(DBI_HASH_HEADER)) { const DBI_HASH_HEADER* hdr = (const DBI_HASH_HEADER*)root; @@ -312,6 +321,7 @@ static void dump_public_symbol(struct pdb_reader* reader, unsigned stream) unsigned size; DBI_PUBLIC_HEADER* hdr;
+ if (!globals_dump_sect("public")) return; hdr = reader->read_stream(reader, stream); if (!hdr) return;
@@ -410,77 +420,81 @@ static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMB return (const void*)((DWORD_PTR)(lib_name + strlen(lib_name) + 1 + 3) & ~3); }
-static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx) +static void pdb_dump_symbols(struct pdb_reader* reader) { PDB_SYMBOLS* symbols; unsigned char* modimage; const char* file; PDB_STRING_TABLE* filesimage; char tcver[32]; + PDB_STREAM_INDEXES sidx;
- sidx->FPO = sidx->unk0 = sidx->unk1 = sidx->unk2 = sidx->unk3 = sidx->sections_stream = - sidx->unk4 = sidx->unk5 = sidx->unk6 = sidx->FPO_EXT = sidx->unk7 = -1; + sidx.FPO = sidx.unk0 = sidx.unk1 = sidx.unk2 = sidx.unk3 = sidx.sections_stream = + sidx.unk4 = sidx.unk5 = sidx.unk6 = sidx.FPO_EXT = sidx.unk7 = -1;
symbols = reader->read_stream(reader, 3); if (!symbols) return;
- switch (symbols->version) + if (globals_dump_sect("DBI")) { - case 0: /* VC 4.0 */ - case 19960307: /* VC 5.0 */ - case 19970606: /* VC 6.0 */ - case 19990903: /* VC 7.0 */ - break; - default: - printf("-Unknown symbol info version %d\n", symbols->version); + switch (symbols->version) + { + case 0: /* VC 4.0 */ + case 19960307: /* VC 5.0 */ + case 19970606: /* VC 6.0 */ + case 19990903: /* VC 7.0 */ + break; + default: + printf("-Unknown symbol info version %d\n", symbols->version); + } + if (symbols->flags & 0x8000) /* new */ + sprintf(tcver, "%u.%u", (symbols->flags >> 8) & 0x7f, symbols->flags & 0xff); + else + sprintf(tcver, "old-%x", symbols->flags); + printf("Symbols:\n" + "\tsignature: %08x\n" + "\tversion: %u\n" + "\tage: %08x\n" + "\tglobal_hash_stream: %u\n" + "\tbuilder: %s\n" + "\tpublic_stream: %u\n" + "\tbldVer: %u\n" + "\tgsym_stream: %u\n" + "\trbldVer: %u\n" + "\tmodule_size: %08x\n" + "\tsectcontrib_size: %08x\n" + "\tsegmap_size: %08x\n" + "\tsrc_module_size: %08x\n" + "\tpdbimport_size: %08x\n" + "\tresvd0: %08x\n" + "\tstream_idx_size: %08x\n" + "\tunknown2_size: %08x\n" + "\tresvd3: %04x\n" + "\tmachine: %s\n" + "\tresvd4 %08x\n", + symbols->signature, + symbols->version, + symbols->age, + symbols->global_hash_stream, + tcver, /* from symbols->flags */ + symbols->public_stream, + symbols->bldVer, + symbols->gsym_stream, + symbols->rbldVer, + symbols->module_size, + symbols->sectcontrib_size, + symbols->segmap_size, + symbols->srcmodule_size, + symbols->pdbimport_size, + symbols->resvd0, + symbols->stream_index_size, + symbols->unknown2_size, + symbols->resvd3, + get_machine_str( symbols->machine ), + symbols->resvd4); } - if (symbols->flags & 0x8000) /* new */ - sprintf(tcver, "%u.%u", (symbols->flags >> 8) & 0x7f, symbols->flags & 0xff); - else - sprintf(tcver, "old-%x", symbols->flags); - printf("Symbols:\n" - "\tsignature: %08x\n" - "\tversion: %u\n" - "\tage: %08x\n" - "\tglobal_hash_stream: %u\n" - "\tbuilder: %s\n" - "\tpublic_stream: %u\n" - "\tbldVer: %u\n" - "\tgsym_stream: %u\n" - "\trbldVer: %u\n" - "\tmodule_size: %08x\n" - "\tsectcontrib_size: %08x\n" - "\tsegmap_size: %08x\n" - "\tsrc_module_size: %08x\n" - "\tpdbimport_size: %08x\n" - "\tresvd0: %08x\n" - "\tstream_idx_size: %08x\n" - "\tunknown2_size: %08x\n" - "\tresvd3: %04x\n" - "\tmachine: %s\n" - "\tresvd4 %08x\n", - symbols->signature, - symbols->version, - symbols->age, - symbols->global_hash_stream, - tcver, /* from symbols->flags */ - symbols->public_stream, - symbols->bldVer, - symbols->gsym_stream, - symbols->rbldVer, - symbols->module_size, - symbols->sectcontrib_size, - symbols->segmap_size, - symbols->srcmodule_size, - symbols->pdbimport_size, - symbols->resvd0, - symbols->stream_index_size, - symbols->unknown2_size, - symbols->resvd3, - get_machine_str( symbols->machine ), - symbols->resvd4); - - if (symbols->sectcontrib_size) + + if (symbols->sectcontrib_size && globals_dump_sect("image")) { const BYTE* src = (const BYTE*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size; const BYTE* last = src + symbols->sectcontrib_size; @@ -542,7 +556,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx
if (!(filesimage = read_string_table(reader))) printf("string table not found\n");
- if (symbols->srcmodule_size) + if (symbols->srcmodule_size && globals_dump_sect("DBI")) { const PDB_SYMBOL_SOURCE*src; int i, j, cfile; @@ -590,7 +604,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx } } } - if (symbols->pdbimport_size) + if (symbols->pdbimport_size && globals_dump_sect("PDB")) { const PDB_SYMBOL_IMPORT* imp; const char* first; @@ -623,7 +637,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx imp = (const PDB_SYMBOL_IMPORT*)(first + ((ptr - first + strlen(ptr) + 1 + 3) & ~3)); } } - if (symbols->segmap_size) + if (symbols->segmap_size && globals_dump_sect("image")) { const struct OMFSegMap* segmap = (const struct OMFSegMap*)((const BYTE*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size + symbols->sectcontrib_size); @@ -654,7 +668,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx printf("\t\t\tSize: %04x\n", desc->cbSeg); } } - if (symbols->stream_index_size) + if (symbols->stream_index_size && globals_dump_sect("image")) { printf("\t------------stream indexes--------------\n"); switch (symbols->stream_index_size) @@ -663,7 +677,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx /* PDB_STREAM_INDEXES is a superset of PDB_STREAM_INDEX_OLD * FIXME: to be confirmed when all fields are fully understood */ - memcpy(sidx, + memcpy(&sidx, (const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size + symbols->sectcontrib_size + symbols->segmap_size + symbols->srcmodule_size + symbols->pdbimport_size + symbols->unknown2_size, @@ -674,15 +688,15 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx "\t?: %04x\n" "\t?: %04x\n" "\tSections stream: %04x\n", - sidx->FPO, sidx->unk0, sidx->unk1, sidx->unk2, sidx->unk3, - sidx->sections_stream); + sidx.FPO, sidx.unk0, sidx.unk1, sidx.unk2, sidx.unk3, + sidx.sections_stream); break; case sizeof(PDB_STREAM_INDEXES): - memcpy(sidx, + memcpy(&sidx, (const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size + symbols->sectcontrib_size + symbols->segmap_size + symbols->srcmodule_size + symbols->pdbimport_size + symbols->unknown2_size, - sizeof(*sidx)); + sizeof(sidx)); printf("\tFPO: %04x\n" "\t?: %04x\n" "\t?: %04x\n" @@ -694,9 +708,9 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx "\t?: %04x\n" "\tFPO-ext: %04x\n" "\t?: %04x\n", - sidx->FPO, sidx->unk0, sidx->unk1, sidx->unk2, sidx->unk3, - sidx->sections_stream, sidx->unk4, sidx->unk5, sidx->unk6, sidx->FPO_EXT, - sidx->unk7); + sidx.FPO, sidx.unk0, sidx.unk1, sidx.unk2, sidx.unk3, + sidx.sections_stream, sidx.unk4, sidx.unk5, sidx.unk6, sidx.FPO_EXT, + sidx.unk7); break; default: printf("unexpected size for stream index %d\n", symbols->stream_index_size); @@ -706,15 +720,15 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx
/* Read global symbol table */ modimage = reader->read_stream(reader, symbols->gsym_stream); - if (modimage) + if (modimage && globals_dump_sect("DBI")) { - printf("\t------------globals-------------\n"); + printf("\t------------globals-------------\n"); codeview_dump_symbols(modimage, 0, pdb_get_stream_size(reader, symbols->gsym_stream)); free(modimage); }
/* Read per-module symbol / linenumber tables */ - if (symbols->module_size) + if (symbols->module_size && globals_dump_sect("DBI")) { SIZE_T module_header_size = symbols->version < 19970000 ? sizeof(PDB_SYMBOL_FILE) : sizeof(PDB_SYMBOL_FILE_EX);
@@ -754,6 +768,13 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx dump_global_symbol(reader, symbols->global_hash_stream); dump_public_symbol(reader, symbols->public_stream);
+ if (globals_dump_sect("image")) + { + pdb_dump_fpo(reader, sidx.FPO); + pdb_dump_fpo_ext(reader, sidx.FPO_EXT); + pdb_dump_sections(reader, sidx.sections_stream); + } + free(symbols); free(filesimage); } @@ -796,6 +817,8 @@ static void pdb_dump_types_hash(struct pdb_reader* reader, const PDB_TYPES* type const unsigned* table; PDB_STRING_TABLE* strbase; unsigned *collision; + + if (!globals_dump_sect("hash")) return; hash = reader->read_stream(reader, types->hash_stream); if (!hash) return;
@@ -914,6 +937,7 @@ 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);
+ if (!globals_dump_sect(strmidx == 2 ? "TPI" : "IPI")) return; if (pdb_get_stream_size(reader, strmidx) < sizeof(*types)) { if (strmidx == 2) @@ -1090,7 +1114,6 @@ static void pdb_jg_dump(void) { UINT *pdw, *ok_bits; UINT i, numok, count; - PDB_STREAM_INDEXES sidx;
printf("Root:\n" "\tVersion: %u\n" @@ -1146,9 +1169,7 @@ static void pdb_jg_dump(void) } pdb_dump_types(&reader, 2, "TPI"); pdb_dump_types(&reader, 4, "IPI"); - pdb_dump_symbols(&reader, &sidx); - pdb_dump_fpo(&reader, sidx.FPO); - pdb_dump_sections(&reader, sidx.sections_stream); + pdb_dump_symbols(&reader); } else printf("-Unable to get root\n");
@@ -1247,7 +1268,6 @@ static void pdb_ds_dump(void) { UINT *pdw, *ok_bits; UINT i, numok, count; - PDB_STREAM_INDEXES sidx;
printf("Root:\n" "\tVersion: %u\n" @@ -1293,10 +1313,7 @@ static void pdb_ds_dump(void)
pdb_dump_types(&reader, 2, "TPI"); pdb_dump_types(&reader, 4, "IPI"); - pdb_dump_symbols(&reader, &sidx); - pdb_dump_fpo(&reader, sidx.FPO); - pdb_dump_fpo_ext(&reader, sidx.FPO_EXT); - pdb_dump_sections(&reader, sidx.sections_stream); + pdb_dump_symbols(&reader); } else printf("-Unable to get root\n");
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- tools/winedump/pdb.c | 341 +++++++++++++++++++++++-------------------- 1 file changed, 185 insertions(+), 156 deletions(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 07b02057d78..0d690d1b0c0 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -103,14 +103,18 @@ static void* pdb_jg_read_stream(struct pdb_reader* reader, DWORD stream_nr) reader->u.jg.toc->streams[stream_nr].size); }
-static void pdb_jg_init(struct pdb_reader* reader) +static BOOL pdb_jg_init(struct pdb_reader* reader) { reader->u.jg.header = PRD(0, sizeof(struct PDB_JG_HEADER)); + if (!reader->u.jg.header) return FALSE; reader->read_stream = pdb_jg_read_stream; reader->u.jg.toc = pdb_jg_read(reader->u.jg.header, reader->u.jg.header->toc_block, reader->u.jg.header->toc.size); memset(reader->stream_used, 0, sizeof(reader->stream_used)); + reader->u.jg.root = reader->read_stream(reader, 1); + if (!reader->u.jg.root) return FALSE; + return TRUE; }
static DWORD pdb_get_num_streams(const struct pdb_reader* reader) @@ -1089,91 +1093,77 @@ static void pdb_dump_sections(struct pdb_reader* reader, unsigned stream_idx)
static const char pdb2[] = "Microsoft C/C++ program database 2.00";
-static void pdb_jg_dump(void) +static void pdb_jg_dump_header_root(struct pdb_reader* reader) { - struct pdb_reader reader; + UINT *pdw, *ok_bits; + UINT i, numok, count; + + if (!globals_dump_sect("PDB")) return;
- /* - * Read in TOC and well-known streams - */ - pdb_jg_init(&reader); printf("Header (JG):\n" "\tident: %.*s\n" "\tsignature: %08x\n" "\tblock_size: %08x\n" "\tfree_list_block: %04x\n" "\ttotal_alloc: %04x\n", - (int)sizeof(pdb2) - 1, reader.u.jg.header->ident, - reader.u.jg.header->signature, - reader.u.jg.header->block_size, - reader.u.jg.header->free_list_block, - reader.u.jg.header->total_alloc); - - reader.u.jg.root = reader.read_stream(&reader, 1); - if (reader.u.jg.root) - { - UINT *pdw, *ok_bits; - UINT i, numok, count; - - printf("Root:\n" - "\tVersion: %u\n" - "\tTimeDateStamp: %08x\n" - "\tAge: %08x\n" - "\tnames: %d\n", - reader.u.jg.root->Version, - reader.u.jg.root->TimeDateStamp, - reader.u.jg.root->Age, - (unsigned)reader.u.jg.root->cbNames); - - pdw = (UINT *)(reader.u.jg.root->names + reader.u.jg.root->cbNames); - numok = *pdw++; - count = *pdw++; - printf("\tStreams directory:\n" - "\t\tok: %08x\n" - "\t\tcount: %08x\n" - "\t\ttable:\n", - numok, count); - - /* bitfield: first dword is len (in dword), then data */ - ok_bits = pdw; - pdw += *ok_bits++ + 1; - if (*pdw++ != 0) - { - printf("unexpected value\n"); - return; - } + (int)sizeof(pdb2) - 1, reader->u.jg.header->ident, + reader->u.jg.header->signature, + reader->u.jg.header->block_size, + reader->u.jg.header->free_list_block, + reader->u.jg.header->total_alloc); + + printf("Root:\n" + "\tVersion: %u\n" + "\tTimeDateStamp: %08x\n" + "\tAge: %08x\n" + "\tnames: %d\n", + reader->u.jg.root->Version, + reader->u.jg.root->TimeDateStamp, + reader->u.jg.root->Age, + (unsigned)reader->u.jg.root->cbNames); + + pdw = (UINT *)(reader->u.jg.root->names + reader->u.jg.root->cbNames); + numok = *pdw++; + count = *pdw++; + printf("\tStreams directory:\n" + "\t\tok: %08x\n" + "\t\tcount: %08x\n" + "\t\ttable:\n", + numok, count);
- for (i = 0; i < count; i++) - { - if (ok_bits[i / 32] & (1 << (i % 32))) - { - UINT string_idx, stream_idx; - string_idx = *pdw++; - stream_idx = *pdw++; - printf("\t\t\t%2d) %-20s => %x\n", i, &reader.u.jg.root->names[string_idx], stream_idx); - numok--; - } - } - if (numok) printf(">>> unmatched present field with found\n"); + /* bitfield: first dword is len (in dword), then data */ + ok_bits = pdw; + pdw += *ok_bits++ + 1; + if (*pdw++ != 0) + { + printf("unexpected value\n"); + return; + }
- /* Check for unknown versions */ - switch (reader.u.jg.root->Version) + for (i = 0; i < count; i++) + { + if (ok_bits[i / 32] & (1 << (i % 32))) { - case 19950623: /* VC 4.0 */ - case 19950814: - case 19960307: /* VC 5.0 */ - case 19970604: /* VC 6.0 */ - break; - default: - printf("-Unknown root block version %d\n", reader.u.jg.root->Version); + UINT string_idx, stream_idx; + string_idx = *pdw++; + stream_idx = *pdw++; + printf("\t\t\t%2d) %-20s => %x\n", i, &reader->u.jg.root->names[string_idx], stream_idx); + numok--; } - pdb_dump_types(&reader, 2, "TPI"); - pdb_dump_types(&reader, 4, "IPI"); - pdb_dump_symbols(&reader); } - else printf("-Unable to get root\n"); + if (numok) printf(">>> unmatched present field with found\n");
- pdb_exit(&reader); + /* Check for unknown versions */ + switch (reader->u.jg.root->Version) + { + case 19950623: /* VC 4.0 */ + case 19950814: + case 19960307: /* VC 5.0 */ + case 19970604: /* VC 6.0 */ + break; + default: + printf("-Unknown root block version %d\n", reader->u.jg.root->Version); + } }
static void* pdb_ds_read(const struct PDB_DS_HEADER* header, const UINT *block_list, int size) @@ -1221,16 +1211,23 @@ static BOOL pdb_ds_init(struct pdb_reader* reader) (const UINT *)((const char*)reader->u.ds.header + reader->u.ds.header->toc_block * reader->u.ds.header->block_size), reader->u.ds.header->toc_size); memset(reader->stream_used, 0, sizeof(reader->stream_used)); + reader->u.ds.root = reader->read_stream(reader, 1); + if (!reader->u.ds.root) return FALSE; return TRUE; }
static const char pdb7[] = "Microsoft C/C++ MSF 7.00";
-static void pdb_ds_dump(void) +static void pdb_ds_dump_header_root(struct pdb_reader* reader) { - struct pdb_reader reader; + unsigned int i, j, ofs; + const UINT *block_list; + UINT *pdw, *ok_bits; + UINT numok, count; + unsigned strmsize;
- pdb_ds_init(&reader); + if (!globals_dump_sect("PDB")) return; + strmsize = pdb_get_stream_size(reader, 1); printf("Header (DS)\n" "\tsignature: %.*s\n" "\tblock_size: %08x\n" @@ -1239,85 +1236,98 @@ static void pdb_ds_dump(void) "\ttoc_size: %08x\n" "\tunknown2: %08x\n" "\ttoc_block: %08x\n", - (int)sizeof(pdb7) - 1, reader.u.ds.header->signature, - reader.u.ds.header->block_size, - reader.u.ds.header->free_list_block, - reader.u.ds.header->num_blocks, - reader.u.ds.header->toc_size, - reader.u.ds.header->unknown2, - reader.u.ds.header->toc_block); - - /* streams with static indexes: - * 0: JG says old toc blocks - * 1: root structure - * 2: types - * 3: modules - * 4: types (second stream) - * other known streams: - * - string table: its index is in the stream table from ROOT object under "/names" - * - type hash table: its index is in the types header (2 and 4) - * - global and public streams: from symbol stream header - * those streams get their indexes out of the PDB_STREAM_INDEXES object - * - FPO data - * - sections - * - extended FPO data - */ - mark_stream_been_read(&reader, 0); /* mark stream #0 as read */ - reader.u.ds.root = reader.read_stream(&reader, 1); - if (reader.u.ds.root) + (int)sizeof(pdb7) - 1, reader->u.ds.header->signature, + reader->u.ds.header->block_size, + reader->u.ds.header->free_list_block, + reader->u.ds.header->num_blocks, + reader->u.ds.header->toc_size, + reader->u.ds.header->unknown2, + reader->u.ds.header->toc_block); + + block_list = reader->u.ds.toc->stream_size + reader->u.ds.toc->num_streams; + printf("\t\tnum_streams: %u\n", reader->u.ds.toc->num_streams); + for (ofs = i = 0; i < reader->u.ds.toc->num_streams; i++) { - UINT *pdw, *ok_bits; - UINT i, numok, count; - - printf("Root:\n" - "\tVersion: %u\n" - "\tTimeDateStamp: %08x\n" - "\tAge: %08x\n" - "\tguid %s\n" - "\tcbNames: %08x\n", - reader.u.ds.root->Version, - reader.u.ds.root->TimeDateStamp, - reader.u.ds.root->Age, - get_guid_str(&reader.u.ds.root->guid), - reader.u.ds.root->cbNames); - pdw = (UINT *)(reader.u.ds.root->names + reader.u.ds.root->cbNames); - numok = *pdw++; - count = *pdw++; - printf("\tStreams directory:\n" - "\t\tok: %08x\n" - "\t\tcount: %08x\n" - "\t\ttable:\n", - numok, count); - - /* bitfield: first dword is len (in dword), then data */ - ok_bits = pdw; - pdw += *ok_bits++ + 1; - if (*pdw++ != 0) + unsigned int nblk = (reader->u.ds.toc->stream_size[i] + reader->u.ds.header->block_size - 1) / reader->u.ds.header->block_size; + printf("\t\tstream[%#x]:\tsize: %u\n", i, reader->u.ds.toc->stream_size[i]); + if (nblk) { - printf("unexpected value\n"); - return; + for (j = 0; j < nblk; j++) + { + if (j % 16 == 0) printf("\t\t\t"); + printf("%4x ", block_list[ofs + j]); + if (j % 16 == 15 || (j + 1 == nblk)) printf("\n"); + } + ofs += nblk; + } + } + + printf("Root:\n" + "\tVersion: %u\n" + "\tTimeDateStamp: %08x\n" + "\tAge: %08x\n" + "\tguid %s\n" + "\tcbNames: %08x\n", + reader->u.ds.root->Version, + reader->u.ds.root->TimeDateStamp, + reader->u.ds.root->Age, + get_guid_str(&reader->u.ds.root->guid), + reader->u.ds.root->cbNames); + pdw = (UINT *)(reader->u.ds.root->names + reader->u.ds.root->cbNames); + numok = *pdw++; + count = *pdw++; + printf("\tStreams directory:\n" + "\t\tok: %08x\n" + "\t\tcount: %08x\n" + "\t\ttable:\n", + numok, count); + + /* bitfield: first dword is len (in dword), then data */ + ok_bits = pdw; + pdw += *ok_bits++ + 1; + if (*pdw++ != 0) + { + printf("unexpected value\n"); + return; + } + + for (i = 0; i < count; i++) + { + if (ok_bits[i / 32] & (1 << (i % 32))) + { + UINT string_idx, stream_idx; + string_idx = *pdw++; + stream_idx = *pdw++; + printf("\t\t\t%2d) %-20s => %x\n", i, &reader->u.ds.root->names[string_idx], stream_idx); + numok--; } + } + if (numok) printf(">>> unmatched present field with found\n"); + if (*pdw++ != 0) + { + printf("unexpected value\n"); + return; + }
- for (i = 0; i < count; i++) + if (pdw + 1 <= (UINT*)((char*)reader->u.ds.root + strmsize)) + { + /* extra information (version reference and features) */ + printf("\tVersion and features\n"); + while (pdw + 1 <= (UINT*)((char*)reader->u.ds.root + strmsize)) { - if (ok_bits[i / 32] & (1 << (i % 32))) + switch (*pdw) { - UINT string_idx, stream_idx; - string_idx = *pdw++; - stream_idx = *pdw++; - printf("\t\t\t%2d) %-20s => %x\n", i, &reader.u.ds.root->names[string_idx], stream_idx); - numok--; + /* version reference */ + case 20091201: printf("\t\tVC110\n"); break; + case 20140508: printf("\t\tVC140\n"); break; + /* features */ + case 0x4D544F4E /* NOTM */: printf("\t\tNo type merge\n"); break; + case 0x494E494D /* MINI */: printf("\t\tMinimal debug info\n"); break; + default: printf("\t\tUnknown value %x\n", *pdw); } + pdw++; } - if (numok) printf(">>> unmatched present field with found\n"); - - pdb_dump_types(&reader, 2, "TPI"); - pdb_dump_types(&reader, 4, "IPI"); - pdb_dump_symbols(&reader); } - else printf("-Unable to get root\n"); - - pdb_exit(&reader); }
enum FileSig get_kind_pdb(void) @@ -1335,20 +1345,39 @@ enum FileSig get_kind_pdb(void)
void pdb_dump(void) { - const char* head; + const BYTE* head; + const char** saved_dumpsect = globals.dumpsect; + static const char* default_dumpsect[] = {"DBI", "TPI", "IPI", NULL}; + struct pdb_reader reader;
-/* init_types(); */ - head = PRD(0, sizeof(pdb2) - 1); - if (head && !memcmp(head, pdb2, sizeof(pdb2) - 1)) + if (!globals.dumpsect) globals.dumpsect = default_dumpsect; + + if ((head = PRD(0, sizeof(pdb2) - 1)) && !memcmp(head, pdb2, sizeof(pdb2) - 1)) { - pdb_jg_dump(); - return; + if (!pdb_jg_init(&reader)) + { + printf("Unable to get header information\n"); + return; + } + + pdb_jg_dump_header_root(&reader); } - head = PRD(0, sizeof(pdb7) - 1); - if (head && !memcmp(head, pdb7, sizeof(pdb7) - 1)) + else if ((head = PRD(0, sizeof(pdb7) - 1)) && !memcmp(head, pdb7, sizeof(pdb7) - 1)) { - pdb_ds_dump(); - return; + if (!pdb_ds_init(&reader)) + { + printf("Unable to get header information\n"); + return; + } + pdb_ds_dump_header_root(&reader); } - printf("Unrecognized header %s\n", head); + mark_stream_been_read(&reader, 0); /* mark stream #0 (old TOC) as read */ + + pdb_dump_types(&reader, 2, "TPI"); + pdb_dump_types(&reader, 4, "IPI"); + pdb_dump_symbols(&reader); + + pdb_exit(&reader); + + globals.dumpsect = saved_dumpsect; }
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- tools/winedump/pdb.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 0d690d1b0c0..8a1787dd7f7 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -49,6 +49,7 @@ struct pdb_reader } u; void* (*read_stream)(struct pdb_reader*, DWORD); DWORD stream_used[1024]; + PDB_STRING_TABLE* global_string_table; };
static inline BOOL has_stream_been_read(struct pdb_reader* reader, unsigned stream_nr) @@ -154,7 +155,7 @@ static void pdb_exit(struct pdb_reader* reader) free(stream); } } - + free(reader->global_string_table); if (reader->read_stream == pdb_jg_read_stream) { free((char*)reader->u.jg.root); @@ -346,7 +347,7 @@ static void dump_public_symbol(struct pdb_reader* reader, unsigned stream) }
static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMBOL_FILE_EX* sym_file, - const char* file_name, PDB_STRING_TABLE* filesimage) + const char* file_name) { const char* lib_name; unsigned char* modimage; @@ -414,7 +415,7 @@ static const void* pdb_dump_dbi_module(struct pdb_reader* reader, const PDB_SYMB codeview_dump_linetab((const char*)modimage + sym_file->symbol_size, TRUE, " "); else if (sym_file->lineno2_size) /* actually, only one of the 2 lineno should be present */ codeview_dump_linetab2((const char*)modimage + sym_file->symbol_size, sym_file->lineno2_size, - filesimage, " "); + reader->global_string_table, " "); /* what's that part ??? */ if (0) dump_data(modimage + sym_file->symbol_size + sym_file->lineno_size + sym_file->lineno2_size, @@ -429,7 +430,6 @@ static void pdb_dump_symbols(struct pdb_reader* reader) PDB_SYMBOLS* symbols; unsigned char* modimage; const char* file; - PDB_STRING_TABLE* filesimage; char tcver[32]; PDB_STREAM_INDEXES sidx;
@@ -558,8 +558,6 @@ static void pdb_dump_symbols(struct pdb_reader* reader) } }
- if (!(filesimage = read_string_table(reader))) printf("string table not found\n"); - if (symbols->srcmodule_size && globals_dump_sect("DBI")) { const PDB_SYMBOL_SOURCE*src; @@ -666,8 +664,8 @@ static void pdb_dump_symbols(struct pdb_reader* reader) printf("\t\t\tOverlay: %04x\n", desc->ovl); printf("\t\t\tGroup: %04x\n", desc->group); printf("\t\t\tFrame: %04x\n", desc->frame); - printf("\t\t\tSegment name: %s\n", desc->iSegName == 0xffff ? "none" : pdb_get_string_table_entry(filesimage, desc->iSegName)); - printf("\t\t\tClass name: %s\n", desc->iClassName == 0xffff ? "none" : pdb_get_string_table_entry(filesimage, desc->iClassName)); + printf("\t\t\tSegment name: %s\n", desc->iSegName == 0xffff ? "none" : pdb_get_string_table_entry(reader->global_string_table, desc->iSegName)); + printf("\t\t\tClass name: %s\n", desc->iClassName == 0xffff ? "none" : pdb_get_string_table_entry(reader->global_string_table, desc->iClassName)); printf("\t\t\tOffset: %08x\n", desc->offset); printf("\t\t\tSize: %04x\n", desc->cbSeg); } @@ -763,10 +761,10 @@ 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, filesimage); + file = pdb_dump_dbi_module(reader, ©, sym_file->filename); } else - file = pdb_dump_dbi_module(reader, (const PDB_SYMBOL_FILE_EX*)file, NULL, filesimage); + file = pdb_dump_dbi_module(reader, (const PDB_SYMBOL_FILE_EX*)file, NULL); } } dump_global_symbol(reader, symbols->global_hash_stream); @@ -780,7 +778,6 @@ static void pdb_dump_symbols(struct pdb_reader* reader) }
free(symbols); - free(filesimage); }
static BOOL is_bit_set(const unsigned* dw, unsigned len, unsigned i) @@ -819,7 +816,6 @@ static void pdb_dump_types_hash(struct pdb_reader* reader, const PDB_TYPES* type void* hash = NULL; unsigned i, strmsize; const unsigned* table; - PDB_STRING_TABLE* strbase; unsigned *collision;
if (!globals_dump_sect("hash")) return; @@ -887,7 +883,8 @@ static void pdb_dump_types_hash(struct pdb_reader* reader, const PDB_TYPES* type { printf("\t\t%08x => %08x\n", table[2 * i + 0], table[2 * i + 1]); } - if (types->type_remap_size && (strbase = read_string_table(reader))) + + if (types->type_remap_size) { unsigned num, capa, count_present, count_deleted; const unsigned* present_bitset; @@ -923,13 +920,12 @@ static void pdb_dump_types_hash(struct pdb_reader* reader, const PDB_TYPES* type is_bit_set(deleted_bitset, count_deleted, i) ? 'D' : '_'); if (is_bit_set(present_bitset, count_present, i)) { - printf(" %s => ", pdb_get_string_table_entry(strbase, *table++)); + printf(" %s => ", pdb_get_string_table_entry(reader->global_string_table, *table++)); pdb_dump_hash_value((const BYTE*)table, types->hash_value_size); table = (const unsigned*)((const BYTE*)table + types->hash_value_size); } printf("\n"); } - free(strbase); printf("\n"); } free(hash); @@ -1034,11 +1030,8 @@ static void pdb_dump_fpo_ext(struct pdb_reader* reader, unsigned stream_idx) { PDB_FPO_DATA* fpoext; unsigned i, size; - PDB_STRING_TABLE* strbase;
if (stream_idx == (WORD)-1) return; - strbase = read_string_table(reader); - if (!strbase) return;
fpoext = reader->read_stream(reader, stream_idx); size = pdb_get_stream_size(reader, stream_idx); @@ -1052,11 +1045,10 @@ static void pdb_dump_fpo_ext(struct pdb_reader* reader, unsigned stream_idx) printf("\t%08x %08x %8x %8x %8x %6x %8x %08x %s\n", fpoext[i].start, fpoext[i].func_size, fpoext[i].locals_size, fpoext[i].params_size, fpoext[i].maxstack_size, fpoext[i].prolog_size, fpoext[i].savedregs_size, fpoext[i].flags, - pdb_get_string_table_entry(strbase, fpoext[i].str_offset)); + pdb_get_string_table_entry(reader->global_string_table, fpoext[i].str_offset)); } } free(fpoext); - free(strbase); }
static void pdb_dump_sections(struct pdb_reader* reader, unsigned stream_idx) @@ -1373,6 +1365,8 @@ void pdb_dump(void) } mark_stream_been_read(&reader, 0); /* mark stream #0 (old TOC) as read */
+ reader.global_string_table = read_string_table(&reader); + pdb_dump_types(&reader, 2, "TPI"); pdb_dump_types(&reader, 4, "IPI"); pdb_dump_symbols(&reader);
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- tools/winedump/pdb.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 8a1787dd7f7..f57f52e73ae 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -218,6 +218,46 @@ static unsigned get_stream_by_name(struct pdb_reader* reader, const char* name) return -1; }
+static void dump_string_table(const PDB_STRING_TABLE* strtable, const char* name, const char* pfx) +{ + const char* end; + const char* ptr; + unsigned* table; + unsigned num_buckets; + unsigned i; + + if (!strtable) + { + printf("%sString table (%s) isn't present\n", pfx, name); + return; + } + printf("%sString table (%s)\n" + "%s\tHeader: %08x\n" + "%s\tLength: %08x\n" + "%s\tHash version: %u\n", + pfx, name, pfx, strtable->magic, pfx, strtable->length, pfx, strtable->hash_version); + ptr = (const char*)(strtable + 1); + end = ptr + strtable->length; + while (ptr < end) + { + printf("%s\t%zu] %s\n", pfx, ptr - (const char*)(strtable + 1), ptr); + ptr += strlen(ptr) + 1; + } + table = (unsigned *)((char*)(strtable + 1) + strtable->length); + num_buckets = *table++; + + if (globals_dump_sect("hash")) + { + printf("%s\tHash:\n" + "%s\t\tnum_strings: %x\n" + "%s\t\tnum_buckets: %x\n", + pfx, pfx, table[num_buckets], pfx, num_buckets); + + for (i = 0; i < num_buckets; i++) + printf("%s\t\t%x] %x\n", pfx, i, table[i]); + } +} + static PDB_STRING_TABLE* read_string_table(struct pdb_reader* reader) { unsigned stream_idx; @@ -229,6 +269,7 @@ static PDB_STRING_TABLE* read_string_table(struct pdb_reader* reader) ret = reader->read_stream(reader, stream_idx); if (!ret) return NULL; stream_size = pdb_get_stream_size(reader, stream_idx); + if (globals_dump_sect("PDB")) dump_string_table(ret, "Global", " "); if (ret->magic == 0xeffeeffe && sizeof(*ret) + ret->length < stream_size) return ret; printf("Improper string table header (magic=%x)\n", ret->magic); dump_data((const unsigned char*)ret, stream_size, " "); @@ -670,6 +711,14 @@ static void pdb_dump_symbols(struct pdb_reader* reader) printf("\t\t\tSize: %04x\n", desc->cbSeg); } } + if (symbols->unknown2_size && globals_dump_sect("PDB")) + { + const char* ptr = (const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size + + symbols->sectcontrib_size + symbols->segmap_size + symbols->srcmodule_size + + symbols->pdbimport_size; + printf("\t------------Unknown2--------------\n"); + dump_string_table((const PDB_STRING_TABLE*)ptr, "Unknown from DBI", "\t"); + } if (symbols->stream_index_size && globals_dump_sect("image")) { printf("\t------------stream indexes--------------\n");
From: Eric Pouech eric.pouech@gmail.com
Especially, thunk related information.
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- include/wine/mscvpdb.h | 4 ++-- tools/winedump/pdb.c | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 19fcab33ab9..29dd83e73b9 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -2656,11 +2656,11 @@ typedef struct unsigned hash_size; unsigned address_map_size; unsigned num_thunks; - unsigned size_thunk; + unsigned thunk_size; unsigned short section_thunk_table; unsigned short _pad0; unsigned offset_thunk_table; - unsigned num_sects; + unsigned num_sections; } DBI_PUBLIC_HEADER;
#include "poppack.h" diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index f57f52e73ae..c76c19fec89 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -366,6 +366,8 @@ static void dump_public_symbol(struct pdb_reader* reader, unsigned stream) { unsigned size; DBI_PUBLIC_HEADER* hdr; + const BYTE* ptr; + unsigned i;
if (!globals_dump_sect("public")) return; hdr = reader->read_stream(reader, stream); @@ -378,12 +380,31 @@ static void dump_public_symbol(struct pdb_reader* reader, unsigned stream) printf("\tHash size: %u\n", hdr->hash_size); printf("\tAddress map size: %u\n", hdr->address_map_size); printf("\tNumber of thunks: %u\n", hdr->num_thunks); - printf("\tSize of thunk: %u\n", hdr->size_thunk); + printf("\tSize of thunk map: %u\n", hdr->thunk_size); printf("\tSection of thunk table: %u\n", hdr->section_thunk_table); printf("\tOffset of thunk table: %u\n", hdr->offset_thunk_table); - printf("\tNumber of sections: %u\n", hdr->num_sects); + printf("\tNumber of sections: %u\n", hdr->num_sections);
- dump_dbi_hash_table((const BYTE*)(hdr + 1), hdr->hash_size, "Public", "\t"); + ptr = (const BYTE*)(hdr + 1); + dump_dbi_hash_table(ptr, hdr->hash_size, "Public", "\t"); + + ptr += hdr->hash_size; + printf("\tAddress map:\n"); + for (i = 0; i < hdr->address_map_size / sizeof(unsigned); i++) + printf("\t\t%u] %08x\n", i, ((const unsigned*)ptr)[i]); + + ptr += hdr->address_map_size; + printf("\tThunk map:\n"); + for (i = 0; i < hdr->num_thunks; i++) + printf("\t\t%u] %08x\n", i, ((const unsigned*)ptr)[i]); + + ptr += hdr->num_thunks * sizeof(unsigned); + printf("\tSection map:\n"); + for (i = 0; i < hdr->num_sections; i++) + printf("\t\t%u] %04x:%08x\n", i, (unsigned short)((const unsigned*)ptr)[2 * i + 1], ((const unsigned*)ptr)[2 * i + 0]); + + if (ptr + hdr->num_sections * 8 != ((const BYTE*)hdr) + size) + printf("Incorrect stream\n"); free(hdr); }