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.

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.
This commit is contained in:
Jozef Lawrynowicz 2018-09-11 22:56:36 +01:00 committed by Tom Tromey
parent b5a9bfbebe
commit db72737006
5 changed files with 91 additions and 0 deletions

View 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.

View File

@ -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);

View 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:

View File

@ -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;
}

View File

@ -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