winedump: Add support for S_DEFRANGE* family of CodeView records.

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:37 +02:00 committed by Alexandre Julliard
parent 5c9c342858
commit d1e1d80c0e
2 changed files with 135 additions and 0 deletions

View File

@ -1245,6 +1245,19 @@ union codeview_fieldtype
* Symbol information
* ======================================== */
struct cv_addr_range
{
unsigned int offStart;
unsigned short isectStart;
unsigned short cbRange;
};
struct cv_addr_gap
{
unsigned short gapStartOffset;
unsigned short cbRange;
};
union codeview_symbol
{
struct
@ -1736,6 +1749,76 @@ union codeview_symbol
unsigned short varflags;
char name[1];
} local_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned int program;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned int program;
unsigned int offParent;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_subfield_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned short reg;
unsigned short attr;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_register_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned int offFramePointer;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_frameptrrel_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned int offFramePointer;
} defrange_frameptr_relfullscope_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned short reg;
unsigned short attr;
unsigned int offParent : 12;
unsigned int padding : 20;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_subfield_register_v3;
struct
{
unsigned short int len;
unsigned short int id;
unsigned short baseReg;
unsigned short spilledUdtMember : 1;
unsigned short padding : 3;
unsigned short offsetParent : 12;
unsigned int offBasePointer;
struct cv_addr_range range;
struct cv_addr_gap gaps[0];
} defrange_registerrel_v3;
};
#define S_COMPILE 0x0001

View File

@ -1136,6 +1136,21 @@ BOOL codeview_dump_types_from_block(const void* table, unsigned long len)
return TRUE;
}
static void dump_defrange(const struct cv_addr_range* range, const void* last, const char* pfx)
{
const struct cv_addr_gap* gap;
printf("%s%04x:%08x range:#%x\n", pfx, range->isectStart, range->offStart, range->cbRange);
for (gap = (const struct cv_addr_gap*)(range + 1); (const void*)(gap + 1) <= last; ++gap)
printf("%s\toffset:%x range:#%x\n", pfx, gap->gapStartOffset, gap->cbRange);
}
/* return adress of first byte after the symbol */
static inline const char* get_last(const union codeview_symbol* sym)
{
return (const char*)sym + sym->generic.len + 2;
}
BOOL codeview_dump_symbols(const void* root, unsigned long size)
{
unsigned int i;
@ -1598,6 +1613,43 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
break;
case S_DEFRANGE:
printf("\tS-DefRange dia:%x\n", sym->defrange_v3.program);
dump_defrange(&sym->defrange_v3.range, get_last(sym), "\t\t");
break;
case S_DEFRANGE_SUBFIELD:
printf("\tS-DefRange-subfield V3 dia:%x off-parent:%x\n",
sym->defrange_subfield_v3.program, sym->defrange_subfield_v3.offParent);
dump_defrange(&sym->defrange_subfield_v3.range, get_last(sym), "\t\t");
break;
case S_DEFRANGE_REGISTER:
printf("\tS-DefRange-register V3 reg:%x attr-unk:%x\n",
sym->defrange_register_v3.reg, sym->defrange_register_v3.attr);
dump_defrange(&sym->defrange_register_v3.range, get_last(sym), "\t\t");
break;
case S_DEFRANGE_FRAMEPOINTER_REL:
printf("\tS-DefRange-framepointer-rel V3 offFP:%x\n",
sym->defrange_frameptrrel_v3.offFramePointer);
dump_defrange(&sym->defrange_frameptrrel_v3.range, get_last(sym), "\t\t");
break;
case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
printf("\tS-DefRange-framepointer-rel-fullscope V3 offFP:%x\n",
sym->defrange_frameptr_relfullscope_v3.offFramePointer);
break;
case S_DEFRANGE_SUBFIELD_REGISTER:
printf("\tS-DefRange-subfield-register V3 reg:%d attr-unk:%x off-parent:%x\n",
sym->defrange_subfield_register_v3.reg,
sym->defrange_subfield_register_v3.attr,
sym->defrange_subfield_register_v3.offParent);
dump_defrange(&sym->defrange_subfield_register_v3.range, get_last(sym), "\t\t");
break;
case S_DEFRANGE_REGISTER_REL:
printf("\tS-DefRange-register-rel V3 reg:%x off-parent:%x off-BP:%x\n",
sym->defrange_registerrel_v3.baseReg, sym->defrange_registerrel_v3.offsetParent,
sym->defrange_registerrel_v3.offBasePointer);
dump_defrange(&sym->defrange_registerrel_v3.range, get_last(sym), "\t\t");
break;
default:
printf(">>> Unsupported symbol-id %x sz=%d\n", sym->generic.id, sym->generic.len + 2);
dump_data((const void*)sym, sym->generic.len + 2, " ");