* psymtab.c (find_pc_sect_symtab_from_partial): Return the symtab
authorTom Tromey <tromey@redhat.com>
Fri, 18 May 2012 14:26:26 +0000 (14:26 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 18 May 2012 14:26:26 +0000 (14:26 +0000)
directly corresponding to the found psymtab.
* dwarf2read.c (recursively_find_pc_sect_symtab): New function.
(dw2_find_pc_sect_symtab): Use it.
* block.h (blockvector_contains_pc): Declare.
* block.c (find_block_in_blockvector): New function.
(blockvector_for_pc_sect): Use it.
(blockvector_contains_pc): New function.

gdb/ChangeLog
gdb/block.c
gdb/block.h
gdb/dwarf2read.c
gdb/psymtab.c

index 4ad8c9604b7e5409e3632348ad8d0639b5277e3c..9cab34ea646851c5c35e5b8da2d314a0ae73a969 100644 (file)
@@ -1,3 +1,14 @@
+2012-05-18  Tom Tromey  <tromey@redhat.com>
+
+       * psymtab.c (find_pc_sect_symtab_from_partial): Return the symtab
+       directly corresponding to the found psymtab.
+       * dwarf2read.c (recursively_find_pc_sect_symtab): New function.
+       (dw2_find_pc_sect_symtab): Use it.
+       * block.h (blockvector_contains_pc): Declare.
+       * block.c (find_block_in_blockvector): New function.
+       (blockvector_for_pc_sect): Use it.
+       (blockvector_contains_pc): New function.
+
 2012-05-18  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * mips-tdep.h (mips_write_pc): New prototype.
index 38b64b33aff462139806e31acaad33eb4093d293..150373005547057a63c761d182cadf0a87d7fa38 100644 (file)
@@ -103,46 +103,19 @@ block_inlined_p (const struct block *bl)
   return BLOCK_FUNCTION (bl) != NULL && SYMBOL_INLINED (BLOCK_FUNCTION (bl));
 }
 
-/* Return the blockvector immediately containing the innermost lexical
-   block containing the specified pc value and section, or 0 if there
-   is none.  PBLOCK is a pointer to the block.  If PBLOCK is NULL, we
-   don't pass this information back to the caller.  */
+/* A helper function that checks whether PC is in the blockvector BL.
+   It returns the containing block if there is one, or else NULL.  */
 
-struct blockvector *
-blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
-                        struct block **pblock, struct symtab *symtab)
+static struct block *
+find_block_in_blockvector (struct blockvector *bl, CORE_ADDR pc)
 {
   struct block *b;
   int bot, top, half;
-  struct blockvector *bl;
-
-  if (symtab == 0)             /* if no symtab specified by caller */
-    {
-      /* First search all symtabs for one whose file contains our pc */
-      symtab = find_pc_sect_symtab (pc, section);
-      if (symtab == 0)
-       return 0;
-    }
-
-  bl = BLOCKVECTOR (symtab);
-
-  /* Then search that symtab for the smallest block that wins.  */
 
   /* If we have an addrmap mapping code addresses to blocks, then use
      that.  */
   if (BLOCKVECTOR_MAP (bl))
-    {
-      b = addrmap_find (BLOCKVECTOR_MAP (bl), pc);
-      if (b)
-        {
-          if (pblock)
-            *pblock = b;
-          return bl;
-        }
-      else
-        return 0;
-    }
-
+    return addrmap_find (BLOCKVECTOR_MAP (bl), pc);
 
   /* Otherwise, use binary search to find the last block that starts
      before PC.  */
@@ -165,14 +138,51 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
     {
       b = BLOCKVECTOR_BLOCK (bl, bot);
       if (BLOCK_END (b) > pc)
-       {
-         if (pblock)
-           *pblock = b;
-         return bl;
-       }
+       return b;
       bot--;
     }
-  return 0;
+
+  return NULL;
+}
+
+/* Return the blockvector immediately containing the innermost lexical
+   block containing the specified pc value and section, or 0 if there
+   is none.  PBLOCK is a pointer to the block.  If PBLOCK is NULL, we
+   don't pass this information back to the caller.  */
+
+struct blockvector *
+blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
+                        struct block **pblock, struct symtab *symtab)
+{
+  struct blockvector *bl;
+  struct block *b;
+
+  if (symtab == 0)             /* if no symtab specified by caller */
+    {
+      /* First search all symtabs for one whose file contains our pc */
+      symtab = find_pc_sect_symtab (pc, section);
+      if (symtab == 0)
+       return 0;
+    }
+
+  bl = BLOCKVECTOR (symtab);
+
+  /* Then search that symtab for the smallest block that wins.  */
+  b = find_block_in_blockvector (bl, pc);
+  if (b == NULL)
+    return NULL;
+
+  if (pblock)
+    *pblock = b;
+  return bl;
+}
+
+/* Return true if the blockvector BV contains PC, false otherwise.  */
+
+int
+blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc)
+{
+  return find_block_in_blockvector (bv, pc) != NULL;
 }
 
 /* Return call_site for specified PC in GDBARCH.  PC must match exactly, it
index b4f92f3eb62338cc3912255335998e1d587125ac..99c478832e89d743afd002aac50a778f50d4561b 100644 (file)
@@ -152,6 +152,8 @@ extern struct blockvector *blockvector_for_pc_sect (CORE_ADDR,
                                                    struct block **,
                                                     struct symtab *);
 
+extern int blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc);
+
 extern struct call_site *call_site_for_pc (struct gdbarch *gdbarch,
                                           CORE_ADDR pc);
 
index fc1a864728d0f7558a60e77a4e08b714e505a51b..1514e1393c00f4c941a05c971ce54ddb1139e8a8 100644 (file)
@@ -2992,6 +2992,30 @@ dw2_expand_symtabs_matching
     }
 }
 
+/* A helper for dw2_find_pc_sect_symtab which finds the most specific
+   symtab.  */
+
+static struct symtab *
+recursively_find_pc_sect_symtab (struct symtab *symtab, CORE_ADDR pc)
+{
+  int i;
+
+  if (BLOCKVECTOR (symtab) != NULL
+      && blockvector_contains_pc (BLOCKVECTOR (symtab), pc))
+    return symtab;
+
+  for (i = 0; symtab->includes[i]; ++i)
+    {
+      struct symtab *s;
+
+      s = recursively_find_pc_sect_symtab (s, pc);
+      if (s != NULL)
+       return s;
+    }
+
+  return NULL;
+}
+
 static struct symtab *
 dw2_find_pc_sect_symtab (struct objfile *objfile,
                         struct minimal_symbol *msymbol,
@@ -3000,6 +3024,7 @@ dw2_find_pc_sect_symtab (struct objfile *objfile,
                         int warn_if_readin)
 {
   struct dwarf2_per_cu_data *data;
+  struct symtab *result;
 
   dw2_setup (objfile);
 
@@ -3014,7 +3039,9 @@ dw2_find_pc_sect_symtab (struct objfile *objfile,
     warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
             paddress (get_objfile_arch (objfile), pc));
 
-  return dw2_instantiate_symtab (data);
+  result = recursively_find_pc_sect_symtab (dw2_instantiate_symtab (data), pc);
+  gdb_assert (result != NULL);
+  return result;
 }
 
 static void
index 814023e894a8c7f602043c308d131a1639249490..e463fff0bc85727742f2bee55b51c41eee310f52 100644 (file)
@@ -397,7 +397,8 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile,
        warning (_("\
 (Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
                 paddress (get_objfile_arch (ps->objfile), pc));
-      return psymtab_to_symtab (ps);
+      psymtab_to_symtab (ps);
+      return ps->symtab;
     }
   return NULL;
 }