winedump: Add support for dumping CodeView records about site information.

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2021-08-24 11:11:49 +02:00 committed by Alexandre Julliard
parent de615a11e5
commit 3935234265
2 changed files with 158 additions and 0 deletions

View File

@ -110,6 +110,7 @@ struct p_string
typedef unsigned short cv_typ16_t;
typedef unsigned int cv_typ_t;
typedef cv_typ_t cv_itemid_t;
/* ======================================== *
* Type information
@ -1819,6 +1820,56 @@ union codeview_symbol
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_registerrel_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned int pParent;
unsigned int pEnd;
cv_itemid_t inlinee;
unsigned char binaryAnnotations[0];
} inline_site_v3;
struct
{
unsigned short int len;
unsigned short int typ;
unsigned int off;
unsigned short sect;
unsigned short _pad0;
cv_typ_t typind;
} callsiteinfo_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned int pParent;
unsigned int pEnd;
cv_itemid_t inlinee;
unsigned int invocations;
unsigned char binaryAnnotations[0];
} inline_site2_v3;
};
enum BinaryAnnotationOpcode
{
BA_OP_Invalid,
BA_OP_CodeOffset,
BA_OP_ChangeCodeOffsetBase,
BA_OP_ChangeCodeOffset,
BA_OP_ChangeCodeLength,
BA_OP_ChangeFile,
BA_OP_ChangeLineOffset,
BA_OP_ChangeLineEndDelta,
BA_OP_ChangeRangeKind,
BA_OP_ChangeColumnStart,
BA_OP_ChangeColumnEndDelta,
BA_OP_ChangeCodeOffsetAndLineOffset,
BA_OP_ChangeCodeLengthAndCodeOffset,
BA_OP_ChangeColumnEnd,
};
#define S_COMPILE 0x0001

View File

@ -1151,6 +1151,93 @@ static inline const char* get_last(const union codeview_symbol* sym)
return (const char*)sym + sym->generic.len + 2;
}
static unsigned binannot_uncompress(const unsigned char** pptr)
{
unsigned res = (unsigned)(-1);
const unsigned char* ptr = *pptr;
if ((*ptr & 0x80) == 0x00)
res = (unsigned)(*ptr++);
else if ((*ptr & 0xC0) == 0x80)
{
res = (unsigned)((*ptr++ & 0x3f) << 8);
res |= *ptr++;
}
else if ((*ptr & 0xE0) == 0xC0)
{
res = (*ptr++ & 0x1f) << 24;
res |= *ptr++ << 16;
res |= *ptr++ << 8;
res |= *ptr++;
}
else res = (unsigned)(-1);
*pptr = ptr;
return res;
}
static void dump_binannot(const unsigned char* ba, const char* last, const char* pfx)
{
while (ba < (const unsigned char*)last)
{
unsigned opcode = binannot_uncompress(&ba);
switch (opcode)
{
case BA_OP_Invalid:
/* not clear if param? */
printf("%sInvalid\n", pfx);
break;
case BA_OP_CodeOffset:
printf("%sCodeOffset %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeCodeOffsetBase:
printf("%sChangeCodeOffsetBase %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeCodeOffset:
printf("%sChangeCodeOffset %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeCodeLength:
printf("%sChangeCodeLength %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeFile:
printf("%sChangeFile %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeLineOffset:
printf("%sChangeLineOffset %d\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeLineEndDelta:
printf("%sChangeLineEndDelta %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeRangeKind:
printf("%sChangeRangeKind %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeColumnStart:
printf("%sChangeColumnStart %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeColumnEndDelta:
printf("%sChangeColumnEndDelta %u\n", pfx, binannot_uncompress(&ba));
break;
case BA_OP_ChangeCodeOffsetAndLineOffset:
{
unsigned p1 = binannot_uncompress(&ba);
printf("%sChangeCodeOffsetAndLineOffset %u %u (0x%x)\n", pfx, p1 & 0xf, p1 >> 4, p1);
}
break;
case BA_OP_ChangeCodeLengthAndCodeOffset:
{
unsigned p1 = binannot_uncompress(&ba);
unsigned p2 = binannot_uncompress(&ba);
printf("%sChangeCodeLengthAndCodeOffset %u %u\n", pfx, p1, p2);
}
break;
case BA_OP_ChangeColumnEnd:
printf("%sChangeColumnEnd %u\n", pfx, binannot_uncompress(&ba));
break;
default: printf("%sUnsupported op %d %x\n", pfx, opcode, opcode); /* may cause issues because of param */
}
}
}
BOOL codeview_dump_symbols(const void* root, unsigned long size)
{
unsigned int i;
@ -1651,6 +1738,26 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
dump_defrange(&sym->defrange_registerrel_v3.range, get_last(sym), "\t\t");
break;
case S_CALLSITEINFO:
printf("Call-site-info V3 %04x:%08x typeindex:%x\n",
sym->callsiteinfo_v3.sect, sym->callsiteinfo_v3.off, sym->callsiteinfo_v3.typind);
break;
case S_INLINESITE:
printf("Inline-site V3 parent:%x end:%x inlinee:%x\n",
sym->inline_site_v3.pParent, sym->inline_site_v3.pEnd, sym->inline_site_v3.inlinee);
dump_binannot(sym->inline_site_v3.binaryAnnotations, get_last(sym), "\t\t");
break;
case S_INLINESITE2:
printf("Inline-site2 V3 parent:%x end:%x inlinee:%x #inv:%u\n",
sym->inline_site2_v3.pParent, sym->inline_site2_v3.pEnd, sym->inline_site2_v3.inlinee,
sym->inline_site2_v3.invocations);
dump_binannot(sym->inline_site2_v3.binaryAnnotations, get_last(sym), "\t\t");
break;
case S_INLINESITE_END:
printf("Inline-site-end\n");
break;
default:
printf("\n\t\t>>> Unsupported symbol-id %x sz=%d\n", sym->generic.id, sym->generic.len + 2);
dump_data((const void*)sym, sym->generic.len + 2, " ");