gdb/
authorUlrich Weigand <uweigand@de.ibm.com>
Fri, 16 May 2008 12:58:49 +0000 (12:58 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Fri, 16 May 2008 12:58:49 +0000 (12:58 +0000)
2008-05-15  Pedro Alves  <pedro@codesourcery.com>
    Ulrich Weigand  <uweigand@de.ibm.com>

* minsyms.c (lookup_minimal_symbol_by_pc_name): New function.
* symtab.h (lookup_minimal_symbol_by_pc_name): Add prototype.

* symtab.c (fixup_section): Remove prototype.  Add ADDR parameter;
use it instead of ginfo->value.address.  Look up minimal symbol by
address and name.  Assume OBJFILE is non-NULL.
(fixup_symbol_section): Ensure we always have an objfile to look
into.  Extract and pass to fixup_section the symbol's address that
will match the minimal symbol's address.
(fixup_psymbol_section): Likewise.

(find_pc_sect_psymtab): Fall back to non-addrmap case when debugging
overlays and the addrmap returned the wrong section.

* dwarf2read.c (var_decode_location): Set SYMBOL_CLASS before
calling fixup_symbol_section.

gdb/testsuite/

2008-05-15  Pedro Alves  <pedro@codesourcery.com>

* gdb.base/fixsection.exp: New file.
* gdb.base/fixsection0.c: New file.
* gdb.base/fixsection1.c: New file.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/minsyms.c
gdb/symtab.c
gdb/symtab.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/fixsection.c [new file with mode: 0644]
gdb/testsuite/gdb.base/fixsection.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/fixsectshr.c [new file with mode: 0644]

index 8d3aea6..3168fc3 100644 (file)
@@ -1,3 +1,23 @@
+2008-05-16  Pedro Alves  <pedro@codesourcery.com>
+           Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * minsyms.c (lookup_minimal_symbol_by_pc_name): New function.
+       * symtab.h (lookup_minimal_symbol_by_pc_name): Add prototype.
+
+       * symtab.c (fixup_section): Remove prototype.  Add ADDR parameter;
+       use it instead of ginfo->value.address.  Look up minimal symbol by
+       address and name.  Assume OBJFILE is non-NULL.
+       (fixup_symbol_section): Ensure we always have an objfile to look
+       into.  Extract and pass to fixup_section the symbol's address that
+       will match the minimal symbol's address.
+       (fixup_psymbol_section): Likewise.
+
+       (find_pc_sect_psymtab): Fall back to non-addrmap case when debugging
+       overlays and the addrmap returned the wrong section.
+
+       * dwarf2read.c (var_decode_location): Set SYMBOL_CLASS before
+       calling fixup_symbol_section.
+
 2008-05-16  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * minsyms.c: Include "target.h".
index 4f1cb1e..67b734f 100644 (file)
@@ -7323,10 +7323,10 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
 
       SYMBOL_VALUE_ADDRESS (sym) =
        read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
+      SYMBOL_CLASS (sym) = LOC_STATIC;
       fixup_symbol_section (sym, objfile);
       SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
                                              SYMBOL_SECTION (sym));
-      SYMBOL_CLASS (sym) = LOC_STATIC;
       return;
     }
 
