📄 dwarf2.c
字号:
if (! TYPE_TARGET_TYPE ( type ))
{
TYPE_TARGET_TYPE ( type ) = alloc_type (); /* TYPE_CODE_UNDEF */
}
type = TYPE_TARGET_TYPE ( type );
}
is_const = TYPE_CONST ( type );
is_volatile = TYPE_VOLATILE ( type );
/* If this is a struct/class/union with no fields, then check whether a
full definition exists somewhere else. This is for systems where a
type definition with no fields is issued for such types, instead of
identifying them as stub types in the first place */
if ( TYPE_IS_OPAQUE ( type ) )
{
char * name = type_name_no_tag ( type );
struct type * newtype = NULL;
if ( name == NULL )
{
//complain (&stub_noname_complaint);
return type;
}
//newtype = lookup_transparent_type (name);
if ( newtype )
make_cv_type ( is_const, is_volatile, newtype, & type );
}
/* Otherwise, rely on the stub flag being set for opaque/stubbed types */
else if ( TYPE_STUB ( type ) )
{
}
if ( TYPE_TARGET_STUB ( type ))
{
struct type * range_type;
struct type * target_type = check_typedef ( TYPE_TARGET_TYPE ( type ));
if ( TYPE_STUB ( target_type ) || TYPE_TARGET_STUB ( target_type ))
{
}
else if ( TYPE_CODE ( type ) == TYPE_CODE_ARRAY
&& TYPE_NFIELDS ( type ) == 1
&& ( TYPE_CODE ( range_type = TYPE_FIELD_TYPE ( type, 0 ))
== TYPE_CODE_RANGE ))
{
/* Now recompute the length of the array type, based on its
number of elements and the target type's length. */
TYPE_LENGTH ( type ) = (( TYPE_FIELD_BITPOS ( range_type, 1 )
- TYPE_FIELD_BITPOS ( range_type, 0 ) + 1 )
* TYPE_LENGTH ( target_type ));
TYPE_FLAGS ( type ) &= ~ TYPE_FLAG_TARGET_STUB;
}
else if ( TYPE_CODE ( type ) == TYPE_CODE_RANGE )
{
TYPE_LENGTH ( type ) = TYPE_LENGTH ( target_type );
TYPE_FLAGS ( type ) &= ~ TYPE_FLAG_TARGET_STUB;
}
}
/* Cache TYPE_LENGTH for future use. */
TYPE_LENGTH ( orig_type ) = TYPE_LENGTH ( type );
return type;
}
static void read_array_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
struct die_info * child_die;
struct type * type = NULL;
struct type * element_type, * range_type, * index_type;
struct type ** range_types = NULL;
struct attribute * attr;
int ndim = 0;
/* Return if we've already decoded this type. */
if ( die->ptype )
{
return;
}
element_type = die_type ( die, cu_header );
if( ! element_type )
{
printf( "find no element type\r\n" );
return;
}
/* Irix 6.2 native cc creates array types without children for
arrays with unspecified length. */
if ( die->has_children == 0 )
{
index_type = dwarf2_fundamental_type ( FT_INTEGER );
range_type = create_range_type ( NULL, index_type, 0, - 1 );
die->ptype = create_array_type ( NULL, element_type, range_type );
return;
}
child_die = die->next;
while ( child_die && child_die->tag )
{
if ( child_die->tag == DW_TAG_subrange_type )
{
int low, high;
/* Default bounds to an array with unspecified length. */
low = 0;
high = - 1;
index_type = die_type ( child_die, cu_header );
attr = dwarf_attr ( child_die, DW_AT_lower_bound );
if ( attr )
{
if ( attr->form == DW_FORM_sdata )
{
low = DW_SND ( attr );
}
else if ( attr->form == DW_FORM_udata
|| attr->form == DW_FORM_data1
|| attr->form == DW_FORM_data2
|| attr->form == DW_FORM_data4
|| attr->form == DW_FORM_data8 )
{
low = DW_UNSND ( attr );
}
else
{
low = 0;
}
}
attr = dwarf_attr ( child_die, DW_AT_upper_bound );
if ( attr )
{
if ( attr->form == DW_FORM_sdata )
{
high = DW_SND ( attr );
}
else if ( attr->form == DW_FORM_udata
|| attr->form == DW_FORM_data1
|| attr->form == DW_FORM_data2
|| attr->form == DW_FORM_data4
|| attr->form == DW_FORM_data8 )
{
high = DW_UNSND ( attr );
}
else if ( attr->form == DW_FORM_block1 )
{
/* GCC encodes arrays with unspecified or dynamic length
with a DW_FORM_block1 attribute.
FIXME: GDB does not yet know how to handle dynamic
arrays properly, treat them as arrays with unspecified
length for now. */
high = - 1;
}
else
{
high = 1;
}
}
/* Create a range type and save it for array type creation. */
if (( ndim % DW_FIELD_ALLOC_CHUNK ) == 0 )
{
range_types = ( struct type **)
realloc ( range_types, ( ndim + DW_FIELD_ALLOC_CHUNK )
* sizeof ( struct type *));
if ( ndim == 0 )
{
}
}
range_types[ndim ++ ] = create_range_type ( NULL, index_type, low, high );
}
child_die = sibling_die ( child_die );
}
/* Dwarf2 dimensions are output from left to right, create the
necessary array types in backwards order. */
type = element_type;
while ( ndim -- > 0 )
type = create_array_type ( NULL, type, range_types[ndim] );
/* Understand Dwarf2 support for vector types (like they occur on
the PowerPC w/ AltiVec). Gcc just adds another attribute to the
array type. This is not part of the Dwarf2/3 standard yet, but a
custom vendor extension. The main difference between a regular
array and the vector variant is that vectors are passed by value
to functions. */
attr = dwarf_attr ( die, DW_AT_GNU_vector );
if ( attr )
TYPE_FLAGS ( type ) |= TYPE_FLAG_VECTOR;
/* Install the type in the die. */
die->ptype = type;
}
static void read_typedef ( struct die_info * die, const struct comp_unit_head * cu_header )
{
struct attribute * attr;
char * name = NULL;
if (! die->ptype )
{
attr = dwarf_attr ( die, DW_AT_name );
if ( attr && DW_STRING ( attr ))
{
name = DW_STRING ( attr );
}
die->ptype = init_type ( TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name );
TYPE_TARGET_TYPE ( die->ptype ) = die_type ( die, cu_header );
}
}
void smash_to_member_type ( struct type * type, struct type * domain, struct type * to_type )
{
smash_type ( type );
TYPE_TARGET_TYPE ( type ) = to_type;
TYPE_DOMAIN_TYPE ( type ) = domain;
TYPE_LENGTH ( type ) = 1; /* In practice, this is never needed. */
TYPE_CODE ( type ) = TYPE_CODE_MEMBER;
}
static void read_tag_ptr_to_member_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
struct type * type;
struct type * to_type;
struct type * domain;
if ( die->ptype )
{
return;
}
type = alloc_type ();
to_type = die_type ( die, cu_header );
domain = die_containing_type ( die, cu_header );
smash_to_member_type ( type, domain, to_type );
die->ptype = type;
}
static void read_tag_volatile_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 ( TYPE_CONST ( base_type ), 1, base_type, 0 );
}
static void read_type_die ( struct die_info * die, const struct comp_unit_head * cu_header )
{
switch ( die->tag )
{
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
read_structure_scope ( die, cu_header );
break;
case DW_TAG_enumeration_type:
read_enumeration ( die, cu_header );
break;
case DW_TAG_subprogram:
case DW_TAG_subroutine_type:
read_subroutine_type ( die, cu_header );
break;
case DW_TAG_array_type:
read_array_type ( die, cu_header );
break;
case DW_TAG_pointer_type:
read_tag_pointer_type ( die, cu_header );
break;
case DW_TAG_ptr_to_member_type:
read_tag_ptr_to_member_type ( die, cu_header );
break;
case DW_TAG_reference_type:
/*
read_tag_reference_type (die, objfile, cu_header);
*/
break;
case DW_TAG_const_type:
read_tag_const_type ( die, cu_header );
break;
case DW_TAG_volatile_type:
read_tag_volatile_type ( die, cu_header );
break;
case DW_TAG_string_type:
/*
read_tag_string_type (die, objfile);
*/
break;
case DW_TAG_typedef:
read_typedef ( die, cu_header );
break;
case DW_TAG_base_type:
read_base_type ( die );
break;
default:
/*
complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
*/
break;
}
}
static struct type * tag_type_to_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
if ( die->ptype )
{
return die->ptype;
}
else
{
read_type_die ( die, cu_header );
if (! die->ptype )
{
printf ( "Dwarf Error: Cannot find type of die." );
}
return die->ptype;
}
}
/* Return the type of the die in question using its DW_AT_type attribute. */
static struct type * die_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
struct type * type;
struct attribute * type_attr;
struct die_info * type_die;
unsigned int ref;
type_attr = dwarf_attr ( die, DW_AT_type );
if (! type_attr )
{
/* A missing DW_AT_type represents a void type. */
return dwarf2_fundamental_type ( FT_VOID );
}
else
{
ref = dwarf2_get_ref_die_offset ( type_attr );
type_die = follow_die_ref ( ref );
if (! type_die )
{
printf ( "Dwarf Error: Cannot find referent at offset %d.", ref );
return NULL;
}
}
type = tag_type_to_type ( type_die, cu_header );
if (! type )
{
printf ( "Dwarf Error: Problem turning type die at offset into gdb type." );
}
return type;
}
static int frame_base_reg;
static CORE_ADDR frame_base_offset;
static CORE_ADDR decode_locdesc ( struct dwarf_block * blk, const struct comp_unit_head * cu_header )
{
int i;
int size = blk->size;
char * data = blk->data;
CORE_ADDR stack[64]; /* stack */
int stacki;
unsigned int bytes_read, unsnd;
unsigned char op;
i = 0;
stacki = 0;
stack[stacki] = 0;
while ( i < size )
{
op = data[i ++ ];
switch ( op )
{
case DW_OP_lit0:
case DW_OP_lit1:
case DW_OP_lit2:
case DW_OP_lit3:
case DW_OP_lit4:
case DW_OP_lit5:
case DW_OP_lit6:
case DW_OP_lit7:
case DW_OP_lit8:
case DW_OP_lit9:
case DW_OP_lit10:
case DW_OP_lit11:
case DW_OP_lit12:
case DW_OP_lit13:
case DW_OP_lit14:
case DW_OP_lit15:
case DW_OP_lit16:
case DW_OP_lit17:
case DW_OP_lit18:
case DW_OP_lit19:
case DW_OP_lit20:
case DW_OP_lit21:
case DW_OP_lit22:
case DW_OP_lit23:
case DW_OP_lit24:
case DW_OP_lit25:
case DW_OP_lit26:
case DW_OP_lit27:
case DW_OP_lit28:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -