This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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, &current_low, &current_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, &current_low, &current_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, &current_low, &current_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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]