diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 4d4b8166473..ca3f120a5d6 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -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 diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 6d463c0ee1b..20471bd23bc 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -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, " ");