Fix PR gdb/20948: --write option to GDB causes segmentation fault
authorJozef Lawrynowicz <jozef.l@mittosystems.com>
Tue, 11 Sep 2018 21:56:36 +0000 (22:56 +0100)
committerTom Tromey <tom@tromey.com>
Mon, 24 Sep 2018 12:20:17 +0000 (06:20 -0600)
When opening a BFD for update, as gdb --write does, modifications to
anything but the contents of sections is restricted.

Do not try to write back any ELF headers in this case.

bfd/ChangeLog
2018-09-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

PR gdb/20948
* elf.c (_bfd_elf_write_object_contents): Return from function
early if abfd->direction == both_direction.

gdb/testsuite/ChangeLog
2018-09-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

PR gdb/20948
* gdb.base/write_mem.exp: New test.
* gdb.base/write_mem.c: Likewise.

bfd/ChangeLog
bfd/elf.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/write_mem.c [new file with mode: 0644]
gdb/testsuite/gdb.base/write_mem.exp [new file with mode: 0644]

index a5c857ad7185ae289629fd813948a33f1fef732d..382df33b36709e5c6044c3b0950f1680a138aecf 100644 (file)
@@ -1,3 +1,9 @@
+2018-09-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
+       PR gdb/20948
+       * elf.c (_bfd_elf_write_object_contents): Return from function
+       early if abfd->direction == both_direction.
+
 2018-09-21  Simon Marchi  <simon.marchi@ericsson.com>
 
        * configure.ac: Check for fls.
index 02d605c19c0443f69655e4cdafe4e716efda4e13..5320ae2237fcb67e39c7fd9f47a8ce81338d2aa1 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -6391,6 +6391,18 @@ _bfd_elf_write_object_contents (bfd *abfd)
   if (! abfd->output_has_begun
       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
     return FALSE;
+  /* Do not rewrite ELF data when the BFD has been opened for update.
+     abfd->output_has_begun was set to TRUE on opening, so creation of new
+     sections, and modification of existing section sizes was restricted.
+     This means the ELF header, program headers and section headers can't have
+     changed.
+     If the contents of any sections has been modified, then those changes have
+     already been written to the BFD.  */
+  else if (abfd->direction == both_direction)
+    {
+      BFD_ASSERT (abfd->output_has_begun);
+      return TRUE;
+    }
 
   i_shdrp = elf_elfsections (abfd);
 
index 877edc0cb5cd5ddd07014aed5a8268ea5bff005a..d15fcff17bd09ad4d2845bdd9d4328e4d64327a3 100644 (file)
@@ -1,3 +1,9 @@
+2018-09-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
+       PR gdb/20948
+       * gdb.base/write_mem.exp: New test.
+       * gdb.base/write_mem.c: Likewise.
+
 2018-09-23  Tom Tromey  <tom@tromey.com>
 
        PR python/18852:
diff --git a/gdb/testsuite/gdb.base/write_mem.c b/gdb/testsuite/gdb.base/write_mem.c
new file mode 100644 (file)
index 0000000..82d8c41
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright (C) 2018 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/>.  */
+
+int main (void)
+{
+  while (1);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/write_mem.exp b/gdb/testsuite/gdb.base/write_mem.exp
new file mode 100644 (file)
index 0000000..db476e7
--- /dev/null
@@ -0,0 +1,47 @@
+# Copyright (C) 2018 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/>.
+
+# Contributed by Jozef Lawrynowicz (jozef.l@mittosystems.com)
+
+# Test for PR gdb/20948
+# Verify that invoking gdb with the --write argument works as expected
+
+global GDBFLAGS
+standard_testfile
+
+if {[build_executable $testfile.exp $testfile \
+       $srcfile [list debug nowarnings] ] == -1} {
+    untested $testfile.exp
+    return -1
+}
+
+set old_gdbflags $GDBFLAGS
+
+# Expect a failure before --write has been added to the command line
+set GDBFLAGS "$old_gdbflags $binfile"
+clean_restart
+test_print_reject "set {int}main = 0x4242" "Cannot access memory at address"
+
+# Setting memory should now work correctly after adding --write
+set GDBFLAGS "$old_gdbflags --write $binfile"
+clean_restart
+gdb_test_no_output "set {int}main = 0x4242"
+
+# Check that memory write persists after quitting GDB
+gdb_exit
+gdb_start
+gdb_test "x /xh main" "<main>:.*4242"
+
+set GDBFLAGS $old_gdbflags