This series contain fixes for winedump for debug information: - it fixes a bunch of incorrect information dumping, - it fixes a case of crash for .DBG files, - it allows dumping very large PDB files (>4G)
Note: for the later item, current tools' read_file() doesn't work with such large files. Instead of fixing read_file(), I opted for letting a dumper for a given file format to only use a fd to the target file, instead of forcing all dumpers to work from a full in-memory image of the target file. This is useful for PDB files, as their underlying storage requires to reassemble non-contiguous blocks, so this saves memory (the in-memory image of the target file) and one copy of the whole file. This means that all functions to guess the file format now uses a fd instead of the full image.
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/pe.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c index 1a813c38db5..96830fd5d3b 100644 --- a/tools/winedump/pe.c +++ b/tools/winedump/pe.c @@ -2617,7 +2617,7 @@ static void dump_dir_delay_imported_functions(void) printf("\n"); }
-static void dump_dir_debug_dir(const IMAGE_DEBUG_DIRECTORY* idd, int idx) +static void dump_dir_debug_dir(const IMAGE_DEBUG_DIRECTORY* idd, int idx, const IMAGE_SECTION_HEADER *first_section) { const char* str;
@@ -2657,8 +2657,7 @@ static void dump_dir_debug_dir(const IMAGE_DEBUG_DIRECTORY* idd, int idx) case IMAGE_DEBUG_TYPE_UNKNOWN: break; case IMAGE_DEBUG_TYPE_COFF: - dump_coff(idd->PointerToRawData, idd->SizeOfData, - IMAGE_FIRST_SECTION(PE_nt_headers)); + dump_coff(idd->PointerToRawData, idd->SizeOfData, first_section); break; case IMAGE_DEBUG_TYPE_CODEVIEW: dump_codeview(idd->PointerToRawData, idd->SizeOfData); @@ -2735,7 +2734,7 @@ static void dump_dir_debug(void)
for (i = 0; i < nb_dbg; i++) { - dump_dir_debug_dir(debugDir, i); + dump_dir_debug_dir(debugDir, i, IMAGE_FIRST_SECTION(PE_nt_headers)); debugDir++; } printf("\n"); @@ -4185,7 +4184,7 @@ void dbg_dump(void)
for (i = 0; i < nb_dbg; i++) { - dump_dir_debug_dir(debugDir, i); + dump_dir_debug_dir(debugDir, i, (const IMAGE_SECTION_HEADER*)(separateDebugHead + 1)); debugDir++; } }
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/msc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 997daab501b..7c61ba128a4 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -79,7 +79,7 @@ static int full_numeric_leaf(struct full_value *fv, const unsigned char *leaf)
case LF_USHORT: length += 2; - fv->v.i = *leaf; + fv->v.i = *(const unsigned short*)leaf; break;
case LF_LONG: @@ -676,21 +676,21 @@ static void do_field(const unsigned char* start, const unsigned char* end) printf("\t\tFriend function V1: '%s' type:%x\n", p_string(&fieldtype->friendfcn_v1.p_name), fieldtype->friendfcn_v1.type); - ptr += 2 + 2 + (1 + fieldtype->stmember_v2.p_name.namelen); + ptr += 2 + 2 + (1 + fieldtype->friendfcn_v1.p_name.namelen); break;
case LF_FRIENDFCN_V2: printf("\t\tFriend function V2: '%s' type:%x\n", p_string(&fieldtype->friendfcn_v2.p_name), fieldtype->friendfcn_v2.type); - ptr += 2 + 2 + 4 + (1 + fieldtype->stmember_v2.p_name.namelen); + ptr += 2 + 2 + 4 + (1 + fieldtype->friendfcn_v2.p_name.namelen); break;
case LF_FRIENDFCN_V3: printf("\t\tFriend function V3: '%s' type:%x\n", fieldtype->friendfcn_v3.name, fieldtype->friendfcn_v3.type); - ptr += 2 + 2 + 4 + (strlen(fieldtype->stmember_v3.name) + 1); + ptr += 2 + 2 + 4 + (strlen(fieldtype->friendfcn_v3.name) + 1); break;
case LF_BCLASS_V1: @@ -713,7 +713,7 @@ static void do_field(const unsigned char* start, const unsigned char* end) case LF_IVBCLASS_V1: leaf_len = numeric_leaf(&value, fieldtype->vbclass_v1.data); printf("\t\t%sirtual base class V1: type:%x (ptr:%x) attr:%s vbpoff:%d ", - (fieldtype->generic.id == LF_VBCLASS_V2) ? "V" : "Indirect v", + (fieldtype->generic.id == LF_VBCLASS_V1) ? "V" : "Indirect v", fieldtype->vbclass_v1.btype, fieldtype->vbclass_v1.vbtype, get_attr(fieldtype->vbclass_v1.attribute), value); ptr += 2 + 2 + 2 + 2 + leaf_len; @@ -724,7 +724,7 @@ static void do_field(const unsigned char* start, const unsigned char* end)
case LF_VBCLASS_V2: case LF_IVBCLASS_V2: - leaf_len = numeric_leaf(&value, fieldtype->vbclass_v1.data); + leaf_len = numeric_leaf(&value, fieldtype->vbclass_v2.data); printf("\t\t%sirtual base class V2: type:%x (ptr:%x) attr:%s vbpoff:%d ", (fieldtype->generic.id == LF_VBCLASS_V2) ? "V" : "Indirect v", fieldtype->vbclass_v2.btype, fieldtype->vbclass_v2.vbtype, @@ -902,7 +902,7 @@ static void codeview_dump_one_type(unsigned curr_type, const union codeview_type str, type->struct_v3.n_element, get_property(type->struct_v3.property), type->struct_v3.fieldlist, type->struct_v3.derived, type->struct_v3.vshape, value); - if (type->union_v3.property.has_decorated_name) + if (type->struct_v3.property.has_decorated_name) printf("\t\tDecorated name:%s\n", str + strlen(str) + 1); break;
@@ -958,7 +958,7 @@ static void codeview_dump_one_type(unsigned curr_type, const union codeview_type type->enumeration_v3.fieldlist, type->enumeration_v3.count, get_property(type->enumeration_v3.property)); - if (type->union_v3.property.has_decorated_name) + if (type->enumeration_v3.property.has_decorated_name) printf("\t\tDecorated name:%s\n", type->enumeration_v3.name + strlen(type->enumeration_v3.name) + 1); break;
@@ -990,7 +990,7 @@ static void codeview_dump_one_type(unsigned curr_type, const union codeview_type case LF_PROCEDURE_V2: printf("\t%x => Procedure V2 ret_type:%x callconv:%s attr:%s (#%u args_type:%x)\n", curr_type, type->procedure_v2.rvtype, - get_callconv(type->procedure_v2.callconv), get_funcattr(type->procedure_v1.funcattr), + get_callconv(type->procedure_v2.callconv), get_funcattr(type->procedure_v2.funcattr), type->procedure_v2.params, type->procedure_v2.arglist); break;
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/pdb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index dc59695a826..4f25428d58f 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -579,10 +579,9 @@ static void pdb_dump_symbols(struct pdb_reader* reader) (symbols->sectcontrib_size - sizeof(unsigned)) / size, size, (symbols->sectcontrib_size - sizeof(unsigned)) % size); - src += sizeof(unsigned); - while (src + size <= last) + for (src += sizeof(unsigned); src + size <= last; src += size) { - range = (const PDB_SYMBOL_RANGE_EX*)(src + sizeof(unsigned)); + range = (const PDB_SYMBOL_RANGE_EX*)src; printf("\tRange #%tu\n", ((const BYTE*)range - ((const BYTE*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size)) / size); printf("\t\tsegment: %04x\n" @@ -607,7 +606,6 @@ static void pdb_dump_symbols(struct pdb_reader* reader) range->unknown); if (version == 0xeffe0000 + 20140516) printf("\t\tcoff_section: %08x\n", *(unsigned*)(range + 1)); - src += size; } } }
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/pdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 4f25428d58f..718356ed207 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -911,7 +911,7 @@ static void pdb_dump_types_hash(struct pdb_reader* reader, const PDB_TYPES* type } printf("\n\tIndexes => offsets:\n"); table = (const unsigned*)((const BYTE*)hash + types->search_offset); - for (i = 0; i < types->search_size / (2 * sizeof(unsigned)); i += 2) + for (i = 0; i < types->search_size / (2 * sizeof(unsigned)); i++) { printf("\t\t%08x => %08x\n", table[2 * i + 0], table[2 * i + 1]); }
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/dump.c | 30 +++++++++++++++++++++++------- tools/winedump/emf.c | 8 ++++---- tools/winedump/emfspool.c | 8 ++++---- tools/winedump/font.c | 10 ++++++---- tools/winedump/lib.c | 8 +++++--- tools/winedump/lnk.c | 10 +++++----- tools/winedump/mf.c | 12 ++++++------ tools/winedump/minidump.c | 10 ++++------ tools/winedump/nls.c | 2 +- tools/winedump/pdb.c | 12 +++++------- tools/winedump/pe.c | 39 +++++++++++++++------------------------ tools/winedump/reg.c | 9 +++++---- tools/winedump/tlb.c | 9 ++++++--- tools/winedump/winedump.h | 26 +++++++++++++------------- 14 files changed, 102 insertions(+), 91 deletions(-)
diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c index fb8e248729f..39007603cc4 100644 --- a/tools/winedump/dump.c +++ b/tools/winedump/dump.c @@ -222,7 +222,7 @@ unsigned long Offset(const void* ptr) static const struct dumper { enum FileSig kind; - enum FileSig (*get_kind)(void); + enum FileSig (*get_kind)( int fd ); file_dumper dumper; /* default dump tool */ } dumpers[] = @@ -248,22 +248,36 @@ dumpers[] =
BOOL dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig) { - BOOL ret = TRUE; + int fd; + struct stat st; + BOOL ret = TRUE; const struct dumper *dpr;
setbuf(stdout, NULL);
- if (!(dump_base = read_file( name, &dump_total_len ))) fatal( "Cannot read file" ); + if ((fd = open( name, O_RDONLY | O_BINARY )) == -1 || + fstat( fd, &st ) == -1) + { + fatal( "Cannot open file\n"); + return FALSE; + }
- printf("Contents of %s: %zu bytes\n\n", name, dump_total_len); + printf("Contents of %s: %lu bytes\n\n", name, (unsigned long)st.st_size);
for (dpr = dumpers; dpr->kind != SIG_UNKNOWN; dpr++) { - if (dpr->get_kind() == dpr->kind && + enum FileSig kind = dpr->get_kind( fd ); + lseek( fd, 0, SEEK_SET ); + if (kind == dpr->kind && (wanted_sig == SIG_UNKNOWN || wanted_sig == dpr->kind)) { - if (fn) fn(); else dpr->dumper(); - break; + dump_base = xmalloc( st.st_size ); + if (read( fd, dump_base, st.st_size ) == st.st_size) + { + dump_total_len = st.st_size; + if (fn) fn(); else dpr->dumper(); + break; + } } } if (dpr->kind == SIG_UNKNOWN) @@ -274,6 +288,8 @@ BOOL dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
if (ret) printf("Done dumping %s\n", name); free( dump_base ); + dump_base = NULL; + close( fd );
return ret; } diff --git a/tools/winedump/emf.c b/tools/winedump/emf.c index 253e7c658c2..bb6b7804f04 100644 --- a/tools/winedump/emf.c +++ b/tools/winedump/emf.c @@ -494,12 +494,12 @@ unsigned long dump_emfrecord(const char *pfx, unsigned long offset) return offset; }
-enum FileSig get_kind_emf(void) +enum FileSig get_kind_emf(int fd) { - const ENHMETAHEADER* hdr; + ENHMETAHEADER hdr;
- hdr = PRD(0, sizeof(*hdr)); - if (hdr && hdr->iType == EMR_HEADER && hdr->dSignature == ENHMETA_SIGNATURE) + if (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr) && + hdr.iType == EMR_HEADER && hdr.dSignature == ENHMETA_SIGNATURE) return SIG_EMF; return SIG_UNKNOWN; } diff --git a/tools/winedump/emfspool.c b/tools/winedump/emfspool.c index d0c90b2236b..f4b44700229 100644 --- a/tools/winedump/emfspool.c +++ b/tools/winedump/emfspool.c @@ -164,12 +164,12 @@ static unsigned long dump_emfspool_record(unsigned long off) return off + sizeof(*hdr) + hdr->cjSize; }
-enum FileSig get_kind_emfspool(void) +enum FileSig get_kind_emfspool(int fd) { - const header *hdr; + header hdr;
- hdr = PRD(0, sizeof(*hdr)); - if (hdr && hdr->dwVersion == EMFSPOOL_VERSION) + if (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr) && + hdr.dwVersion == EMFSPOOL_VERSION) return SIG_EMFSPOOL; return SIG_UNKNOWN; } diff --git a/tools/winedump/font.c b/tools/winedump/font.c index ca4065340c3..9d69e3a94c8 100644 --- a/tools/winedump/font.c +++ b/tools/winedump/font.c @@ -81,11 +81,13 @@ typedef struct
/* FIXME: recognize and dump also NE/PE wrapped fonts */
-enum FileSig get_kind_fnt(void) +enum FileSig get_kind_fnt(int fd) { - const WINFNT *fnt = PRD(0, sizeof(WINFNT)); - if (fnt && (fnt->dfVersion == 0x200 || fnt->dfVersion == 0x300) && - PRD(0, fnt->dfSize) != NULL) + WINFNT fnt; + + if (read(fd, &fnt, sizeof(fnt)) == sizeof(fnt) && + (fnt.dfVersion == 0x200 || fnt.dfVersion == 0x300) && + fnt.dfSize <= lseek(fd, 0, SEEK_END)) return SIG_FNT; return SIG_UNKNOWN; } diff --git a/tools/winedump/lib.c b/tools/winedump/lib.c index 0b94adb9b33..f40cd879dbd 100644 --- a/tools/winedump/lib.c +++ b/tools/winedump/lib.c @@ -130,10 +130,12 @@ static void dump_long_import(const void *base, const IMAGE_SECTION_HEADER *ish, } }
-enum FileSig get_kind_lib(void) +enum FileSig get_kind_lib( int fd ) { - const char* arch = PRD(0, IMAGE_ARCHIVE_START_SIZE); - if (arch && !strncmp(arch, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE)) + char tmp[IMAGE_ARCHIVE_START_SIZE]; + + if (read( fd, tmp, sizeof(tmp) ) == sizeof(tmp) && + !strncmp( tmp, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE )) return SIG_COFFLIB; return SIG_UNKNOWN; } diff --git a/tools/winedump/lnk.c b/tools/winedump/lnk.c index 194b6b40403..5427eec3f49 100644 --- a/tools/winedump/lnk.c +++ b/tools/winedump/lnk.c @@ -514,13 +514,13 @@ static void dump_raw_block(const DATABLOCK_HEADER* bhdr)
static const GUID CLSID_ShellLink = {0x00021401L, 0, 0, {0xC0,0,0,0,0,0,0,0x46}};
-enum FileSig get_kind_lnk(void) +enum FileSig get_kind_lnk( int fd ) { - const LINK_HEADER* hdr; + LINK_HEADER hdr;
- hdr = PRD(0, sizeof(*hdr)); - if (hdr && hdr->dwSize == sizeof(LINK_HEADER) && - !memcmp(&hdr->MagicGuid, &CLSID_ShellLink, sizeof(GUID))) + if (read( fd, &hdr, sizeof(hdr) ) == sizeof(hdr) && + hdr.dwSize == sizeof(LINK_HEADER) && + !memcmp( &hdr.MagicGuid, &CLSID_ShellLink, sizeof(GUID) )) return SIG_LNK; return SIG_UNKNOWN; } diff --git a/tools/winedump/mf.c b/tools/winedump/mf.c index dac8be200af..d264ddf3d89 100644 --- a/tools/winedump/mf.c +++ b/tools/winedump/mf.c @@ -198,14 +198,14 @@ static int dump_mfrecord(void) return 0; }
-enum FileSig get_kind_mf(void) +enum FileSig get_kind_mf(int fd) { - const METAHEADER *hdr; + METAHEADER hdr;
- hdr = PRD(0, sizeof(*hdr)); - if (hdr && (hdr->mtType == METAFILE_MEMORY || hdr->mtType == METAFILE_DISK) - && hdr->mtHeaderSize == sizeof(METAHEADER) / sizeof(WORD) - && (hdr->mtVersion == 0x0100 || hdr->mtVersion == 0x0300)) + if (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr) + && (hdr.mtType == METAFILE_MEMORY || hdr.mtType == METAFILE_DISK) + && hdr.mtHeaderSize == sizeof(METAHEADER) / sizeof(WORD) + && (hdr.mtVersion == 0x0100 || hdr.mtVersion == 0x0300)) return SIG_MF; return SIG_UNKNOWN; } diff --git a/tools/winedump/minidump.c b/tools/winedump/minidump.c index d8010ea0159..dfda36c719a 100644 --- a/tools/winedump/minidump.c +++ b/tools/winedump/minidump.c @@ -42,14 +42,12 @@ static const char *get_mdmp_str(DWORD rva) return "<<?>>"; }
-enum FileSig get_kind_mdmp(void) +enum FileSig get_kind_mdmp(int fd) { - const DWORD* pdw; + DWORD dw;
- pdw = PRD(0, sizeof(DWORD)); - if (!pdw) {printf("Can't get main signature, aborting\n"); return SIG_UNKNOWN;} - - if (*pdw == 0x504D444D /* "MDMP" */) return SIG_MDMP; + if (read(fd, &dw, sizeof(dw)) == sizeof(dw) && dw == 0x504D444D /* "MDMP" */) + return SIG_MDMP; return SIG_UNKNOWN; }
diff --git a/tools/winedump/nls.c b/tools/winedump/nls.c index b52518604c8..4225666076e 100644 --- a/tools/winedump/nls.c +++ b/tools/winedump/nls.c @@ -1278,7 +1278,7 @@ void nls_dump(void) fprintf( stderr, "Unrecognized file name '%s'\n", globals.input_name ); }
-enum FileSig get_kind_nls(void) +enum FileSig get_kind_nls( int fd ) { if (strlen( globals.input_name ) < 5) return SIG_UNKNOWN; if (strcasecmp( globals.input_name + strlen(globals.input_name) - 4, ".nls" )) return SIG_UNKNOWN; diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 718356ed207..2d56c7b8a21 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -1346,15 +1346,13 @@ static void pdb_ds_dump_header_root(struct pdb_reader* reader) } }
-enum FileSig get_kind_pdb(void) +enum FileSig get_kind_pdb( int fd ) { - const char* head; + char tmp[max(sizeof(pdb7), sizeof(pdb2)) - 1];
- head = PRD(0, sizeof(pdb2) - 1); - if (head && !memcmp(head, pdb2, sizeof(pdb2) - 1)) - return SIG_PDB; - head = PRD(0, sizeof(pdb7) - 1); - if (head && !memcmp(head, pdb7, sizeof(pdb7) - 1)) + if (read(fd, tmp, sizeof(tmp)) == sizeof(tmp) && + (!memcmp(tmp, pdb2, sizeof(pdb2) - 1) || + !memcmp(tmp, pdb7, sizeof(pdb7) - 1))) return SIG_PDB; return SIG_UNKNOWN; } diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c index 96830fd5d3b..9c8fd613c7c 100644 --- a/tools/winedump/pe.c +++ b/tools/winedump/pe.c @@ -4131,14 +4131,12 @@ static void dump_dir_tls(void) printf(" }\n\n"); }
-enum FileSig get_kind_dbg(void) +enum FileSig get_kind_dbg( int fd ) { - const WORD* pw; + WORD w;
- pw = PRD(0, sizeof(WORD)); - if (!pw) {printf("Can't get main signature, aborting\n"); return 0;} - - if (*pw == 0x4944 /* "DI" */) return SIG_DBG; + if (read( fd, &w, sizeof(w) ) == sizeof(w) && w == 0x4944 /* "DI" */) + return SIG_DBG; return SIG_UNKNOWN; }
@@ -4770,27 +4768,20 @@ static void dump_symbol_table(void) dump_coff_symbol_table(sym, numsym, IMAGE_FIRST_SECTION(PE_nt_headers)); }
-enum FileSig get_kind_exec(void) +enum FileSig get_kind_exec( int fd ) { - const WORD* pw; - const DWORD* pdw; - const IMAGE_DOS_HEADER* dh; - - pw = PRD(0, sizeof(WORD)); - if (!pw) {printf("Can't get main signature, aborting\n"); return 0;} - - if (*pw != IMAGE_DOS_SIGNATURE) return SIG_UNKNOWN; + IMAGE_DOS_HEADER dos_hdr; + DWORD pe_sig;
- if ((dh = PRD(0, sizeof(IMAGE_DOS_HEADER)))) + if (read( fd, &dos_hdr, sizeof(dos_hdr) ) != sizeof(dos_hdr) || + dos_hdr.e_magic != IMAGE_DOS_SIGNATURE) + return SIG_UNKNOWN; + /* the signature is the first DWORD */ + if (pread( fd, &pe_sig, sizeof(pe_sig), dos_hdr.e_lfanew ) == sizeof(pe_sig)) { - /* the signature is the first DWORD */ - pdw = PRD(dh->e_lfanew, sizeof(DWORD)); - if (pdw) - { - if (*pdw == IMAGE_NT_SIGNATURE) return SIG_PE; - if (*(const WORD *)pdw == IMAGE_OS2_SIGNATURE) return SIG_NE; - if (*(const WORD *)pdw == IMAGE_VXD_SIGNATURE) return SIG_LE; - } + if (pe_sig == IMAGE_NT_SIGNATURE) return SIG_PE; + if (LOWORD(pe_sig) == IMAGE_OS2_SIGNATURE) return SIG_NE; + if (LOWORD(pe_sig) == IMAGE_VXD_SIGNATURE) return SIG_LE; return SIG_DOS; } return SIG_UNKNOWN; diff --git a/tools/winedump/reg.c b/tools/winedump/reg.c index 29478e06592..885ca359be8 100644 --- a/tools/winedump/reg.c +++ b/tools/winedump/reg.c @@ -134,12 +134,13 @@ static unsigned int header_checksum(const header *h) return checksum; }
-enum FileSig get_kind_reg(void) +enum FileSig get_kind_reg( int fd ) { - const header *hdr; + header hdr;
- hdr = PRD(0, BLOCK_SIZE); - if (hdr && !memcmp(&hdr->signature, "regf", sizeof(hdr->signature))) + if (read( fd, &hdr, sizeof(hdr) ) == sizeof(hdr) && + BLOCK_SIZE <= lseek( fd, 0, SEEK_END ) && + !memcmp(&hdr.signature, "regf", sizeof(hdr.signature))) return SIG_REG; return SIG_UNKNOWN; } diff --git a/tools/winedump/tlb.c b/tools/winedump/tlb.c index 3c795162f0e..62d3c7410c8 100644 --- a/tools/winedump/tlb.c +++ b/tools/winedump/tlb.c @@ -2132,9 +2132,12 @@ void tlb_dump_resource( void *ptr, size_t size, const char *prefix ) dump_total_len = prev_dump_total_len; }
-enum FileSig get_kind_tlb(void) +enum FileSig get_kind_tlb( int fd ) { - const DWORD *sig = PRD(0, sizeof(DWORD)); - if (sig && (*sig == MSFT_MAGIC || *sig == SLTG_MAGIC)) return SIG_TLB; + DWORD sig; + + if (read( fd, &sig, sizeof(sig) ) == sizeof(sig) && + (sig == MSFT_MAGIC || sig == SLTG_MAGIC)) + return SIG_TLB; return SIG_UNKNOWN; } diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index d15eacf2971..3ee4906553b 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -240,35 +240,35 @@ void dump_optional_header(const IMAGE_OPTIONAL_HEADER32 *); void dump_section(const IMAGE_SECTION_HEADER *, const char* strtable); void dump_section_characteristics(DWORD characteristics, const char* sep);
-enum FileSig get_kind_exec(void); +enum FileSig get_kind_exec( int fd ); void dos_dump( void ); void pe_dump( void ); void ne_dump( void ); void le_dump( void ); -enum FileSig get_kind_mdmp(void); +enum FileSig get_kind_mdmp( int fd ); void mdmp_dump( void ); -enum FileSig get_kind_lib(void); +enum FileSig get_kind_lib( int fd ); void lib_dump( void ); -enum FileSig get_kind_dbg(void); +enum FileSig get_kind_dbg( int fd ); void dbg_dump( void ); -enum FileSig get_kind_lnk(void); +enum FileSig get_kind_lnk( int fd ); void lnk_dump( void ); -enum FileSig get_kind_emf(void); +enum FileSig get_kind_emf( int fd ); unsigned long dump_emfrecord(const char *pfx, unsigned long offset); void emf_dump( void ); -enum FileSig get_kind_emfspool(void); +enum FileSig get_kind_emfspool( int fd ); void emfspool_dump(void); -enum FileSig get_kind_mf(void); +enum FileSig get_kind_mf( int fd ); void mf_dump(void); -enum FileSig get_kind_pdb(void); +enum FileSig get_kind_pdb( int fd ); void pdb_dump(void); -enum FileSig get_kind_fnt(void); +enum FileSig get_kind_fnt( int fd ); void fnt_dump( void ); -enum FileSig get_kind_tlb(void); +enum FileSig get_kind_tlb( int fd ); void tlb_dump(void); -enum FileSig get_kind_nls(void); +enum FileSig get_kind_nls( int fd ); void nls_dump(void); -enum FileSig get_kind_reg(void); +enum FileSig get_kind_reg( int fd ); void reg_dump(void);
extern void tlb_dump_resource( void *ptr, size_t size, const char *prefix );
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/msc.c | 8 +- tools/winedump/dump.c | 23 ++++-- tools/winedump/pdb.c | 170 +++++++++++++++++++++++--------------- tools/winedump/winedump.h | 2 +- 4 files changed, 123 insertions(+), 80 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 22ec5230f7a..5ace388c9d2 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2274,7 +2274,7 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, { struct symt_function* top_func = NULL; struct symt_function* curr_func = NULL; - int i, length; + unsigned int i, length; struct symt_block* block = NULL; struct symt* symt; struct symt_compiland* compiland = NULL; @@ -3044,7 +3044,7 @@ static BOOL pdb_global_feed_public(const struct msc_debug_info* msc_dbg, const u */
static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list, - int size) + unsigned int size) { int i, num_blocks; BYTE* buffer; @@ -3063,7 +3063,7 @@ static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list }
static void* pdb_ds_read(const struct PDB_DS_HEADER* pdb, const UINT *block_list, - int size) + unsigned int size) { int i, num_blocks; BYTE* buffer; @@ -3342,7 +3342,7 @@ static BOOL pdb_init_type_parse(const struct msc_debug_info* msc_dbg, { const BYTE* ptr; DWORD* offset; - int i; + unsigned int i;
ctp->hash_stream = NULL; ctp->offset = NULL; diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c index 39007603cc4..f9b31d91a23 100644 --- a/tools/winedump/dump.c +++ b/tools/winedump/dump.c @@ -224,13 +224,14 @@ static const struct dumper enum FileSig kind; enum FileSig (*get_kind)( int fd ); file_dumper dumper; /* default dump tool */ + void (*alt_dumper)( int fd ); } dumpers[] = { {SIG_DOS, get_kind_exec, dos_dump}, {SIG_PE, get_kind_exec, pe_dump}, {SIG_DBG, get_kind_dbg, dbg_dump}, - {SIG_PDB, get_kind_pdb, pdb_dump}, + {SIG_PDB, get_kind_pdb, .alt_dumper = pdb_dump}, {SIG_NE, get_kind_exec, ne_dump}, {SIG_LE, get_kind_exec, le_dump}, {SIG_COFFLIB, get_kind_lib, lib_dump}, @@ -268,16 +269,22 @@ BOOL dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig) { enum FileSig kind = dpr->get_kind( fd ); lseek( fd, 0, SEEK_SET ); - if (kind == dpr->kind && - (wanted_sig == SIG_UNKNOWN || wanted_sig == dpr->kind)) + if (kind == dpr->kind && (wanted_sig == SIG_UNKNOWN || wanted_sig == dpr->kind)) { - dump_base = xmalloc( st.st_size ); - if (read( fd, dump_base, st.st_size ) == st.st_size) + if (fn || dpr->dumper) { - dump_total_len = st.st_size; - if (fn) fn(); else dpr->dumper(); - break; + dump_base = xmalloc( st.st_size ); + if (read( fd, dump_base, st.st_size ) == st.st_size) + { + dump_total_len = st.st_size; + if (fn) fn(); else dpr->dumper(); + } } + else if (dpr->alt_dumper) + { + dpr->alt_dumper( fd ); + } + break; } } if (dpr->kind == SIG_UNKNOWN) diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 2d56c7b8a21..be628fb375b 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -30,25 +30,28 @@ #include "winbase.h" #include "winedump.h"
+#define NUMBER_OF(x, y) (((x) + (y) - 1) / (y)) + struct pdb_reader { + int fd; union { struct { - const struct PDB_JG_HEADER* header; + const struct PDB_JG_HEADER header; const struct PDB_JG_TOC* toc; const struct PDB_JG_ROOT* root; } jg; struct { - const struct PDB_DS_HEADER* header; + const struct PDB_DS_HEADER header; const struct PDB_DS_TOC* toc; const struct PDB_DS_ROOT* root; } ds; } u; void* (*read_stream)(struct pdb_reader*, DWORD); - DWORD stream_used[1024]; + DWORD *stream_used; PDB_STRING_TABLE* global_string_table; };
@@ -67,20 +70,23 @@ static inline void clear_stream_been_read(struct pdb_reader* reader, unsigned st reader->stream_used[stream_nr / 32] &= ~(1 << (stream_nr % 32)); }
-static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list, int size) +static void* pdb_jg_read(int fd, const struct PDB_JG_HEADER* pdb, const WORD* block_list, int size) { int i, nBlocks; BYTE* buffer;
if (!size) return NULL;
- nBlocks = (size + pdb->block_size - 1) / pdb->block_size; + nBlocks = NUMBER_OF(size, pdb->block_size); buffer = xmalloc(nBlocks * pdb->block_size);
for (i = 0; i < nBlocks; i++) - memcpy(buffer + i * pdb->block_size, - (const char*)pdb + block_list[i] * pdb->block_size, pdb->block_size); - + if (pread(fd, buffer + i * pdb->block_size, pdb->block_size, + block_list[i] * pdb->block_size) != pdb->block_size) + { + free(buffer); + return NULL; + } return buffer; }
@@ -97,25 +103,37 @@ static void* pdb_jg_read_stream(struct pdb_reader* reader, DWORD stream_nr) return NULL; block_list = (const WORD*) &reader->u.jg.toc->streams[reader->u.jg.toc->num_streams]; for (i = 0; i < stream_nr; i++) - block_list += (reader->u.jg.toc->streams[i].size + - reader->u.jg.header->block_size - 1) / reader->u.jg.header->block_size; + block_list += NUMBER_OF(reader->u.jg.toc->streams[i].size, reader->u.jg.header.block_size);
- return pdb_jg_read(reader->u.jg.header, block_list, + return pdb_jg_read(reader->fd, &reader->u.jg.header, block_list, reader->u.jg.toc->streams[stream_nr].size); }
-static BOOL pdb_jg_init(struct pdb_reader* reader) +static BOOL pdb_jg_init(int fd, struct pdb_reader* reader) { - reader->u.jg.header = PRD(0, sizeof(struct PDB_JG_HEADER)); - if (!reader->u.jg.header) return FALSE; + unsigned size_blocks; + WORD *blocks; + BOOL ret = FALSE; + + if (pread(fd, (void*)&reader->u.jg.header, sizeof(reader->u.jg.header), 0) != sizeof(reader->u.jg.header)) return FALSE; + reader->fd = fd; 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; + size_blocks = NUMBER_OF(reader->u.jg.header.toc.size, reader->u.jg.header.block_size) * sizeof(blocks[0]); + blocks = xmalloc(size_blocks); + ret = pread(fd, blocks, size_blocks, + offsetof(struct PDB_JG_HEADER, toc_block)) == size_blocks; + + if (ret) + ret = (reader->u.jg.toc = pdb_jg_read(fd, &reader->u.jg.header, blocks, + reader->u.jg.header.toc.size)) != NULL; + free(blocks); + if (ret) + ret = (reader->stream_used = calloc(sizeof(DWORD), + NUMBER_OF(reader->u.jg.toc->num_streams, sizeof(DWORD) * 8))) != NULL; + if (ret) + ret = (reader->u.jg.root = reader->read_stream(reader, 1)) != NULL; + + return ret; }
static DWORD pdb_get_num_streams(const struct pdb_reader* reader) @@ -156,6 +174,7 @@ static void pdb_exit(struct pdb_reader* reader) } } free(reader->global_string_table); + free(reader->stream_used); if (reader->read_stream == pdb_jg_read_stream) { free((char*)reader->u.jg.root); @@ -1130,11 +1149,11 @@ static void pdb_jg_dump_header_root(struct pdb_reader* reader) "\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); + (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" @@ -1186,19 +1205,23 @@ static void pdb_jg_dump_header_root(struct pdb_reader* reader) } }
-static void* pdb_ds_read(const struct PDB_DS_HEADER* header, const UINT *block_list, int size) +static void* pdb_ds_read(int fd, const struct PDB_DS_HEADER* header, const UINT *block_list, unsigned int size) { - int i, nBlocks; + unsigned int i, nBlocks; BYTE* buffer;
if (!size) return NULL;
- nBlocks = (size + header->block_size - 1) / header->block_size; + nBlocks = NUMBER_OF(size, header->block_size); buffer = xmalloc(nBlocks * header->block_size);
for (i = 0; i < nBlocks; i++) - memcpy(buffer + i * header->block_size, - (const char*)header + block_list[i] * header->block_size, header->block_size); + if (pread(fd, buffer + i * header->block_size, header->block_size, + (size_t)block_list[i] * header->block_size) != header->block_size) + { + free(buffer); + return NULL; + }
return buffer; } @@ -1216,24 +1239,35 @@ static void* pdb_ds_read_stream(struct pdb_reader* reader, DWORD stream_number) return NULL; block_list = reader->u.ds.toc->stream_size + reader->u.ds.toc->num_streams; for (i = 0; i < stream_number; i++) - block_list += (reader->u.ds.toc->stream_size[i] + reader->u.ds.header->block_size - 1) / - reader->u.ds.header->block_size; + block_list += NUMBER_OF(reader->u.ds.toc->stream_size[i], reader->u.ds.header.block_size);
- return pdb_ds_read(reader->u.ds.header, block_list, reader->u.ds.toc->stream_size[stream_number]); + return pdb_ds_read(reader->fd, &reader->u.ds.header, block_list, reader->u.ds.toc->stream_size[stream_number]); }
-static BOOL pdb_ds_init(struct pdb_reader* reader) +static BOOL pdb_ds_init(int fd, struct pdb_reader* reader) { - reader->u.ds.header = PRD(0, sizeof(*reader->u.ds.header)); - if (!reader->u.ds.header) return FALSE; + unsigned size_blocks; + unsigned *blocks; + BOOL ret; + + if (pread(fd, (void*)&reader->u.ds.header, sizeof(reader->u.ds.header), 0) != sizeof(reader->u.ds.header)) return FALSE; + reader->fd = fd; reader->read_stream = pdb_ds_read_stream; - reader->u.ds.toc = pdb_ds_read(reader->u.ds.header, - (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; + size_blocks = NUMBER_OF(reader->u.ds.header.toc_size, reader->u.ds.header.block_size) * sizeof(blocks[0]); + blocks = xmalloc(size_blocks); + ret = pread(fd, blocks, size_blocks, + (size_t)reader->u.ds.header.toc_block * reader->u.ds.header.block_size) == size_blocks; + if (ret) + ret = (reader->u.ds.toc = pdb_ds_read(reader->fd, &reader->u.ds.header, + blocks, reader->u.ds.header.toc_size)) != NULL; + free(blocks); + if (ret) + ret = (reader->stream_used = calloc(sizeof(DWORD), + NUMBER_OF(reader->u.ds.toc->num_streams, sizeof(DWORD) * 8))) != NULL; + if (ret) + ret = (reader->u.ds.root = reader->read_stream(reader, 1)) != NULL; + + return ret; }
static const char pdb7[] = "Microsoft C/C++ MSF 7.00"; @@ -1256,19 +1290,19 @@ static void pdb_ds_dump_header_root(struct pdb_reader* reader) "\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); + (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++) { - unsigned int nblk = (reader->u.ds.toc->stream_size[i] + reader->u.ds.header->block_size - 1) / reader->u.ds.header->block_size; + unsigned int nblk = NUMBER_OF(reader->u.ds.toc->stream_size[i], reader->u.ds.header.block_size); printf("\t\tstream[%#x]:\tsize: %u\n", i, reader->u.ds.toc->stream_size[i]); if (nblk) { @@ -1357,33 +1391,35 @@ enum FileSig get_kind_pdb( int fd ) return SIG_UNKNOWN; }
-void pdb_dump(void) +void pdb_dump(int fd) { - const BYTE* head; + char tmp[max(sizeof(pdb2), sizeof(pdb7)) - 1]; const char** saved_dumpsect = globals.dumpsect; static const char* default_dumpsect[] = {"DBI", "TPI", "IPI", NULL}; struct pdb_reader reader;
if (!globals.dumpsect) globals.dumpsect = default_dumpsect;
- if ((head = PRD(0, sizeof(pdb2) - 1)) && !memcmp(head, pdb2, sizeof(pdb2) - 1)) + if (read(fd, tmp, sizeof(tmp)) == sizeof(tmp)) { - if (!pdb_jg_init(&reader)) + if (!memcmp(tmp, pdb2, sizeof(pdb2) - 1)) { - printf("Unable to get header information\n"); - return; + if (!pdb_jg_init(fd, &reader)) + { + printf("Unable to get header information\n"); + return; + } + pdb_jg_dump_header_root(&reader); } - - pdb_jg_dump_header_root(&reader); - } - else if ((head = PRD(0, sizeof(pdb7) - 1)) && !memcmp(head, pdb7, sizeof(pdb7) - 1)) - { - if (!pdb_ds_init(&reader)) + else if (!memcmp(tmp, pdb7, sizeof(pdb7) - 1)) { - printf("Unable to get header information\n"); - return; + if (!pdb_ds_init(fd, &reader)) + { + printf("Unable to get header information\n"); + return; + } + pdb_ds_dump_header_root(&reader); } - pdb_ds_dump_header_root(&reader); } mark_stream_been_read(&reader, 0); /* mark stream #0 (old TOC) as read */
diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index 3ee4906553b..0e257ab3c72 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -261,7 +261,7 @@ void emfspool_dump(void); enum FileSig get_kind_mf( int fd ); void mf_dump(void); enum FileSig get_kind_pdb( int fd ); -void pdb_dump(void); +void pdb_dump(int fd); enum FileSig get_kind_fnt( int fd ); void fnt_dump( void ); enum FileSig get_kind_tlb( int fd );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151092
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4306: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000005900F6, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032