[PATCH 11/12] [WineDump]: fixes a couple of issues with types table
walking
Eric Pouech
eric.pouech at wanadoo.fr
Fri Jan 5 14:43:23 CST 2007
- aligning types to DWORD boundaries
- splitted types dumping functions into two versions (one without
offsets table, the second one with offset table)
A+
---
tools/winedump/debug.c | 7 +
tools/winedump/msc.c | 537 +++++++++++++++++++++++----------------------
tools/winedump/pdb.c | 2
tools/winedump/winedump.h | 3
4 files changed, 285 insertions(+), 264 deletions(-)
diff --git a/tools/winedump/debug.c b/tools/winedump/debug.c
index 9029e39..4936680 100644
--- a/tools/winedump/debug.c
+++ b/tools/winedump/debug.c
@@ -190,7 +190,12 @@ static int dump_cv_sst_global_types(cons
data = PRD(fileoffset + sizeof(OMFGlobalTypes) + sizeof(DWORD) * types->cTypes, sz);
if (!data) {printf("Can't OMF-SymHash details, aborting\n"); return FALSE;}
- codeview_dump_types(data, sz);
+ /* doc says:
+ * - for NB07 & NB08 (that we don't support yet), offsets are from types
+ * - for NB09, offsets are from data
+ * For now, we only support the later
+ */
+ codeview_dump_types_from_offsets(data, (const DWORD*)(types + 1), types->cTypes);
return TRUE;
}
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index 178c3d4..00e690a 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -507,291 +507,306 @@ #endif
}
}
-int codeview_dump_types(const void* table, unsigned long len)
+static void codeview_dump_one_type(unsigned curr_type, const union codeview_type* type)
{
- unsigned int curr_type = 0x1000;
- const unsigned char*ptr = table;
+ const union codeview_reftype* reftype = (const union codeview_reftype*)type;
int i, leaf_len, value;
const char* str;
- while (ptr - (const unsigned char*)table < len)
+ switch (type->generic.id)
{
- const union codeview_type* type = (const union codeview_type*)ptr;
- const union codeview_reftype* reftype = (const union codeview_reftype*)ptr;
- int retv = TRUE;
-
- switch (type->generic.id)
+ case LF_POINTER_V1:
+ printf("\t%x => Pointer V1 to type:%x\n",
+ curr_type, type->pointer_v1.datatype);
+ break;
+ case LF_POINTER_V2:
+ printf("\t%x => Pointer V2 to type:%x\n",
+ curr_type, type->pointer_v2.datatype);
+ break;
+ case LF_ARRAY_V1:
+ leaf_len = numeric_leaf(&value, &type->array_v1.arrlen);
+ printf("\t%x => Array V1-'%s'[%u type:%x] type:%x\n",
+ curr_type, p_string(PSTRING(&type->array_v1.arrlen, leaf_len)),
+ value, type->array_v1.idxtype, type->array_v1.elemtype);
+ break;
+ case LF_ARRAY_V2:
+ leaf_len = numeric_leaf(&value, &type->array_v2.arrlen);
+ printf("\t%x => Array V2-'%s'[%u type:%x] type:%x\n",
+ curr_type, p_string(PSTRING(&type->array_v2.arrlen, leaf_len)),
+ value, type->array_v2.idxtype, type->array_v2.elemtype);
+ break;
+ case LF_ARRAY_V3:
+ leaf_len = numeric_leaf(&value, &type->array_v3.arrlen);
+ str = (const char*)&type->array_v3.arrlen + leaf_len;
+ printf("\t%x => Array V3-'%s'[%u type:%x] type:%x\n",
+ curr_type, str, value,
+ type->array_v3.idxtype, type->array_v3.elemtype);
+ break;
+
+ /* a bitfields is a CodeView specific data type which represent a bitfield
+ * in a structure or a class. For now, we store it in a SymTag-like type
+ * (so that the rest of the process is seamless), but check at udt inclusion
+ * type for its presence
+ */
+ case LF_BITFIELD_V1:
+ printf("\t%x => Bitfield V1:%x offset:%u #bits:%u\n",
+ curr_type, reftype->bitfield_v1.type, reftype->bitfield_v1.bitoff,
+ reftype->bitfield_v1.nbits);
+ break;
+
+ case LF_BITFIELD_V2:
+ printf("\t%x => Bitfield V2:%x offset:%u #bits:%u\n",
+ curr_type, reftype->bitfield_v2.type, reftype->bitfield_v2.bitoff,
+ reftype->bitfield_v2.nbits);
+ break;
+
+ case LF_FIELDLIST_V1:
+ case LF_FIELDLIST_V2:
+ printf("\t%x => Fieldlist\n", curr_type);
+ do_field(reftype->fieldlist.list, (const BYTE*)type + reftype->generic.len + 2);
+ break;
+
+ case LF_STRUCTURE_V1:
+ case LF_CLASS_V1:
+ leaf_len = numeric_leaf(&value, &type->struct_v1.structlen);
+ printf("\t%x => %s V1 '%s' elts:%u prop:%u fieldlist-type:%x derived-type:%x vshape:%x size:%u\n",
+ curr_type, type->generic.id == LF_CLASS_V1 ? "Class" : "Struct",
+ p_string(PSTRING(&type->struct_v1.structlen, leaf_len)),
+ type->struct_v1.n_element, type->struct_v1.property,
+ type->struct_v1.fieldlist, type->struct_v1.derived,
+ type->struct_v1.vshape, value);
+ break;
+
+ case LF_STRUCTURE_V2:
+ case LF_CLASS_V2:
+ leaf_len = numeric_leaf(&value, &type->struct_v2.structlen);
+ printf("\t%x => %s V2 '%s' elts:%u prop:%u\n"
+ " fieldlist-type:%x derived-type:%x vshape:%x size:%u\n",
+ curr_type, type->generic.id == LF_CLASS_V2 ? "Class" : "Struct",
+ p_string(PSTRING(&type->struct_v2.structlen, leaf_len)),
+ type->struct_v2.n_element, type->struct_v2.property,
+ type->struct_v2.fieldlist, type->struct_v2.derived,
+ type->struct_v2.vshape, value);
+ break;
+
+ case LF_STRUCTURE_V3:
+ case LF_CLASS_V3:
+ leaf_len = numeric_leaf(&value, &type->struct_v3.structlen);
+ str = (const char*)&type->struct_v3.structlen + leaf_len;
+ printf("\t%x => %s V3 '%s' elts:%u prop:%u\n"
+ " fieldlist-type:%x derived-type:%x vshape:%x size:%u\n",
+ curr_type, type->generic.id == LF_CLASS_V3 ? "Class" : "Struct",
+ str, type->struct_v3.n_element, type->struct_v3.property,
+ type->struct_v3.fieldlist, type->struct_v3.derived,
+ type->struct_v3.vshape, value);
+ break;
+
+ case LF_UNION_V1:
+ leaf_len = numeric_leaf(&value, &type->union_v1.un_len);
+ printf("\t%x => Union V1 '%s' count:%u prop:%u fieldlist-type:%x size:%u\n",
+ curr_type, p_string(PSTRING(&type->union_v1.un_len, leaf_len)),
+ type->union_v1.count, type->union_v1.property,
+ type->union_v1.fieldlist, value);
+ break;
+
+ case LF_UNION_V2:
+ leaf_len = numeric_leaf(&value, &type->union_v2.un_len);
+ printf("\t%x => Union V2 '%s' count:%u prop:%u fieldlist-type:%x size:%u\n",
+ curr_type, p_string(PSTRING(&type->union_v2.un_len, leaf_len)),
+ type->union_v2.count, type->union_v2.property,
+ type->union_v2.fieldlist, value);
+ break;
+
+ case LF_UNION_V3:
+ leaf_len = numeric_leaf(&value, &type->union_v3.un_len);
+ str = (const char*)&type->union_v3.un_len + leaf_len;
+ printf("\t%x => Union V3 '%s' count:%u prop:%u fieldlist-type:%x size:%u\n",
+ curr_type, str, type->union_v3.count,
+ type->union_v3.property, type->union_v3.fieldlist, value);
+ break;
+
+ case LF_ENUM_V1:
+ printf("\t%x => Enum V1 '%s' type:%x field-type:%x count:%u property:%x\n",
+ curr_type, p_string(&type->enumeration_v1.p_name),
+ type->enumeration_v1.type,
+ type->enumeration_v1.fieldlist,
+ type->enumeration_v1.count,
+ type->enumeration_v1.property);
+ break;
+
+ case LF_ENUM_V2:
+ printf("\t%x => Enum V2 '%s' type:%x field-type:%x count:%u property:%x\n",
+ curr_type, p_string(&type->enumeration_v2.p_name),
+ type->enumeration_v2.type,
+ type->enumeration_v2.fieldlist,
+ type->enumeration_v2.count,
+ type->enumeration_v2.property);
+ break;
+
+ case LF_ENUM_V3:
+ printf("\t%x => Enum V3 '%s' type:%x field-type:%x count:%u property:%x\n",
+ curr_type, type->enumeration_v3.name,
+ type->enumeration_v3.type,
+ type->enumeration_v3.fieldlist,
+ type->enumeration_v3.count,
+ type->enumeration_v3.property);
+ break;
+
+ case LF_ARGLIST_V1:
+ printf("\t%x => Arglist V1(#%u):", curr_type, reftype->arglist_v1.num);
+ for (i = 0; i < reftype->arglist_v1.num; i++)
{
- case LF_POINTER_V1:
- printf("\t%x => Pointer V1 to type:%x\n",
- curr_type, type->pointer_v1.datatype);
- break;
- case LF_POINTER_V2:
- printf("\t%x => Pointer V2 to type:%x\n",
- curr_type, type->pointer_v2.datatype);
- break;
- case LF_ARRAY_V1:
- leaf_len = numeric_leaf(&value, &type->array_v1.arrlen);
- printf("\t%x => Array V1-'%s'[%u type:%x] type:%x\n",
- curr_type, p_string(PSTRING(&type->array_v1.arrlen, leaf_len)),
- value, type->array_v1.idxtype, type->array_v1.elemtype);
- break;
- case LF_ARRAY_V2:
- leaf_len = numeric_leaf(&value, &type->array_v2.arrlen);
- printf("\t%x => Array V2-'%s'[%u type:%x] type:%x\n",
- curr_type, p_string(PSTRING(&type->array_v2.arrlen, leaf_len)),
- value, type->array_v2.idxtype, type->array_v2.elemtype);
- break;
- case LF_ARRAY_V3:
- leaf_len = numeric_leaf(&value, &type->array_v3.arrlen);
- str = (const char*)&type->array_v3.arrlen + leaf_len;
- printf("\t%x => Array V3-'%s'[%u type:%x] type:%x\n",
- curr_type, str, value,
- type->array_v3.idxtype, type->array_v3.elemtype);
- break;
-
-
- /* a bitfields is a CodeView specific data type which represent a bitfield
- * in a structure or a class. For now, we store it in a SymTag-like type
- * (so that the rest of the process is seamless), but check at udt inclusion
- * type for its presence
- */
- case LF_BITFIELD_V1:
- printf("\t%x => Bitfield V1:%x offset:%u #bits:%u\n",
- curr_type, reftype->bitfield_v1.type, reftype->bitfield_v1.bitoff,
- reftype->bitfield_v1.nbits);
- break;
-
- case LF_BITFIELD_V2:
- printf("\t%x => Bitfield V2:%x offset:%u #bits:%u\n",
- curr_type, reftype->bitfield_v2.type, reftype->bitfield_v2.bitoff,
- reftype->bitfield_v2.nbits);
- break;
-
- case LF_FIELDLIST_V1:
- case LF_FIELDLIST_V2:
- printf("\t%x => Fieldlist\n", curr_type);
- do_field(reftype->fieldlist.list, ptr + reftype->generic.len + 2);
- break;
-
- case LF_STRUCTURE_V1:
- case LF_CLASS_V1:
- leaf_len = numeric_leaf(&value, &type->struct_v1.structlen);
- printf("\t%x => %s V1 '%s' elts:%u prop:%u fieldlist-type:%x derived-type:%x vshape:%x size:%u\n",
- curr_type, type->generic.id == LF_CLASS_V1 ? "Class" : "Struct",
- p_string(PSTRING(&type->struct_v1.structlen, leaf_len)),
- type->struct_v1.n_element, type->struct_v1.property,
- type->struct_v1.fieldlist, type->struct_v1.derived,
- type->struct_v1.vshape, value);
- break;
-
- case LF_STRUCTURE_V2:
- case LF_CLASS_V2:
- leaf_len = numeric_leaf(&value, &type->struct_v2.structlen);
- printf("\t%x => %s V2 '%s' elts:%u prop:%u\n"
- " fieldlist-type:%x derived-type:%x vshape:%x size:%u\n",
- curr_type, type->generic.id == LF_CLASS_V2 ? "Class" : "Struct",
- p_string(PSTRING(&type->struct_v2.structlen, leaf_len)),
- type->struct_v2.n_element, type->struct_v2.property,
- type->struct_v2.fieldlist, type->struct_v2.derived,
- type->struct_v2.vshape, value);
- break;
-
- case LF_STRUCTURE_V3:
- case LF_CLASS_V3:
- leaf_len = numeric_leaf(&value, &type->struct_v3.structlen);
- str = (const char*)&type->struct_v3.structlen + leaf_len;
- printf("\t%x => %s V3 '%s' elts:%u prop:%u\n"
- " fieldlist-type:%x derived-type:%x vshape:%x size:%u\n",
- curr_type, type->generic.id == LF_CLASS_V3 ? "Class" : "Struct",
- str, type->struct_v3.n_element, type->struct_v3.property,
- type->struct_v3.fieldlist, type->struct_v3.derived,
- type->struct_v3.vshape, value);
- break;
-
- case LF_UNION_V1:
- leaf_len = numeric_leaf(&value, &type->union_v1.un_len);
- printf("\t%x => Union V1 '%s' count:%u prop:%u fieldlist-type:%x size:%u\n",
- curr_type, p_string(PSTRING(&type->union_v1.un_len, leaf_len)),
- type->union_v1.count, type->union_v1.property,
- type->union_v1.fieldlist, value);
- break;
-
- case LF_UNION_V2:
- leaf_len = numeric_leaf(&value, &type->union_v2.un_len);
- printf("\t%x => Union V2 '%s' count:%u prop:%u fieldlist-type:%x size:%u\n",
- curr_type, p_string(PSTRING(&type->union_v2.un_len, leaf_len)),
- type->union_v2.count, type->union_v2.property,
- type->union_v2.fieldlist, value);
- break;
-
- case LF_UNION_V3:
- leaf_len = numeric_leaf(&value, &type->union_v3.un_len);
- str = (const char*)&type->union_v3.un_len + leaf_len;
- printf("\t%x => Union V3 '%s' count:%u prop:%u fieldlist-type:%x size:%u\n",
- curr_type, str, type->union_v3.count,
- type->union_v3.property, type->union_v3.fieldlist, value);
- break;
-
- case LF_ENUM_V1:
- printf("\t%x => Enum V1 '%s' type:%x field-type:%x count:%u property:%x\n",
- curr_type, p_string(&type->enumeration_v1.p_name),
- type->enumeration_v1.type,
- type->enumeration_v1.fieldlist,
- type->enumeration_v1.count,
- type->enumeration_v1.property);
- break;
-
- case LF_ENUM_V2:
- printf("\t%x => Enum V2 '%s' type:%x field-type:%x count:%u property:%x\n",
- curr_type, p_string(&type->enumeration_v2.p_name),
- type->enumeration_v2.type,
- type->enumeration_v2.fieldlist,
- type->enumeration_v2.count,
- type->enumeration_v2.property);
- break;
-
- case LF_ENUM_V3:
- printf("\t%x => Enum V3 '%s' type:%x field-type:%x count:%u property:%x\n",
- curr_type, type->enumeration_v3.name,
- type->enumeration_v3.type,
- type->enumeration_v3.fieldlist,
- type->enumeration_v3.count,
- type->enumeration_v3.property);
- break;
-
- case LF_ARGLIST_V1:
- printf("\t%x => Arglist V1(#%u):", curr_type, reftype->arglist_v1.num);
- for (i = 0; i < reftype->arglist_v1.num; i++)
- {
- printf(" %x", reftype->arglist_v1.args[i]);
- }
- printf("\n");
- break;
-
- case LF_ARGLIST_V2:
- printf("\t%x => Arglist V2(#%u):", curr_type, reftype->arglist_v2.num);
- for (i = 0; i < reftype->arglist_v2.num; i++)
- {
- printf("\t %x", reftype->arglist_v2.args[i]);
- }
- printf("\t\n");
- break;
-
- case LF_PROCEDURE_V1:
- /* FIXME: unknown could be the calling convention for the proc */
- printf("\t%x => Procedure V1 ret_type:%x call:%x (#%u args_type:%x)\n",
- curr_type, type->procedure_v1.rvtype,
- type->procedure_v1.call, type->procedure_v1.params,
- type->procedure_v1.arglist);
- break;
- case LF_PROCEDURE_V2:
- printf("\t%x => Procedure V2 ret_type:%x unk:%x (#%u args_type:%x)\n",
- curr_type, type->procedure_v2.rvtype,
- type->procedure_v2.call, type->procedure_v2.params,
- type->procedure_v2.arglist);
- break;
-
- case LF_MFUNCTION_V2:
- printf("\t%x => MFunction V2 ret-type:%x call:%x class-type:%x this-type:%x\n"
- "\t\t#args:%x args-type:%x this_adjust:%x\n",
- curr_type,
- type->mfunction_v2.rvtype,
- type->mfunction_v2.call,
- type->mfunction_v2.class_type,
- type->mfunction_v2.this_type,
- type->mfunction_v2.params,
- type->mfunction_v2.arglist,
- type->mfunction_v2.this_adjust);
- break;
+ printf(" %x", reftype->arglist_v1.args[i]);
+ }
+ printf("\n");
+ break;
- case LF_MODIFIER_V1:
- printf("\t%x => Modifier V1 type:%x modif:%x\n",
- curr_type, type->modifier_v1.type, type->modifier_v1.attribute);
- break;
- case LF_MODIFIER_V2:
- printf("\t%x => Modifier V2 type:%x modif:%x\n",
- curr_type, type->modifier_v2.type, type->modifier_v2.attribute);
- break;
+ case LF_ARGLIST_V2:
+ printf("\t%x => Arglist V2(#%u):", curr_type, reftype->arglist_v2.num);
+ for (i = 0; i < reftype->arglist_v2.num; i++)
+ {
+ printf("\t %x", reftype->arglist_v2.args[i]);
+ }
+ printf("\t\n");
+ break;
+
+ case LF_PROCEDURE_V1:
+ /* FIXME: unknown could be the calling convention for the proc */
+ printf("\t%x => Procedure V1 ret_type:%x call:%x (#%u args_type:%x)\n",
+ curr_type, type->procedure_v1.rvtype,
+ type->procedure_v1.call, type->procedure_v1.params,
+ type->procedure_v1.arglist);
+ break;
+
+ case LF_PROCEDURE_V2:
+ printf("\t%x => Procedure V2 ret_type:%x unk:%x (#%u args_type:%x)\n",
+ curr_type, type->procedure_v2.rvtype,
+ type->procedure_v2.call, type->procedure_v2.params,
+ type->procedure_v2.arglist);
+ break;
+
+ case LF_MFUNCTION_V2:
+ printf("\t%x => MFunction V2 ret-type:%x call:%x class-type:%x this-type:%x\n"
+ "\t\t#args:%x args-type:%x this_adjust:%x\n",
+ curr_type,
+ type->mfunction_v2.rvtype,
+ type->mfunction_v2.call,
+ type->mfunction_v2.class_type,
+ type->mfunction_v2.this_type,
+ type->mfunction_v2.params,
+ type->mfunction_v2.arglist,
+ type->mfunction_v2.this_adjust);
+ break;
+
+ case LF_MODIFIER_V1:
+ printf("\t%x => Modifier V1 type:%x modif:%x\n",
+ curr_type, type->modifier_v1.type, type->modifier_v1.attribute);
+ break;
+
+ case LF_MODIFIER_V2:
+ printf("\t%x => Modifier V2 type:%x modif:%x\n",
+ curr_type, type->modifier_v2.type, type->modifier_v2.attribute);
+ break;
+
+ case LF_METHODLIST_V1:
+ {
+ const unsigned short* pattr = (const unsigned short*)((const char*)type + 4);
- case LF_METHODLIST_V1:
+ printf("\t%x => Method list\n", curr_type);
+ while ((const char*)pattr < (const char*)type + type->generic.len + 2)
{
- const unsigned short* pattr = (const unsigned short*)((const char*)type + 4);
-
- printf("\t%x => Method list\n", curr_type);
- while ((const char*)pattr < (const char*)type + type->generic.len + 2)
+ switch ((*pattr >> 2) & 7)
{
- switch ((*pattr >> 2) & 7)
- {
- case 4: case 6:
- printf("\t\t\tattr:%s type:%x vtab-offset:%x\n",
- get_attr(pattr[0]), pattr[1],
- *(const unsigned*)(&pattr[2]));
- pattr += 3;
- break;
- default:
- printf("\t\t\tattr:%s type:%x\n",
- get_attr(pattr[0]), pattr[1]);
- pattr += 2;
- }
+ case 4: case 6:
+ printf("\t\t\tattr:%s type:%x vtab-offset:%x\n",
+ get_attr(pattr[0]), pattr[1],
+ *(const unsigned*)(&pattr[2]));
+ pattr += 3;
+ break;
+ default:
+ printf("\t\t\tattr:%s type:%x\n",
+ get_attr(pattr[0]), pattr[1]);
+ pattr += 2;
}
}
- break;
+ }
+ break;
- case LF_METHODLIST_V2:
- {
- const unsigned* pattr = (const unsigned*)((const char*)type + 4);
+ case LF_METHODLIST_V2:
+ {
+ const unsigned* pattr = (const unsigned*)((const char*)type + 4);
- printf("\t%x => Method list\n", curr_type);
- while ((const char*)pattr < (const char*)type + type->generic.len + 2)
+ printf("\t%x => Method list\n", curr_type);
+ while ((const char*)pattr < (const char*)type + type->generic.len + 2)
+ {
+ switch ((*pattr >> 2) & 7)
{
- switch ((*pattr >> 2) & 7)
- {
- case 4: case 6:
- printf("\t\t\tattr:%s type:%x vtab-offset:%x\n",
- get_attr(pattr[0]), pattr[1], pattr[2]);
- pattr += 3;
- break;
- default:
- printf("\t\t\tattr:%s type:%x\n",
- get_attr(pattr[0]), pattr[1]);
- pattr += 2;
- }
+ case 4: case 6:
+ printf("\t\t\tattr:%s type:%x vtab-offset:%x\n",
+ get_attr(pattr[0]), pattr[1], pattr[2]);
+ pattr += 3;
+ break;
+ default:
+ printf("\t\t\tattr:%s type:%x\n",
+ get_attr(pattr[0]), pattr[1]);
+ pattr += 2;
}
}
- break;
+ }
+ break;
- case LF_VTSHAPE_V1:
+ case LF_VTSHAPE_V1:
+ {
+ int count = *(const unsigned short*)((const char*)type + 4);
+ int shift = 0;
+ const char* ptr = (const char*)type + 6;
+ const char* desc[] = {"Near", "Far", "Thin", "Disp to outtermost",
+ "Pointer to metaclass", "Near32", "Far32"};
+ printf("\t%x => VT Shape #%d: ", curr_type, count);
+ while (count--)
{
- int count = *(const unsigned short*)((const char*)type + 4);
- int shift = 0;
- const char* ptr = (const char*)type + 6;
- const char* desc[] = {"Near", "Far", "Thin", "Disp to outtermost",
- "Pointer to metaclass", "Near32", "Far32"};
- printf("\t%x => VT Shape #%d: ", curr_type, count);
- while (count--)
- {
- if (((*ptr << shift) & 0xF) <= 6)
- printf("%s ", desc[(*ptr << shift) & 0xF]);
- else
- printf("%x ", (*ptr << shift) & 0xF);
- if (shift == 0) shift = 4; else {shift = 0; ptr++;}
- }
- printf("\n");
+ if (((*ptr << shift) & 0xF) <= 6)
+ printf("%s ", desc[(*ptr << shift) & 0xF]);
+ else
+ printf("%x ", (*ptr << shift) & 0xF);
+ if (shift == 0) shift = 4; else {shift = 0; ptr++;}
}
- break;
-
- default:
- printf(">>> Unsupported type-id %x for %x\n", type->generic.id, curr_type);
- dump_data((const void*)type, type->generic.len + 2, "");
- break;
+ printf("\n");
}
+ break;
- if (!retv)
- return FALSE;
+ default:
+ printf(">>> Unsupported type-id %x for %x\n", type->generic.id, curr_type);
+ dump_data((const void*)type, type->generic.len + 2, "");
+ break;
+ }
+}
+
+int codeview_dump_types_from_offsets(const void* table, const DWORD* offsets, unsigned num_types)
+{
+ unsigned long i;
+
+ for (i = 0; i < num_types; i++)
+ {
+ codeview_dump_one_type(0x1000 + i,
+ (const union codeview_type*)((const char*)table + offsets[i]));
+ }
+
+ return TRUE;
+}
+
+int codeview_dump_types_from_block(const void* table, unsigned long len)
+{
+ unsigned int curr_type = 0x1000;
+ const unsigned char*ptr = table;
+ while (ptr - (const unsigned char*)table < len)
+ {
+ const union codeview_type* type = (const union codeview_type*)ptr;
+
+ codeview_dump_one_type(curr_type, type);
curr_type++;
- ptr += type->generic.len + 2;
+ ptr += (type->generic.len + 2 + 3) & ~3;
}
return TRUE;
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c
index 3074745..bd71ede 100644
--- a/tools/winedump/pdb.c
+++ b/tools/winedump/pdb.c
@@ -458,7 +458,7 @@ static void pdb_dump_types(struct pdb_re
types->search_len,
types->unknown_offset,
types->unknown_len);
- codeview_dump_types((const char*)types + types->type_offset, types->type_size);
+ codeview_dump_types_from_block((const char*)types + types->type_offset, types->type_size);
free((char*)types);
}
diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h
index 8aee2f9..d6c1507 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -259,7 +259,8 @@ void emf_dump( void );
enum FileSig get_kind_pdb(void);
void pdb_dump(void);
int codeview_dump_symbols(const void* root, unsigned long size);
-int codeview_dump_types(const void* table, unsigned long len);
+int codeview_dump_types_from_offsets(const void* table, const DWORD* offsets, unsigned num_types);
+int codeview_dump_types_from_block(const void* table, unsigned long len);
void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr);
void dump_codeview(unsigned long ptr, unsigned long len);
More information about the wine-patches
mailing list