Commit 64144519 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

winedump, dbghelp: In .pdb files (>= VC2005), handle the case where the…

winedump, dbghelp: In .pdb files (>= VC2005), handle the case where the codeview_linetab2_file structure is not the first one.
parent ad440940
...@@ -1362,48 +1362,72 @@ static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const B ...@@ -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, 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; unsigned i;
DWORD addr; DWORD addr;
const struct codeview_linetab2_block* lbh; const struct codeview_linetab2* lt2;
const struct codeview_linetab2_file* fd; const struct codeview_linetab2* lt2_files = NULL;
const struct codeview_lt2blk_lines* lines_blk;
const struct codeview_linetab2_file*fd;
unsigned source; unsigned source;
struct symt_function* func; struct symt_function* func;
if (*(const DWORD*)linetab != 0x000000f4) return; /* locate LT2_FILES_BLOCK (if any) */
offset = *((const DWORD*)linetab + 1); lt2 = (const struct codeview_linetab2*)linetab;
while ((const BYTE*)(lt2 + 1) < linetab + size)
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))
{ {
if (lbh->header != 0x000000f2) if (lt2->header == LT2_FILES_BLOCK)
/* FIXME: should also check that whole lbh fits in linetab + size */
{ {
TRACE("block end %x\n", lbh->header); lt2_files = lt2;
break; break;
} }
addr = codeview_get_address(msc_dbg, lbh->seg, lbh->start); lt2 = codeview_linetab2_next_block(lt2);
TRACE("block from %04x:%08x #%x (%x lines)\n", }
lbh->seg, lbh->start, lbh->size, lbh->nlines); if (!lt2_files)
fd = (const struct codeview_linetab2_file*)(linetab + 8 + lbh->file_offset); {
/* FIXME: should check that string is within strimage + strsize */ TRACE("No LT2_FILES_BLOCK found\n");
source = source_new(msc_dbg->module, NULL, strimage + fd->offset); return;
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 = (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", case LT2_LINES_BLOCK:
lbh->seg, lbh->start, addr, func ? func->symt.tag : -1); 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; continue;
} }
for (i = 0; i < lbh->nlines; i++) lt2 = codeview_linetab2_next_block(lt2);
{
symt_add_func_line(msc_dbg->module, func, source,
lbh->l[i].lineno ^ 0x80000000, lbh->l[i].offset - lbh->start);
}
} }
} }
......
...@@ -1642,14 +1642,28 @@ struct startend ...@@ -1642,14 +1642,28 @@ struct startend
unsigned int end; 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 /* there's a new line tab structure from MS Studio 2005 and after
* it's made of: * it's made of a list of codeview_linetab2 blocks.
* DWORD 000000f4 * We've only seen (so far) list with a single LT2_FILES_BLOCK and several
* DWORD lineblk_offset (counting bytes after this field) * LT2_LINES_BLOCK. The LT2_FILES block has been encountered either as first
* an array of codeview_linetab2_file structures * or last block of the list.
* an array (starting at <lineblk_offset>) of codeview_linetab2_block structures * 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 struct codeview_linetab2_file
{ {
DWORD offset; /* offset in string table for filename */ DWORD offset; /* offset in string table for filename */
...@@ -1658,16 +1672,21 @@ struct codeview_linetab2_file ...@@ -1658,16 +1672,21 @@ struct codeview_linetab2_file
WORD pad0; /* always 0 */ 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 */ struct codeview_linetab2 lt2; /* LT2_LINE_BLOCK */
DWORD size_of_block; /* next block is at # bytes after this field */ DWORD start; /* start address of function with line numbers */
DWORD start; /* start address of function with line numbers */ DWORD seg; /* segment of function with line numbers */
DWORD seg; /* segment of function with line numbers */ DWORD size; /* size of function with line numbers */
DWORD size; /* size of function with line numbers */ DWORD file_offset; /* offset for accessing corresponding codeview_linetab2_file */
DWORD file_offset; /* offset for accessing corresponding codeview_linetab2_file */ DWORD nlines; /* number of lines in this block */
DWORD nlines; /* number of lines in this block */ DWORD size_lines; /* number of bytes following for line number information */
DWORD size_lines; /* number of bytes following for line number information */
struct { struct {
DWORD offset; /* offset (from <seg>:<start>) for line number */ DWORD offset; /* offset (from <seg>:<start>) for line number */
DWORD lineno; /* the line number (OR:ed with 0x80000000 why ???) */ DWORD lineno; /* the line number (OR:ed with 0x80000000 why ???) */
......
...@@ -1417,36 +1417,62 @@ void codeview_dump_linetab(const char* linetab, DWORD size, BOOL pascal_str, con ...@@ -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) void codeview_dump_linetab2(const char* linetab, DWORD size, const char* strimage, DWORD strsize, const char* pfx)
{ {
DWORD offset;
unsigned i; unsigned i;
const struct codeview_linetab2_block* lbh; const struct codeview_linetab2* lt2;
const struct codeview_linetab2_file* fd; const struct codeview_linetab2* lt2_files = NULL;
const struct codeview_lt2blk_lines* lines_blk;
if (*(const DWORD*)linetab != 0x000000f4) return; const struct codeview_linetab2_file*fd;
offset = *((const DWORD*)linetab + 1);
lbh = (const struct codeview_linetab2_block*)(linetab + 8 + offset); /* locate LT2_FILES_BLOCK (if any) */
while ((const char*)lbh < linetab + size) lt2 = (const struct codeview_linetab2*)linetab;
while ((const char*)(lt2 + 1) < linetab + size)
{ {
if (lbh->header != 0x000000f2) if (lt2->header == LT2_FILES_BLOCK)
/* FIXME: should also check that whole lbh fits in linetab + size */
{ {
/* printf("%sblock end %x\n", pfx, lbh->header); */ lt2_files = lt2;
break; break;
} }
printf("%sblock from %04x:%08x #%x (%x lines)\n", lt2 = codeview_linetab2_next_block(lt2);
pfx, lbh->seg, lbh->start, lbh->size, lbh->nlines); }
fd = (const struct codeview_linetab2_file*)(linetab + 8 + lbh->file_offset); if (!lt2_files)
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], printf("%sNo LT2_FILES_BLOCK found\n", pfx);
fd->md5[ 4], fd->md5[ 5], fd->md5[ 6], fd->md5[ 7], return;
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 */ lt2 = (const struct codeview_linetab2*)linetab;
printf("%s file=%s\n", pfx, strimage ? strimage + fd->offset : "--none--"); while ((const char*)(lt2 + 1) < linetab + size)
for (i = 0; i < lbh->nlines; i++) {
/* 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);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment