This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[dictionary] set bounds info correctly in symtabs
- From: David Carlton <carlton at kealia dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Mon, 15 Dec 2003 13:24:51 -0800
- Subject: [dictionary] set bounds info correctly in symtabs
For a while, local users have been complaining that GDB generates tons
of "pc in read in psymtab, but not in symtab" messages. Which is
annoying (and the gratuitous extra "in" doesn't help). :-) I finally
got around to tracking this down; it turns out that the psymtabs are
correct and the symtabs are wrong in this case. Specifically, in
dwarf2read.c, psymtab_to_symtab_1 and read_file_scope, when
determining the PC bounds of the file, assume that all functions are
children of the DW_TAG_compile_unit die, which isn't the case once
DW_TAG_namesepace appears. (Actually, it seems to me that
DW_TAG_class_type could already cause problems; it's just that GCC
doesn't generate debug info in a form that could trigger this issue.)
I've applied the attached patch to my branch. This problem is on
mainline, too, though (and has been there since 5.3, alas); I'll
submit a mainline patch in a bit. It shouldn't affect people using
any released version of GCC, since they don't use DW_TAG_namespace.
(Whoops, there's a typo in a comment. I'll fix that in a sec.)
David Carlton
carlton@kealia.com
2003-12-15 David Carlton <carlton@kealia.com>
* dwarf2read.c (get_scope_pc_bounds): New.
(psymtab_to_symtab_1): Use get_scope_pc_bounds.
(read_file_scope): Ditto.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.66.4.38
diff -u -p -r1.66.4.38 dwarf2read.c
--- dwarf2read.c 12 Nov 2003 00:20:58 -0000 1.66.4.38
+++ dwarf2read.c 15 Dec 2003 21:14:43 -0000
@@ -840,6 +840,10 @@ static int dwarf2_get_pc_bounds (struct
CORE_ADDR *, CORE_ADDR *, struct objfile *,
const struct comp_unit_head *);
+static void get_scope_pc_bounds (struct die_info *,
+ CORE_ADDR *, CORE_ADDR *, struct objfile *,
+ const struct comp_unit_head *);
+
static void dwarf2_add_field (struct field_info *, struct die_info *,
struct objfile *, const struct comp_unit_head *);
@@ -1977,31 +1981,7 @@ psymtab_to_symtab_1 (struct partial_symt
/* Do line number decoding in read_file_scope () */
process_die (dies, objfile, &cu_header);
- if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile, &cu_header))
- {
- /* Some compilers don't define a DW_AT_high_pc attribute for
- 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->child != NULL)
- {
- child_die = dies->child;
- while (child_die && child_die->tag)
- {
- if (child_die->tag == DW_TAG_subprogram)
- {
- CORE_ADDR low, high;
-
- if (dwarf2_get_pc_bounds (child_die, &low, &high,
- objfile, &cu_header))
- {
- highpc = max (highpc, high);
- }
- }
- child_die = sibling_die (child_die);
- }
- }
- }
+ get_scope_pc_bounds (dies, &lowpc, &highpc, objfile, &cu_header);
symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
/* Set symtab language to language from DW_AT_language.
@@ -2125,28 +2105,7 @@ read_file_scope (struct die_info *die, s
bfd *abfd = objfile->obfd;
struct line_header *line_header = 0;
- if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
- {
- if (die->child != NULL)
- {
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- if (child_die->tag == DW_TAG_subprogram)
- {
- CORE_ADDR low, high;
-
- if (dwarf2_get_pc_bounds (child_die, &low, &high,
- objfile, cu_header))
- {
- lowpc = min (lowpc, low);
- highpc = max (highpc, high);
- }
- }
- child_die = sibling_die (child_die);
- }
- }
- }
+ get_scope_pc_bounds (die, &lowpc, &highpc, objfile, cu_header);
/* If we didn't find a lowpc, set it to highpc to avoid complaints
from finish_block. */
@@ -2575,6 +2534,69 @@ dwarf2_get_pc_bounds (struct die_info *d
*lowpc = low;
*highpc = high;
return ret;
+}
+
+/* Get the low and high pc's represented by the scope DIE, and store
+ them in *LOWPC and *HIGHPC. If the correct values can't be
+ determined, set *LOWPC to -1 and *HIGHPC to 0. */
+static void
+get_scope_pc_bounds (struct die_info *die,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ CORE_ADDR best_low = (CORE_ADDR) -1;
+ CORE_ADDR best_high = (CORE_ADDR) 0;
+ CORE_ADDR current_low, current_high;
+
+ if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high,
+ objfile, cu_header))
+ {
+ best_low = current_low;
+ best_high = current_high;
+ }
+ else
+ {
+ struct die_info *child = die->child;
+
+ while (child && child->tag)
+ {
+ switch (child->tag) {
+ case DW_TAG_subprogram:
+ if (dwarf2_get_pc_bounds (child, ¤t_low, ¤t_high,
+ objfile, cu_header));
+ {
+ best_low = min (best_low, current_low);
+ best_high = max (best_high, current_high);
+ }
+ break;
+ case DW_TAG_namespace:
+ /* FIXME: carlton/2003-12-15: Should we do this for
+ DW_TAG_class_type/DW_TAG_structure_type, too? I think
+ that current GCC's always generate the DIEs
+ corresponding to definitions methods of classes at
+ namespace scope, but I don't see any reason why they
+ have to. */
+ get_scope_pc_bounds (child, ¤t_low, ¤t_high,
+ objfile, cu_header);
+
+ if (current_low != ((CORE_ADDR) -1))
+ {
+ best_low = min (best_low, current_low);
+ best_high = max (best_high, current_high);
+ }
+ break;
+ default:
+ /* Ignore. */
+ break;
+ }
+
+ child = sibling_die (child);
+ }
+ }
+
+ *lowpc = best_low;
+ *highpc = best_high;
}
/* Add an aggregate field to the field list. */