winedump: First stab at dumping the "new" line information out of pdb files.
This commit is contained in:
parent
f8380ba37a
commit
ac42ebb5dc
|
@ -1654,6 +1654,37 @@ struct codeview_linetab
|
||||||
const unsigned int* offtab;
|
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
|
* PDB file information
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -160,6 +160,8 @@ static void pdb_dump_symbols(struct pdb_reader* reader)
|
||||||
PDB_SYMBOLS* symbols;
|
PDB_SYMBOLS* symbols;
|
||||||
unsigned char* modimage;
|
unsigned char* modimage;
|
||||||
const char* file;
|
const char* file;
|
||||||
|
char* filesimage;
|
||||||
|
DWORD filessize = 0;
|
||||||
|
|
||||||
symbols = reader->read_file(reader, 3);
|
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, " ");
|
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)
|
if (symbols->srcmodule_size)
|
||||||
{
|
{
|
||||||
const PDB_SYMBOL_SOURCE*src;
|
const PDB_SYMBOL_SOURCE*src;
|
||||||
|
@ -408,7 +425,12 @@ static void pdb_dump_symbols(struct pdb_reader* reader)
|
||||||
/* line number info */
|
/* line number info */
|
||||||
if (lineno_size)
|
if (lineno_size)
|
||||||
codeview_dump_linetab((const char*)modimage + symbol_size, lineno_size, TRUE, " ");
|
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 ??? */
|
/* what's that part ??? */
|
||||||
if (0)
|
if (0)
|
||||||
dump_data(modimage + symbol_size + lineno_size, total_size - (symbol_size + lineno_size), " ");
|
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);
|
file = (char*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3);
|
||||||
}
|
}
|
||||||
free(symbols);
|
free(symbols);
|
||||||
|
free(filesimage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pdb_dump_types(struct pdb_reader* reader)
|
static void pdb_dump_types(struct pdb_reader* reader)
|
||||||
|
|
|
@ -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_offsets(const void* table, const DWORD* offsets, unsigned num_types);
|
||||||
int codeview_dump_types_from_block(const void* table, unsigned long len);
|
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_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_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr);
|
||||||
void dump_codeview(unsigned long ptr, unsigned long len);
|
void dump_codeview(unsigned long ptr, unsigned long len);
|
||||||
|
|
Loading…
Reference in New Issue