Eric Pouech : winedump: First stab at dumping the "new" line information out of pdb files.

Alexandre Julliard julliard at winehq.org
Wed Oct 1 14:09:19 CDT 2008


Module: wine
Branch: master
Commit: ac42ebb5dc9fe121657e0a8254e7208de73a7ae4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ac42ebb5dc9fe121657e0a8254e7208de73a7ae4

Author: Eric Pouech <eric.pouech at orange.fr>
Date:   Mon Sep 29 21:32:21 2008 +0200

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 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-cvs mailing list