From ac42ebb5dc9fe121657e0a8254e7208de73a7ae4 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 29 Sep 2008 21:32:21 +0200 Subject: [PATCH] winedump: First stab at dumping the "new" line information out of pdb files. --- include/wine/mscvpdb.h | 31 +++++++++++++++++++++++++++++++ tools/winedump/msc.c | 36 ++++++++++++++++++++++++++++++++++++ tools/winedump/pdb.c | 25 ++++++++++++++++++++++++- tools/winedump/winedump.h | 1 + 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 2136ab8dadb..caf6db92dd4 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1654,6 +1654,37 @@ struct codeview_linetab const unsigned int* offtab; }; +/* there's a new line tab structure from MS Studio 2005 and after + * it's made of: + * DWORD 000000f4 + * DWORD lineblk_offset (counting bytes after this field) + * an array of codeview_linetab2_file structures + * an array (starting at ) of codeview_linetab2_block structures + */ + +struct codeview_linetab2_file +{ + DWORD offset; /* offset in string table for filename */ + WORD unk; /* always 0x0110... type of following information ??? */ + BYTE md5[16]; /* MD5 signature of file (signature on file's content or name ???) */ + WORD pad0; /* always 0 */ +}; + +struct codeview_linetab2_block +{ + DWORD header; /* 0x000000f2 */ + DWORD size_of_block; /* next block is at # bytes after this field */ + DWORD start; /* start address of function with line numbers */ + DWORD seg; /* segment of function with line numbers */ + DWORD size; /* size of function with line numbers */ + DWORD file_offset; /* offset for accessing corresponding codeview_linetab2_file */ + DWORD nlines; /* number of lines in this block */ + DWORD size_lines; /* number of bytes following for line number information */ + struct { + DWORD offset; /* offset (from :) for line number */ + DWORD lineno; /* the line number (OR:ed with 0x80000000 why ???) */ + } l[1]; /* actually array of */ +}; /* ======================================== * * PDB file information diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 0351cacac34..1d9ff77b085 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1365,3 +1365,39 @@ void codeview_dump_linetab(const char* linetab, DWORD size, BOOL pascal_str, con } } } + +void codeview_dump_linetab2(const char* linetab, DWORD size, const char* strimage, DWORD strsize, const char* pfx) +{ + DWORD offset; + unsigned i; + const struct codeview_linetab2_block* lbh; + const struct codeview_linetab2_file* fd; + + if (*(const DWORD*)linetab != 0x000000f4) return; + offset = *((const DWORD*)linetab + 1); + lbh = (const struct codeview_linetab2_block*)(linetab + 8 + offset); + while ((const char*)lbh < linetab + size) + { + if (lbh->header != 0x000000f2) + /* FIXME: should also check that whole lbh fits in linetab + size */ + { + /* printf("%sblock end %x\n", pfx, lbh->header); */ + break; + } + printf("%sblock from %04x:%08x #%x (%x lines)\n", + pfx, lbh->seg, lbh->start, lbh->size, lbh->nlines); + fd = (const struct codeview_linetab2_file*)(linetab + 8 + lbh->file_offset); + printf("%s md5=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + pfx, fd->md5[ 0], fd->md5[ 1], fd->md5[ 2], fd->md5[ 3], + fd->md5[ 4], fd->md5[ 5], fd->md5[ 6], fd->md5[ 7], + fd->md5[ 8], fd->md5[ 9], fd->md5[10], fd->md5[11], + fd->md5[12], fd->md5[13], fd->md5[14], fd->md5[15]); + /* FIXME: should check that string is within strimage + strsize */ + printf("%s file=%s\n", pfx, strimage ? strimage + fd->offset : "--none--"); + for (i = 0; i < lbh->nlines; i++) + { + printf("%s offset=%08x line=%d\n", pfx, lbh->l[i].offset, lbh->l[i].lineno ^ 0x80000000); + } + lbh = (const struct codeview_linetab2_block*)((const char*)lbh + 8 + lbh->size_of_block); + } +} diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 72a63fde110..3641ff6a2d2 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -160,6 +160,8 @@ static void pdb_dump_symbols(struct pdb_reader* reader) PDB_SYMBOLS* symbols; unsigned char* modimage; const char* file; + char* filesimage; + DWORD filessize = 0; symbols = reader->read_file(reader, 3); @@ -210,6 +212,21 @@ static void pdb_dump_symbols(struct pdb_reader* reader) dump_data(src, symbols->offset_size, " "); } + filesimage = reader->read_file(reader, 12); /* FIXME: really fixed ??? */ + if (filesimage) + { + if (*(const DWORD*)filesimage == 0xeffeeffe) + { + filessize = *(const DWORD*)(filesimage + 8); + } + else + { + printf("wrong header %x expecting 0xeffeeffe\n", *(const DWORD*)filesimage); + free(filesimage); + filesimage = NULL; + } + } + if (symbols->srcmodule_size) { const PDB_SYMBOL_SOURCE*src; @@ -408,7 +425,12 @@ static void pdb_dump_symbols(struct pdb_reader* reader) /* line number info */ if (lineno_size) codeview_dump_linetab((const char*)modimage + symbol_size, lineno_size, TRUE, " "); - + /* anyway, lineno_size doesn't see to really be the size of the line number information, and + * it's not clear yet when to call for linetab2... + */ + codeview_dump_linetab2((const char*)modimage + symbol_size + lineno_size, + total_size - (symbol_size + lineno_size), + filesimage + 12, filessize, " "); /* what's that part ??? */ if (0) dump_data(modimage + symbol_size + lineno_size, total_size - (symbol_size + lineno_size), " "); @@ -419,6 +441,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader) file = (char*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3); } free(symbols); + free(filesimage); } static void pdb_dump_types(struct pdb_reader* reader) diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index d2bf9d3d1f1..f71103e09f1 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -256,6 +256,7 @@ int codeview_dump_symbols(const void* root, unsigned long size); int codeview_dump_types_from_offsets(const void* table, const DWORD* offsets, unsigned num_types); int codeview_dump_types_from_block(const void* table, unsigned long len); void codeview_dump_linetab(const char* linetab, DWORD size, BOOL pascal_str, const char* pfx); +void codeview_dump_linetab2(const char* linetab, DWORD size, const char* strimage, DWORD strsize, const char* pfx); void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr); void dump_codeview(unsigned long ptr, unsigned long len);