mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-29 21:13:52 +08:00
2003-09-30 David Carlton <carlton@kealia.com>
* dwarf2read.c (struct die_info): Add 'parent' field; replace 'has_children' and 'next' by 'child' and 'sibling'. (read_comp_unit): Rework algorithm, breaking body into read_die_and_children and read_die_and_siblings. (read_die_and_children, read_die_and_siblings): New. (read_full_die): Add 'has_children' argument; set it instead of the die's 'has_children' field. Minor formatting cleanup. (free_die_list): Use die->child and die->sibling instead of die->next. (dump_die_list): Ditto. (sibling_die): Use die->sibling. (psymtab_to_symtab_1): Use die's 'child' field in place of its 'has_children' and 'next' fields. (process_die, read_file_scope, read_func_scope) (read_lexical_block_scope, read_structure_scope) (read_enumeration, read_array_type, read_common_block) (read_namespace, read_subroutine_type, dump_die): Ditto.
This commit is contained in:
parent
1fc0d17365
commit
639d11d308
@ -1,3 +1,23 @@
|
||||
2003-09-30 David Carlton <carlton@kealia.com>
|
||||
|
||||
* dwarf2read.c (struct die_info): Add 'parent' field; replace
|
||||
'has_children' and 'next' by 'child' and 'sibling'.
|
||||
(read_comp_unit): Rework algorithm, breaking body into
|
||||
read_die_and_children and read_die_and_siblings.
|
||||
(read_die_and_children, read_die_and_siblings): New.
|
||||
(read_full_die): Add 'has_children' argument; set it instead of
|
||||
the die's 'has_children' field. Minor formatting cleanup.
|
||||
(free_die_list): Use die->child and die->sibling instead of
|
||||
die->next.
|
||||
(dump_die_list): Ditto.
|
||||
(sibling_die): Use die->sibling.
|
||||
(psymtab_to_symtab_1): Use die's 'child' field in place of its
|
||||
'has_children' and 'next' fields.
|
||||
(process_die, read_file_scope, read_func_scope)
|
||||
(read_lexical_block_scope, read_structure_scope)
|
||||
(read_enumeration, read_array_type, read_common_block)
|
||||
(read_namespace, read_subroutine_type, dump_die): Ditto.
|
||||
|
||||
2003-09-30 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* rs6000-tdep.c (rs6000_gdbarch_init): Set the PowerOpen red zone
|
||||
|
223
gdb/dwarf2read.c
223
gdb/dwarf2read.c
@ -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 ();
|
||||
|
||||
cur_ptr = info_ptr;
|
||||
nesting_level = 0;
|
||||
first_die = last_die = NULL;
|
||||
do
|
||||
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)
|
||||
{
|
||||
cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header);
|
||||
if (die->has_children)
|
||||
{
|
||||
nesting_level++;
|
||||
}
|
||||
if (die->tag == 0)
|
||||
{
|
||||
nesting_level--;
|
||||
}
|
||||
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->next = NULL;
|
||||
die->sibling = NULL;
|
||||
die->parent = parent;
|
||||
return die;
|
||||
}
|
||||
|
||||
/* Enter die in reference hash table */
|
||||
store_in_ref_table (die->offset, 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;
|
||||
first_die = last_sibling = NULL;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct die_info *die
|
||||
= read_die_and_children (cur_ptr, abfd, cu_header,
|
||||
&cur_ptr, parent);
|
||||
|
||||
if (!first_die)
|
||||
{
|
||||
first_die = last_die = die;
|
||||
first_die = die;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_die->next = die;
|
||||
last_die = die;
|
||||
last_sibling->sibling = die;
|
||||
}
|
||||
|
||||
if (die->tag == 0)
|
||||
{
|
||||
*new_info_ptr = cur_ptr;
|
||||
return first_die;
|
||||
}
|
||||
else
|
||||
{
|
||||
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, "\thas children: %s\n",
|
||||
dwarf_bool_name (die->has_children));
|
||||
dwarf_bool_name (die->child != NULL));
|
||||
|
||||
fprintf_unfiltered (gdb_stderr, "\tattributes:\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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user