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

mscvpdb.h: Update some line number oriented definitions.

parent 23fe1ad9
......@@ -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;
......
......@@ -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;
}
}
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