The following serie adds definitions and dumping facility for a couple of more codeview records. It also adds more internal PDB details to winedump.
---
Eric Pouech (14): tools/winedump: correctly support flags in public records (V1 and V2) tools/winedump: added support for dumping S_LOCAL symbol record tools/winedump: added support for S_DEFRANGE* family of CodeView records tools/winedump: print symbol id when dumping symbols tools/winedump: now dumping CodeView records about site information tools/winedump: added support for CALLERS/CALLEES/INLINEES codeview records tools/winedump: added support for buildinfo codeview record tools/winedump: added support for dumping trampoline codeview records tools/winedump: now dumping heap_alloc_site CodeView records tools/winedump: added support for dumping filestatic Codeview records tools/winedump: added support for dumping stream of fixed index 4 tools/winedump: now dumping information about type's hash stream tools/winedump: now dumping CodeView types records found in IPI stream (#4) tools/winedump: correct and update a couple of info in PDB symbol stream header
dlls/dbghelp/msc.c | 10 +- include/wine/mscvpdb.h | 270 +++++++++++++++++++++++++++- tools/winedump/msc.c | 390 +++++++++++++++++++++++++++++++++++------ tools/winedump/pdb.c | 100 +++++++++-- 4 files changed, 689 insertions(+), 81 deletions(-)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/msc.c | 4 ++-- include/wine/mscvpdb.h | 4 ++-- tools/winedump/msc.c | 32 +++++++++++++++++++++++++------- 3 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 380511d0b55..f77592664ef 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2058,7 +2058,7 @@ static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BY { symt_new_public(msc_dbg->module, compiland, terminate_string(&sym->public_v1.p_name), - sym->public_v1.symtype == SYMTYPE_FUNCTION, + sym->public_v1.pubsymflags == SYMTYPE_FUNCTION, codeview_get_address(msc_dbg, sym->public_v1.segment, sym->public_v1.offset), 1); } break; @@ -2067,7 +2067,7 @@ static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BY { symt_new_public(msc_dbg->module, compiland, terminate_string(&sym->public_v2.p_name), - sym->public_v2.symtype == SYMTYPE_FUNCTION, + sym->public_v2.pubsymflags == SYMTYPE_FUNCTION, codeview_get_address(msc_dbg, sym->public_v2.segment, sym->public_v2.offset), 1); } break; diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 2ed9a9fe192..9e544108bdd 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1368,7 +1368,7 @@ union codeview_symbol unsigned short int id; unsigned int offset; unsigned short segment; - cv_typ16_t symtype; + unsigned short pubsymflags; struct p_string p_name; } public_v1;
@@ -1376,7 +1376,7 @@ union codeview_symbol { unsigned short int len; unsigned short int id; - cv_typ_t symtype; + unsigned int pubsymflags; unsigned int offset; unsigned short segment; struct p_string p_name; diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 7f93f3e7701..c7ca3eea77a 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -457,6 +457,20 @@ static const char* get_callconv(unsigned cc) return callconv; }
+static const char* get_pubflags(unsigned flags) +{ + static char ret[32]; + + ret[0] = '\0'; +#define X(s) {if (ret[0]) strcat(ret, ";"); strcat(ret, s);} + if (flags & 1) X("code"); + if (flags & 2) X("func"); + if (flags & 4) X("manage"); + if (flags & 8) X("msil"); +#undef X + return ret; +} + static void do_field(const unsigned char* start, const unsigned char* end) { /* @@ -1134,21 +1148,25 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) sym->data_v3.symtype); break;
+ case S_PUB32_16t: + printf("\tS-Public V1 '%s' %04x:%08x flags:%s\n", + get_symbol_str(p_string(&sym->public_v1.p_name)), + sym->public_v1.segment, sym->public_v1.offset, + get_pubflags(sym->public_v1.pubsymflags)); + break; + case S_PUB32_ST: - printf("\tS-Public V2 '%s' %04x:%08x type:%08x\n", + printf("\tS-Public V2 '%s' %04x:%08x flags:%s\n", get_symbol_str(p_string(&sym->public_v2.p_name)), sym->public_v2.segment, sym->public_v2.offset, - sym->public_v2.symtype); + get_pubflags(sym->public_v2.pubsymflags)); break;
case S_PUB32: - printf("\tS-Public V3 '%s' %04x:%08x flags%s%s%s%s\n", + printf("\tS-Public V3 '%s' %04x:%08x flags:%s\n", get_symbol_str(sym->public_v3.name), sym->public_v3.segment, sym->public_v3.offset, - (sym->public_v3.pubsymflags & 1) ? "-code" : "", - (sym->public_v3.pubsymflags & 2) ? "-func" : "", - (sym->public_v3.pubsymflags & 4) ? "-manage" : "", - (sym->public_v3.pubsymflags & 8) ? "-msil" : ""); + get_pubflags(sym->public_v3.pubsymflags)); break;
case S_DATAREF:
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 9 +++++++++ tools/winedump/msc.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 9e544108bdd..4d4b8166473 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1727,6 +1727,15 @@ union codeview_symbol unsigned short inst_len; unsigned int index; } heap_alloc_site; + + struct + { + unsigned short int len; + unsigned short int id; + cv_typ_t symtype; + unsigned short varflags; + char name[1]; + } local_v3; };
#define S_COMPILE 0x0001 diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index c7ca3eea77a..6d463c0ee1b 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -288,6 +288,33 @@ static const char* get_funcattr(unsigned attr) return tmp; }
+static const char* get_varflags(unsigned flags) +{ + static char tmp[1024]; + unsigned pos = 0; + + if (!flags) return "none"; +#define X(s) {if (pos) tmp[pos++] = ';'; strcpy(tmp + pos, s); pos += strlen(s);} + if (flags & 0x0001) X("param"); + if (flags & 0x0002) X("addr-taken"); + if (flags & 0x0004) X("compiler-gen"); + if (flags & 0x0008) X("aggregated"); + if (flags & 0x0010) X("in-aggreate"); + if (flags & 0x0020) X("aliased"); + if (flags & 0x0040) X("alias"); + if (flags & 0x0080) X("retval"); + if (flags & 0x0100) X("optimized-out"); + if (flags & 0x0200) X("enreg-global"); + if (flags & 0x0400) X("enreg-static"); + if (flags & 0xf800) pos += sprintf(tmp, "unk:%x", flags & 0xf800); +#undef X + + tmp[pos] = '\0'; + assert(pos < sizeof(tmp)); + + return tmp; +} + static const char* get_machine(unsigned m) { const char* machine; @@ -1564,6 +1591,13 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) sym->thread_v3.segment, sym->thread_v3.offset, sym->thread_v3.symtype); break;
+ case S_LOCAL: + printf("\tS-Local V3 '%s' type=%x flags=%s\n", + sym->local_v3.name, sym->local_v3.symtype, + get_varflags(sym->local_v3.varflags)); + + 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, " ");
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/winedump/msc.c | 52 ++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+)
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, " ");
In CV records, the cv_itemid is used to reference other symbols, so we need to print out the symbol id
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- tools/winedump/msc.c | 121 +++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 60 deletions(-)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 20471bd23bc..d1d3674daca 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1166,6 +1166,8 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) const union codeview_symbol* sym = (const union codeview_symbol*)((const char*)root + i); length = sym->generic.len + 2; if (!sym->generic.id || length < 4) break; + printf("\t%04x => ", i + 4); /* ref is made after id and len */ + switch (sym->generic.id) { /* @@ -1174,7 +1176,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) */ case S_GDATA32_ST: case S_LDATA32_ST: - printf("\tS-%s-Data V2 '%s' %04x:%08x type:%08x\n", + printf("%s-Data V2 '%s' %04x:%08x type:%08x\n", sym->generic.id == S_GDATA32_ST ? "Global" : "Local", get_symbol_str(p_string(&sym->data_v2.p_name)), sym->data_v2.segment, sym->data_v2.offset, sym->data_v2.symtype); @@ -1183,7 +1185,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) case S_LDATA32: case S_GDATA32: /* EPP case S_DATA32: */ - printf("\tS-%s-Data V3 '%s' (%04x:%08x) type:%08x\n", + printf("%s-Data V3 '%s' (%04x:%08x) type:%08x\n", sym->generic.id == S_GDATA32 ? "Global" : "Local", get_symbol_str(sym->data_v3.name), sym->data_v3.segment, sym->data_v3.offset, @@ -1191,21 +1193,21 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_PUB32_16t: - printf("\tS-Public V1 '%s' %04x:%08x flags:%s\n", + printf("Public V1 '%s' %04x:%08x flags:%s\n", get_symbol_str(p_string(&sym->public_v1.p_name)), sym->public_v1.segment, sym->public_v1.offset, get_pubflags(sym->public_v1.pubsymflags)); break;
case S_PUB32_ST: - printf("\tS-Public V2 '%s' %04x:%08x flags:%s\n", + printf("Public V2 '%s' %04x:%08x flags:%s\n", get_symbol_str(p_string(&sym->public_v2.p_name)), sym->public_v2.segment, sym->public_v2.offset, get_pubflags(sym->public_v2.pubsymflags)); break;
case S_PUB32: - printf("\tS-Public V3 '%s' %04x:%08x flags:%s\n", + printf("Public V3 '%s' %04x:%08x flags:%s\n", get_symbol_str(sym->public_v3.name), sym->public_v3.segment, sym->public_v3.offset, get_pubflags(sym->public_v3.pubsymflags)); @@ -1214,7 +1216,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) case S_DATAREF: case S_PROCREF: case S_LPROCREF: - printf("\tS-%sref V3 '%s' mod:%04x sym:%08x name:%08x\n", + printf("%sref V3 '%s' %04x:%08x name:%08x\n", sym->generic.id == S_DATAREF ? "Data" : (sym->generic.id == S_PROCREF ? "Proc" : "Lproc"), get_symbol_str(sym->refsym2_v3.name), @@ -1227,7 +1229,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) * a PLT slot in the normal jargon that everyone else uses. */ case S_THUNK32_ST: - printf("\tS-Thunk V1 '%s' (%04x:%08x#%x) type:%x\n", + printf("Thunk V1 '%s' (%04x:%08x#%x) type:%x\n", p_string(&sym->thunk_v1.p_name), sym->thunk_v1.segment, sym->thunk_v1.offset, sym->thunk_v1.thunk_len, sym->thunk_v1.thtype); @@ -1235,7 +1237,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_THUNK32: - printf("\tS-Thunk V3 '%s' (%04x:%08x#%x) type:%x\n", + printf("Thunk V3 '%s' (%04x:%08x#%x) type:%x\n", sym->thunk_v3.name, sym->thunk_v3.segment, sym->thunk_v3.offset, sym->thunk_v3.thunk_len, sym->thunk_v3.thtype); @@ -1245,13 +1247,13 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) /* Global and static functions */ case S_GPROC32_16t: case S_LPROC32_16t: - printf("\tS-%s-Proc V1: '%s' (%04x:%08x#%x) type:%x attr:%x\n", + printf("%s-Proc V1: '%s' (%04x:%08x#%x) type:%x attr:%x\n", sym->generic.id == S_GPROC32_16t ? "Global" : "-Local", p_string(&sym->proc_v1.p_name), sym->proc_v1.segment, sym->proc_v1.offset, sym->proc_v1.proc_len, sym->proc_v1.proctype, sym->proc_v1.flags); - printf("\t Debug: start=%08x end=%08x\n", + printf("\t\tDebug: start=%08x end=%08x\n", sym->proc_v1.debug_start, sym->proc_v1.debug_end); if (nest_block) { @@ -1266,13 +1268,13 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
case S_GPROC32_ST: case S_LPROC32_ST: - printf("\tS-%s-Proc V2: '%s' (%04x:%08x#%x) type:%x attr:%x\n", + printf("%s-Proc V2: '%s' (%04x:%08x#%x) type:%x attr:%x\n", sym->generic.id == S_GPROC32_ST ? "Global" : "-Local", p_string(&sym->proc_v2.p_name), sym->proc_v2.segment, sym->proc_v2.offset, sym->proc_v2.proc_len, sym->proc_v2.proctype, sym->proc_v2.flags); - printf("\t Debug: start=%08x end=%08x\n", + printf("\t\tDebug: start=%08x end=%08x\n", sym->proc_v2.debug_start, sym->proc_v2.debug_end); if (nest_block) { @@ -1287,13 +1289,13 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
case S_LPROC32: case S_GPROC32: - printf("\tS-%s-Procedure V3 '%s' (%04x:%08x#%x) type:%x attr:%x\n", + printf("%s-Procedure V3 '%s' (%04x:%08x#%x) type:%x attr:%x\n", sym->generic.id == S_GPROC32 ? "Global" : "Local", sym->proc_v3.name, sym->proc_v3.segment, sym->proc_v3.offset, sym->proc_v3.proc_len, sym->proc_v3.proctype, sym->proc_v3.flags); - printf("\t Debug: start=%08x end=%08x\n", + printf("\t\tDebug: start=%08x end=%08x\n", sym->proc_v3.debug_start, sym->proc_v3.debug_end); if (nest_block) { @@ -1308,49 +1310,49 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
/* Function parameters and stack variables */ case S_BPREL32_16t: - printf("\tS-BP-relative V1: '%s' @%d type:%x (%s)\n", + printf("BP-relative V1: '%s' @%d type:%x (%s)\n", p_string(&sym->stack_v1.p_name), sym->stack_v1.offset, sym->stack_v1.symtype, curr_func); break;
case S_BPREL32_ST: - printf("\tS-BP-relative V2: '%s' @%d type:%x (%s)\n", + printf("BP-relative V2: '%s' @%d type:%x (%s)\n", p_string(&sym->stack_v2.p_name), sym->stack_v2.offset, sym->stack_v2.symtype, curr_func); break;
case S_BPREL32: - printf("\tS-BP-relative V3: '%s' @%d type:%x (in %s)\n", + printf("BP-relative V3: '%s' @%d type:%x (in %s)\n", sym->stack_v3.name, sym->stack_v3.offset, sym->stack_v3.symtype, curr_func); break;
case S_REGREL32: - printf("\tS-Reg-relative V3: '%s' @%d type:%x reg:%x (in %s)\n", + printf("Reg-relative V3: '%s' @%d type:%x reg:%x (in %s)\n", sym->regrel_v3.name, sym->regrel_v3.offset, sym->regrel_v3.symtype, sym->regrel_v3.reg, curr_func); break;
case S_REGISTER_16t: - printf("\tS-Register V1 '%s' in %s type:%x register:%x\n", + printf("Register V1 '%s' in %s type:%x register:%x\n", p_string(&sym->register_v1.p_name), curr_func, sym->register_v1.reg, sym->register_v1.type); break;
case S_REGISTER_ST: - printf("\tS-Register V2 '%s' in %s type:%x register:%x\n", + printf("Register V2 '%s' in %s type:%x register:%x\n", p_string(&sym->register_v2.p_name), curr_func, sym->register_v2.reg, sym->register_v2.type); break;
case S_REGISTER: - printf("\tS-Register V3 '%s' in %s type:%x register:%x\n", + printf("Register V3 '%s' in %s type:%x register:%x\n", sym->register_v3.name, curr_func, sym->register_v3.reg, sym->register_v3.type); break;
case S_BLOCK32_ST: - printf("\tS-Block V1 '%s' in '%s' (%04x:%08x#%08x)\n", + printf("Block V1 '%s' in '%s' (%04x:%08x#%08x)\n", p_string(&sym->block_v1.p_name), curr_func, sym->block_v1.segment, sym->block_v1.offset, @@ -1359,7 +1361,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_BLOCK32: - printf("\tS-Block V3 '%s' in '%s' (%04x:%08x#%08x) parent:%u end:%x\n", + printf("Block V3 '%s' in '%s' (%04x:%08x#%08x) parent:%u end:%x\n", sym->block_v3.name, curr_func, sym->block_v3.segment, sym->block_v3.offset, sym->block_v3.length, sym->block_v3.parent, sym->block_v3.end); @@ -1368,7 +1370,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
/* Additional function information */ case S_FRAMEPROC: - printf("\tS-Frame-Info V2: frame-size:%x unk2:%x unk3:%x saved-regs-sz:%x eh(%04x:%08x) flags:%08x\n", + printf("Frame-Info V2: frame-size:%x unk2:%x unk3:%x saved-regs-sz:%x eh(%04x:%08x) flags:%08x\n", sym->frame_info_v2.sz_frame, sym->frame_info_v2.unknown2, sym->frame_info_v2.unknown3, @@ -1379,7 +1381,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_FRAMECOOKIE: - printf("\tSecurity Cookie V3 @%d unk:%x\n", + printf("Security Cookie V3 @%d unk:%x\n", sym->security_cookie_v3.offset, sym->security_cookie_v3.unknown); break;
@@ -1387,18 +1389,18 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) if (nest_block) { nest_block--; - printf("\tS-End-Of block (%u)\n", nest_block); + printf("End-Of block (%u)\n", nest_block); } else { - printf("\tS-End-Of %s\n", curr_func); + printf("End-Of %s\n", curr_func); free(curr_func); curr_func = NULL; } break;
case S_COMPILE: - printf("\tS-Compile V1 machine:%s lang:%s _unk:%x '%s'\n", + printf("Compile V1 machine:%s lang:%s _unk:%x '%s'\n", get_machine(sym->compile_v1.machine), get_language(sym->compile_v1.flags.language), sym->compile_v1.flags._dome, @@ -1406,7 +1408,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_COMPILE2_ST: - printf("\tS-Compile2-V2 lang:%s machine:%s _unk:%x front-end:%d.%d.%d back-end:%d.%d.%d '%s'\n", + printf("Compile2-V2 lang:%s machine:%s _unk:%x front-end:%d.%d.%d back-end:%d.%d.%d '%s'\n", get_language(sym->compile2_v2.flags.iLanguage), get_machine(sym->compile2_v2.machine), sym->compile2_v2.flags._dome, @@ -1424,7 +1426,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_COMPILE2: - printf("\tS-Compile2-V3 lang:%s machine:%s _unk:%x front-end:%d.%d.%d back-end:%d.%d.%d '%s'\n", + printf("Compile2-V3 lang:%s machine:%s _unk:%x front-end:%d.%d.%d back-end:%d.%d.%d '%s'\n", get_language(sym->compile2_v3.flags.iLanguage), get_machine(sym->compile2_v3.machine), sym->compile2_v3.flags._dome, @@ -1442,7 +1444,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_COMPILE3: - printf("\tS-Compile3-V3 lang:%s machine:%s _unk:%x front-end:%d.%d.%d back-end:%d.%d.%d '%s'\n", + printf("Compile3-V3 lang:%s machine:%s _unk:%x front-end:%d.%d.%d back-end:%d.%d.%d '%s'\n", get_language(sym->compile3_v3.flags.iLanguage), get_machine(sym->compile3_v3.machine), sym->compile3_v3.flags._dome, @@ -1468,23 +1470,23 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_OBJNAME: - printf("\tS-ObjName V3 sig:%x '%s'\n", + printf("ObjName V3 sig:%x '%s'\n", sym->objname_v3.signature, sym->objname_v3.name); break;
case S_OBJNAME_ST: - printf("\tS-ObjName V1 sig:%x '%s'\n", + printf("ObjName V1 sig:%x '%s'\n", sym->objname_v1.signature, p_string(&sym->objname_v1.p_name)); break;
case S_LABEL32_ST: - printf("\tS-Label V1 '%s' in '%s' (%04x:%08x)\n", + printf("Label V1 '%s' in '%s' (%04x:%08x)\n", p_string(&sym->label_v1.p_name), curr_func, sym->label_v1.segment, sym->label_v1.offset); break;
case S_LABEL32: - printf("\tS-Label V3 '%s' in '%s' (%04x:%08x) flag:%x\n", + printf("Label V3 '%s' in '%s' (%04x:%08x) flag:%x\n", sym->label_v3.name, curr_func, sym->label_v3.segment, sym->label_v3.offset, sym->label_v3.flags); break; @@ -1495,7 +1497,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) struct full_value fv;
vlen = full_numeric_leaf(&fv, &sym->constant_v2.cvalue); - printf("\tS-Constant V2 '%s' = %s type:%x\n", + printf("Constant V2 '%s' = %s type:%x\n", p_string(PSTRING(&sym->constant_v2.cvalue, vlen)), full_value_string(&fv), sym->constant_v2.type); } @@ -1507,24 +1509,24 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) struct full_value fv;
vlen = full_numeric_leaf(&fv, &sym->constant_v3.cvalue); - printf("\tS-Constant V3 '%s' = %s type:%x\n", + printf("Constant V3 '%s' = %s type:%x\n", (const char*)&sym->constant_v3.cvalue + vlen, full_value_string(&fv), sym->constant_v3.type); } break;
case S_UDT_16t: - printf("\tS-Udt V1 '%s': type:0x%x\n", + printf("Udt V1 '%s': type:0x%x\n", p_string(&sym->udt_v1.p_name), sym->udt_v1.type); break;
case S_UDT_ST: - printf("\tS-Udt V2 '%s': type:0x%x\n", + printf("Udt V2 '%s': type:0x%x\n", p_string(&sym->udt_v2.p_name), sym->udt_v2.type); break;
case S_UDT: - printf("\tS-Udt V3 '%s': type:0x%x\n", + printf("Udt V3 '%s': type:0x%x\n", sym->udt_v3.name, sym->udt_v3.type); break; /* @@ -1533,11 +1535,11 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) * into the symbol length count. We need to skip it. */ case S_PROCREF_ST: - printf("\tS-Procref V1 "); goto doaref; + printf("Procref V1 "); goto doaref; case S_DATAREF_ST: - printf("\tS-Dataref V1 "); goto doaref; + printf("Dataref V1 "); goto doaref; case S_LPROCREF_ST: - printf("\tS-L-Procref V1 "); goto doaref; + printf("L-Procref V1 "); goto doaref; doaref: { const struct p_string* pname; @@ -1555,12 +1557,12 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_SSEARCH: - printf("\tSSearch V1: (%04x:%08x)\n", + printf("Search V1: (%04x:%08x)\n", sym->ssearch_v1.segment, sym->ssearch_v1.offset); break;
case S_SECTION: - printf("\tSSection Info: seg=%04x ?=%04x rva=%08x size=%08x attr=%08x %s\n", + printf("Section Info: seg=%04x ?=%04x rva=%08x size=%08x attr=%08x %s\n", *(const unsigned short*)((const char*)sym + 4), *(const unsigned short*)((const char*)sym + 6), *(const unsigned*)((const char*)sym + 8), @@ -1570,7 +1572,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_COFFGROUP: - printf("\tSSubSection Info: addr=%04x:%08x size=%08x attr=%08x %s\n", + printf("SubSection Info: addr=%04x:%08x size=%08x attr=%08x %s\n", *(const unsigned short*)((const char*)sym + 16), *(const unsigned*)((const char*)sym + 12), *(const unsigned*)((const char*)sym + 4), @@ -1579,13 +1581,13 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) break;
case S_EXPORT: - printf("\tSEntryPoint: id=%x '%s'\n", + printf("EntryPoint: id=%x '%s'\n", *(const unsigned*)((const char*)sym + 4), (const char*)sym + 8); break;
case S_LTHREAD32_16t: case S_GTHREAD32_16t: - printf("\tS-Thread %s Var V1 '%s' seg=%04x offset=%08x type=%x\n", + printf("Thread %s Var V1 '%s' seg=%04x offset=%08x type=%x\n", sym->generic.id == S_LTHREAD32_16t ? "global" : "local", p_string(&sym->thread_v1.p_name), sym->thread_v1.segment, sym->thread_v1.offset, sym->thread_v1.symtype); @@ -1593,7 +1595,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
case S_LTHREAD32_ST: case S_GTHREAD32_ST: - printf("\tS-Thread %s Var V2 '%s' seg=%04x offset=%08x type=%x\n", + printf("Thread %s Var V2 '%s' seg=%04x offset=%08x type=%x\n", sym->generic.id == S_LTHREAD32_ST ? "global" : "local", p_string(&sym->thread_v2.p_name), sym->thread_v2.segment, sym->thread_v2.offset, sym->thread_v2.symtype); @@ -1601,57 +1603,56 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
case S_LTHREAD32: case S_GTHREAD32: - printf("\tS-Thread %s Var V3 '%s' seg=%04x offset=%08x type=%x\n", + printf("Thread %s Var V3 '%s' seg=%04x offset=%08x type=%x\n", sym->generic.id == S_LTHREAD32 ? "global" : "local", sym->thread_v3.name, sym->thread_v3.segment, sym->thread_v3.offset, sym->thread_v3.symtype); break;
case S_LOCAL: - printf("\tS-Local V3 '%s' type=%x flags=%s\n", + printf("Local V3 '%s' type=%x flags=%s\n", sym->local_v3.name, sym->local_v3.symtype, get_varflags(sym->local_v3.varflags)); - break;
case S_DEFRANGE: - printf("\tS-DefRange dia:%x\n", sym->defrange_v3.program); + printf("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", + printf("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", + printf("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", + printf("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", + printf("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", + printf("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", + printf("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); + 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, " "); } }
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 51 +++++++++++++++++++++++ tools/winedump/msc.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index ca3f120a5d6..20b3314ea04 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -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 diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index d1d3674daca..aba14af8643 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -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, " ");
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 13 +++++++++++++ tools/winedump/msc.c | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 20b3314ea04..4ab83ef1f02 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1852,6 +1852,16 @@ union codeview_symbol unsigned char binaryAnnotations[0]; } inline_site2_v3;
+ struct + { + unsigned short int len; + unsigned short int id; + unsigned int count; + cv_typ_t funcs[0]; /* array of cuntions, count entries */ +#if 0 + unsigned int invocations[0]; /* array of count entries, paires with funcs */ +#endif + } function_list_v3; };
enum BinaryAnnotationOpcode @@ -2025,6 +2035,9 @@ enum BinaryAnnotationOpcode #define S_GDATA_HLSL32_EX 0x1164 #define S_LDATA_HLSL32_EX 0x1165
+/* not documented yet on MS CV github repo, but that's how LLVM calls it */ +#define S_INLINEES 0x1168 + /* ======================================== * * Line number information * ======================================== */ diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index aba14af8643..8948428427b 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1758,6 +1758,25 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) printf("Inline-site-end\n"); break;
+ case S_CALLEES: + case S_CALLERS: + case S_INLINEES: + { + unsigned i, ninvoc; + const unsigned* invoc; + const char* tag; + + if (sym->generic.id == S_CALLERS) tag = "Callers"; + else if (sym->generic.id == S_CALLEES) tag = "Callees"; + else tag = "Inlinees"; + printf("%s V3 count:%u\n", tag, sym->function_list_v3.count); + invoc = (const unsigned*)&sym->function_list_v3.funcs[sym->function_list_v3.count]; + ninvoc = (const unsigned*)get_last(sym) - invoc; + + for (i = 0; i < sym->function_list_v3.count; ++i) + printf("\t\tfunc:%x invoc:%u\n", sym->function_list_v3.funcs[i], i < ninvoc ? invoc[i] : 0); + } + 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, " ");
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 7 +++++++ tools/winedump/msc.c | 4 ++++ 2 files changed, 11 insertions(+)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 4ab83ef1f02..3c3ef487b63 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1821,6 +1821,13 @@ union codeview_symbol struct cv_addr_gap gaps[0]; } defrange_registerrel_v3;
+ struct + { + unsigned short int len; + unsigned short int id; + cv_itemid_t itemid; + } build_info_v3; + struct { unsigned short int len; diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 8948428427b..0fa96205e20 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1743,6 +1743,10 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) sym->callsiteinfo_v3.sect, sym->callsiteinfo_v3.off, sym->callsiteinfo_v3.typind); break;
+ case S_BUILDINFO: + printf("Build-info V3 item:%04x\n", sym->build_info_v3.itemid); + 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);
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 12 ++++++++++++ tools/winedump/msc.c | 10 ++++++++++ 2 files changed, 22 insertions(+)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 3c3ef487b63..42455cbd0fe 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1497,6 +1497,18 @@ union codeview_symbol char name[1]; } block_v3;
+ struct + { + unsigned short int len; + unsigned short int id; + unsigned short trampType; /* 0: incremental, 1: branchisland */ + unsigned short cbThunk; + unsigned int offThunk; + unsigned int offTarget; + unsigned short sectThunk; + unsigned short sectTarget; + } trampoline_v3; + struct { unsigned short int len; diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 0fa96205e20..f5d2d15774d 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1566,6 +1566,16 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) sym->objname_v1.signature, p_string(&sym->objname_v1.p_name)); break;
+ case S_TRAMPOLINE: + printf("Trampoline V3 kind:%u %04x:%08x#%x -> %04x:%08x\n", + sym->trampoline_v3.trampType, + sym->trampoline_v3.sectThunk, + sym->trampoline_v3.offThunk, + sym->trampoline_v3.cbThunk, + sym->trampoline_v3.sectTarget, + sym->trampoline_v3.offTarget); + break; + case S_LABEL32_ST: printf("Label V1 '%s' in '%s' (%04x:%08x)\n", p_string(&sym->label_v1.p_name),
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/msc.c | 6 +++--- include/wine/mscvpdb.h | 4 ++-- tools/winedump/msc.c | 9 +++++++++ 3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index f77592664ef..6d623f336ed 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -1993,9 +1993,9 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo TRACE("S-Align V1\n"); break; case S_HEAPALLOCSITE: - TRACE("heap site: offset=0x%08x at sect_idx 0x%04x, inst_len 0x%08x, index 0x%08x\n", - sym->heap_alloc_site.offset, sym->heap_alloc_site.sect_idx, - sym->heap_alloc_site.inst_len, sym->heap_alloc_site.index); + TRACE("S-heap site V3: offset=0x%08x at sect_idx 0x%04x, inst_len 0x%08x, index 0x%08x\n", + sym->heap_alloc_site_v3.offset, sym->heap_alloc_site_v3.sect_idx, + sym->heap_alloc_site_v3.inst_len, sym->heap_alloc_site_v3.index); break;
/* the symbols we can safely ignore for now */ diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 42455cbd0fe..766f20d2732 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1751,8 +1751,8 @@ union codeview_symbol unsigned int offset; unsigned short sect_idx; unsigned short inst_len; - unsigned int index; - } heap_alloc_site; + cv_typ_t index; + } heap_alloc_site_v3;
struct { diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index f5d2d15774d..62152ed6ea0 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1791,6 +1791,15 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) printf("\t\tfunc:%x invoc:%u\n", sym->function_list_v3.funcs[i], i < ninvoc ? invoc[i] : 0); } break; + + case S_HEAPALLOCSITE: + printf("Heap-alloc-site V3 %04x:%08x#%x type:%04x\n", + sym->heap_alloc_site_v3.sect_idx, + sym->heap_alloc_site_v3.offset, + sym->heap_alloc_site_v3.inst_len, + sym->heap_alloc_site_v3.index); + 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, " ");
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 10 ++++++++++ tools/winedump/msc.c | 8 ++++++++ 2 files changed, 18 insertions(+)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 766f20d2732..a72e0b58158 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -1881,6 +1881,16 @@ union codeview_symbol unsigned int invocations[0]; /* array of count entries, paires with funcs */ #endif } function_list_v3; + + struct + { + unsigned short int len; + unsigned short int id; + cv_typ_t typind; + unsigned int modOffset; + unsigned short varflags; + char name[1]; + } file_static_v3; };
enum BinaryAnnotationOpcode diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 62152ed6ea0..65e6beb1006 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1800,6 +1800,14 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size) sym->heap_alloc_site_v3.index); break;
+ case S_FILESTATIC: + printf("File-static V3 '%s' type:%04x modOff:%08x flags:%s\n", + sym->file_static_v3.name, + sym->file_static_v3.typind, + sym->file_static_v3.modOffset, + get_varflags(sym->file_static_v3.varflags)); + 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, " ");
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- tools/winedump/pdb.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index dcfbea85b4c..a2c4360b67a 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -562,11 +562,13 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx free(filesimage); }
-static void pdb_dump_types(struct pdb_reader* reader) +/* there are two 'type' related streams, but with different indexes... */ +static void pdb_dump_types(struct pdb_reader* reader, unsigned strmidx, const char* strmname) { PDB_TYPES* types = NULL;
- types = reader->read_file(reader, 2); + types = reader->read_file(reader, strmidx); + if (!types) return;
switch (types->version) { @@ -581,7 +583,7 @@ static void pdb_dump_types(struct pdb_reader* reader) }
/* Read type table */ - printf("Types:\n" + printf("Types (%s):\n" "\tversion: %u\n" "\ttype_offset: %08x\n" "\tfirst_index: %x\n" @@ -597,6 +599,7 @@ static void pdb_dump_types(struct pdb_reader* reader) "\tsearch_len: %x\n" "\tunknown_offset: %x\n" "\tunknown_len: %x\n", + strmname, types->version, types->type_offset, types->first_index, @@ -782,7 +785,8 @@ static void pdb_jg_dump(void) default: printf("-Unknown root block version %d\n", reader.u.jg.root->Version); } - pdb_dump_types(&reader); + pdb_dump_types(&reader, 2, "TPI"); + pdb_dump_types(&reader, 4, "IPI"); pdb_dump_symbols(&reader, &sidx); pdb_dump_fpo(&reader, sidx.FPO); pdb_dump_segments(&reader, sidx.segments); @@ -926,7 +930,8 @@ static void pdb_ds_dump(void) } if (numok) printf(">>> unmatched present field with found\n");
- pdb_dump_types(&reader); + pdb_dump_types(&reader, 2, "TPI"); + pdb_dump_types(&reader, 4, "IPI"); pdb_dump_symbols(&reader, &sidx); pdb_dump_fpo(&reader, sidx.FPO); pdb_dump_fpo_ext(&reader, sidx.FPO_EXT);
(mainly header)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- tools/winedump/pdb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index a2c4360b67a..05e02c841e3 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -562,6 +562,21 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx free(filesimage); }
+static void pdb_dump_types_hash(struct pdb_reader* reader, unsigned file, const char* strmname) +{ + void* hash = NULL; + DWORD size; + + hash = reader->read_file(reader, file); + if (!hash) return; + + size = pdb_get_file_size(reader, file); + + printf("Types (%s) hash:\n", strmname); + dump_data(hash, size, " "); + free(hash); +} + /* there are two 'type' related streams, but with different indexes... */ static void pdb_dump_types(struct pdb_reader* reader, unsigned strmidx, const char* strmname) { @@ -616,6 +631,7 @@ static void pdb_dump_types(struct pdb_reader* reader, unsigned strmidx, const ch types->unknown_offset, types->unknown_len); codeview_dump_types_from_block((const char*)types + types->type_offset, types->type_size); + pdb_dump_types_hash(reader, types->file, strmname); free(types); }
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- include/wine/mscvpdb.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/winedump/msc.c | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index a72e0b58158..35143291f22 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -124,6 +124,7 @@ union codeview_type unsigned short int id; } generic;
+ /* types found in TPI stream (#2) */ struct { unsigned short int len; @@ -360,6 +361,61 @@ union codeview_type cv_typ_t arglist; unsigned int this_adjust; } mfunction_v2; + + /* types found in IPI stream (#4) */ + struct + { + unsigned short int len; + unsigned short int id; /* LF_FUNC_ID */ + cv_itemid_t scopeId; + cv_typ_t type; + char name[1]; + } func_id_v3; + + struct + { + unsigned short int len; + unsigned short int id; /* LF_MFUNC_ID */ + cv_typ_t parentType; + cv_typ_t type; + char name[1]; + } mfunc_id_v3; + + struct + { + unsigned short int len; + unsigned short int id; /* LF_STRING_ID */ + cv_itemid_t strid; + char name[1]; + } string_id_v3; + + struct + { + unsigned short int len; + unsigned short int id; /* LF_UDT_SRC_LINE */ + cv_typ_t type; + cv_itemid_t src; + unsigned int line; + } udt_src_line_v3; + + struct + { + unsigned short int len; + unsigned short int id; /* LF_UDT_MOD_SRC_LINE */ + cv_typ_t type; + cv_itemid_t src; + unsigned int line; + unsigned short imod; + } udt_mod_src_line_v3; + + struct + { + unsigned short int len; + unsigned short int id; /* LF_BUILDINFO */ + unsigned short count; + cv_itemid_t arg[1]; + } buildinfo_v3; + };
union codeview_reftype @@ -1216,6 +1272,17 @@ union codeview_fieldtype #define LF_NESTTYPE_V3 0x1510 #define LF_ONEMETHOD_V3 0x1511
+/* leaves found in second type type (aka IPI) + * for simplicity, stored in the same union as other TPI leaves + */ +#define LF_FUNC_ID 0x1601 +#define LF_MFUNC_ID 0x1602 +#define LF_BUILDINFO 0x1603 +#define LF_SUBSTR_LIST 0x1604 +#define LF_STRING_ID 0x1605 +#define LF_UDT_SRC_LINE 0x1606 +#define LF_UDT_MOD_SRC_LINE 0x1607 + #define LF_NUMERIC 0x8000 /* numeric leaf types */ #define LF_CHAR 0x8000 #define LF_SHORT 0x8001 diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index 65e6beb1006..25cfcba0630 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -814,6 +814,7 @@ static void codeview_dump_one_type(unsigned curr_type, const union codeview_type
switch (type->generic.id) { + /* types from TPI (aka #2) stream */ case LF_POINTER_V1: printf("\t%x => Pointer V1 to type:%x\n", curr_type, type->pointer_v1.datatype); @@ -1099,6 +1100,49 @@ static void codeview_dump_one_type(unsigned curr_type, const union codeview_type printf("\n"); break;
+ /* types from IPI (aka #4) stream */ + case LF_FUNC_ID: + printf("\t%x => FuncId %s scopeId:%04x type:%04x\n", + curr_type, type->func_id_v3.name, + type->func_id_v3.scopeId, type->func_id_v3.type); + break; + case LF_MFUNC_ID: + printf("\t%x => MFuncId %s parent:%04x type:%04x\n", + curr_type, type->mfunc_id_v3.name, + type->mfunc_id_v3.parentType, type->mfunc_id_v3.type); + break; + case LF_BUILDINFO: + printf("\t%x => BuildInfo count:%d\n", curr_type, type->buildinfo_v3.count); + if (type->buildinfo_v3.count >= 1) printf("\t\tcurrent dir: %04x\n", type->buildinfo_v3.arg[0]); + if (type->buildinfo_v3.count >= 2) printf("\t\tbuild tool: %04x\n", type->buildinfo_v3.arg[1]); + if (type->buildinfo_v3.count >= 3) printf("\t\tsource file: %04x\n", type->buildinfo_v3.arg[2]); + if (type->buildinfo_v3.count >= 4) printf("\t\tPDB file: %04x\n", type->buildinfo_v3.arg[3]); + if (type->buildinfo_v3.count >= 5) printf("\t\tArguments: %04x\n", type->buildinfo_v3.arg[4]); + break; + case LF_SUBSTR_LIST: + printf("\t%x => SubstrList V3(#%u):", curr_type, reftype->arglist_v2.num); + for (j = 0; j < reftype->arglist_v2.num; j++) + { + printf("\t %x", reftype->arglist_v2.args[j]); + } + printf("\t\n"); + break; + case LF_STRING_ID: + printf("\t%x => StringId %s strid:%04x\n", + curr_type, type->string_id_v3.name, type->string_id_v3.strid); + break; + case LF_UDT_SRC_LINE: + printf("\t%x => Udt-SrcLine type:%04x src:%04x line:%d\n", + curr_type, type->udt_src_line_v3.type, + type->udt_src_line_v3.src, type->udt_src_line_v3.line); + break; + case LF_UDT_MOD_SRC_LINE: + printf("\t%x => Udt-ModSrcLine type:%04x src:%04x line:%d mod:%d\n", + curr_type, type->udt_mod_src_line_v3.type, + type->udt_mod_src_line_v3.src, type->udt_mod_src_line_v3.line, + type->udt_mod_src_line_v3.imod); + break; + default: printf(">>> Unsupported type-id %x for %x\n", type->generic.id, curr_type); dump_data((const void*)type, type->generic.len + 2, "");
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/msc.c | 4 +-- include/wine/mscvpdb.h | 14 ++++++---- tools/winedump/pdb.c | 69 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 67 insertions(+), 20 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 6d623f336ed..72b03960803 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2392,8 +2392,8 @@ static void pdb_convert_symbols_header(PDB_SYMBOLS* symbols, symbols->hash_size = old->hash_size; symbols->srcmodule_size = old->srcmodule_size; symbols->pdbimport_size = 0; - symbols->hash1_file = old->hash1_file; - symbols->hash2_file = old->hash2_file; + symbols->global_file = old->global_file; + symbols->public_file = old->public_file; symbols->gsym_file = old->gsym_file;
*header_size = sizeof(PDB_SYMBOLS_OLD); diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h index 35143291f22..c9ab4abb166 100644 --- a/include/wine/mscvpdb.h +++ b/include/wine/mscvpdb.h @@ -2367,8 +2367,8 @@ typedef struct _PDB_SYMBOL_IMPORT
typedef struct _PDB_SYMBOLS_OLD { - WORD hash1_file; - WORD hash2_file; + WORD global_file; + WORD public_file; WORD gsym_file; WORD pad; DWORD module_size; @@ -2381,11 +2381,13 @@ typedef struct _PDB_SYMBOLS { DWORD signature; DWORD version; - DWORD unknown; - DWORD hash1_file; - DWORD hash2_file; + DWORD age; + WORD global_file; + WORD flags; + WORD public_file; + WORD bldVer; WORD gsym_file; - WORD unknown1; + WORD rbldVer; DWORD module_size; DWORD offset_size; DWORD hash_size; diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 05e02c841e3..dc89308bd67 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -222,6 +222,36 @@ static void *read_string_table(struct pdb_reader* reader) return NULL; }
+static void dump_global_symbol(struct pdb_reader* reader, unsigned file) +{ + void* global = NULL; + DWORD size; + + global = reader->read_file(reader, file); + if (!global) return; + + size = pdb_get_file_size(reader, file); + + printf("Global symbols table:\n"); + dump_data(global, size, "\t"); + free(global); +} + +static void dump_public_symbol(struct pdb_reader* reader, unsigned file) +{ + void* public = NULL; + DWORD size; + + public = reader->read_file(reader, file); + if (!public) return; + + size = pdb_get_file_size(reader, file); + + printf("Public symbols table:\n"); + dump_data(public, size, "\t"); + free(public); +} + static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx) { PDB_SYMBOLS* symbols; @@ -229,6 +259,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx const char* file; char* filesimage; DWORD filessize = 0; + char tcver[32];
sidx->FPO = sidx->unk0 = sidx->unk1 = sidx->unk2 = sidx->unk3 = sidx->segments = sidx->unk4 = sidx->unk5 = sidx->unk6 = sidx->FPO_EXT = sidx->unk7 = -1; @@ -246,14 +277,20 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx default: printf("-Unknown symbol info version %d\n", symbols->version); } + if (symbols->flags & 0x8000) /* new */ + snprintf(tcver, sizeof(tcver), "%u.%u", (symbols->flags >> 8) & 0x7f, symbols->flags & 0xff); + else + snprintf(tcver, sizeof(tcver), "old-%x", symbols->flags); printf("Symbols:\n" "\tsignature: %08x\n" "\tversion: %u\n" - "\tunknown: %08x\n" - "\thash1_file: %08x\n" - "\thash2_file: %08x\n" - "\tgsym_file: %04x\n" - "\tunknown1: %04x\n" + "\tage: %08x\n" + "\tglobal_file: %u\n" + "\tbuilder: %s\n" + "\tpublic_file: %u\n" + "\tbldVer: %u\n" + "\tgsym_file: %u\n" + "\trbldVer: %u\n" "\tmodule_size: %08x\n" "\toffset_size: %08x\n" "\thash_size: %08x\n" @@ -264,14 +301,16 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx "\tunknown2_size: %08x\n" "\tresvd3: %04x\n" "\tmachine: %s\n" - "\tresvd[4] %08x\n", + "\tresvd4 %08x\n", symbols->signature, symbols->version, - symbols->unknown, - symbols->hash1_file, - symbols->hash2_file, + symbols->age, + symbols->global_file, + tcver, /* from symbols->flags */ + symbols->public_file, + symbols->bldVer, symbols->gsym_file, - symbols->unknown1, + symbols->rbldVer, symbols->module_size, symbols->offset_size, symbols->hash_size, @@ -558,6 +597,8 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx file_name += strlen(file_name) + 1; file = (char*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3); } + dump_global_symbol(reader, symbols->global_file); + dump_public_symbol(reader, symbols->public_file); free(symbols); free(filesimage); } @@ -883,18 +924,22 @@ static void pdb_ds_dump(void) reader.u.ds.header->unknown2, reader.u.ds.header->toc_page);
- /* files: - * 0: JG says old toc pages, I'd say free pages (tbc, low prio) + /* files with static indexes: + * 0: JG says old toc pages * 1: root structure * 2: types * 3: modules + * 4: types (second stream) * other known streams: * - string table: its index is in the stream table from ROOT object under "/names" + * - type hash table: its index is in the types header (2 and 4) + * - global and public streams: from symbol stream header * those streams get their indexes out of the PDB_STREAM_INDEXES object * - FPO data * - segments * - extended FPO data */ + reader.file_used[0] |= 1; /* mark stream #0 as read */ reader.u.ds.root = reader.read_file(&reader, 1); if (reader.u.ds.root) {