PR gdb/17968 - [ppc64] SEGV in ppc64_elf_get_synthetic_symtab reading a separate debug file

Message ID 54E3D152.6020804@redhat.com
State New, archived
Headers

Commit Message

Martin Sebor Feb. 17, 2015, 11:40 p.m. UTC
  The original patch was missing a linker script file added
as part of the test suite. Attached is an updated patch
with the script. Below are test results for ppc64le.

		=== gdb Summary ===

                               PATCHED   unpatched
# of expected passes		27832       27830
# of unexpected failures	87          87
# of unexpected successes	1           1
# of expected failures		57          57
# of known failures		54          54
# of unresolved testcases	1           1
# of untested testcases		35          35
# of unsupported tests		264         264

On 02/17/2015 01:06 PM, Martin Sebor wrote:
> The attached patch fixes the SEGV and lets GDB successfully
> load all kernel modules installed by default on RHEL 7. GDB
> still aborts when attempting to list functions in many of
> the modules but that's a separate problem (bug #17993).
>
> The patch has been tested on ppc64 with the results below.
>
>          === gdb Summary ===
>
>                                PATCHED   unpatched
> # of expected passes            29991       29989
> # of unexpected failures        103         103
> # of unexpected successes       1           1
> # of expected failures          67          67
> # of known failures             54          54
> # of untested testcases         32          32
> # of unsupported tests          190         190
>
> Martin
>
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0bd0792..288ec7d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@ 
+2015-02-16  Martin Sebor  <msebor@redhat.com>
+
+	PR gdb/17968
+	* elread.c (elf_symfile_read): Use synth_abfd only for shared and
+	executable objects (but not relocatable files).
+
 2015-02-13  Doug Evans  <dje@google.com>
 
 	* cp-namespace.c (cp_basic_lookup_symbol): Rename parameter
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 65c63f0..b1074e0 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1183,19 +1183,22 @@  elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags,
       elf_rel_plt_read (objfile, dyn_symbol_table);
     }
 
-  /* Contrary to binutils --strip-debug/--only-keep-debug the strip command from
-     elfutils (eu-strip) moves even the .symtab section into the .debug file.
+  /* Both the Binutils strip command and the Elfutils eu-strip command
+     remove the .symtab section from executables or dynamic object files
+     (but not from reloacatable object files like Linux kernel modules)
+     and move it into the .debug file.
 
      bfd_get_synthetic_symtab on ppc64 for each function descriptor ELF symbol
      'name' creates a new BSF_SYNTHETIC ELF symbol '.name' with its code
-     address.  But with eu-strip files bfd_get_synthetic_symtab would fail to
-     read the code address from .opd while it reads the .symtab section from
-     a separate debug info file as the .opd section is SHT_NOBITS there.
+     address.  But with stripped files without the .symtab section
+     bfd_get_synthetic_symtab would fail to read the code address from .opd
+     while it reads the .symtab section from a separate debug info file as
+     the .opd section is SHT_NOBITS there.
 
      With SYNTH_ABFD the .opd section will be read from the original
      backlinked binary where it is valid.  */
 
-  if (objfile->separate_debug_objfile_backlink)
+if (abfd->flags & (EXEC_P | DYNAMIC) && objfile->separate_debug_objfile_backlink)
     synth_abfd = objfile->separate_debug_objfile_backlink->obfd;
   else
     synth_abfd = abfd;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 4693abe..9042471 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@ 
+2015-02-16  Martin Sebor  <msebor@redhat.com>
+
+	PR gdb/17968
+	* gdb.base/strip-relocatable.c: New file.
+	* gdb.base/strip-relocatable.exp: New file.
+	* gdb.base/strip-relocatable.lds: New file.
+
 2015-02-11  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	* gdb.python/py-framefilter.exp (pagination quit - *): New tests.