index ca9ba9a..59febf2 100644 (file)
@@ -332,6 +332,41 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
 }
 
 /* Look through all the current minimal symbol tables and find the
+   first minimal symbol that matches NAME and PC.  If OBJF is non-NULL,
+   limit the search to that objfile.  Returns a pointer to the minimal
+   symbol that matches, or NULL if no match is found.  */
+
+struct minimal_symbol *
+lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
+                                 struct objfile *objf)
+{
+  struct objfile *objfile;
+  struct minimal_symbol *msymbol;
+
+  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+
+  for (objfile = object_files;
+       objfile != NULL;
+       objfile = objfile->next)
+    {
+      if (objf == NULL || objf == objfile
+         || objf->separate_debug_objfile == objfile)
+       {
+         for (msymbol = objfile->msymbol_hash[hash];
+              msymbol != NULL;
+              msymbol = msymbol->hash_next)
+           {
+             if (SYMBOL_VALUE_ADDRESS (msymbol) == pc
+                 && strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0)
+               return msymbol;
+           }
+       }
+    }
+
+  return NULL;
+}
+
+/* Look through all the current minimal symbol tables and find the
    first minimal symbol that matches NAME and is a solib trampoline.
    If OBJF is non-NULL, limit the search to that objfile.  Returns a
    pointer to the minimal symbol that matches, or NULL if no match is
index 3d4389e..33efe12 100644 (file)
@@ -110,8 +110,6 @@ struct symbol *lookup_symbol_aux_psymtabs (int block_index,
                                           const domain_enum domain,
                                           struct symtab **symtab);
 
-static void fixup_section (struct general_symbol_info *, struct objfile *);
-
 static int file_matches (char *, char **, int);
 
 static void print_symbol_info (domain_enum,
@@ -878,6 +876,23 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
        pst = addrmap_find (objfile->psymtabs_addrmap, pc);
        if (pst != NULL)
          {
+           /* FIXME: addrmaps currently do not handle overlayed sections,
+              so fall back to the non-addrmap case if we're debugging 
+              overlays and the addrmap returned the wrong section.  */
+           if (overlay_debugging && msymbol && section)
+             {
+               struct partial_symbol *p;
+               /* NOTE: This assumes that every psymbol has a
+                  corresponding msymbol, which is not necessarily
+                  true; the debug info might be much richer than the
+                  object's symbol table.  */
+               p = find_pc_sect_psymbol (pst, pc, section);
+               if (!p
+                   || SYMBOL_VALUE_ADDRESS (p)
+                      != SYMBOL_VALUE_ADDRESS (msymbol))
+                 continue;
+             }
+
            /* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
               PSYMTABS_ADDRMAP we used has already the best 1-byte
               granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
@@ -1010,23 +1025,23 @@ find_pc_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc)
    out of the minimal symbols and stash that in the debug symbol.  */
 
 static void
-fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
+fixup_section (struct general_symbol_info *ginfo,
+              CORE_ADDR addr, struct objfile *objfile)
 {
   struct minimal_symbol *msym;
-  msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
 
   /* First, check whether a minimal symbol with the same name exists
      and points to the same address.  The address check is required
      e.g. on PowerPC64, where the minimal symbol for a function will
      point to the function descriptor, while the debug symbol will
      point to the actual function code.  */
-  if (msym
-      && SYMBOL_VALUE_ADDRESS (msym) == ginfo->value.address)
+  msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
+  if (msym)
     {
       ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
       ginfo->section = SYMBOL_SECTION (msym);
     }
-  else if (objfile)
+  else
     {
       /* Static, function-local variables do appear in the linker
         (minimal) symbols, but are frequently given names that won't
@@ -1064,11 +1079,7 @@ fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
         this reason, we still attempt a lookup by name prior to doing
         a search of the section table.  */
         
-      CORE_ADDR addr;
       struct obj_section *s;
-
-      addr = ginfo->value.address;
-
       ALL_OBJFILE_OSECTIONS (objfile, s)
        {
          int idx = s->the_bfd_section->index;
@@ -1087,13 +1098,42 @@ fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
 struct symbol *
 fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
 {
+  CORE_ADDR addr;
+
   if (!sym)
     return NULL;
 
   if (SYMBOL_BFD_SECTION (sym))
     return sym;
 
-  fixup_section (&sym->ginfo, objfile);
+  /* We either have an OBJFILE, or we can get at it from the sym's
+     symtab.  Anything else is a bug.  */
+  gdb_assert (objfile || SYMBOL_SYMTAB (sym));
+
+  if (objfile == NULL)
+    objfile = SYMBOL_SYMTAB (sym)->objfile;
+
+  /* We should have an objfile by now.  */
+  gdb_assert (objfile);
+
+  switch (SYMBOL_CLASS (sym))
+    {
+    case LOC_STATIC:
+    case LOC_LABEL:
+    case LOC_INDIRECT:
+      addr = SYMBOL_VALUE_ADDRESS (sym);
+      break;
+    case LOC_BLOCK:
+      addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+      break;
+
+    default:
+      /* Nothing else will be listed in the minsyms -- no use looking
+        it up.  */
+      return sym;
+    }
+
+  fixup_section (&sym->ginfo, addr, objfile);
 
   return sym;
 }
@@ -1101,13 +1141,31 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
 struct partial_symbol *
 fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
 {
+  CORE_ADDR addr;
+
   if (!psym)
     return NULL;
 
   if (SYMBOL_BFD_SECTION (psym))
     return psym;
 
-  fixup_section (&psym->ginfo, objfile);
+  gdb_assert (objfile);
+
+  switch (SYMBOL_CLASS (psym))
+    {
+    case LOC_STATIC:
+    case LOC_LABEL:
+    case LOC_INDIRECT:
+    case LOC_BLOCK:
+      addr = SYMBOL_VALUE_ADDRESS (psym);
+      break;
+    default:
+      /* Nothing else will be listed in the minsyms -- no use looking
+        it up.  */
+      return psym;
+    }
+
+  fixup_section (&psym->ginfo, addr, objfile);
 
   return psym;
 }
index ef8cade..37ce3f4 100644 (file)
@@ -1183,6 +1183,9 @@ struct minimal_symbol *lookup_minimal_symbol_solib_trampoline (const char *,
                                                               struct objfile
                                                               *);
 
+extern struct minimal_symbol *lookup_minimal_symbol_by_pc_name
+                               (CORE_ADDR, const char *, struct objfile *);
+
 extern struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR);
 
 extern struct minimal_symbol *lookup_minimal_symbol_by_pc_section (CORE_ADDR,
index 682cf00..0158acc 100644 (file)
@@ -1,3 +1,9 @@
+2008-05-16  Pedro Alves  <pedro@codesourcery.com>
+
+       * gdb.base/fixsection.exp: New file.
+       * gdb.base/fixsection0.c: New file.
+       * gdb.base/fixsection1.c: New file.
+
 2008-05-16  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 
        * gdb.base/annota1.exp: Accept printf@... in place of printf.
diff --git a/gdb/testsuite/gdb.base/fixsection.c b/gdb/testsuite/gdb.base/fixsection.c
new file mode 100644 (file)
index 0000000..ed0c77b
--- /dev/null
@@ -0,0 +1,35 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   This file was written by Pedro Alves (pedro@codesourcery.com).  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern FILE *force_static_fun (void);
+
+static void *
+static_fun (void *arg)
+{
+    return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+  static_fun (NULL);
+  force_static_fun ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/fixsection.exp b/gdb/testsuite/gdb.base/fixsection.exp
new file mode 100644 (file)
index 0000000..8954adc
--- /dev/null
@@ -0,0 +1,71 @@
+# Copyright (C) 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+set testfile "fixsection"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+set libfile "fixsectshr"
+set libsrc ${srcdir}/${subdir}/${libfile}.c
+set lib_sl ${objdir}/${subdir}/${libfile}.sl
+
+set lib_opts [list debug nowarnings]
+set exec_opts [list debug nowarnings shlib=$lib_sl]
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != ""
+     || [gdb_compile $srcfile $binfile executable $exec_opts] != ""} {
+    untested "Could not compile either $libsrc or $srcfile."
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_load_shlibs ${lib_sl}
+
+if ![runto_main] then {
+    fail "Can't run to main"
+    return 1;
+}
+
+#
+# set breakpoint at static function static_fun
+#
+gdb_test "break static_fun" \
+    "Breakpoint.*at.* file .*${srcfile}, line.*" \
+    "breakpoint at static_fun"
+
+#
+# exit gdb
+#
+gdb_exit
diff --git a/gdb/testsuite/gdb.base/fixsectshr.c b/gdb/testsuite/gdb.base/fixsectshr.c
new file mode 100644 (file)
index 0000000..8470826
--- /dev/null
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+static FILE *static_fun = NULL;
+
+FILE *
+force_static_fun (void)
+{
+  return static_fun;
+}