From: Eric Pouech eric.pouech@gmail.com
- removed the details parameter from load_one_type (the two passes split didn't even correspond to the details split) - correctly move forward handling for unions & enum in first pass
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/msc.c | 486 ++++++++++++++++++++++----------------------- 1 file changed, 241 insertions(+), 245 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 583f75aed2f..dfb5cac94aa 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -613,7 +613,7 @@ static void codeview_clear_type_table(void)
static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp, unsigned curr_type, - const union codeview_type* type, BOOL details); + const union codeview_type* type);
static void* codeview_cast_symt(struct symt* symt, enum SymTagEnum tag) { @@ -626,7 +626,7 @@ static void* codeview_cast_symt(struct symt* symt, enum SymTagEnum tag) }
static struct symt* codeview_fetch_type(struct codeview_type_parse* ctp, - unsigned typeno, BOOL details) + unsigned typeno) { struct symt* symt; const union codeview_type* p; @@ -634,29 +634,40 @@ static struct symt* codeview_fetch_type(struct codeview_type_parse* ctp, if (!typeno) return NULL; if ((symt = codeview_get_type(typeno, TRUE))) return symt;
- /* forward declaration */ - if (!(p = codeview_jump_to_type(ctp, typeno))) + if ((p = codeview_jump_to_type(ctp, typeno))) + symt = codeview_parse_one_type(ctp, typeno, p); + if (!symt) FIXME("Couldn't load type %x\n", typeno); + return symt; +} + +static BOOL codeview_is_remapable_type(const union codeview_type* type) +{ + switch (type->generic.id) { - FIXME("Cannot locate type %x\n", typeno); - return NULL; + case LF_STRUCTURE_V1: + case LF_CLASS_V1: + case LF_STRUCTURE_V2: + case LF_CLASS_V2: + case LF_STRUCTURE_V3: + case LF_CLASS_V3: + case LF_UNION_V1: + case LF_UNION_V2: + case LF_UNION_V3: + case LF_ENUM_V1: + case LF_ENUM_V2: + case LF_ENUM_V3: + return TRUE; + default: return FALSE; } - symt = codeview_parse_one_type(ctp, typeno, p, details); - if (!symt) FIXME("Couldn't load forward type %x\n", typeno); - return symt; }
static struct symt* codeview_add_type_pointer(struct codeview_type_parse* ctp, - struct symt* existing, unsigned int pointee_type) { struct symt* pointee;
- if (existing) - { - existing = codeview_cast_symt(existing, SymTagPointerType); - return existing; - } - pointee = codeview_fetch_type(ctp, pointee_type, FALSE); + pointee = codeview_fetch_type(ctp, pointee_type); + if (!pointee) return NULL; return &symt_new_pointer(ctp->module, pointee, ctp->module->cpu->word_size)->symt; }
@@ -666,8 +677,8 @@ static struct symt* codeview_add_type_array(struct codeview_type_parse* ctp, unsigned int indextype, unsigned int arr_len) { - struct symt* elem = codeview_fetch_type(ctp, elemtype, FALSE); - struct symt* index = codeview_fetch_type(ctp, indextype, FALSE); + struct symt* elem = codeview_fetch_type(ctp, elemtype); + struct symt* index = codeview_fetch_type(ctp, indextype); DWORD64 elem_size; DWORD count = 0;
@@ -680,14 +691,20 @@ static struct symt* codeview_add_type_array(struct codeview_type_parse* ctp, return &symt_new_array(ctp->module, 0, count, elem, index)->symt; }
-static BOOL codeview_add_type_enum_field_list(struct module* module, +static BOOL codeview_add_type_enum_field_list(struct codeview_type_parse* ctp, struct symt_enum* symt, - const union codeview_reftype* ref_type) + unsigned typeno) { - const unsigned char* ptr = ref_type->fieldlist.list; - const unsigned char* last = (const BYTE*)ref_type + ref_type->generic.len + 2; + const union codeview_reftype* ref_type; + const unsigned char* ptr; + const unsigned char* last; const union codeview_fieldtype* type;
+ if (!typeno) return TRUE; + if (!(ref_type = codeview_jump_to_type(ctp, typeno))) return FALSE; + ptr = ref_type->fieldlist.list; + last = (const BYTE*)ref_type + ref_type->generic.len + 2; + while (ptr < last) { if (*ptr >= 0xf0) /* LF_PAD... */ @@ -705,7 +722,7 @@ static BOOL codeview_add_type_enum_field_list(struct module* module, int value, vlen = numeric_leaf(&value, &type->enumerate_v1.value); const struct p_string* p_name = (const struct p_string*)((const unsigned char*)&type->enumerate_v1.value + vlen);
- symt_add_enum_element(module, symt, terminate_string(p_name), value); + symt_add_enum_element(ctp->module, symt, terminate_string(p_name), value); ptr += 2 + 2 + vlen + (1 + p_name->namelen); break; } @@ -714,7 +731,7 @@ static BOOL codeview_add_type_enum_field_list(struct module* module, int value, vlen = numeric_leaf(&value, &type->enumerate_v3.value); const char* name = (const char*)&type->enumerate_v3.value + vlen;
- symt_add_enum_element(module, symt, name, value); + symt_add_enum_element(ctp->module, symt, name, value); ptr += 2 + 2 + vlen + (1 + strlen(name)); break; } @@ -740,19 +757,19 @@ static void codeview_add_udt_element(struct codeview_type_parse* ctp, { case LF_BITFIELD_V1: symt_add_udt_element(ctp->module, symt, name, - codeview_fetch_type(ctp, cv_type->bitfield_v1.type, FALSE), + codeview_fetch_type(ctp, cv_type->bitfield_v1.type), value, cv_type->bitfield_v1.bitoff, cv_type->bitfield_v1.nbits); return; case LF_BITFIELD_V2: symt_add_udt_element(ctp->module, symt, name, - codeview_fetch_type(ctp, cv_type->bitfield_v2.type, FALSE), + codeview_fetch_type(ctp, cv_type->bitfield_v2.type), value, cv_type->bitfield_v2.bitoff, cv_type->bitfield_v2.nbits); return; } } - subtype = codeview_fetch_type(ctp, type, FALSE); + subtype = codeview_fetch_type(ctp, type);
if (subtype) { @@ -984,60 +1001,30 @@ static int codeview_add_type_struct_field_list(struct codeview_type_parse* ctp, return TRUE; }
-static struct symt* codeview_add_type_enum(struct codeview_type_parse* ctp, - struct symt* existing, - const char* name, - unsigned fieldlistno, - unsigned basetype) -{ - struct symt_enum* symt; - - if (existing) - { - if (!(symt = codeview_cast_symt(existing, SymTagEnum))) return NULL; - /* should also check that all fields are the same */ - } - else - { - symt = symt_new_enum(ctp->module, name, - codeview_fetch_type(ctp, basetype, FALSE)); - if (fieldlistno) - { - const union codeview_reftype* fieldlist; - fieldlist = codeview_jump_to_type(ctp, fieldlistno); - codeview_add_type_enum_field_list(ctp->module, symt, fieldlist); - } - } - return &symt->symt; -} - static struct symt* codeview_add_type_struct(struct codeview_type_parse* ctp, - struct symt* existing, const char* name, int structlen, enum UdtKind kind, cv_property_t property) { struct symt_udt* symt; + struct symt* existing = NULL;
/* if we don't have an existing type, try to find one with same name * FIXME: what to do when several types in different CUs have same name ? */ - if (!existing) + void* ptr; + struct symt_ht* type; + struct hash_table_iter hti; + + hash_table_iter_init(&ctp->module->ht_types, &hti, name); + while ((ptr = hash_table_iter_up(&hti))) { - void* ptr; - struct symt_ht* type; - struct hash_table_iter hti; + type = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
- hash_table_iter_init(&ctp->module->ht_types, &hti, name); - while ((ptr = hash_table_iter_up(&hti))) + if (type->symt.tag == SymTagUDT && + type->hash_elt.name && !strcmp(type->hash_elt.name, name)) { - type = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt); - - if (type->symt.tag == SymTagUDT && - type->hash_elt.name && !strcmp(type->hash_elt.name, name)) - { - existing = &type->symt; - break; - } + existing = &type->symt; + break; } } if (existing) @@ -1057,21 +1044,12 @@ static struct symt* codeview_add_type_struct(struct codeview_type_parse* ctp, return &symt->symt; }
-static struct symt* codeview_new_func_signature(struct codeview_type_parse* ctp, - struct symt* existing, +static struct symt* codeview_new_func_signature(struct codeview_type_parse* ctp, enum CV_call_e call_conv) { struct symt_function_signature* sym;
- if (existing) - { - sym = codeview_cast_symt(existing, SymTagFunctionType); - if (!sym) return NULL; - } - else - { - sym = symt_new_function_signature(ctp->module, NULL, call_conv); - } + sym = symt_new_function_signature(ctp->module, NULL, call_conv); return &sym->symt; }
@@ -1082,7 +1060,7 @@ static void codeview_add_func_signature_args(struct codeview_type_parse* ctp, { const union codeview_reftype* reftype;
- sym->rettype = codeview_fetch_type(ctp, ret_type, FALSE); + sym->rettype = codeview_fetch_type(ctp, ret_type); if (args_list && (reftype = codeview_jump_to_type(ctp, args_list))) { unsigned int i; @@ -1091,12 +1069,12 @@ static void codeview_add_func_signature_args(struct codeview_type_parse* ctp, case LF_ARGLIST_V1: for (i = 0; i < reftype->arglist_v1.num; i++) symt_add_function_signature_parameter(ctp->module, sym, - codeview_fetch_type(ctp, reftype->arglist_v1.args[i], FALSE)); + codeview_fetch_type(ctp, reftype->arglist_v1.args[i])); break; case LF_ARGLIST_V2: for (i = 0; i < reftype->arglist_v2.num; i++) symt_add_function_signature_parameter(ctp->module, sym, - codeview_fetch_type(ctp, reftype->arglist_v2.args[i], FALSE)); + codeview_fetch_type(ctp, reftype->arglist_v2.args[i])); break; default: FIXME("Unexpected leaf %x for signature's pmt\n", reftype->generic.id); @@ -1106,15 +1084,12 @@ static void codeview_add_func_signature_args(struct codeview_type_parse* ctp,
static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp, unsigned curr_type, - const union codeview_type* type, BOOL details) + const union codeview_type* type) { - struct symt* symt; + struct symt* symt = NULL; int value, leaf_len; const struct p_string* p_name; const char* c_name; - struct symt* existing; - - existing = codeview_get_type(curr_type, TRUE);
switch (type->generic.id) { @@ -1128,7 +1103,7 @@ static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp, type->modifier_v1.attribute & 0x02 ? "volatile " : "", type->modifier_v1.attribute & 0x04 ? "unaligned " : "", type->modifier_v1.attribute & ~0x07 ? "unknown " : ""); - symt = codeview_fetch_type(ctp, type->modifier_v1.type, details); + symt = codeview_fetch_type(ctp, type->modifier_v1.type); break; case LF_MODIFIER_V2: /* FIXME: we don't handle modifiers, but readd previous type on the curr_type */ @@ -1138,214 +1113,141 @@ static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp, type->modifier_v2.attribute & 0x02 ? "volatile " : "", type->modifier_v2.attribute & 0x04 ? "unaligned " : "", type->modifier_v2.attribute & ~0x07 ? "unknown " : ""); - symt = codeview_fetch_type(ctp, type->modifier_v2.type, details); + symt = codeview_fetch_type(ctp, type->modifier_v2.type); break;
case LF_POINTER_V1: - symt = codeview_add_type_pointer(ctp, existing, type->pointer_v1.datatype); + symt = codeview_add_type_pointer(ctp, type->pointer_v1.datatype); break; case LF_POINTER_V2: - symt = codeview_add_type_pointer(ctp, existing, type->pointer_v2.datatype); + symt = codeview_add_type_pointer(ctp, type->pointer_v2.datatype); break;
case LF_ARRAY_V1: - if (existing) symt = codeview_cast_symt(existing, SymTagArrayType); - else - { - leaf_len = numeric_leaf(&value, &type->array_v1.arrlen); - p_name = (const struct p_string*)((const unsigned char*)&type->array_v1.arrlen + leaf_len); - symt = codeview_add_type_array(ctp, terminate_string(p_name), - type->array_v1.elemtype, - type->array_v1.idxtype, value); - } + leaf_len = numeric_leaf(&value, &type->array_v1.arrlen); + p_name = (const struct p_string*)((const unsigned char*)&type->array_v1.arrlen + leaf_len); + symt = codeview_add_type_array(ctp, terminate_string(p_name), + type->array_v1.elemtype, + type->array_v1.idxtype, value); break; case LF_ARRAY_V2: - if (existing) symt = codeview_cast_symt(existing, SymTagArrayType); - else - { - leaf_len = numeric_leaf(&value, &type->array_v2.arrlen); - p_name = (const struct p_string*)((const unsigned char*)&type->array_v2.arrlen + leaf_len); + leaf_len = numeric_leaf(&value, &type->array_v2.arrlen); + p_name = (const struct p_string*)((const unsigned char*)&type->array_v2.arrlen + leaf_len);
- symt = codeview_add_type_array(ctp, terminate_string(p_name), - type->array_v2.elemtype, - type->array_v2.idxtype, value); - } + symt = codeview_add_type_array(ctp, terminate_string(p_name), + type->array_v2.elemtype, + type->array_v2.idxtype, value); break; case LF_ARRAY_V3: - if (existing) symt = codeview_cast_symt(existing, SymTagArrayType); - else - { - leaf_len = numeric_leaf(&value, &type->array_v3.arrlen); - c_name = (const char*)&type->array_v3.arrlen + leaf_len; + leaf_len = numeric_leaf(&value, &type->array_v3.arrlen); + c_name = (const char*)&type->array_v3.arrlen + leaf_len;
- symt = codeview_add_type_array(ctp, c_name, - type->array_v3.elemtype, - type->array_v3.idxtype, value); - } + symt = codeview_add_type_array(ctp, c_name, + type->array_v3.elemtype, + type->array_v3.idxtype, value); break;
case LF_STRUCTURE_V1: case LF_CLASS_V1: - leaf_len = numeric_leaf(&value, &type->struct_v1.structlen); - p_name = (const struct p_string*)((const unsigned char*)&type->struct_v1.structlen + leaf_len); - symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name), value, - type->generic.id == LF_CLASS_V1 ? UdtClass : UdtStruct, - type->struct_v1.property); - if (details) - { - codeview_add_type(curr_type, symt); - if (!type->struct_v1.property.is_forward_defn) - codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt, - type->struct_v1.fieldlist); - } + if (!type->struct_v1.property.is_forward_defn) + codeview_add_type_struct_field_list(ctp, (struct symt_udt*)codeview_get_type(curr_type, TRUE), + type->struct_v1.fieldlist); break;
case LF_STRUCTURE_V2: case LF_CLASS_V2: - leaf_len = numeric_leaf(&value, &type->struct_v2.structlen); - p_name = (const struct p_string*)((const unsigned char*)&type->struct_v2.structlen + leaf_len); - symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name), value, - type->generic.id == LF_CLASS_V2 ? UdtClass : UdtStruct, - type->struct_v2.property); - if (details) - { - codeview_add_type(curr_type, symt); - if (!type->struct_v2.property.is_forward_defn) - codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt, - type->struct_v2.fieldlist); - } + if (!type->struct_v2.property.is_forward_defn) + codeview_add_type_struct_field_list(ctp, (struct symt_udt*)codeview_get_type(curr_type, TRUE), + type->struct_v2.fieldlist); break;
case LF_STRUCTURE_V3: case LF_CLASS_V3: - leaf_len = numeric_leaf(&value, &type->struct_v3.structlen); - c_name = (const char*)&type->struct_v3.structlen + leaf_len; - symt = codeview_add_type_struct(ctp, existing, c_name, value, - type->generic.id == LF_CLASS_V3 ? UdtClass : UdtStruct, - type->struct_v3.property); - if (details) - { - codeview_add_type(curr_type, symt); - if (!type->struct_v3.property.is_forward_defn) - codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt, - type->struct_v3.fieldlist); - } + if (!type->struct_v3.property.is_forward_defn) + codeview_add_type_struct_field_list(ctp, (struct symt_udt*)codeview_get_type(curr_type, TRUE), + type->struct_v3.fieldlist); break;
case LF_UNION_V1: - leaf_len = numeric_leaf(&value, &type->union_v1.un_len); - p_name = (const struct p_string*)((const unsigned char*)&type->union_v1.un_len + leaf_len); - symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name), - value, UdtUnion, type->union_v1.property); - if (details) - { - codeview_add_type(curr_type, symt); - codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt, + if (!type->union_v1.property.is_forward_defn) + codeview_add_type_struct_field_list(ctp, (struct symt_udt*)codeview_get_type(curr_type, TRUE), type->union_v1.fieldlist); - } break;
case LF_UNION_V2: - leaf_len = numeric_leaf(&value, &type->union_v2.un_len); - p_name = (const struct p_string*)((const unsigned char*)&type->union_v2.un_len + leaf_len); - symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name), - value, UdtUnion, type->union_v2.property); - if (details) - { - codeview_add_type(curr_type, symt); - codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt, + if (!type->union_v2.property.is_forward_defn) + codeview_add_type_struct_field_list(ctp, (struct symt_udt*)codeview_get_type(curr_type, TRUE), type->union_v2.fieldlist); - } break;
case LF_UNION_V3: - leaf_len = numeric_leaf(&value, &type->union_v3.un_len); - c_name = (const char*)&type->union_v3.un_len + leaf_len; - symt = codeview_add_type_struct(ctp, existing, c_name, - value, UdtUnion, type->union_v3.property); - if (details) - { - codeview_add_type(curr_type, symt); - codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt, + if (!type->union_v3.property.is_forward_defn) + codeview_add_type_struct_field_list(ctp, (struct symt_udt*)codeview_get_type(curr_type, TRUE), type->union_v3.fieldlist); - } break;
case LF_ENUM_V1: - symt = codeview_add_type_enum(ctp, existing, - terminate_string(&type->enumeration_v1.p_name), - type->enumeration_v1.fieldlist, - type->enumeration_v1.type); + { + struct symt_enum* senum = (struct symt_enum*)codeview_get_type(curr_type, TRUE); + senum->base_type = codeview_fetch_type(ctp, type->enumeration_v1.type); + codeview_add_type_enum_field_list(ctp, senum, type->enumeration_v1.fieldlist); + } break;
case LF_ENUM_V2: - symt = codeview_add_type_enum(ctp, existing, - terminate_string(&type->enumeration_v2.p_name), - type->enumeration_v2.fieldlist, - type->enumeration_v2.type); + { + struct symt_enum* senum = (struct symt_enum*)codeview_get_type(curr_type, TRUE); + senum->base_type = codeview_fetch_type(ctp, type->enumeration_v2.type); + codeview_add_type_enum_field_list(ctp, senum, type->enumeration_v2.fieldlist); + } break;
case LF_ENUM_V3: - symt = codeview_add_type_enum(ctp, existing, type->enumeration_v3.name, - type->enumeration_v3.fieldlist, - type->enumeration_v3.type); + { + struct symt_enum* senum = (struct symt_enum*)codeview_get_type(curr_type, TRUE); + senum->base_type = codeview_fetch_type(ctp, type->enumeration_v3.type); + codeview_add_type_enum_field_list(ctp, senum, type->enumeration_v3.fieldlist); + } break;
case LF_PROCEDURE_V1: - symt = codeview_new_func_signature(ctp, existing, type->procedure_v1.callconv); - if (details) - { - codeview_add_type(curr_type, symt); - codeview_add_func_signature_args(ctp, - (struct symt_function_signature*)symt, - type->procedure_v1.rvtype, - type->procedure_v1.arglist); - } + symt = codeview_new_func_signature(ctp, type->procedure_v1.callconv); + codeview_add_func_signature_args(ctp, + (struct symt_function_signature*)symt, + type->procedure_v1.rvtype, + type->procedure_v1.arglist); break; case LF_PROCEDURE_V2: - symt = codeview_new_func_signature(ctp, existing,type->procedure_v2.callconv); - if (details) - { - codeview_add_type(curr_type, symt); - codeview_add_func_signature_args(ctp, - (struct symt_function_signature*)symt, - type->procedure_v2.rvtype, - type->procedure_v2.arglist); - } + symt = codeview_new_func_signature(ctp,type->procedure_v2.callconv); + codeview_add_func_signature_args(ctp, + (struct symt_function_signature*)symt, + type->procedure_v2.rvtype, + type->procedure_v2.arglist); break;
case LF_MFUNCTION_V1: /* FIXME: for C++, this is plain wrong, but as we don't use arg types * nor class information, this would just do for now */ - symt = codeview_new_func_signature(ctp, existing, type->mfunction_v1.callconv); - if (details) - { - codeview_add_type(curr_type, symt); - codeview_add_func_signature_args(ctp, - (struct symt_function_signature*)symt, - type->mfunction_v1.rvtype, - type->mfunction_v1.arglist); - } + symt = codeview_new_func_signature(ctp, type->mfunction_v1.callconv); + codeview_add_func_signature_args(ctp, + (struct symt_function_signature*)symt, + type->mfunction_v1.rvtype, + type->mfunction_v1.arglist); break; case LF_MFUNCTION_V2: /* FIXME: for C++, this is plain wrong, but as we don't use arg types * nor class information, this would just do for now */ - symt = codeview_new_func_signature(ctp, existing, type->mfunction_v2.callconv); - if (details) - { - codeview_add_type(curr_type, symt); - codeview_add_func_signature_args(ctp, - (struct symt_function_signature*)symt, - type->mfunction_v2.rvtype, - type->mfunction_v2.arglist); - } + symt = codeview_new_func_signature(ctp, type->mfunction_v2.callconv); + codeview_add_func_signature_args(ctp, + (struct symt_function_signature*)symt, + type->mfunction_v2.rvtype, + type->mfunction_v2.arglist); break;
case LF_VTSHAPE_V1: /* this is an ugly hack... FIXME when we have C++ support */ - if (!(symt = existing)) { char buf[128]; snprintf(buf, sizeof(buf), "__internal_vt_shape_%x\n", curr_type); @@ -1357,7 +1259,99 @@ static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp, dump(type, 2 + type->generic.len); return NULL; } - return codeview_add_type(curr_type, symt) ? symt : NULL; + return symt && codeview_add_type(curr_type, symt) ? symt : NULL; +} + +static struct symt* codeview_parse_remapable_type(struct codeview_type_parse* ctp, + unsigned curr_type, + const union codeview_type* type) +{ + struct symt* symt; + int value, leaf_len; + const struct p_string* p_name; + const char* c_name; + + switch (type->generic.id) + { + case LF_STRUCTURE_V1: + case LF_CLASS_V1: + leaf_len = numeric_leaf(&value, &type->struct_v1.structlen); + p_name = (const struct p_string*)((const unsigned char*)&type->struct_v1.structlen + leaf_len); + symt = codeview_add_type_struct(ctp, terminate_string(p_name), value, + type->generic.id == LF_CLASS_V1 ? UdtClass : UdtStruct, + type->struct_v1.property); + break; + + case LF_STRUCTURE_V2: + case LF_CLASS_V2: + leaf_len = numeric_leaf(&value, &type->struct_v2.structlen); + p_name = (const struct p_string*)((const unsigned char*)&type->struct_v2.structlen + leaf_len); + symt = codeview_add_type_struct(ctp, terminate_string(p_name), value, + type->generic.id == LF_CLASS_V2 ? UdtClass : UdtStruct, + type->struct_v2.property); + break; + + case LF_STRUCTURE_V3: + case LF_CLASS_V3: + leaf_len = numeric_leaf(&value, &type->struct_v3.structlen); + c_name = (const char*)&type->struct_v3.structlen + leaf_len; + symt = codeview_add_type_struct(ctp, c_name, value, + type->generic.id == LF_CLASS_V3 ? UdtClass : UdtStruct, + type->struct_v3.property); + break; + + case LF_UNION_V1: + leaf_len = numeric_leaf(&value, &type->union_v1.un_len); + p_name = (const struct p_string*)((const unsigned char*)&type->union_v1.un_len + leaf_len); + symt = codeview_add_type_struct(ctp, terminate_string(p_name), + value, UdtUnion, type->union_v1.property); + break; + + case LF_UNION_V2: + leaf_len = numeric_leaf(&value, &type->union_v2.un_len); + p_name = (const struct p_string*)((const unsigned char*)&type->union_v2.un_len + leaf_len); + symt = codeview_add_type_struct(ctp, terminate_string(p_name), + value, UdtUnion, type->union_v2.property); + break; + + case LF_UNION_V3: + leaf_len = numeric_leaf(&value, &type->union_v3.un_len); + c_name = (const char*)&type->union_v3.un_len + leaf_len; + symt = codeview_add_type_struct(ctp, c_name, + value, UdtUnion, type->union_v3.property); + break; + + case LF_ENUM_V1: + symt = &symt_new_enum(ctp->module, terminate_string(&type->enumeration_v1.p_name), NULL)->symt; + break; + + case LF_ENUM_V2: + symt = &symt_new_enum(ctp->module, terminate_string(&type->enumeration_v2.p_name), NULL)->symt; + break; + + case LF_ENUM_V3: + symt = &symt_new_enum(ctp->module, type->enumeration_v3.name, NULL)->symt; + break; + + default: symt = NULL; + } + return symt && codeview_add_type(curr_type, symt) ? symt : NULL; +} + +static BOOL codeview_is_top_level_type(const union codeview_type* type) +{ + /* type records we're interested in are the ones referenced by symbols + * The known ranges are (X mark the ones we want): + * X 0000-0016 for V1 types + * 0200-020c for V1 types referenced by other types + * 0400-040f for V1 types (complex lists & sets) + * X 1000-100f for V2 types + * 1200-120c for V2 types referenced by other types + * 1400-140f for V1 types (complex lists & sets) + * X 1500-150d for V3 types + * 8000-8010 for numeric leafes + */ + return !(type->generic.id & 0x8600) || (type->generic.id & 0x0100); }
static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp) @@ -1370,23 +1364,25 @@ static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp) cv_current_module->defined_types = calloc(ctp->header.last_index - ctp->header.first_index, sizeof(*cv_current_module->defined_types));
+ /* phase I: only load remapable types (struct/class/union/enum), but without their content + * handle also forward declarations + */ for (curr_type = ctp->header.first_index; curr_type < ctp->header.last_index; curr_type++) { type = codeview_jump_to_type(ctp, curr_type); - - /* type records we're interested in are the ones referenced by symbols - * The known ranges are (X mark the ones we want): - * X 0000-0016 for V1 types - * 0200-020c for V1 types referenced by other types - * 0400-040f for V1 types (complex lists & sets) - * X 1000-100f for V2 types - * 1200-120c for V2 types referenced by other types - * 1400-140f for V1 types (complex lists & sets) - * X 1500-150d for V3 types - * 8000-8010 for numeric leafes - */ - if (!(type->generic.id & 0x8600) || (type->generic.id & 0x0100)) - codeview_parse_one_type(ctp, curr_type, type, TRUE); + if (codeview_is_top_level_type(type)) + codeview_parse_remapable_type(ctp, curr_type, type); + } + /* phase II: non remapable types: load (but since they can be indirectly + * loaded (from another type), don't load them twice) + * rematable types: they can't be loaded indirectly, so load their content + */ + for (curr_type = ctp->header.first_index; curr_type < ctp->header.last_index; curr_type++) + { + type = codeview_jump_to_type(ctp, curr_type); + if (codeview_is_top_level_type(type) && + (!codeview_get_type(curr_type, TRUE) || codeview_is_remapable_type(type))) + codeview_parse_one_type(ctp, curr_type, type); }
return TRUE;