+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".
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;
}
}
/* 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
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,
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
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
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;
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;
}
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;
}
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,
+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.
--- /dev/null
+/* 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;
+}
--- /dev/null
+# 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
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+static FILE *static_fun = NULL;
+
+FILE *
+force_static_fun (void)
+{
+ return static_fun;
+}