📄 msc.c
字号:
case LF_NESTTYPE_V1:
/* FIXME: ignored for now */
ptr += 2 + 2 + (1 + type->nesttype_v1.p_name.namelen);
break;
case LF_NESTTYPE_V2:
/* FIXME: ignored for now */
ptr += 2 + 2 + 4 + (1 + type->nesttype_v2.p_name.namelen);
break;
case LF_VFUNCTAB_V1:
/* FIXME: ignored for now */
ptr += 2 + 2;
break;
case LF_VFUNCTAB_V2:
/* FIXME: ignored for now */
ptr += 2 + 2 + 4;
break;
case LF_ONEMETHOD_V1:
/* FIXME: ignored for now */
switch ((type->onemethod_v1.attribute >> 2) & 7)
{
case 4: case 6: /* (pure) introducing virtual method */
ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt_v1.p_name.namelen);
break;
default:
ptr += 2 + 2 + 2 + (1 + type->onemethod_v1.p_name.namelen);
break;
}
break;
case LF_ONEMETHOD_V2:
/* FIXME: ignored for now */
switch ((type->onemethod_v2.attribute >> 2) & 7)
{
case 4: case 6: /* (pure) introducing virtual method */
ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod_virt_v2.p_name.namelen);
break;
default:
ptr += 2 + 2 + 4 + (1 + type->onemethod_v2.p_name.namelen);
break;
}
break;
default:
FIXME("Unsupported type %04x in STRUCT field list\n", type->generic.id);
return FALSE;
}
}
return codeview_add_type(typeno, &symt->symt);
}
static int codeview_add_type_enum(struct module* module, unsigned int typeno,
const char* name, unsigned int fieldlist)
{
struct symt_enum* symt = symt_new_enum(module, name);
struct symt* list = codeview_get_type(fieldlist, FALSE);
/* FIXME: this is rather ugly !!! */
if (list) symt->vchildren = ((struct symt_enum*)list)->vchildren;
return codeview_add_type(typeno, &symt->symt);
}
static int codeview_add_type_struct(struct module* module, unsigned int typeno,
const char* name, int structlen,
unsigned int fieldlist, enum UdtKind kind)
{
struct symt_udt* symt = symt_new_udt(module, name, structlen, kind);
struct symt* list = codeview_get_type(fieldlist, FALSE);
/* FIXME: this is rather ugly !!! */
if (list) symt->vchildren = ((struct symt_udt*)list)->vchildren;
return codeview_add_type(typeno, &symt->symt);
}
static int codeview_new_func_signature(struct module* module, unsigned typeno,
unsigned ret_type)
{
struct symt* symt;
symt = &symt_new_function_signature(module,
codeview_get_type(ret_type, FALSE))->symt;
return codeview_add_type(typeno, symt);
}
static int codeview_parse_type_table(struct module* module, const char* table,
int len)
{
unsigned int curr_type = 0x1000;
const char* ptr = table;
int retv;
const union codeview_type* type;
int value, leaf_len;
const struct p_string* p_name;
const char* c_name;
while (ptr - table < len)
{
retv = TRUE;
type = (const union codeview_type*)ptr;
switch (type->generic.id)
{
case LF_MODIFIER_V1:
/* FIXME: we don't handle modifiers,
* but readd previous type on the curr_type
*/
WARN("Modifier on %x: %s%s%s%s\n",
type->modifier_v1.type,
type->modifier_v1.attribute & 0x01 ? "const " : "",
type->modifier_v1.attribute & 0x02 ? "volatile " : "",
type->modifier_v1.attribute & 0x04 ? "unaligned " : "",
type->modifier_v1.attribute & ~0x07 ? "unknown " : "");
codeview_add_type(curr_type,
codeview_get_type(type->modifier_v1.type, FALSE));
break;
case LF_MODIFIER_V2:
/* FIXME: we don't handle modifiers, but readd previous type on the curr_type */
WARN("Modifier on %x: %s%s%s%s\n",
type->modifier_v2.type,
type->modifier_v2.attribute & 0x01 ? "const " : "",
type->modifier_v2.attribute & 0x02 ? "volatile " : "",
type->modifier_v2.attribute & 0x04 ? "unaligned " : "",
type->modifier_v2.attribute & ~0x07 ? "unknown " : "");
codeview_add_type(curr_type,
codeview_get_type(type->modifier_v2.type, FALSE));
break;
case LF_POINTER_V1:
retv = codeview_add_type_pointer(module, curr_type,
type->pointer_v1.datatype);
break;
case LF_POINTER_V2:
retv = codeview_add_type_pointer(module, curr_type,
type->pointer_v2.datatype);
break;
case LF_ARRAY_V1:
leaf_len = numeric_leaf(&value, &type->array_v1.arrlen);
p_name = (const struct p_string*)((const unsigned char*)&type->array_v1.arrlen + leaf_len);
retv = codeview_add_type_array(module, curr_type, terminate_string(p_name),
type->array_v1.elemtype, value);
break;
case LF_ARRAY_V2:
leaf_len = numeric_leaf(&value, &type->array_v2.arrlen);
p_name = (const struct p_string*)((const unsigned char*)&type->array_v2.arrlen + leaf_len);
retv = codeview_add_type_array(module, curr_type, terminate_string(p_name),
type->array_v2.elemtype, value);
break;
case LF_ARRAY_V3:
leaf_len = numeric_leaf(&value, &type->array_v3.arrlen);
c_name = (const char*)&type->array_v3.arrlen + leaf_len;
retv = codeview_add_type_array(module, curr_type, c_name,
type->array_v3.elemtype, value);
break;
case LF_BITFIELD_V1:
/* a bitfield 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
*/
retv = codeview_add_type_bitfield(curr_type, type->bitfield_v1.bitoff,
type->bitfield_v1.nbits,
type->bitfield_v1.type);
break;
case LF_BITFIELD_V2:
retv = codeview_add_type_bitfield(curr_type, type->bitfield_v2.bitoff,
type->bitfield_v2.nbits,
type->bitfield_v2.type);
break;
case LF_FIELDLIST_V1:
case LF_FIELDLIST_V2:
{
/*
* A 'field list' is a CodeView-specific data type which doesn't
* directly correspond to any high-level data type. It is used
* to hold the collection of members of a struct, class, union
* or enum type. The actual definition of that type will follow
* later, and refer to the field list definition record.
*
* As we don't have a field list type ourselves, we look ahead
* in the field list to try to find out whether this field list
* will be used for an enum or struct type, and create a dummy
* type of the corresponding sort. Later on, the definition of
* the 'real' type will copy the member / enumeration data.
*/
const char* list = type->fieldlist.list;
int len = (ptr + type->generic.len + 2) - list;
if (((const union codeview_fieldtype*)list)->generic.id == LF_ENUMERATE_V1 ||
((const union codeview_fieldtype*)list)->generic.id == LF_ENUMERATE_V3)
retv = codeview_add_type_enum_field_list(module, curr_type, list, len);
else
retv = codeview_add_type_struct_field_list(module, curr_type, list, len);
}
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);
retv = codeview_add_type_struct(module, curr_type, terminate_string(p_name),
value, type->struct_v1.fieldlist,
type->generic.id == LF_CLASS_V1 ? UdtClass : UdtStruct);
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);
retv = codeview_add_type_struct(module, curr_type, terminate_string(p_name),
value, type->struct_v2.fieldlist,
type->generic.id == LF_CLASS_V2 ? UdtClass : UdtStruct);
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;
retv = codeview_add_type_struct(module, curr_type, c_name,
value, type->struct_v3.fieldlist,
type->generic.id == LF_CLASS_V3 ? UdtClass : UdtStruct);
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);
retv = codeview_add_type_struct(module, curr_type, terminate_string(p_name),
value, type->union_v1.fieldlist, UdtUnion);
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);
retv = codeview_add_type_struct(module, curr_type, terminate_string(p_name),
value, type->union_v2.fieldlist, UdtUnion);
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;
retv = codeview_add_type_struct(module, curr_type, c_name,
value, type->union_v3.fieldlist, UdtUnion);
case LF_ENUM_V1:
retv = codeview_add_type_enum(module, curr_type, terminate_string(&type->enumeration_v1.p_name),
type->enumeration_v1.field);
break;
case LF_ENUM_V2:
retv = codeview_add_type_enum(module, curr_type, terminate_string(&type->enumeration_v2.p_name),
type->enumeration_v2.field);
break;
case LF_ENUM_V3:
retv = codeview_add_type_enum(module, curr_type, type->enumeration_v3.name,
type->enumeration_v3.field);
break;
case LF_PROCEDURE_V1:
retv = codeview_new_func_signature(module, curr_type,
type->procedure_v1.rvtype);
break;
case LF_PROCEDURE_V2:
retv = codeview_new_func_signature(module, curr_type,
type->procedure_v2.rvtype);
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
*/
retv = codeview_new_func_signature(module, curr_type,
type->mfunction_v1.rvtype);
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
*/
retv = codeview_new_func_signature(module, curr_type,
type->mfunction_v2.rvtype);
break;
case LF_ARGLIST_V1:
case LF_ARGLIST_V2:
{
static int once;
if (!once++)
FIXME("Not adding parameters' types to function signature\n");
}
break;
default:
FIXME("Unsupported type-id leaf %x\n", type->generic.id);
dump(type, 2 + type->generic.len);
break;
}
if (!retv) return FALSE;
curr_type++;
ptr += type->generic.len + 2;
}
return TRUE;
}
/*========================================================================
* Process CodeView line number information.
*/
static struct codeview_linetab* codeview_snarf_linetab(struct module* module,
const char* linetab, int size,
BOOL pascal_str)
{
int file_segcount;
char filename[PATH_MAX];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -