📄 dwarf2.c
字号:
break;
case FT_SIGNED_INTEGER:
type = init_type ( TYPE_CODE_INT,
4,/* 字节数 */
0, "int" ); /* FIXME -fnf */
break;
case FT_UNSIGNED_INTEGER:
type = init_type ( TYPE_CODE_INT,
4,/* 字节数 */
TYPE_FLAG_UNSIGNED, "unsigned int" );
break;
case FT_LONG:
type = init_type ( TYPE_CODE_INT,
5,/* 字节数 */
0, "long" );
break;
case FT_SIGNED_LONG:
type = init_type ( TYPE_CODE_INT,
5,/* 字节数 */
0, "long" ); /* FIXME -fnf */
break;
case FT_UNSIGNED_LONG:
type = init_type ( TYPE_CODE_INT,
5,/* 字节数 */
TYPE_FLAG_UNSIGNED, "unsigned long" );
break;
case FT_LONG_LONG:
type = init_type ( TYPE_CODE_INT,
8,/* 字节数 */
0, "long long" );
break;
case FT_SIGNED_LONG_LONG:
type = init_type ( TYPE_CODE_INT,
8,/* 字节数 */
0, "signed long long" );
break;
case FT_UNSIGNED_LONG_LONG:
type = init_type ( TYPE_CODE_INT,
8,/* 字节数 */
TYPE_FLAG_UNSIGNED, "unsigned long long" );
break;
case FT_FLOAT:
type = init_type ( TYPE_CODE_FLT,
4,/* 字节数 */
0, "float" );
break;
case FT_DBL_PREC_FLOAT:
type = init_type ( TYPE_CODE_FLT,
8,/* 字节数 */
0, "double" );
break;
case FT_EXT_PREC_FLOAT:
type = init_type ( TYPE_CODE_FLT,
8,/* 字节数 */
0, "long double" );
break;
case FT_TEMPLATE_ARG:
type = init_type ( TYPE_CODE_TEMPLATE_ARG,
0,
0, "<template arg>" );
break;
}
return ( type );
}
static void read_structure_scope ( struct die_info * die, const struct comp_unit_head * cu_header )
{
struct type * ptype;
struct attribute * attr;
ptype = ( struct type * ) malloc( sizeof( struct type ));
memset ( ptype, 0, sizeof ( struct type ));
ptype->pmain_type = ( struct main_type *)malloc( sizeof( struct main_type ));
memset ( ptype->pmain_type, 0, sizeof ( struct main_type ));
ptype->pmain_type->code = TYPE_CODE_UNDEF;
ptype->pmain_type->vptr_fieldno = - 1;
ptype->chain = ptype;
attr = dwarf_attr ( die, DW_AT_name );
if ( attr && DW_STRING ( attr ))
{
TYPE_TAG_NAME ( ptype ) = ( char *)malloc( strlen ( DW_STRING ( attr )) + 1 );
memset( TYPE_TAG_NAME ( ptype ), 0, strlen ( DW_STRING ( attr )) + 1 );
memcpy( TYPE_TAG_NAME ( ptype ), DW_STRING ( attr ), strlen ( DW_STRING ( attr )));
//ptype->pmain_type->tag_name =
}
if( die->tag == DW_TAG_structure_type )
{
ptype->pmain_type->code = TYPE_CODE_STRUCT; /* struct */
}
else if( die->tag == DW_TAG_union_type )
{
ptype->pmain_type->code = TYPE_CODE_UNION; /* union */
}
else
{
/* class not support */
ptype->pmain_type->code = TYPE_CODE_STRUCT; /* struct */
}
attr = dwarf_attr( die, DW_AT_byte_size ); /* 长度属性 */
if( attr )
{
/* 如果存在 */
TYPE_LENGTH( ptype ) = DW_UNSND( attr );
}
/* We need to add the type field to the die immediately so we don't
infinitely recurse when dealing with pointers to the structure
type within the structure itself. */
die->ptype = ptype;
if ( die->has_children && ! die_is_declaration ( die ))
{
struct field_info fi;
struct die_info * child_die;
memset (& fi, 0, sizeof ( struct field_info ));
child_die = die->next;
while ( child_die && child_die->tag )
{
if ( child_die->tag == DW_TAG_member )
{
dwarf2_add_field (& fi, child_die, cu_header );
}
else if ( child_die->tag == DW_TAG_variable )
{
/* C++ static member. */
dwarf2_add_field (& fi, child_die, cu_header );
}
else if ( child_die->tag == DW_TAG_subprogram )
{
/* C++ member function. */
/*
process_die (child_die, objfile, cu_header);
dwarf2_add_member_fn (&fi, child_die, type, cu_header);
*/
}
else if ( child_die->tag == DW_TAG_inheritance )
{
/* C++ base class field. */
/*
dwarf2_add_field (&fi, child_die,cu_header);
*/
}
else
{
process_die ( child_die, cu_header );
}
child_die = sibling_die ( child_die );
}
/* Attach fields and member functions to the type. */
if ( fi.nfields )
dwarf2_attach_fields_to_type (& fi, ptype );
if ( fi.nfnfields )
{
dwarf2_attach_fn_fields_to_type (& fi, ptype );
/* Get the type which refers to the base class (possibly this
class itself) which contains the vtable pointer for the current
class from the DW_AT_containing_type attribute. */
if ( dwarf_attr ( die, DW_AT_containing_type ) != NULL )
{
}
}
new_symbol ( die, ptype, cu_header );
}
else
{
/* No children, must be stub.
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;*/
}
}
static struct type * alloc_type_instance ( struct type * oldtype )
{
struct type * ptype;
/* Allocate the structure. */
{
ptype = ( struct type * )malloc( sizeof( struct type ));
memset ( ptype, 0, sizeof ( struct type ));
}
ptype->pmain_type = oldtype->pmain_type;
ptype->chain = ptype;
return ( ptype );
}
/* Create a new type with instance flags NEW_FLAGS, based on TYPE.
If STORAGE is non-NULL, create the new type instance there. */
struct type *
make_qualified_type ( struct type * type, int new_flags,
struct type * storage )
{
struct type * ntype;
ntype = type;
do {
if ( TYPE_INSTANCE_FLAGS ( ntype ) == new_flags )
return ntype;
ntype = ntype->chain;
} while ( ntype != type );
/* Create a new type instance. */
if ( storage == NULL )
{
ntype = alloc_type_instance ( type );
}
else
{
ntype = storage;
ntype->pmain_type = type->pmain_type;
ntype->chain = ntype;
}
/* Pointers or references to the original type are not relevant to
the new type. */
ntype->pointer_type = 0;
ntype->reference_type = 0;
ntype->chain = type->chain;
/* Chain the new qualified type to the old type. */
type->chain = ntype;
/* Now set the instance flags and return the new type. */
TYPE_INSTANCE_FLAGS ( ntype ) = new_flags;
return ntype;
}
struct type * make_cv_type ( int cnst, int voltl, struct type * type, struct type ** typeptr )
{
register struct type * ntype; /* New type */
int new_flags = ( TYPE_INSTANCE_FLAGS ( type )
& ~( TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE ));
if ( cnst )
new_flags |= TYPE_FLAG_CONST;
if ( voltl )
new_flags |= TYPE_FLAG_VOLATILE;
ntype = make_qualified_type ( type, new_flags, typeptr ? * typeptr : NULL );
if ( typeptr != NULL )
* typeptr = ntype;
return ntype;
}
static void read_tag_const_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
struct type * base_type;
if ( die->ptype )
{
return;
}
base_type = die_type ( die, cu_header );
die->ptype = make_cv_type ( 1, TYPE_VOLATILE ( base_type ), base_type, 0 );
}
struct type * create_range_type ( struct type * result_type, struct type * index_type,
int low_bound, int high_bound )
{
if ( result_type == NULL )
{
result_type = alloc_type ();
}
TYPE_CODE ( result_type ) = TYPE_CODE_RANGE;
TYPE_TARGET_TYPE ( result_type ) = index_type;
if ( TYPE_STUB ( index_type ))
TYPE_FLAGS ( result_type ) |= TYPE_FLAG_TARGET_STUB;
else
TYPE_LENGTH ( result_type ) = TYPE_LENGTH ( check_typedef ( index_type ));
TYPE_NFIELDS ( result_type ) = 2; /* 个数 */
TYPE_FIELDS ( result_type ) = ( struct field *)malloc( 2 * sizeof ( struct field )); /* 分配 */
memset ( TYPE_FIELDS ( result_type ), 0, 2 * sizeof ( struct field )); /* 清0 */
TYPE_FIELD_BITPOS ( result_type, 0 ) = low_bound;
TYPE_FIELD_BITPOS ( result_type, 1 ) = high_bound;
// TYPE_FIELD_TYPE (result_type, 0) = builtin_type_int; /* FIXME */
// TYPE_FIELD_TYPE (result_type, 1) = builtin_type_int; /* FIXME */
if ( low_bound >= 0 )
TYPE_FLAGS ( result_type ) |= TYPE_FLAG_UNSIGNED;
return ( result_type );
}
int get_discrete_bounds ( struct type * type, int * lowp, int * highp )
{
// CHECK_TYPEDEF (type);
switch ( TYPE_CODE ( type ))
{
case TYPE_CODE_RANGE:
* lowp = TYPE_LOW_BOUND ( type );
* highp = TYPE_HIGH_BOUND ( type );
return 1;
case TYPE_CODE_ENUM:
if ( TYPE_NFIELDS ( type ) > 0 )
{
/* The enums may not be sorted by value, so search all
entries */
int i;
* lowp = * highp = TYPE_FIELD_BITPOS ( type, 0 );
for ( i = 0; i < TYPE_NFIELDS ( type ); i ++)
{
if ( TYPE_FIELD_BITPOS ( type, i ) < * lowp )
* lowp = TYPE_FIELD_BITPOS ( type, i );
if ( TYPE_FIELD_BITPOS ( type, i ) > * highp )
* highp = TYPE_FIELD_BITPOS ( type, i );
}
/* Set unsigned indicator if warranted. */
if (* lowp >= 0 )
{
TYPE_FLAGS ( type ) |= TYPE_FLAG_UNSIGNED;
}
}
else
{
* lowp = 0;
* highp = - 1;
}
return 0;
case TYPE_CODE_BOOL:
* lowp = 0;
* highp = 1;
return 0;
case TYPE_CODE_INT:
if ( TYPE_LENGTH ( type ) > sizeof ( unsigned int )) /* Too big */
return - 1;
if (! TYPE_UNSIGNED ( type ))
{
* lowp = -( 1 << ( TYPE_LENGTH ( type ) * 8 - 1 )); /* int */
* highp = -* lowp - 1;
return 0;
}
/* ... fall through for unsigned ints ... */
case TYPE_CODE_CHAR:
* lowp = 0;
/* This round-about calculation is to avoid shifting by
TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work
if TYPE_LENGTH (type) == sizeof (LONGEST). */
* highp = 1 << ( TYPE_LENGTH ( type ) * 8 - 1 );
* highp = (* highp - 1 ) | * highp;
return 0;
default:
return - 1;
}
}
struct type * create_array_type ( struct type * result_type, struct type * element_type,
struct type * range_type )
{
unsigned int low_bound, high_bound;
if ( result_type == NULL )
{
result_type = alloc_type ();
}
TYPE_CODE ( result_type ) = TYPE_CODE_ARRAY;
TYPE_TARGET_TYPE ( result_type ) = element_type;
if ( get_discrete_bounds ( range_type, ( int *)& low_bound, ( int *)& high_bound ) < 0 )
low_bound = high_bound = 0;
element_type = check_typedef ( element_type );
TYPE_LENGTH ( result_type ) =
TYPE_LENGTH ( element_type ) * ( high_bound - low_bound + 1 );
TYPE_NFIELDS ( result_type ) = 1;
TYPE_FIELDS ( result_type ) =
( struct field *) malloc ( sizeof ( struct field ));
memset ( TYPE_FIELDS ( result_type ), 0, sizeof ( struct field ));
TYPE_FIELD_TYPE ( result_type, 0 ) = range_type;
TYPE_VPTR_FIELDNO ( result_type ) = - 1;
/* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */
if ( TYPE_LENGTH ( result_type ) == 0 )
TYPE_FLAGS ( result_type ) |= TYPE_FLAG_TARGET_STUB;
return ( result_type );
}
char * type_name_no_tag ( register const struct type * type )
{
if ( TYPE_TAG_NAME ( type ) != NULL )
return TYPE_TAG_NAME ( type );
/* Is there code which expects this to return the name if there is no
tag name? My guess is that this is mainly used for C++ in cases where
the two will always be the same. */
return TYPE_NAME ( type );
}
struct type * check_typedef ( struct type * type )
{
struct type * orig_type = type;
int is_const, is_volatile;
while ( TYPE_CODE ( type ) == TYPE_CODE_TYPEDEF )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -