https://sourceware.org/bugzilla/show_bug.cgi?id=29939
Bug ID: 29939 Summary: -z pack-relative-relocs --no-keep-memory -pie tries to write a yet-to-be-loaded section content Product: binutils Version: 2.40 (HEAD) Status: NEW Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: arsen at aarsen dot me Target Milestone: --- GCC: gcc-12 (Gentoo 12.2.1_p20221217 p6) 12.2.1 20221217 LD: GNU ld (Gentoo 2.39 p5) 2.39.0, and GNU ld (GNU Binutils) 2.39.50.20221218 Binutils patches for the former: https://dev.gentoo.org/~dilfridge/distfiles/binutils-2.39-patches-5.tar.xz (though they should not be relevant, since they're mostly build issue related things) The latter is a clean build of 20d8836e4ac6e416fda53152d453328934a2ea46 (Most of the) relevant files: https://www.aarsen.me/~arsen/bfdbug.tar.xz The above is missing some parts of the GCC distribution, but removing the LTO and linker plugin bits suffices to work around that AFAICT (and I can still reproduce after doing that) Running cmdline from within var/tmp/portage/net-libs/webkit-gtk-2.38.3-r500/work/webkitgtk-2.38.3_build/: Program terminated with signal SIGSEGV, Segmentation fault. #0 bfd_putl64 (data=41888, p=0x0) at /usr/src/debug/sys-devel/binutils-2.39-r4/binutils-2.39/bfd/libbfd.c:877 877 addr[0] = (data >> (0*8)) & 0xff; (gdb) bt #0 bfd_putl64 (data=41888, p=0x0) at /usr/src/debug/sys-devel/binutils-2.39-r4/binutils-2.39/bfd/libbfd.c:877 #1 0x00007f8149508f38 in elf_x86_size_or_finish_relative_reloc (is_x86_64=is_x86_64@entry=true, info=info@entry=0x557de9d62e20 <link_info>, htab=htab@entry=0x557dea2eb5d0, unaligned=unaligned@entry=false, outrel=outrel@entry=0x7ffd284ac870) at /usr/src/debug/sys-devel/binutils-2.39-r4/binutils-2.39/bfd/elfxx-x86.c:1546 #2 0x00007f8149509381 in _bfd_elf_x86_finish_relative_relocs (info=0x557de9d62e20 <link_info>) at /usr/src/debug/sys-devel/binutils-2.39-r4/binutils-2.39/bfd/elfxx-x86.c:1912 #3 0x00007f8149538e80 in bfd_elf_final_link (abfd=0x557dea2e9490, info=0x557de9d62e20 <link_info>) at /usr/src/debug/sys-devel/binutils-2.39-r4/binutils-2.39/bfd/elflink.c:12737 ... on this fairly complex link. That block is: (gdb) list /usr/src/debug/sys-devel/binutils-2.39-r4/binutils-2.39/bfd/elfxx-x86.c:1546 1541 } 1542 else 1543 { 1544 if (rel.r_offset >= sec->size) 1545 abort (); 1546 htab->elf_write_addend 1547 (info->output_bfd, outrel->r_addend, 1548 (elf_section_data (sec)->this_hdr.contents 1549 + rel.r_offset)); 1550 } (gdb) I ran a bisect for this error, and it'd appear to have been here since DT_RELR was added in 5af6f000d88622107e7382d337af2884fd211da2 --- This combination of flags fails even for simple programs; a hello world crashed, and so did even less: [i] ~/gcc/binutils-bld/ld $ ld -z pack-relative-relocs --no-keep-memory -pie /usr/lib/gcc/x86_64-pc-linux-gnu/12/crtbeginS.o ld: warning: cannot find entry symbol _start; defaulting to 0000000000001020 Segmentation fault (core dumped) ... in the same place as the above. I wrote a patch that does fix the simple case: https://www.aarsen.me/~arsen/0001-ld.bfd-Fix-no-keep-memory-z-pack-relative-relocs-seg.patch [i] ~/gcc/binutils-bld/ld 139 $ ./ld-new -z pack-relative-relocs --no-keep-memory -pie /usr/lib/gcc/x86_64-pc-linux-gnu/12/crtbeginS.o ./ld-new: warning: cannot find entry symbol _start; defaulting to 0000000000001020 ./ld-new: /usr/lib/gcc/x86_64-pc-linux-gnu/12/crtbeginS.o:(.text+0xa): undefined reference to `__TMC_END__' ./ld-new: /usr/lib/gcc/x86_64-pc-linux-gnu/12/crtbeginS.o:(.text+0x3a): undefined reference to `__TMC_END__' ./ld-new: a.out: hidden symbol `__TMC_END__' isn't defined ./ld-new: final link failed: bad value [i] ~/gcc/binutils-bld/ld 1 $ ... but it causes a file truncation error with the complex case: [c] ~/.../webkit-gtk-2.38.3-r500/work/webkitgtk-2.38.3_build$ sh -x ../../../../../../../../binutils-bld/ld/cmdline + .../binutils-bld/ld/ld-new -plugin ... ../../../../../../../../binutils-bld/ld/ld-new: error: bin/LLIntSettingsExtractor(.data.rel.ro.local) is too large (0x28 bytes) ../../../../../../../../binutils-bld/ld/ld-new: BFD (GNU Binutils) 2.39.50.20221218 internal error, aborting at ../../binutils-gdb/bfd/elfxx-x86.c:1566 in elf_x86_size_or_finish_relative_reloc ../../../../../../../../binutils-bld/ld/ld-new: Please report this bug. /home/arsen/gcc/binutils-bld/ld/ld-new: error: bin/LLIntSettingsExtractor(.data.rel.ro.local) is too large (0x28 bytes) In GDB: Breakpoint 1, _bfd_abort (file=file@entry=0x555555753410 "../../binutils-gdb/bfd/elfxx-x86.c", line=line@entry=1566, fn=fn@entry=0x555555753a40 <__PRETTY_FUNCTION__.7> "elf_x86_size_or_finish_relative_reloc") at ../../binutils-gdb/bfd/bfd.c:1785 1785 if (fn != NULL) (gdb) p bfd_error $1 = bfd_error_file_truncated (gdb) This error gets set at _bfd_section_size_insane: if ((ufile_ptr) sec->filepos > filesize || size > filesize - sec->filepos) { bfd_set_error (bfd_error_file_truncated); return true; } I suspect I'm misunderstanding how loading and discarding sections for !keep_memory works. Sadly, I'm low on time for figuring out how to fix it properly. PS: Sorry about the external links; I'm decently sure Bugzilla wouldn't like a 13MB archive. -- You are receiving this mail because: You are on the CC list for the bug.