This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Fix PR gdb/20948: --write option to GDB causes segmentation fault
- From: Jozef Lawrynowicz <jozef dot l at mittosystems dot com>
- To: binutils at sourceware dot org
- Date: Thu, 13 Sep 2018 11:55:16 +0100
- Subject: [PATCH] Fix PR gdb/20948: --write option to GDB causes segmentation fault
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.
Successfully tested with no regressions on x86_64-pc-linux-gnu with
the binutils, gas, ld and gdb testsuites.
The PR is assigned to GDB, but the fix is to BFD, hence the
submission to binutils mailing list instead of GDB.
>From b61a0bf98f7effdbee30f0a2b9dfe488b69edf54 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Tue, 11 Sep 2018 22:56:36 +0100
Subject: [PATCH] Fix PR gdb/20948: --write option to GDB causes segmentation
fault
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.
PR gdb/20948
* bfd/elf.c (_bfd_elf_write_object_contents): Return from function
early if abfd->direction == both_direction.
* gdb/testsuite/gdb.base/write_mem.exp: New test.
* gdb/testsuite/gdb.base/write_mem.c: Likewise.
---
bfd/elf.c | 12 ++++++++++++
gdb/testsuite/gdb.base/write_mem.c | 7 +++++++
gdb/testsuite/gdb.base/write_mem.exp | 30 ++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+)
create mode 100644 gdb/testsuite/gdb.base/write_mem.c
create mode 100644 gdb/testsuite/gdb.base/write_mem.exp
diff --git a/bfd/elf.c b/bfd/elf.c
index 02d605c..5320ae2 100644
--- 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);
diff --git a/gdb/testsuite/gdb.base/write_mem.c b/gdb/testsuite/gdb.base/write_mem.c
new file mode 100644
index 0000000..941f172
--- /dev/null
+++ b/gdb/testsuite/gdb.base/write_mem.c
@@ -0,0 +1,7 @@
+/* Test for PR gdb/20948. */
+
+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
index 0000000..e1f393a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/write_mem.exp
@@ -0,0 +1,30 @@
+# 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
--
2.7.4