[PATCH] [WineDump, DbgHelp]: in .pdb files (>= VC2005), handle the case where the codeview_linetab2_file structure is not the first one
Eric Pouech
eric.pouech at orange.fr
Sat Oct 31 08:57:40 CDT 2009
A+
---
dlls/dbghelp/msc.c | 82 +++++++++++++++++++++++++++++++-----------------
include/wine/mscvpdb.h | 47 +++++++++++++++++++---------
tools/winedump/msc.c | 74 +++++++++++++++++++++++++++++--------------
3 files changed, 136 insertions(+), 67 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 2932d26..d31dd71 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1362,48 +1362,72 @@ static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const B
}
static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const BYTE* linetab, DWORD size,
- const char* strimage, DWORD strsize)
+ const char* strimage, DWORD strsize)
{
- DWORD offset;
unsigned i;
DWORD addr;
- const struct codeview_linetab2_block* lbh;
- const struct codeview_linetab2_file* fd;
+ const struct codeview_linetab2* lt2;
+ const struct codeview_linetab2* lt2_files = NULL;
+ const struct codeview_lt2blk_lines* lines_blk;
+ const struct codeview_linetab2_file*fd;
unsigned source;
struct symt_function* func;
- if (*(const DWORD*)linetab != 0x000000f4) return;
- offset = *((const DWORD*)linetab + 1);
-
- for (lbh = (const struct codeview_linetab2_block*)(linetab + 8 + offset);
- (const BYTE*)lbh < linetab + size;
- lbh = (const struct codeview_linetab2_block*)((const char*)lbh + 8 + lbh->size_of_block))
+ /* locate LT2_FILES_BLOCK (if any) */
+ lt2 = (const struct codeview_linetab2*)linetab;
+ while ((const BYTE*)(lt2 + 1) < linetab + size)
{
- if (lbh->header != 0x000000f2)
- /* FIXME: should also check that whole lbh fits in linetab + size */
+ if (lt2->header == LT2_FILES_BLOCK)
{
- TRACE("block end %x\n", lbh->header);
+ lt2_files = lt2;
break;
}
- addr = codeview_get_address(msc_dbg, lbh->seg, lbh->start);
- TRACE("block from %04x:%08x #%x (%x lines)\n",
- lbh->seg, lbh->start, lbh->size, lbh->nlines);
- fd = (const struct codeview_linetab2_file*)(linetab + 8 + lbh->file_offset);
- /* FIXME: should check that string is within strimage + strsize */
- source = source_new(msc_dbg->module, NULL, strimage + fd->offset);
- func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
- /* FIXME: at least labels support line numbers */
- if (!func || func->symt.tag != SymTagFunction)
+ lt2 = codeview_linetab2_next_block(lt2);
+ }
+ if (!lt2_files)
+ {
+ TRACE("No LT2_FILES_BLOCK found\n");
+ return;
+ }
+
+ lt2 = (const struct codeview_linetab2*)linetab;
+ while ((const BYTE*)(lt2 + 1) < linetab + size)
+ {
+ /* FIXME: should also check that whole lines_blk fits in linetab + size */
+ switch (lt2->header)
{
- WARN("--not a func at %04x:%08x %x tag=%d\n",
- lbh->seg, lbh->start, addr, func ? func->symt.tag : -1);
+ case LT2_LINES_BLOCK:
+ lines_blk = (const struct codeview_lt2blk_lines*)lt2;
+ /* FIXME: should check that file_offset is within the LT2_FILES_BLOCK we've seen */
+ addr = codeview_get_address(msc_dbg, lines_blk->seg, lines_blk->start);
+ TRACE("block from %04x:%08x #%x (%x lines)\n",
+ lines_blk->seg, lines_blk->start, lines_blk->size, lines_blk->nlines);
+ fd = (const struct codeview_linetab2_file*)((const char*)lt2_files + 8 + lines_blk->file_offset);
+ /* FIXME: should check that string is within strimage + strsize */
+ source = source_new(msc_dbg->module, NULL, strimage + fd->offset);
+ func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
+ /* FIXME: at least labels support line numbers */
+ if (!func || func->symt.tag != SymTagFunction)
+ {
+ WARN("--not a func at %04x:%08x %x tag=%d\n",
+ lines_blk->seg, lines_blk->start, addr, func ? func->symt.tag : -1);
+ break;
+ }
+ for (i = 0; i < lines_blk->nlines; i++)
+ {
+ symt_add_func_line(msc_dbg->module, func, source,
+ lines_blk->l[i].lineno ^ 0x80000000,
+ lines_blk->l[i].offset - lines_blk->start);
+ }
+ break;
+ case LT2_FILES_BLOCK: /* skip */
+ break;
+ default:
+ TRACE("Block end %x\n", lt2->header);
+ lt2 = (const struct codeview_linetab2*)((const char*)linetab + size);
continue;
}
- for (i = 0; i < lbh->nlines; i++)
- {
- symt_add_func_line(msc_dbg->module, func, source,
- lbh->l[i].lineno ^ 0x80000000, lbh->l[i].offset - lbh->start);
- }
+ lt2 = codeview_linetab2_next_block(lt2);
}
}
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index 9d52a65..2aefa87 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -1642,14 +1642,28 @@ struct startend
unsigned int end;
};
+#define LT2_LINES_BLOCK 0x000000f2
+#define LT2_FILES_BLOCK 0x000000f4
+
/* 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
+ * it's made of a list of codeview_linetab2 blocks.
+ * We've only seen (so far) list with a single LT2_FILES_BLOCK and several
+ * LT2_LINES_BLOCK. The LT2_FILES block has been encountered either as first
+ * or last block of the list.
+ * A LT2_FILES contains one or several codeview_linetab2_file:s
*/
+struct codeview_linetab2
+{
+ DWORD header;
+ DWORD size_of_block;
+};
+
+static inline const struct codeview_linetab2* codeview_linetab2_next_block(const struct codeview_linetab2* lt2)
+{
+ return (const struct codeview_linetab2*)((const char*)(lt2 + 1) + lt2->size_of_block);
+}
+
struct codeview_linetab2_file
{
DWORD offset; /* offset in string table for filename */
@@ -1658,16 +1672,21 @@ struct codeview_linetab2_file
WORD pad0; /* always 0 */
};
-struct codeview_linetab2_block
+struct codeview_lt2blk_files
+{
+ struct codeview_linetab2 lt2; /* LT2_FILES */
+ struct codeview_linetab2_file file[1];
+};
+
+struct codeview_lt2blk_lines
{
- 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 codeview_linetab2 lt2; /* LT2_LINE_BLOCK */
+ 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 ???) */
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index b029852..95cc251 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -1417,36 +1417,62 @@ 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)
+ const struct codeview_linetab2* lt2;
+ const struct codeview_linetab2* lt2_files = NULL;
+ const struct codeview_lt2blk_lines* lines_blk;
+ const struct codeview_linetab2_file*fd;
+
+ /* locate LT2_FILES_BLOCK (if any) */
+ lt2 = (const struct codeview_linetab2*)linetab;
+ while ((const char*)(lt2 + 1) < linetab + size)
{
- if (lbh->header != 0x000000f2)
- /* FIXME: should also check that whole lbh fits in linetab + size */
+ if (lt2->header == LT2_FILES_BLOCK)
{
- /* printf("%sblock end %x\n", pfx, lbh->header); */
+ lt2_files = lt2;
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++)
+ lt2 = codeview_linetab2_next_block(lt2);
+ }
+ if (!lt2_files)
+ {
+ printf("%sNo LT2_FILES_BLOCK found\n", pfx);
+ return;
+ }
+
+ lt2 = (const struct codeview_linetab2*)linetab;
+ while ((const char*)(lt2 + 1) < linetab + size)
+ {
+ /* FIXME: should also check that whole lbh fits in linetab + size */
+ switch (lt2->header)
{
- printf("%s offset=%08x line=%d\n", pfx, lbh->l[i].offset, lbh->l[i].lineno ^ 0x80000000);
+ case LT2_LINES_BLOCK:
+ lines_blk = (const struct codeview_lt2blk_lines*)lt2;
+ printf("%sblock from %04x:%08x #%x (%x lines) fo=%x\n",
+ pfx, lines_blk->seg, lines_blk->start, lines_blk->size,
+ lines_blk->nlines, lines_blk->file_offset);
+ /* FIXME: should check that file_offset is within the LT2_FILES_BLOCK we've seen */
+ fd = (const struct codeview_linetab2_file*)((const char*)lt2_files + 8 + lines_blk->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 < lines_blk->nlines; i++)
+ {
+ printf("%s offset=%08x line=%d\n",
+ pfx, lines_blk->l[i].offset, lines_blk->l[i].lineno ^ 0x80000000);
+ }
+ break;
+ case LT2_FILES_BLOCK: /* skip */
+ break;
+ default:
+ printf("%sblock end %x\n", pfx, lt2->header);
+ lt2 = (const struct codeview_linetab2*)((const char*)linetab + size);
+ continue;
}
- lbh = (const struct codeview_linetab2_block*)((const char*)lbh + 8 + lbh->size_of_block);
+ lt2 = codeview_linetab2_next_block(lt2);
}
}
More information about the wine-patches
mailing list