From 779bd270818aeb064c2d218ad8f80a3b608f95c9 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Mon, 26 Aug 2013 18:43:40 +0000 Subject: [PATCH] PR symtab/15885 * dwarf2read.c (dw2_dump): Print some minimal information indicating .gdb_index is in use. * symfile.c (reread_symbols): Reset objfile->sf. testsuite/ * gdb.dwarf2/Makefile.in (EXECUTABLES): Add gdb-index. (clean): rm -f *.gdb-index *.with-index. * gdb.dwarf2/gdb-index.exp: New testcase. --- gdb/ChangeLog | 5 ++ gdb/dwarf2read.c | 17 ++++- gdb/symfile.c | 6 ++ gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.dwarf2/Makefile.in | 3 +- gdb/testsuite/gdb.dwarf2/gdb-index.exp | 101 +++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 gdb/testsuite/gdb.dwarf2/gdb-index.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c0ff6ea8e3..108bcca15f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,10 @@ 2013-08-26 Doug Evans + PR symtab/15885 + * dwarf2read.c (dw2_dump): Print some minimal information indicating + .gdb_index is in use. + * symfile.c (reread_symbols): Reset objfile->sf. + * NEWS: Document "mt print objfiles" now takes optional regexp. * symmisc.c (maintenance_print_objfiles): Argument is now an optional regexp of objfiles to print. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index d1ce9460ba..6027f78115 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -3357,10 +3357,25 @@ dw2_print_stats (struct objfile *objfile) printf_filtered (_(" Number of unread CUs: %d\n"), count); } +/* This dumps minimal information about the index. + It is called via "mt print objfiles". + One use is to verify .gdb_index has been loaded by the + gdb.dwarf2/gdb-index.exp testcase. */ + static void dw2_dump (struct objfile *objfile) { - /* Nothing worth printing. */ + dw2_setup (objfile); + gdb_assert (dwarf2_per_objfile->using_index); + printf_filtered (".gdb_index:"); + if (dwarf2_per_objfile->index_table != NULL) + { + printf_filtered (" version %d\n", + dwarf2_per_objfile->index_table->version); + } + else + printf_filtered (" faked for \"readnow\"\n"); + printf_filtered ("\n"); } static void diff --git a/gdb/symfile.c b/gdb/symfile.c index d1e024f1e7..b95721eae4 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -2504,6 +2504,12 @@ reread_symbols (void) empty. We could use obstack_specify_allocation but gdb_obstack.h specifies the alloc/dealloc functions. */ obstack_init (&objfile->objfile_obstack); + + /* Reset the sym_fns pointer. The ELF reader can change it + based on whether .gdb_index is present, and we need it to + start over. PR symtab/15885 */ + objfile->sf = find_sym_fns (objfile->obfd); + build_objfile_section_table (objfile); terminate_minimal_symbol_table (objfile); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 8d8f075189..570c2bc527 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2013-08-26 Doug Evans + PR symtab/15885 + * gdb.dwarf2/Makefile.in (EXECUTABLES): Add gdb-index. + (clean): rm -f *.gdb-index *.with-index. + * gdb.dwarf2/gdb-index.exp: New testcase. + * lib/gdb.exp (run_on_host): Moved here from gnu-debugdata.exp. * gdb.base/gnu-debugdata.exp (run): Moved to gdb.exp and renamed to run_on_host. All callers updated. diff --git a/gdb/testsuite/gdb.dwarf2/Makefile.in b/gdb/testsuite/gdb.dwarf2/Makefile.in index d29901ae84..e77204e3de 100644 --- a/gdb/testsuite/gdb.dwarf2/Makefile.in +++ b/gdb/testsuite/gdb.dwarf2/Makefile.in @@ -21,7 +21,7 @@ VPATH = @srcdir@ srcdir = @srcdir@ EXECUTABLES = *.x pr10770 dw2-cp-infcall-ref-static dw2-inline-param \ - dw2-noloc dw2-ranges dw2-ref-missing-frame dw2-unresolved + dw2-noloc dw2-ranges dw2-ref-missing-frame dw2-unresolved gdb-index all info install-info dvi install uninstall installcheck check: @echo "Nothing to be done for $@..." @@ -31,6 +31,7 @@ clean mostlyclean: -rm -f core core.coremaker coremaker.core corefile -rm -f *.dwo *.dwp -rm -f $(EXECUTABLES) + -rm -f *.gdb-index *.with-index distclean maintainer-clean realclean: clean -rm -f *~ core diff --git a/gdb/testsuite/gdb.dwarf2/gdb-index.exp b/gdb/testsuite/gdb.dwarf2/gdb-index.exp new file mode 100644 index 0000000000..bc976cfc1e --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/gdb-index.exp @@ -0,0 +1,101 @@ +# Copyright 2013 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 . + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile main.c + +if { [prepare_for_testing "${testfile}.exp" "${testfile}" \ + [list ${srcfile}]] } { + return -1 +} + +# Add a .gdb_index section to PROGRAM. +# PROGRAM is assumed to be the output of standard_output_file. +# Returns the path of the program or "" if there is a failure. +# If there is a failure it will have already been logged. + +proc add_gdb_index { program } { + set index_file ${program}.gdb-index + verbose -log "index_file: ${index_file}" + remote_file host delete ${index_file} + gdb_test_no_output "save gdb-index [file dirname ${index_file}]" + + # No point in continuing if generating the index failed. + # N.B.: There are times when gdb won't create an index, and it's not a + # failure. However, in our case we need an index. So if you find one + # not being generated, you'll either have to tweak the .c file or maybe + # add a flag to force an index to be generated. + if { [remote_file host exists ${index_file}] } { + pass "gdb-index file created" + } else { + fail "gdb-index file created" + return "" + } + + set program_with_index ${program}.with-index + if {[run_on_host "objcopy" [transform objcopy] "--remove-section .gdb_index --add-section .gdb_index=$index_file --set-section-flags .gdb_index=readonly ${program} ${program_with_index}"]} { + return "" + } + return ${program_with_index} +} + +# Build a copy of the program with .gdb_index. +# But only if the toolchain didn't already create one: gdb doesn't support +# building an index from a program already using one. + +set test "check if index present" +gdb_test_multiple "mt print objfiles ${testfile}" $test { + -re "gdb_index.*${gdb_prompt} $" { + set binfile_with_index $binfile + } + -re "Psymtabs.*${gdb_prompt} $" { + set binfile_with_index [add_gdb_index $binfile] + if { ${binfile_with_index} == "" } { + return -1 + } + } +} + +# Ok, we have a copy of $binfile with .gdb_index. +# Restart gdb and verify the index was used. + +clean_restart ${binfile_with_index} +gdb_test "mt print objfiles ${testfile}" \ + "gdb_index.*" \ + ".gdb_index used" + +# Make gdb re-read symbols and see if .gdb_index still gets used. +# symtab/15885 + +# There is gdb_touch_execfile, but it doesn't handle remote hosts. +# Is touch portable enough? +# First make sure enough time has passed, file mtime resolution is seconds. +gdb_test_no_output "shell sleep 1" +if {[run_on_host "touch binary" touch ${binfile_with_index}]} { + return -1 +} + +if ![runto_main] { + return -1 +} +gdb_test "mt print objfiles ${testfile}" \ + "gdb_index.*" \ + ".gdb_index used after symbol reloading"