@ -315,13 +315,14 @@ struct attr_abbrev
struct die_info
{
enum dwarf_tag tag ; /* Tag indicating type of die */
unsigned short has_children ; /* Does the die have children */
unsigned int abbrev ; /* Abbrev number */
unsigned int offset ; /* Offset in .debug_info section */
unsigned int num_attrs ; /* Number of attributes */
struct attribute * attrs ; /* An array of attributes */
struct die_info * next_ref ; /* Next die in ref hash table */
struct die_info * next ; /* Next die in linked list */
struct die_info * child ; /* Its first child, if any. */
struct die_info * sibling ; /* Its next sibling, if any. */
struct die_info * parent ; /* Its parent, if any. */
struct type * type ; /* Cached type information */
} ;
@ -716,7 +717,7 @@ static char *read_partial_die (struct partial_die_info *,
const struct comp_unit_head * ) ;
static char * read_full_die ( struct die_info * * , bfd * , char * ,
const struct comp_unit_head * ) ;
const struct comp_unit_head * , int * ) ;
static char * read_attribute ( struct attribute * , struct attr_abbrev * ,
bfd * , char * , const struct comp_unit_head * ) ;
@ -873,6 +874,16 @@ static void read_subroutine_type (struct die_info *, struct objfile *,
static struct die_info * read_comp_unit ( char * , bfd * ,
const struct comp_unit_head * ) ;
static struct die_info * read_die_and_children ( char * info_ptr , bfd * abfd ,
const struct comp_unit_head * ,
char * * new_info_ptr ,
struct die_info * parent ) ;
static struct die_info * read_die_and_siblings ( char * info_ptr , bfd * abfd ,
const struct comp_unit_head * ,
char * * new_info_ptr ,
struct die_info * parent ) ;
static void free_die_list ( struct die_info * ) ;
static struct cleanup * make_cleanup_free_die_list ( struct die_info * ) ;
@ -1836,9 +1847,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
the compilation unit . If the DW_AT_high_pc is missing ,
synthesize it , by scanning the DIE ' s below the compilation unit . */
highpc = 0 ;
if ( dies - > has_children )
if ( dies - > child ! = NULL )
{
child_die = dies - > next ;
child_die = dies - > child ;
while ( child_die & & child_die - > tag )
{
if ( child_die - > tag = = DW_TAG_subprogram )
@ -1958,7 +1969,7 @@ process_die (struct die_info *die, struct objfile *objfile,
processing_has_namespace_info = 1 ;
processing_current_namespace = " " ;
}
gdb_assert ( ! die - > has_children ) ;
gdb_assert ( die - > child = = NULL ) ;
break ;
default :
new_symbol ( die , NULL , objfile , cu_header ) ;
@ -1988,9 +1999,9 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
if ( ! dwarf2_get_pc_bounds ( die , & lowpc , & highpc , objfile , cu_header ) )
{
if ( die - > has_children )
if ( die - > child ! = NULL )
{
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
if ( child_die - > tag = = DW_TAG_subprogram )
@ -2069,9 +2080,9 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
initialize_cu_func_list ( ) ;
/* Process all dies in compilation unit. */
if ( die - > has_children )
if ( die - > child ! = NULL )
{
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
process_die ( child_die , objfile , cu_header ) ;
@ -2209,9 +2220,9 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
list_in_scope = & local_symbols ;
if ( die - > has_children )
if ( die - > child ! = NULL )
{
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
process_die ( child_die , objfile , cu_header ) ;
@ -2259,9 +2270,9 @@ read_lexical_block_scope (struct die_info *die, struct objfile *objfile,
highpc + = baseaddr ;
push_context ( 0 , lowpc ) ;
if ( die - > has_children )
if ( die - > child ! = NULL )
{
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
process_die ( child_die , objfile , cu_header ) ;
@ -2936,7 +2947,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
type within the structure itself . */
die - > type = type ;
if ( die - > has_children & & ! die_is_declaration ( die ) )
if ( die - > child ! = NULL & & ! die_is_declaration ( die ) )
{
struct field_info fi ;
struct die_info * child_die ;
@ -2944,7 +2955,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
memset ( & fi , 0 , sizeof ( struct field_info ) ) ;
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
@ -3082,9 +3093,9 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
num_fields = 0 ;
fields = NULL ;
if ( die - > has_children )
if ( die - > child ! = NULL )
{
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
if ( child_die - > tag ! = DW_TAG_enumerator )
@ -3163,7 +3174,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
/* Irix 6.2 native cc creates array types without children for
arrays with unspecified length . */
if ( die - > has_ children = = 0 )
if ( die - > child = = NULL )
{
index_type = dwarf2_fundamental_type ( objfile , FT_INTEGER ) ;
range_type = create_range_type ( NULL , index_type , 0 , - 1 ) ;
@ -3172,7 +3183,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
}
back_to = make_cleanup ( null_cleanup , NULL ) ;
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
if ( child_die - > tag = = DW_TAG_subrange_type )
@ -3324,9 +3335,9 @@ read_common_block (struct die_info *die, struct objfile *objfile,
" common block member " ) ;
}
}
if ( die - > has_children )
if ( die - > child ! = NULL )
{
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
sym = new_symbol ( child_die , NULL , objfile , cu_header ) ;
@ -3412,9 +3423,9 @@ read_namespace (struct die_info *die, struct objfile *objfile,
strlen ( processing_current_namespace ) ) ;
}
if ( die - > has_children )
if ( die - > child ! = NULL )
{
struct die_info * child_die = die - > next ;
struct die_info * child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
@ -3649,7 +3660,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
| | cu_language = = language_cplus )
TYPE_FLAGS ( ftype ) | = TYPE_FLAG_PROTOTYPED ;
if ( die - > has_children )
if ( die - > child ! = NULL )
{
struct die_info * child_die ;
int nparams = 0 ;
@ -3658,7 +3669,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
/* Count the number of parameters.
FIXME : GDB currently ignores vararg functions , but knows about
vararg member functions . */
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
if ( child_die - > tag = = DW_TAG_formal_parameter )
@ -3673,7 +3684,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
TYPE_FIELDS ( ftype ) = ( struct field * )
TYPE_ALLOC ( ftype , nparams * sizeof ( struct field ) ) ;
child_die = die - > next ;
child_die = die - > child ;
while ( child_die & & child_die - > tag )
{
if ( child_die - > tag = = DW_TAG_formal_parameter )
@ -3808,46 +3819,89 @@ static struct die_info *
read_comp_unit ( char * info_ptr , bfd * abfd ,
const struct comp_unit_head * cu_header )
{
struct die_info * first_die , * last_die , * die ;
char * cur_ptr ;
int nesting_level ;
/* Reset die reference table; we are
building new ones now . */
dwarf2_empty_hash_tables ( ) ;
return read_die_and_children ( info_ptr , abfd , cu_header , & info_ptr , NULL ) ;
}
/* Read a single die and all its descendents. Set the die's sibling
field to NULL ; set other fields in the die correctly , and set all
of the descendents ' fields correctly . Set * NEW_INFO_PTR to the
location of the info_ptr after reading all of those dies . PARENT
is the parent of the die in question . */
static struct die_info *
read_die_and_children ( char * info_ptr , bfd * abfd ,
const struct comp_unit_head * cu_header ,
char * * new_info_ptr ,
struct die_info * parent )
{
struct die_info * die ;
char * cur_ptr ;
int has_children ;
cur_ptr = read_full_die ( & die , abfd , info_ptr , cu_header , & has_children ) ;
store_in_ref_table ( die - > offset , die ) ;
if ( has_children )
{
die - > child = read_die_and_siblings ( cur_ptr , abfd , cu_header ,
new_info_ptr , die ) ;
}
else
{
die - > child = NULL ;
* new_info_ptr = cur_ptr ;
}
die - > sibling = NULL ;
die - > parent = parent ;
return die ;
}
/* Read a die, all of its descendents, and all of its siblings; set
all of the fields of all of the dies correctly . Arguments are as
in read_die_and_children . */
static struct die_info *
read_die_and_siblings ( char * info_ptr , bfd * abfd ,
const struct comp_unit_head * cu_header ,
char * * new_info_ptr ,
struct die_info * parent )
{
struct die_info * first_die , * last_sibling ;
char * cur_ptr ;
cur_ptr = info_ptr ;
nesting_level = 0 ;
first_die = last_die = NULL ;
do
first_die = last_sibling = NULL ;
while ( 1 )
{
cur_ptr = read_full_die ( & die , abfd , cur_ptr , cu_header ) ;
if ( die - > has_children )
struct die_info * die
= read_die_and_children ( cur_ptr , abfd , cu_header ,
& cur_ptr , parent ) ;
if ( ! first_die )
{
nesting_level + + ;
first_die = die ;
}
if ( die - > tag = = 0 )
else
{
nesting_level - - ;
last_sibling - > sibling = die ;
}
die - > next = NULL ;
/* Enter die in reference hash table */
store_in_ref_table ( die - > offset , die ) ;
if ( ! first_die )
if ( die - > tag = = 0 )
{
first_die = last_die = die ;
* new_info_ptr = cur_ptr ;
return first_die ;
}
else
{
last_die - > next = die ;
last_die = die ;
last_sibling = die ;
}
}
while ( nesting_level > 0 ) ;
return first_die ;
}
/* Free a linked list of dies. */
@ -3860,7 +3914,9 @@ free_die_list (struct die_info *dies)
die = dies ;
while ( die )
{
next = die - > next ;
if ( die - > child ! = NULL )
free_die_list ( die - > child ) ;
next = die - > sibling ;
xfree ( die - > attrs ) ;
xfree ( die ) ;
die = next ;
@ -4173,12 +4229,14 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
return info_ptr ;
}
/* Read the die from the .debug_info section buffer. And set diep to
point to a newly allocated die with its information . */
/* Read the die from the .debug_info section buffer. Set DIEP to
point to a newly allocated die with its information , except for its
child , sibling , and parent fields . Set HAS_CHILDREN to tell
whether the die has children or not . */
static char *
read_full_die ( struct die_info * * diep , bfd * abfd , char * info_ptr ,
const struct comp_unit_head * cu_header )
const struct comp_unit_head * cu_header , int * has_children )
{
unsigned int abbrev_number , bytes_read , i , offset ;
struct abbrev_info * abbrev ;
@ -4194,19 +4252,20 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
die - > abbrev = abbrev_number ;
die - > type = NULL ;
* diep = die ;
* has_children = 0 ;
return info_ptr ;
}
abbrev = dwarf2_lookup_abbrev ( abbrev_number , cu_header ) ;
if ( ! abbrev )
{
error ( " Dwarf Error: could not find abbrev number %d [in module %s] " , abbrev_number ,
bfd_get_filename ( abfd ) ) ;
error ( " Dwarf Error: could not find abbrev number %d [in module %s] " ,
abbrev_number ,
bfd_get_filename ( abfd ) ) ;
}
die = dwarf_alloc_die ( ) ;
die - > offset = offset ;
die - > tag = abbrev - > tag ;
die - > has_children = abbrev - > has_children ;
die - > abbrev = abbrev_number ;
die - > type = NULL ;
@ -4221,6 +4280,7 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
}
* diep = die ;
* has_children = abbrev - > has_children ;
return info_ptr ;
}
@ -5822,43 +5882,7 @@ copy_die (struct die_info *old_die)
static struct die_info *
sibling_die ( struct die_info * die )
{
int nesting_level = 0 ;
if ( ! die - > has_children )
{
if ( die - > next & & ( die - > next - > tag = = 0 ) )
{
return NULL ;
}
else
{
return die - > next ;
}
}
else
{
do
{
if ( die - > has_children )
{
nesting_level + + ;
}
if ( die - > tag = = 0 )
{
nesting_level - - ;
}
die = die - > next ;
}
while ( nesting_level ) ;
if ( die & & ( die - > tag = = 0 ) )
{
return NULL ;
}
else
{
return die ;
}
}
return die - > sibling ;
}
/* Get linkage name of a die, return NULL if not found. */
@ -6727,7 +6751,7 @@ dump_die (struct die_info *die)
fprintf_unfiltered ( gdb_stderr , " Die: %s (abbrev = %d, offset = %d) \n " ,
dwarf_tag_name ( die - > tag ) , die - > abbrev , die - > offset ) ;
fprintf_unfiltered ( gdb_stderr , " \t has children: %s \n " ,
dwarf_bool_name ( die - > has_children ) ) ;
dwarf_bool_name ( die - > child ! = NULL ) ) ;
fprintf_unfiltered ( gdb_stderr , " \t attributes: \n " ) ;
for ( i = 0 ; i < die - > num_attrs ; + + i )
@ -6790,7 +6814,10 @@ dump_die_list (struct die_info *die)
while ( die )
{
dump_die ( die ) ;
die = die - > next ;
if ( die - > child ! = NULL )
dump_die_list ( die - > child ) ;
if ( die - > sibling ! = NULL )
dump_die_list ( die - > sibling ) ;
}
}