[PATCH 17/19] [WineDump]: first stab at dumping the "new" line information out of pdb files
Eric Pouech
eric.pouech at orange.fr
Mon Sep 29 14:32:21 CDT 2008
A+
---
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 deletions(-)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index 2136ab8..caf6db9 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 <lineblk_offset>) 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 <seg>:<start>) for line number */
+ DWORD lineno; /* the line number (OR:ed with 0x80000000 why ???) */
+ } l[1]; /* actually array of <nlines> */
+};
/* ======================================== *
* PDB file information
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index 0351cac..1d9ff77 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 72a63fd..3641ff6 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 d2bf9d3..f71103e 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);
More information about the wine-patches
mailing list