diff --git a/gdb/testsuite/gdb.base/strip-relocatable.c b/gdb/testsuite/gdb.base/strip-relocatable.c
new file mode 100644
index 0000000..03a2a51
--- /dev/null
+++ b/gdb/testsuite/gdb.base/strip-relocatable.c
@@ -0,0 +1,3 @@ 
+void foo (void) __attribute__ ((section (".bar")));
+void foo (void) { }
+
diff --git a/gdb/testsuite/gdb.base/strip-relocatable.exp b/gdb/testsuite/gdb.base/strip-relocatable.exp
new file mode 100644
index 0000000..3a1aeee
--- /dev/null
+++ b/gdb/testsuite/gdb.base/strip-relocatable.exp
@@ -0,0 +1,87 @@ 
+# Copyright (C) 2015 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/>.
+
+standard_testfile
+
+# Full pathname of the test source file.
+set srcpath ${srcdir}/${subdir}/$srcfile
+
+# Full pathname of the linker script.
+set ldspath ${srcdir}/${subdir}/[file rootname $srcfile].lds
+
+# Compile only with debugging.
+if {[target_compile $srcpath $binfile.o object debug] != ""} then {
+    untested ${testfile}.exp
+    return -1
+}
+
+# Invoke the linker to create a relocatable file for Binutils testing.
+if {[target_link $binfile.o $binfile.bu "--build-id -r -T $ldspath"] != ""} then {
+    untested $testfile.exp
+    return -1
+}
+
+# Verify that a command succeeded.  Returns 1 on success, 0 on failure.
+proc verify { command } {
+    set status [catch {remote_exec build $command} -1]
+    if {[lindex $status 0] != 0} {
+	return 0
+    }
+    return 1
+}
+
+# Create a copy of the relocatable file for Elfutils testing.
+verify "cp $binfile.bu $binfile.eu"
+
+# Verify that GDB can read symbols from a relocatable file stripped
+# using Binutils strip and objcopy commands.
+set test "relocatable file stripped using Binutils"
+
+if {   [# Copy debug info from the relocatable file into a separate .dbg file.
+	verify "objcopy --only-keep-debug $binfile.bu $binfile.bu.dbg"] &&
+       [# Strip debug (and other unneeded) sections from the relocatable
+	# file.
+	verify "strip --strip-debug --strip-unneeded $binfile.bu"] &&
+       [# Insert the .gnu_debuglink section into the relocatable file
+	# pointing at the separate .dbg file.
+	verify "objcopy --add-gnu-debuglink $binfile.bu.dbg $binfile.bu"]} {
+
+    # Restart the debugger with the relocatable file as an operand.
+    clean_restart $binfile.bu
+
+    # Print the type of the function foo defined in the test file
+    # and verify that it has the expected type.
+    gdb_test "ptype foo" "type = void \\(void\\)" \
+	"symbols in a Binutils-stripped file"
+}
+
+
+# Repeat the same test as above but with Elfutils.  I.e., verify
+# that GDB can read symbols from a relocatable file stripped using
+# the Eflutils eu-strip command.
+set test "relocatable file stripped using Elfutils"
+
+# Use eu-strip to strip debug info from the relocatable file
+# and move it into a separate .dbg file in one step.
+if {[verify "eu-strip -f $binfile.eu.dbg $binfile.eu" ]} {
+
+    # Restart the debugger with the relocatable file as an operand.
+    clean_restart $testfile.eu
+
+    # Print the type of the function foo defined in the test file
+    # and verify that it has the expected type.
+    gdb_test "ptype foo" "type = void \\(void\\)" \
+	"symbols in an Elfutils-stripped file"
+}
diff --git a/gdb/testsuite/gdb.base/strip-relocatable.lds b/gdb/testsuite/gdb.base/strip-relocatable.lds
new file mode 100644
index 0000000..24259c2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/strip-relocatable.lds
@@ -0,0 +1,3 @@ 
+SECTIONS {
+  .foobar : { *(.bar) }
+}