aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2006-02-09 18:18:41 +0000
committerDaniel Jacobowitz <drow@false.org>2006-02-09 18:18:41 +0000
commit5afb4e9982174f0cfb0c05ff8408ec7c893955f8 (patch)
tree3e666ca002893c6f89b4e5ec28f1a41c1db7dd05
parent6d74f28b36e29b8708881b60e2e6505047813b0b (diff)
downloadfsf-binutils-gdb-5afb4e9982174f0cfb0c05ff8408ec7c893955f8.zip
fsf-binutils-gdb-5afb4e9982174f0cfb0c05ff8408ec7c893955f8.tar.gz
fsf-binutils-gdb-5afb4e9982174f0cfb0c05ff8408ec7c893955f8.tar.bz2
* dwarf2read.c (struct dwarf2_per_cu_data): Reduce length to
30 bits. Add load_all_dies flag. (load_partial_dies): Load all DIEs if per_cu->load_all_dies is set. Load DW_TAG_member by default. Remove internal_error call. (find_partial_die): Reload the compilation unit if we can not find a DIE in the cache. Call internal_error here if we still can not find the DIE.
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/dwarf2read.c84
2 files changed, 79 insertions, 15 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9ce015c..ea1463e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2006-02-09 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * dwarf2read.c (struct dwarf2_per_cu_data): Reduce length to
+ 30 bits. Add load_all_dies flag.
+ (load_partial_dies): Load all DIEs if per_cu->load_all_dies is set.
+ Load DW_TAG_member by default. Remove internal_error call.
+ (find_partial_die): Reload the compilation unit if we can not find
+ a DIE in the cache. Call internal_error here if we still can not
+ find the DIE.
+
2006-02-10 Nick Roberts <nickrob@snap.net.nz>
* breakpoint.c (print_one_breakpoint): Add break to case
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 85152a3..6fe9245 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -360,16 +360,22 @@ struct dwarf2_cu
struct dwarf2_per_cu_data
{
- /* The start offset and length of this compilation unit. 2**31-1
+ /* The start offset and length of this compilation unit. 2**30-1
bytes should suffice to store the length of any compilation unit
- if it doesn't, GDB will fall over anyway. */
unsigned long offset;
- unsigned long length : 31;
+ unsigned long length : 30;
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
unsigned long queued : 1;
+ /* This flag will be set if we need to load absolutely all DIEs
+ for this compilation unit, instead of just the ones we think
+ are interesting. It gets set if we look for a DIE in the
+ hash table and don't find it. */
+ unsigned int load_all_dies : 1;
+
/* Set iff currently read in. */
struct dwarf2_cu *cu;
@@ -5144,12 +5150,16 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
struct partial_die_info *parent_die, *last_die, *first_die = NULL;
struct abbrev_info *abbrev;
unsigned int bytes_read;
+ unsigned int load_all = 0;
int nesting_level = 1;
parent_die = NULL;
last_die = NULL;
+ if (cu->per_cu && cu->per_cu->load_all_dies)
+ load_all = 1;
+
cu->partial_dies
= htab_create_alloc_ex (cu->header.length / 12,
partial_die_hash,
@@ -5185,12 +5195,17 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
continue;
}
- /* Check whether this DIE is interesting enough to save. */
- if (!is_type_tag_for_partial (abbrev->tag)
+ /* Check whether this DIE is interesting enough to save. Normally
+ we would not be interested in members here, but there may be
+ later variables referencing them via DW_AT_specification (for
+ static members). */
+ if (!load_all
+ && !is_type_tag_for_partial (abbrev->tag)
&& abbrev->tag != DW_TAG_enumerator
&& abbrev->tag != DW_TAG_subprogram
&& abbrev->tag != DW_TAG_variable
- && abbrev->tag != DW_TAG_namespace)
+ && abbrev->tag != DW_TAG_namespace
+ && abbrev->tag != DW_TAG_member)
{
/* Otherwise we skip to the next sibling, if any. */
info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu);
@@ -5290,9 +5305,11 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
Adding more things than necessary to the hash table is harmless
except for the performance cost. Adding too few will result in
- internal errors in find_partial_die. */
+ wasted time in find_partial_die, when we reread the compilation
+ unit with load_all_dies set. */
- if (abbrev->tag == DW_TAG_subprogram
+ if (load_all
+ || abbrev->tag == DW_TAG_subprogram
|| abbrev->tag == DW_TAG_variable
|| abbrev->tag == DW_TAG_namespace
|| part_die->is_declaration)
@@ -5312,7 +5329,8 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
languages we have to, both so that we can get at method physnames
to infer fully qualified class names, and for DW_AT_specification. */
if (last_die->has_children
- && (last_die->tag == DW_TAG_namespace
+ && (load_all
+ || last_die->tag == DW_TAG_namespace
|| last_die->tag == DW_TAG_enumeration_type
|| (cu->language != language_c
&& (last_die->tag == DW_TAG_class_type
@@ -5464,10 +5482,6 @@ find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu)
part_die.offset = offset;
lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset);
- if (lookup_die == NULL)
- internal_error (__FILE__, __LINE__,
- _("could not find partial DIE in cache\n"));
-
return lookup_die;
}
@@ -5476,11 +5490,16 @@ find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu)
static struct partial_die_info *
find_partial_die (unsigned long offset, struct dwarf2_cu *cu)
{
- struct dwarf2_per_cu_data *per_cu;
+ struct dwarf2_per_cu_data *per_cu = NULL;
+ struct partial_die_info *pd = NULL;
if (offset >= cu->header.offset
&& offset < cu->header.offset + cu->header.length)
- return find_partial_die_in_comp_unit (offset, cu);
+ {
+ pd = find_partial_die_in_comp_unit (offset, cu);
+ if (pd != NULL)
+ return pd;
+ }
per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
@@ -5492,7 +5511,42 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu)
}
per_cu->cu->last_used = 0;
- return find_partial_die_in_comp_unit (offset, per_cu->cu);
+ pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+
+ if (pd == NULL && per_cu->load_all_dies == 0)
+ {
+ struct cleanup *back_to;
+ struct partial_die_info comp_unit_die;
+ struct abbrev_info *abbrev;
+ unsigned int bytes_read;
+ char *info_ptr;
+
+ per_cu->load_all_dies = 1;
+
+ /* Re-read the DIEs. */
+ back_to = make_cleanup (null_cleanup, 0);
+ if (per_cu->cu->dwarf2_abbrevs == NULL)
+ {
+ dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu);
+ back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
+ }
+ info_ptr = per_cu->cu->header.first_die_ptr;
+ abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
+ info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
+ per_cu->cu->objfile->obfd, info_ptr,
+ per_cu->cu);
+ if (comp_unit_die.has_children)
+ load_partial_dies (per_cu->cu->objfile->obfd, info_ptr, 0, per_cu->cu);
+ do_cleanups (back_to);
+
+ pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ }
+
+ if (pd == NULL)
+ internal_error (__FILE__, __LINE__,
+ _("could not find partial DIE 0x%lx in cache [from module %s]\n"),
+ offset, bfd_get_filename (cu->objfile->obfd));
+ return pd;
}
/* Adjust PART_DIE before generating a symbol for it. This function