Fixed tools/winedump and dlls/dbghelp to use that information (instead of trying to guess it, with an erroneous result)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/msc.c | 7 ++++--- include/wine/mscvpdb.h | 4 ++-- tools/winedump/pdb.c | 24 ++++++++++++------------ 3 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index a1f009cf678..4aaee196370 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2424,6 +2424,7 @@ static void pdb_convert_symbol_file(const PDB_SYMBOLS* symbols, sfile->range.index = sym_file->range.index; sfile->symbol_size = sym_file->symbol_size; sfile->lineno_size = sym_file->lineno_size; + sfile->lineno2_size = sym_file->lineno2_size; *size = sizeof(PDB_SYMBOL_FILE) - 1; } else @@ -2818,14 +2819,14 @@ static BOOL pdb_process_internal(const struct process* pcs, codeview_snarf(msc_dbg, modimage, sizeof(DWORD), sfile.symbol_size, TRUE);
+ if (sfile.lineno_size && sfile.lineno2_size) FIXME("Both line info present... only supporting first\n"); if (sfile.lineno_size) codeview_snarf_linetab(msc_dbg, modimage + sfile.symbol_size, sfile.lineno_size, pdb_file->kind == PDB_JG); - if (files_image) - codeview_snarf_linetab2(msc_dbg, modimage + sfile.symbol_size + sfile.lineno_size, - pdb_get_file_size(pdb_file, sfile.file) - sfile.symbol_size - sfile.lineno_size, + else if (sfile.lineno2_size && files_image) + codeview_snarf_linetab2(msc_dbg, modimage + sfile.symbol_size, sfile.lineno2_size, files_image + 12, files_size);
pdb_free(modimage); diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 1ede937abc4..53eeec96916 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -2343,7 +2343,7 @@ typedef struct _PDB_SYMBOL_FILE WORD file; DWORD symbol_size; DWORD lineno_size; - DWORD unknown2; + DWORD lineno2_size; DWORD nSrcFiles; DWORD attribute; CHAR filename[1]; @@ -2357,7 +2357,7 @@ typedef struct _PDB_SYMBOL_FILE_EX WORD file; DWORD symbol_size; DWORD lineno_size; - DWORD unknown2; + DWORD lineno2_size; DWORD nSrcFiles; DWORD attribute; DWORD reserved[2]; diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 71a2bc49cc8..bbaf1cb94e8 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -466,7 +466,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx file = (const char*)symbols + sizeof(PDB_SYMBOLS); while (file - (const char*)symbols < sizeof(PDB_SYMBOLS) + symbols->module_size) { - int file_nr, symbol_size, lineno_size; + int file_nr, symbol_size, lineno_size, lineno2_size; const char* file_name;
if (symbols->version < 19970000) @@ -476,6 +476,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx file_name = sym_file->filename; symbol_size = sym_file->symbol_size; lineno_size = sym_file->lineno_size; + lineno2_size = sym_file->lineno2_size; printf("\t--------symbol file----------- %s\n", file_name); printf("\tgot symbol_file\n" "\t\tunknown1: %08x\n" @@ -491,7 +492,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx "\t\tfile: %04x\n" "\t\tsymb size: %08x\n" "\t\tline size: %08x\n" - "\t\tunknown2: %08x\n" + "\t\tline2 size: %08x\n" "\t\tnSrcFiles: %08x\n" "\t\tattribute: %08x\n", sym_file->unknown1, @@ -506,7 +507,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx sym_file->file, sym_file->symbol_size, sym_file->lineno_size, - sym_file->unknown2, + sym_file->lineno2_size, sym_file->nSrcFiles, sym_file->attribute); } @@ -517,6 +518,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx file_name = sym_file->filename; symbol_size = sym_file->symbol_size; lineno_size = sym_file->lineno_size; + lineno2_size = sym_file->lineno2_size; printf("\t--------symbol file----------- %s\n", file_name); printf("\t\tunknown1: %08x\n" "\t\trange\n" @@ -533,7 +535,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx "\t\tfile: %04x\n" "\t\tsymb size: %08x\n" "\t\tline size: %08x\n" - "\t\tunknown2: %08x\n" + "\t\tline2 size: %08x\n" "\t\tnSrcFiles: %08x\n" "\t\tattribute: %08x\n" "\t\treserved/0: %08x\n" @@ -552,7 +554,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx sym_file->file, sym_file->symbol_size, sym_file->lineno_size, - sym_file->unknown2, + sym_file->lineno2_size, sym_file->nSrcFiles, sym_file->attribute, sym_file->reserved[0], @@ -569,15 +571,13 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx /* line number info */ if (lineno_size) codeview_dump_linetab((const char*)modimage + symbol_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 ? filesimage + 12 : NULL, filessize, " "); + else if (lineno2_size) /* actually, only one of the 2 lineno should be present */ + codeview_dump_linetab2((const char*)modimage + symbol_size, lineno2_size, + filesimage ? filesimage + 12 : NULL, filessize, " "); /* what's that part ??? */ if (0) - dump_data(modimage + symbol_size + lineno_size, total_size - (symbol_size + lineno_size), " "); + dump_data(modimage + symbol_size + lineno_size + lineno2_size, + total_size - (symbol_size + lineno_size + lineno2_size), " "); free(modimage); }
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- tools/winedump/msc.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 12d1a9e62ab..18c591f44ef 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -675,12 +675,14 @@ static void do_field(const unsigned char* start, const unsigned char* end) printf("\t\tFriend function V1: '%s' type:%x\n", p_string(&fieldtype->friendfcn_v1.p_name), fieldtype->friendfcn_v1.type); + ptr += 2 + 2 + (1 + fieldtype->stmember_v2.p_name.namelen); break;
case LF_FRIENDFCN_V2: printf("\t\tFriend function V2: '%s' type:%x\n", p_string(&fieldtype->friendfcn_v2.p_name), fieldtype->friendfcn_v2.type); + ptr += 2 + 2 + 4 + (1 + fieldtype->stmember_v2.p_name.namelen); break;
#if 0 @@ -735,10 +737,12 @@ static void do_field(const unsigned char* start, const unsigned char* end)
case LF_FRIENDCLS_V1: printf("\t\tFriend class V1: type:%x\n", fieldtype->friendcls_v1.type); + ptr += 2 + 2; break;
case LF_FRIENDCLS_V2: printf("\t\tFriend class V2: type:%x\n", fieldtype->friendcls_v2.type); + ptr += 2 + 2 + 4; break;
case LF_NESTTYPE_V1: @@ -777,11 +781,13 @@ static void do_field(const unsigned char* start, const unsigned char* end) case LF_VFUNCOFF_V1: printf("\t\tVirtual function table offset V1: type:%x offset:%x\n", fieldtype->vfuncoff_v1.type, fieldtype->vfuncoff_v1.offset); + ptr += 2 + 2 + 4; break;
case LF_VFUNCOFF_V2: printf("\t\tVirtual function table offset V2: type:%x offset:%x\n", fieldtype->vfuncoff_v2.type, fieldtype->vfuncoff_v2.offset); + ptr += 2 + 2 + 4 + 4; break;
default:
Update tools/winedump accordingly
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 9 +++++++++ tools/winedump/msc.c | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 53eeec96916..ca5422c3a65 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -566,6 +566,14 @@ union codeview_fieldtype struct p_string p_name; } friendfcn_v2;
+ struct + { + unsigned short int id; + short int _pad0; + cv_typ_t type; + char name[1]; + } friendfcn_v3; + struct { unsigned short int id; @@ -1266,6 +1274,7 @@ union codeview_fieldtype #define LF_STRUCTURE_V3 0x1505 #define LF_UNION_V3 0x1506 #define LF_ENUM_V3 0x1507 +#define LF_FRIENDFCN_V3 0x150c #define LF_MEMBER_V3 0x150d #define LF_STMEMBER_V3 0x150e #define LF_METHOD_V3 0x150f diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 18c591f44ef..dca8bcf9560 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -685,13 +685,12 @@ static void do_field(const unsigned char* start, const unsigned char* end) ptr += 2 + 2 + 4 + (1 + fieldtype->stmember_v2.p_name.namelen); break;
-#if 0 case LF_FRIENDFCN_V3: printf("\t\tFriend function V3: '%s' type:%x\n", fieldtype->friendfcn_v3.name, fieldtype->friendfcn_v3.type); + ptr += 2 + 2 + 4 + (strlen(fieldtype->stmember_v3.name) + 1); break; -#endif
case LF_BCLASS_V1: leaf_len = numeric_leaf(&value, &fieldtype->bclass_v1.offset);
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- tools/winedump/msc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index dca8bcf9560..d537764b442 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -789,6 +789,16 @@ static void do_field(const unsigned char* start, const unsigned char* end) ptr += 2 + 2 + 4 + 4; break;
+ case LF_INDEX_V1: + printf("\t\tIndex V1: index:%x\n", fieldtype->index_v1.ref); + ptr += 2 + 2; + break; + + case LF_INDEX_V2: + printf("\t\tIndex V2: index:%x\n", fieldtype->index_v2.ref); + ptr += 2 + 2 + 4; + break; + default: printf(">>> Unsupported field-id %x\n", fieldtype->generic.id); dump_data((const void*)fieldtype, 0x30, "\t");
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- tools/winedump/pdb.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index bbaf1cb94e8..ed4877cd10a 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -468,18 +468,21 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx { int file_nr, symbol_size, lineno_size, lineno2_size; const char* file_name; - + const char* lib_name; + if (symbols->version < 19970000) { const PDB_SYMBOL_FILE* sym_file = (const PDB_SYMBOL_FILE*) file; file_nr = sym_file->file; file_name = sym_file->filename; + lib_name = file_name + strlen(file_name) + 1; symbol_size = sym_file->symbol_size; lineno_size = sym_file->lineno_size; lineno2_size = sym_file->lineno2_size; - printf("\t--------symbol file----------- %s\n", file_name); - printf("\tgot symbol_file\n" - "\t\tunknown1: %08x\n" + printf("\t--------symbol file-----------\n"); + printf("\tName: %s\n", file_name); + if (strcmp(file_name, lib_name)) printf("\tLibrary: %s\n", lib_name); + printf("\t\tunknown1: %08x\n" "\t\trange\n" "\t\t\tsegment: %04x\n" "\t\t\tpad1: %04x\n" @@ -514,12 +517,16 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx else { const PDB_SYMBOL_FILE_EX* sym_file = (const PDB_SYMBOL_FILE_EX*) file; + file_nr = sym_file->file; file_name = sym_file->filename; + lib_name = file_name + strlen(file_name) + 1; symbol_size = sym_file->symbol_size; lineno_size = sym_file->lineno_size; lineno2_size = sym_file->lineno2_size; - printf("\t--------symbol file----------- %s\n", file_name); + printf("\t--------symbol file-----------\n"); + printf("\tName: %s\n", file_name); + if (strcmp(file_name, lib_name)) printf("\tLibrary: %s\n", lib_name); printf("\t\tunknown1: %08x\n" "\t\trange\n" "\t\t\tsegment: %04x\n" @@ -581,8 +588,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx free(modimage); }
- file_name += strlen(file_name) + 1; - file = (char*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3); + file = (char*)((DWORD_PTR)(lib_name + strlen(lib_name) + 1 + 3) & ~3); } dump_global_symbol(reader, symbols->global_file); dump_public_symbol(reader, symbols->public_file);
Currently, they are described as linetab2 internally. And they miss quite a number of elements.
From MS' docs, they are described as debug subsection (inside PDB's SYMBOL
stream)
Update include/wine/mscvpdb.h to describe those. Update tools/winedump to dump them properly.
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 103 +++++++++++++++++++++++++++++++++ tools/winedump/msc.c | 148 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 206 insertions(+), 45 deletions(-)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index ca5422c3a65..733b4ab5336 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -2162,6 +2162,109 @@ enum BinaryAnnotationOpcode * Line number information * ======================================== */
+enum DEBUG_S_SUBSECTION_TYPE +{ + DEBUG_S_IGNORE = 0x80000000, /* bit flag: when set, ignore whole subsection content */ + + DEBUG_S_SYMBOLS = 0xf1, + DEBUG_S_LINES, + DEBUG_S_STRINGTABLE, + DEBUG_S_FILECHKSMS, + DEBUG_S_FRAMEDATA, + DEBUG_S_INLINEELINES, + DEBUG_S_CROSSSCOPEIMPORTS, + DEBUG_S_CROSSSCOPEEXPORTS, + + DEBUG_S_IL_LINES, + DEBUG_S_FUNC_MDTOKEN_MAP, + DEBUG_S_TYPE_MDTOKEN_MAP, + DEBUG_S_MERGED_ASSEMBLYINPUT, + + DEBUG_S_COFF_SYMBOL_RVA, +}; + +struct CV_DebugSSubsectionHeader_t +{ + enum DEBUG_S_SUBSECTION_TYPE type; + unsigned cbLen; +}; + +struct CV_DebugSLinesHeader_t +{ + unsigned offCon; + unsigned short segCon; + unsigned short flags; + unsigned cbCon; +}; + +struct CV_DebugSLinesFileBlockHeader_t +{ + unsigned offFile; + unsigned nLines; + unsigned cbBlock; + /* followed by two variable length arrays + * CV_Line_t lines[nLines]; + * ^ columns present when CV_DebugSLinesHeader_t.flags has CV_LINES_HAVE_COLUMNS set + * CV_Column_t columns[nLines]; + */ +}; + +#define CV_LINES_HAVE_COLUMNS 0x0001 + +struct CV_Line_t +{ + unsigned offset; + unsigned linenumStart:24; + unsigned deltaLineEnd:7; + unsigned fStatement:1; +}; + +struct CV_Column_t +{ + unsigned short offColumnStart; + unsigned short offColumnEnd; +}; + +struct CV_Checksum_t /* this one is not defined in microsoft pdb information */ +{ + unsigned strOffset; /* offset in string table for filename */ + unsigned char size; /* size of checksum */ + unsigned char method; /* method used to compute check sum */ + unsigned char checksum[0]; /* (size) bytes */ + /* result is padded on 4-byte boundary */ +}; + +#define CV_INLINEE_SOURCE_LINE_SIGNATURE 0x0 +#define CV_INLINEE_SOURCE_LINE_SIGNATURE_EX 0x1 + +typedef struct CV_InlineeSourceLine_t +{ + cv_itemid_t inlinee; /* function id */ + unsigned fileId; /* offset in DEBUG_S_FILECHKSMS */ + unsigned sourceLineNum; /* first line number */ +} InlineeSourceLine; + +typedef struct CV_InlineeSourceLineEx_t +{ + cv_itemid_t inlinee; /* function id */ + unsigned fileId; /* offset in DEBUG_S_FILECHKSMS */ + unsigned sourceLineNum; /* first line number */ + unsigned int countOfExtraFiles; + unsigned extraFileId[0]; +} InlineeSourceLineEx; + +#ifdef __WINESRC__ +/* those are Wine only helpers */ +/* align ptr on sz boundary; sz must be a power of 2 */ +#define CV_ALIGN(ptr, sz) ((const void*)(((DWORD_PTR)(ptr) + ((sz) - 1)) & ~((sz) - 1))) +/* move after (ptr) record */ +#define CV_RECORD_AFTER(ptr) ((const void*)((ptr) + 1)) +/* move after (ptr) record and a gap of sz bytes */ +#define CV_RECORD_GAP(ptr, sz) ((const void*)((const char*)((ptr) + 1) + (sz))) +/* test whether ptr record is within limit boundary */ +#define CV_IS_INSIDE(ptr, limit) (CV_RECORD_AFTER(ptr) <= (const void*)(limit)) +#endif /* __WINESRC__ */ + struct codeview_linetab_block { unsigned short seg; diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index d537764b442..79dd022a088 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1927,61 +1927,119 @@ void codeview_dump_linetab(const char* linetab, BOOL pascal_str, const char* pfx void codeview_dump_linetab2(const char* linetab, DWORD size, const char* strimage, DWORD strsize, const char* pfx) { unsigned i; - 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) + const struct CV_DebugSSubsectionHeader_t* hdr; + const struct CV_DebugSSubsectionHeader_t* next_hdr; + const struct CV_DebugSLinesHeader_t* lines_hdr; + const struct CV_DebugSLinesFileBlockHeader_t* files_hdr; + const struct CV_Column_t* cols; + const struct CV_Checksum_t* chksms; + const struct CV_InlineeSourceLine_t* inlsrc; + const struct CV_InlineeSourceLineEx_t* inlsrcex; + + static const char* subsect_types[] = /* starting at 0xf1 */ { - if (lt2->header == LT2_FILES_BLOCK) + "SYMBOLS", "LINES", "STRINGTABLE", "FILECHKSMS", + "FRAMEDATA", "INLINEELINES", "CROSSSCOPEIMPORTS", "CROSSSCOPEEXPORTS", + "IL_LINES", "FUNC_MDTOKEN_MAP", "TYPE_MDTOKEN_MAP", "MERGED_ASSEMBLYINPUT", + "COFF_SYMBOL_RVA" + }; + hdr = (const struct CV_DebugSSubsectionHeader_t*)linetab; + while (CV_IS_INSIDE(hdr, linetab + size)) + { + next_hdr = CV_RECORD_GAP(hdr, hdr->cbLen); + if (hdr->type & DEBUG_S_IGNORE) { - lt2_files = lt2; - break; + printf("%s------ debug subsection <ignored>\n", pfx); + hdr = next_hdr; + continue; } - 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------ debug subsection %s\n", pfx, + (hdr->type >= 0xf1 && hdr->type - 0xf1 < ARRAY_SIZE(subsect_types)) ? + subsect_types[hdr->type - 0xf1] : "<<unknown>>"); + switch (hdr->type) { - 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++) + case DEBUG_S_LINES: + lines_hdr = CV_RECORD_AFTER(hdr); + printf("%s block from %04x:%08x flags:%x size=%u\n", + pfx, lines_hdr->segCon, lines_hdr->offCon, lines_hdr->flags, lines_hdr->cbCon); + files_hdr = CV_RECORD_AFTER(lines_hdr); + /* FIXME: as of today partial coverage: + * - only one files_hdr has been seen in PDB files + * OTOH, MS github presents two different structures + * llvm ? one or two + * - next files_hdr (depending on previous question, can be a void question) + * is code correct ; what do MS and llvm do? + */ + while (CV_IS_INSIDE(files_hdr, next_hdr)) { - printf("%s offset=%08x line=%d\n", - pfx, lines_blk->l[i].offset, lines_blk->l[i].lineno ^ 0x80000000); + const struct CV_Line_t* lines; + printf("%s file=%u lines=%d size=%x\n", pfx, files_hdr->offFile, + files_hdr->nLines, files_hdr->cbBlock); + lines = CV_RECORD_AFTER(files_hdr); + cols = (const struct CV_Column_t*)&lines[files_hdr->nLines]; + for (i = 0; i < files_hdr->nLines; i++) + { + printf("%s offset=%8x line=%d deltaLineEnd=%u %s", + pfx, lines[i].offset, lines[i].linenumStart, lines[i].deltaLineEnd, + lines[i].fStatement ? "statement" : "expression"); + if (lines_hdr->flags & CV_LINES_HAVE_COLUMNS) + printf(" cols[start=%u end=%u]", + cols[i].offColumnStart, cols[i].offColumnEnd); + printf("\n"); + } + if (lines_hdr->flags & CV_LINES_HAVE_COLUMNS) + files_hdr = (const struct CV_DebugSLinesFileBlockHeader_t*)&cols[files_hdr->nLines]; + else + files_hdr = (const struct CV_DebugSLinesFileBlockHeader_t*)&lines[files_hdr->nLines]; } break; - case LT2_FILES_BLOCK: /* skip */ + case DEBUG_S_FILECHKSMS: + chksms = CV_RECORD_AFTER(hdr); + while (CV_IS_INSIDE(chksms, next_hdr)) + { + const char* meth[] = {"None", "MD5", "SHA1", "SHA256"}; + printf("%s %d] name=%s size=%u method=%s checksum=[", + pfx, (unsigned)((const char*)chksms - (const char*)(hdr + 1)), + strimage ? strimage + chksms->strOffset : "--none--", + chksms->size, chksms->method < ARRAY_SIZE(meth) ? meth[chksms->method] : "<<unknown>>"); + for (i = 0; i < chksms->size; ++i) printf("%02x", chksms->checksum[i]); + printf("]\n"); + chksms = CV_ALIGN(CV_RECORD_GAP(chksms, chksms->size), 4); + } + break; + case DEBUG_S_INLINEELINES: + /* subsection starts with a DWORD signature */ + switch (*(DWORD*)CV_RECORD_AFTER(hdr)) + { + case CV_INLINEE_SOURCE_LINE_SIGNATURE: + inlsrc = CV_RECORD_GAP(hdr, sizeof(DWORD)); + while (CV_IS_INSIDE(inlsrc, next_hdr)) + { + printf("%s inlinee=%x fileref=%d srcstart=%d\n", + pfx, inlsrc->inlinee, inlsrc->fileId, inlsrc->sourceLineNum); + ++inlsrc; + } + break; + case CV_INLINEE_SOURCE_LINE_SIGNATURE_EX: + inlsrcex = CV_RECORD_GAP(hdr, sizeof(DWORD)); + while (CV_IS_INSIDE(inlsrcex, next_hdr)) + { + printf("%s inlinee=%x fileref=%d srcstart=%d numExtraFiles=%d\n", + pfx, inlsrcex->inlinee, inlsrcex->fileId, inlsrcex->sourceLineNum, + inlsrcex->countOfExtraFiles); + inlsrcex = CV_RECORD_GAP(inlsrcex, inlsrcex->countOfExtraFiles * sizeof(inlsrcex->extraFileId[0])); + } + break; + default: + printf("%sUnknown signature %x in INLINEELINES subsection\n", pfx, *(DWORD*)CV_RECORD_AFTER(hdr)); + break; + } break; default: - printf("%sblock end %x\n", pfx, lt2->header); - lt2 = (const struct codeview_linetab2*)(linetab + size); - continue; + dump_data(CV_RECORD_AFTER(hdr), hdr->cbLen, pfx); + break; } - lt2 = codeview_linetab2_next_block(lt2); + hdr = next_hdr; } }
Removed obsolete linetab2 definitions from include/wine/mscvpdb.h
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/msc.c | 107 ++++++++++++++++++++++++++---------------------- include/wine/mscvpdb.h | 51 ----------------------- 2 files changed, 59 insertions(+), 99 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 4aaee196370..b4487d583cb 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -1465,70 +1465,81 @@ static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const { unsigned i; DWORD_PTR addr; - 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; + const struct CV_DebugSSubsectionHeader_t* hdr; + const struct CV_DebugSSubsectionHeader_t* hdr_next; + const struct CV_DebugSSubsectionHeader_t* hdr_files = NULL; + const struct CV_DebugSLinesHeader_t* lines_hdr; + const struct CV_DebugSLinesFileBlockHeader_t* files_hdr; + const struct CV_Line_t* lines; + const struct CV_Checksum_t* chksms; unsigned source; struct symt_function* func;
- /* locate LT2_FILES_BLOCK (if any) */ - lt2 = (const struct codeview_linetab2*)linetab; - while ((const BYTE*)(lt2 + 1) < linetab + size) + /* locate DEBUG_S_FILECHKSMS (if any) */ + hdr = (const struct CV_DebugSSubsectionHeader_t*)linetab; + while (CV_IS_INSIDE(hdr, linetab + size)) { - if (lt2->header == LT2_FILES_BLOCK) + if (hdr->type == DEBUG_S_FILECHKSMS) { - lt2_files = lt2; + hdr_files = hdr; break; } - lt2 = codeview_linetab2_next_block(lt2); + hdr = CV_RECORD_GAP(hdr, hdr->cbLen); } - if (!lt2_files) + if (!hdr_files) { - TRACE("No LT2_FILES_BLOCK found\n"); + TRACE("No DEBUG_S_FILECHKSMS 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) - { - case LT2_LINES_BLOCK: - /* Skip blocks that are too small - Intel C Compiler generates these. */ - if (lt2->size_of_block < sizeof (struct codeview_lt2blk_lines)) break; - 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 (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite)) + hdr = (const struct CV_DebugSSubsectionHeader_t*)linetab; + while (CV_IS_INSIDE(hdr, linetab + size)) + { + hdr_next = CV_RECORD_GAP(hdr, hdr->cbLen); + if (!(hdr->type & DEBUG_S_IGNORE)) + { + /* FIXME: should also check that whole lines_blk fits in linetab + size */ + switch (hdr->type) { - WARN("--not a func at %04x:%08x %lx tag=%d\n", - lines_blk->seg, lines_blk->start, addr, func ? func->symt.tag : -1); + case DEBUG_S_LINES: + lines_hdr = CV_RECORD_AFTER(hdr); + files_hdr = CV_RECORD_AFTER(lines_hdr); + /* Skip blocks that are too small - Intel C Compiler generates these. */ + if (!CV_IS_INSIDE(files_hdr, hdr_next)) break; + addr = codeview_get_address(msc_dbg, lines_hdr->segCon, lines_hdr->offCon); + TRACE("block from %04x:%08x #%x\n", + lines_hdr->segCon, lines_hdr->offCon, lines_hdr->cbCon); + chksms = CV_RECORD_GAP(hdr_files, files_hdr->offFile); + if (!CV_IS_INSIDE(chksms, CV_RECORD_GAP(hdr_files, hdr_files->cbLen))) + { + WARN("Corrupt PDB file: offset in CHKSMS subsection is invalid\n"); + break; + } + source = source_new(msc_dbg->module, NULL, + (chksms->strOffset < strsize) ? strimage + chksms->strOffset : "<<stroutofbounds>>"); + func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr); + /* FIXME: at least labels support line numbers */ + if (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite)) + { + WARN("--not a func at %04x:%08x %Ix tag=%d\n", + lines_hdr->segCon, lines_hdr->offCon, addr, func ? func->symt.tag : -1); + break; + } + lines = CV_RECORD_AFTER(files_hdr); + for (i = 0; i < files_hdr->nLines; i++) + { + symt_add_func_line(msc_dbg->module, func, source, + lines[i].linenumStart, + func->address + lines[i].offset); + } + break; + case DEBUG_S_FILECHKSMS: /* skip */ + break; + default: break; } - for (i = 0; i < lines_blk->nlines; i++) - { - symt_add_func_line(msc_dbg->module, func, source, - lines_blk->l[i].lineno ^ 0x80000000, - func->address + lines_blk->l[i].offset); - } - 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; } - lt2 = codeview_linetab2_next_block(lt2); + hdr = hdr_next; } }
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 733b4ab5336..dcd0e4db303 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -2279,57 +2279,6 @@ 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 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 */ - 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_lt2blk_files -{ - struct codeview_linetab2 lt2; /* LT2_FILES */ - struct codeview_linetab2_file file[1]; -}; - -struct codeview_lt2blk_lines -{ - 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 ???) */ - } l[1]; /* actually array of <nlines> */ -}; - /* ======================================== * * PDB file information * ======================================== */
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/dbghelp.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/dbghelp.h b/include/dbghelp.h index 4dad9cd45e9..248b3ab418d 100644 --- a/include/dbghelp.h +++ b/include/dbghelp.h @@ -1128,6 +1128,14 @@ BOOL WINAPI SymAddSymbolW(HANDLE, ULONG64, PCWSTR, DWORD64, DWORD, DWORD); BOOL WINAPI SymDeleteSymbol(HANDLE, ULONG64, PCSTR, DWORD64, DWORD); BOOL WINAPI SymDeleteSymbolW(HANDLE, ULONG64, PCWSTR, DWORD64, DWORD);
+typedef struct _OMAP +{ + ULONG rva; + ULONG rvaTo; +} OMAP, *POMAP; + +BOOL WINAPI SymGetOmaps(HANDLE, DWORD64, POMAP*, PDWORD64, POMAP*, PDWORD64); + /************************* * Source Files * *************************/
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dbghelp_private.h | 15 +++++++++++++++ dlls/dbghelp/msc.c | 10 +++++----- include/wine/mscvpdb.h | 23 ----------------------- 3 files changed, 20 insertions(+), 28 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 5682acadf65..61173b34b5a 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -663,6 +663,21 @@ struct cpu
extern struct cpu* dbghelp_current_cpu DECLSPEC_HIDDEN;
+/* PDB and Codeview */ + +struct msc_debug_info +{ + struct module* module; + int nsect; + const IMAGE_SECTION_HEADER* sectp; + int nomap; + const OMAP* omapp; + const BYTE* root; +}; + +/* coff.c */ +extern BOOL coff_process_info(const struct msc_debug_info* msc_dbg) DECLSPEC_HIDDEN; + /* dbghelp.c */ extern struct process* process_find_by_handle(HANDLE hProcess) DECLSPEC_HIDDEN; extern BOOL validate_addr64(DWORD64 addr) DECLSPEC_HIDDEN; diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index b4487d583cb..97991be057f 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -1551,15 +1551,15 @@ static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg, unsigned int offset) { int nomap = msc_dbg->nomap; - const OMAP_DATA* omapp = msc_dbg->omapp; + const OMAP* omapp = msc_dbg->omapp; int i;
if (!nomap || !omapp) return offset;
/* FIXME: use binary search */ for (i = 0; i < nomap - 1; i++) - if (omapp[i].from <= offset && omapp[i+1].from > offset) - return !omapp[i].to ? 0 : omapp[i].to + (offset - omapp[i].from); + if (omapp[i].rva <= offset && omapp[i+1].rva > offset) + return !omapp[i].rvaTo ? 0 : omapp[i].rvaTo + (offset - omapp[i].rva);
return 0; } @@ -3414,8 +3414,8 @@ BOOL pe_load_debug_directory(const struct process* pcs, struct module* module, { if (dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC) { - msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA); - msc_dbg.omapp = (const OMAP_DATA*)(mapping + dbg[i].PointerToRawData); + msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP); + msc_dbg.omapp = (const OMAP*)(mapping + dbg[i].PointerToRawData); break; } } diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index dcd0e4db303..e199aff785f 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -2520,29 +2520,6 @@ typedef struct _PDB_FPO_DATA
#include "poppack.h"
-/* ---------------------------------------------- - * Information used for parsing - * ---------------------------------------------- */ - -typedef struct -{ - DWORD from; - DWORD to; -} OMAP_DATA; - -struct msc_debug_info -{ - struct module* module; - int nsect; - const IMAGE_SECTION_HEADER* sectp; - int nomap; - const OMAP_DATA* omapp; - const BYTE* root; -}; - -/* coff.c */ -extern BOOL coff_process_info(const struct msc_debug_info* msc_dbg); - /* =================================================== * The old CodeView stuff (for NB09 and NB11) * =================================================== */