From 94277a38987e6809e7a80208ebb1f77cc2c17d46 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Tue, 17 Oct 2006 20:17:45 +0000 Subject: [PATCH] gdb/ * Makefile.in (symtab.o): Update. * symtab.h (matching_bfd_section): New prototype. * symtab.c (matching_bfd_section): New. (find_pc_sect_psymbol, find_pc_sect_symtab): Use it. * minsyms.c (lookup_minimal_symbol_by_pc_section): Likewise. * printcmd.c (sym_info): Ignore separate debug objfiles. gdb/testsuite/ * gdb.base/sepdebug.exp: Remove debug format test. * lib/gdb.exp (gdb_gnu_strip_debug): Perform debug format test. Handle no-symtab. * gdb.base/sepsymtab.c, gdb.base/sepsymtab.exp: New. --- gdb/ChangeLog | 9 +++++ gdb/Makefile.in | 2 +- gdb/minsyms.c | 4 +-- gdb/printcmd.c | 5 +++ gdb/symtab.c | 65 ++++++++++++++++++++++++++++++++++-- gdb/symtab.h | 2 ++ gdb/testsuite/ChangeLog | 7 ++++ gdb/testsuite/gdb.base/sepdebug.exp | 33 ------------------ gdb/testsuite/gdb.base/sepsymtab.c | 23 +++++++++++++ gdb/testsuite/gdb.base/sepsymtab.exp | 53 +++++++++++++++++++++++++++++ gdb/testsuite/lib/gdb.exp | 57 +++++++++++++++++++++++++++++-- 11 files changed, 219 insertions(+), 41 deletions(-) create mode 100644 gdb/testsuite/gdb.base/sepsymtab.c create mode 100644 gdb/testsuite/gdb.base/sepsymtab.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0972ca6..aac9f67 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2006-10-17 Daniel Jacobowitz + * Makefile.in (symtab.o): Update. + * symtab.h (matching_bfd_section): New prototype. + * symtab.c (matching_bfd_section): New. + (find_pc_sect_psymbol, find_pc_sect_symtab): Use it. + * minsyms.c (lookup_minimal_symbol_by_pc_section): Likewise. + * printcmd.c (sym_info): Ignore separate debug objfiles. + +2006-10-17 Daniel Jacobowitz + * remote.c (remote_pid_to_str): Capitalize "Thread". 2006-10-15 Daniel Jacobowitz diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 07892b8..0479802 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2754,7 +2754,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \ $(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \ $(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \ $(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \ - $(gdb_stat_h) $(cp_abi_h) $(observer_h) + $(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \ $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \ $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \ diff --git a/gdb/minsyms.c b/gdb/minsyms.c index ae4c23a..b257c85 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -360,7 +360,6 @@ lookup_minimal_symbol_solib_trampoline (const char *name, return NULL; } - /* Search through the minimal symbol table for each objfile and find the symbol whose address is the largest address that is still less than or equal to PC, and matches SECTION (if non-NULL). Returns a @@ -491,7 +490,8 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) don't fill the bfd_section member, so don't throw away symbols on those platforms. */ && SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL - && SYMBOL_BFD_SECTION (&msymbol[hi]) != section) + && (!matching_bfd_sections + (SYMBOL_BFD_SECTION (&msymbol[hi]), section))) { hi--; continue; diff --git a/gdb/printcmd.c b/gdb/printcmd.c index ade7802..210a1c0 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -983,6 +983,11 @@ sym_info (char *arg, int from_tty) addr = parse_and_eval_address (arg); ALL_OBJSECTIONS (objfile, osect) { + /* Only process each object file once, even if there's a separate + debug file. */ + if (objfile->separate_debug_objfile_backlink) + continue; + sect = osect->the_bfd_section; sect_addr = overlay_mapped_address (addr, sect); diff --git a/gdb/symtab.c b/gdb/symtab.c index 2832dd1..10c723a 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -56,6 +56,7 @@ #include #include "cp-abi.h" #include "observer.h" +#include "gdb_assert.h" /* Prototypes for local functions */ @@ -706,6 +707,64 @@ init_sal (struct symtab_and_line *sal) } +/* Return 1 if the two sections are the same, or if they could + plausibly be copies of each other, one in an original object + file and another in a separated debug file. */ + +int +matching_bfd_sections (asection *first, asection *second) +{ + struct objfile *obj; + + /* If they're the same section, then they match. */ + if (first == second) + return 1; + + /* If either is NULL, give up. */ + if (first == NULL || second == NULL) + return 0; + + /* This doesn't apply to absolute symbols. */ + if (first->owner == NULL || second->owner == NULL) + return 0; + + /* If they're in the same object file, they must be different sections. */ + if (first->owner == second->owner) + return 0; + + /* Check whether the two sections are potentially corresponding. They must + have the same size, address, and name. We can't compare section indexes, + which would be more reliable, because some sections may have been + stripped. */ + if (bfd_get_section_size (first) != bfd_get_section_size (second)) + return 0; + + if (bfd_get_section_vma (first->owner, first) + != bfd_get_section_vma (second->owner, second)) + return 0; + + if (bfd_get_section_name (first->owner, first) == NULL + || bfd_get_section_name (second->owner, second) == NULL + || strcmp (bfd_get_section_name (first->owner, first), + bfd_get_section_name (second->owner, second)) != 0) + return 0; + + /* Otherwise check that they are in corresponding objfiles. */ + + ALL_OBJFILES (obj) + if (obj->obfd == first->owner) + break; + gdb_assert (obj != NULL); + + if (obj->separate_debug_objfile != NULL + && obj->separate_debug_objfile->obfd == second->owner) + return 1; + if (obj->separate_debug_objfile_backlink != NULL + && obj->separate_debug_objfile_backlink->obfd == second->owner) + return 1; + + return 0; +} /* Find which partial symtab contains PC and SECTION. Return 0 if none. We return the psymtab that contains a symbol whose address @@ -845,7 +904,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, if (section) /* match on a specific section */ { fixup_psymbol_section (p, psymtab->objfile); - if (SYMBOL_BFD_SECTION (p) != section) + if (!matching_bfd_sections (SYMBOL_BFD_SECTION (p), section)) continue; } best_pc = SYMBOL_VALUE_ADDRESS (p); @@ -869,7 +928,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, if (section) /* match on a specific section */ { fixup_psymbol_section (p, psymtab->objfile); - if (SYMBOL_BFD_SECTION (p) != section) + if (!matching_bfd_sections (SYMBOL_BFD_SECTION (p), section)) continue; } best_pc = SYMBOL_VALUE_ADDRESS (p); @@ -1902,7 +1961,7 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section) ALL_BLOCK_SYMBOLS (b, iter, sym) { fixup_symbol_section (sym, objfile); - if (section == SYMBOL_BFD_SECTION (sym)) + if (matching_bfd_sections (SYMBOL_BFD_SECTION (sym), section)) break; } if (sym == NULL) diff --git a/gdb/symtab.h b/gdb/symtab.h index bef9aaa..4a980c1 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1316,6 +1316,8 @@ extern char **make_source_files_completion_list (char *, char *); /* symtab.c */ +int matching_bfd_sections (asection *, asection *); + extern struct partial_symtab *find_main_psymtab (void); extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 440fde9..7396d50 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2006-10-17 Daniel Jacobowitz + * gdb.base/sepdebug.exp: Remove debug format test. + * lib/gdb.exp (gdb_gnu_strip_debug): Perform debug format test. + Handle no-symtab. + * gdb.base/sepsymtab.c, gdb.base/sepsymtab.exp: New. + +2006-10-17 Daniel Jacobowitz + * gdb.threads/manythreads.c (thread_function, main): Don't cast int to pointer or pointer to int. * gdb.threads/manythreads.exp: Don't expect the string "LWP". diff --git a/gdb/testsuite/gdb.base/sepdebug.exp b/gdb/testsuite/gdb.base/sepdebug.exp index 5bc00c5..4593549 100644 --- a/gdb/testsuite/gdb.base/sepdebug.exp +++ b/gdb/testsuite/gdb.base/sepdebug.exp @@ -47,39 +47,6 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -# FIXME: this is nasty. We need to check for the stabs debug format. -# To do this we must run gdb on the unstripped executable, list 'main' -# (as to have a default source file), use get_debug_format (which does -# 'info source') and then see if the debug info is stabs. If so, we -# bail out. We cannot do this any other way because get_debug_format -# finds out the debug format using gdb itself, and in case of stabs we -# get an error loading the program if it is already stripped. An -# alternative would be to find out the debug info from the flags -# passed to dejagnu when the test is run. - -gdb_exit -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_load ${binfile} -gdb_test "list main" "" "" -get_debug_format -if { [test_debug_format "stabs"] } then { - # the separate debug info feature doesn't work well in binutils with stabs. - # It produces a corrupted debug info only file, and gdb chokes on it. - # It is almost impossible to capture the failing message out of gdb, - # because it happens inside gdb_load. At that point any error message - # is intercepted by dejagnu itself, and, because of the error threshold, - # any faulty test result is changed into an UNRESOLVED. - # (see dejagnu/lib/framework.exp) - unsupported "no separate debug info handling with stabs" - return -1 -} elseif { [test_debug_format "unknown"] } then { - # gdb doesn't know what the debug format is. We are out of luck here. - unsupported "unknown debugging format" - return -1 -} -gdb_exit - # Note: the procedure gdb_gnu_strip_debug will produce an executable called # ${binfile}, which is just like the executable ($binfile) but without # the debuginfo. Instead $binfile has a .gnudebuglink section which contains diff --git a/gdb/testsuite/gdb.base/sepsymtab.c b/gdb/testsuite/gdb.base/sepsymtab.c new file mode 100644 index 0000000..1c53958 --- /dev/null +++ b/gdb/testsuite/gdb.base/sepsymtab.c @@ -0,0 +1,23 @@ +/* Copyright 2006 + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +int +main (int argc, char **argv, char **envp) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/sepsymtab.exp b/gdb/testsuite/gdb.base/sepsymtab.exp new file mode 100644 index 0000000..b386f3c --- /dev/null +++ b/gdb/testsuite/gdb.base/sepsymtab.exp @@ -0,0 +1,53 @@ +# Copyright 2006 +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if $tracelevel then { + strace $tracelevel +} + +# +# test running programs +# + +set testfile "sepsymtab" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ + executable {debug}] != "" } { + untested sepsymtab.exp + return -1 +} + +if [gdb_gnu_strip_debug $binfile no-main] { + # check that you have a recent version of strip and objcopy installed + unsupported "cannot produce separate debug info files" + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set command "info sym main" +set command_regex [string_to_regexp $command] +gdb_test_multiple "$command" "$command" { + -re "^${command_regex}\[\r\n\]+main in section \[^\r\n\]+\[\r\n\]+$gdb_prompt \$" { + pass "$command" + } +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 0d8a430..86c7e1d 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -2276,7 +2276,7 @@ proc gdb_skip_bogus_test { msg } { # Note: the procedure gdb_gnu_strip_debug will produce an executable called # ${binfile}.dbglnk, which is just like the executable ($binfile) but without # the debuginfo. Instead $binfile has a .gnu_debuglink section which contains -# the name of a idebuginfo only file. This file will be stored in the +# the name of a debuginfo only file. This file will be stored in the # gdb.base/.debug subdirectory. # Functions for separate debug info testing @@ -2307,8 +2307,45 @@ proc separate_debug_filename { exec } { return $debug_file } +# Create stripped files for DEST, replacing it. If ARGS is passed, it is a +# list of optional flags. The only currently supported flag is no-main, +# which removes the symbol entry for main from the separate debug file. -proc gdb_gnu_strip_debug { dest } { +proc gdb_gnu_strip_debug { dest args } { + + # First, make sure that we can do this. This is nasty. We need to + # check for the stabs debug format. To do this we must run gdb on + # the unstripped executable, list 'main' (as to have a default + # source file), use get_debug_format (which does 'info source') + # and then see if the debug info is stabs. If so, we bail out. We + # cannot do this any other way because get_debug_format finds out + # the debug format using gdb itself, and in case of stabs we get + # an error loading the program if it is already stripped. An + # alternative would be to find out the debug info from the flags + # passed to dejagnu when the test is run. + + gdb_exit + gdb_start + gdb_load ${dest} + gdb_test "list main" "" "" + get_debug_format + if { [test_debug_format "stabs"] } then { + # The separate debug info feature doesn't work well in + # binutils with stabs. It produces a corrupted debug info + # only file, and gdb chokes on it. It is almost impossible to + # capture the failing message out of gdb, because it happens + # inside gdb_load. At that point any error message is + # intercepted by dejagnu itself, and, because of the error + # threshold, any faulty test result is changed into an + # UNRESOLVED. (see dejagnu/lib/framework.exp) + unsupported "no separate debug info handling with stabs" + return -1 + } elseif { [test_debug_format "unknown"] } then { + # gdb doesn't know what the debug format is. We are out of luck here. + unsupported "unknown debugging format" + return -1 + } + gdb_exit set debug_file [separate_debug_filename $dest] set strip_to_file_program strip @@ -2342,6 +2379,22 @@ proc gdb_gnu_strip_debug { dest } { return 1 } + # If no-main is passed, strip the symbol for main from the separate + # file. This is to simulate the behavior of elfutils's eu-strip, which + # leaves the symtab in the original file only. There's no way to get + # objcopy or strip to remove the symbol table without also removing the + # debugging sections, so this is as close as we can get. + if { [llength $args] == 1 && [lindex $args 0] == "no-main" } { + set result [catch "exec $objcopy_program -N main ${debug_file} ${debug_file}-tmp" output] + verbose "result is $result" + verbose "output is $output" + if {$result == 1} { + return 1 + } + file delete "${debug_file}" + file rename "${debug_file}-tmp" "${debug_file}" + } + # Link the two previous output files together, adding the .gnu_debuglink # section to the stripped_file, containing a pointer to the debug_file, # save the new file in dest. -- 2.7.4