2008-01-23 Pedro Alves Match symbol/msymbol/bfd_section by address. gdb/ * symtab.c (fixup_section): Add addr parameter. If possible, lookup the minimal symbol by address. If that fails, fallback to the old by-name method. (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. * dwarf2read.c (var_decode_location): Set SYMBOL_CLASS before calling fixup_symbol_section. gdb/testsuite/ * gdb.base/fixsection.exp: New file. * gdb.base/fixsection0.c: New file. * gdb.base/fixsection1.c: New file. --- gdb/dwarf2read.c | 2 gdb/symtab.c | 70 ++++++++++++++++++++++++++++++--- gdb/testsuite/gdb.base/fixsection.c | 35 ++++++++++++++++ gdb/testsuite/gdb.base/fixsection.exp | 71 ++++++++++++++++++++++++++++++++++ gdb/testsuite/gdb.base/fixsectshr.c | 10 ++++ 5 files changed, 180 insertions(+), 8 deletions(-) Index: src/gdb/symtab.c =================================================================== --- src.orig/gdb/symtab.c 2008-05-13 19:04:29.000000000 +0100 +++ src/gdb/symtab.c 2008-05-13 19:14:31.000000000 +0100 @@ -110,8 +110,6 @@ struct symbol *lookup_symbol_aux_psymtab 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, @@ -1010,10 +1008,20 @@ find_pc_psymbol (struct partial_symtab * 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); + struct minimal_symbol *msym = NULL; + if (addr != ~(CORE_ADDR) 0) + /* If we have an address to lookup, use it. */ + msym = lookup_minimal_symbol_by_pc (addr); + + if (!msym + || addr != SYMBOL_VALUE_ADDRESS (msym) + || strcmp (DEPRECATED_SYMBOL_NAME (msym), ginfo->name) != 0) + /* Try by looking up by name. Not perfect, since it can match the + wrong symbol. */ + 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 @@ -1087,13 +1095,45 @@ fixup_section (struct general_symbol_inf 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 || (sym->symtab && sym->symtab->objfile)); + + if (objfile == NULL) + objfile = sym->symtab->objfile; + + /* We should have an objfile by now. */ + gdb_assert (objfile); + + switch (SYMBOL_CLASS (sym)) + { + case LOC_UNRESOLVED: + addr = ~(CORE_ADDR) 0; + break; + 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,29 @@ fixup_symbol_section (struct symbol *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_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: src/gdb/dwarf2read.c =================================================================== --- src.orig/gdb/dwarf2read.c 2008-05-13 19:04:29.000000000 +0100 +++ src/gdb/dwarf2read.c 2008-05-13 19:14:31.000000000 +0100 @@ -7323,10 +7323,10 @@ var_decode_location (struct attribute *a 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: src/gdb/testsuite/gdb.base/fixsectshr.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.base/fixsectshr.c 2008-05-13 19:14:31.000000000 +0100 @@ -0,0 +1,10 @@ +#include +#include + +static FILE *static_fun = NULL; + +FILE * +force_static_fun (void) +{ + return static_fun; +} Index: src/gdb/testsuite/gdb.base/fixsection.exp =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.base/fixsection.exp 2008-05-13 19:14:31.000000000 +0100 @@ -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 . + +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 Index: src/gdb/testsuite/gdb.base/fixsection.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.base/fixsection.c 2008-05-13 19:14:31.000000000 +0100 @@ -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 . + + This file was written by Pedro Alves (pedro@codesourcery.com). */ + +#include +#include + +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; +}