[PATCH v4 4/6] dlls/dbghelp{pdb}: clearly separate the type loading into two passes
Eric Pouech
wine at gitlab.winehq.org
Thu Jun 2 03:29:00 CDT 2022
From: Eric Pouech <eric.pouech at 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 at 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;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/73
More information about the wine-devel
mailing list