[PATCH] Fix segmentation fault after opening an existing BFD for update PR gdb/20948

Jozef Lawrynowicz jozef.l@mittosystems.com
Mon Mar 19 13:23:00 GMT 2018


GDB segfaults when invoking it with the --write option, then quitting. First
reported in PR gdb/20948.

When GDB is invoked with the --write option, bfd_fopen is called with the "r+b"
flags (see comment #3 from the above PR for more info). A reduced test case
for the segfault using BFD only is below:

bfdbug.c
---
#include<bfd.h>

int main(int argc, char **argv)
{
   bfd *abfd = bfd_fopen(argv[1], "default", "r+", -1);
   bfd_check_format(abfd, bfd_object);
   bfd_close(abfd);
}
---

gcc bfdbug.c -g -static ./build/bfd/libbfd.a ./build/libiberty/libiberty.a -lopcodes -lz -ldl -o bfdbug
cp bfdbug test.elf
./build/gdb/gdb -ex run -ex quit --args ./bfdbug test.elf

Program received signal SIGSEGV, Segmentation fault.
_bfd_elf_strtab_finalize (tab=0x0) at ../../bfd/elf-strtab.c:371

---

The attached patch fixes the above seg fault, and therefore the GDB segfault
with --write, by initializing elf_shstrtab(bfd) when a bfd is opened for update.

Before writing elf_shstrtab and other section data back to the BFD, the filepos
of all the sections has to be recomputed. This is done in a new function,
_bfd_elf_recompute_section_file_positions, which takes the functionality
from _bfd_elf_compute_section_file_positions that is required to ensure the ELF
data is written back correctly.

With this patch, you can now, for example, get a section, modify the contents
and see those changes in the output BFD. After adding the following
to the example code above, we can see the string FOOBAR in the
"objdump -sj .data test.elf" output:

asection *section = bfd_get_section_by_name (abfd, ".data");
/* In ASCII:        "F"   "O"   "O"   "B"   "A"   "R"    */
char contents[] = {0x46, 0x4F, 0x4F, 0x42, 0x41, 0x52};
bfd_set_section_contents(abfd, section, contents, (file_ptr)0, sizeof(contents));

However, since output_has_begun is TRUE when the bfd is opened
for update, changes cannot be made to the size or order of sections, among
other things.

Tested gas, binutils, ld, gdb with no regressions for x86_64-pc-linux-gnu.
The "readelf -Ss" output is identical for both the before (bfdbug) and after
(test.elf) ELF files, indicating that the .strtab, .shstrtab and .symtab have
been read and written back correctly.

I couldn't work out where the above testcase would fit into the binutils
testsuite, and figured the build process for the testcase might be awkward
given the reliance on library calls. I've instead included a GDB test which
uses the --write functionality, and checks that the changes to memory in the
loaded ELF file persist after quitting GDB.

If this this patch is acceptable I would appreciate if someone could commit it
for me, as I don't have write access.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Fix-segmentation-fault-after-opening-an-existing-BFD.patch
Type: text/x-patch
Size: 7650 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20180319/d005d99b/attachment.bin>


More information about the Binutils mailing list