Attempted to build glibc for sh4-unknown-linux-gnu target and got the following errors: LANG=C bash -x ./trigger-linker-system.sh + sh4-unknown-linux-gnu-ld -plugin /usr/libexec/gcc/sh4-unknown-linux-gnu/6.4.0/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/sh4-unknown-linux-gnu/6.4.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccvxcoL0.res --sysroot=/usr/sh4-unknown-linux-gnu -m shlelf_linux -static -o /tmp/portage/cross-sh4-unknown-linux-gnu/glibc-9999/work/build-default-sh4-unknown-linux-gnu-nptl/elf/sln -L/usr/lib/gcc/sh4-unknown-linux-gnu/6.4.0 -L/usr/lib/gcc/sh4-unknown-linux-gnu/6.4.0/../../../../sh4-unknown-linux-gnu/lib -L/usr/sh4-unknown-linux-gnu/lib -L/usr/sh4-unknown-linux-gnu/usr/lib -O1 --as-needed --hash-style=gnu /tmp/portage/cross-sh4-unknown-linux-gnu/glibc-9999/work/build-default-sh4-unknown-linux-gnu-nptl/csu/crt1.o /tmp/portage/cross-sh4-unknown-linux-gnu/glibc-9999/work/build-default-sh4-unknown-linux-gnu-nptl/csu/crti.o /usr/lib/gcc/sh4-unknown-linux-gnu/6.4.0/crtbeginT.o /tmp/portage/cross-sh4-unknown-linux-gnu/glibc-9999/work/build-default-sh4-unknown-linux-gnu-nptl/elf/sln.o /tmp/portage/cross-sh4-unknown-linux-gnu/glibc-9999/work/build-default-sh4-unknown-linux-gnu-nptl/elf/static-stubs.o --start-group /tmp/portage/cross-sh4-unknown-linux-gnu/glibc-9999/work/build-default-sh4-unknown-linux-gnu-nptl/libc.a -lgcc --end-group /usr/lib/gcc/sh4-unknown-linux-gnu/6.4.0/crtend.o /tmp/portage/cross-sh4-unknown-linux-gnu/glibc-9999/work/build-default-sh4-unknown-linux-gnu-nptl/csu/crtn.o sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.29.1 p3) 2.29.1 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.29.1-r1/work/binutils-2.29.1/bfd/elf32-sh.c:5171 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.29.1 p3) 2.29.1 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.29.1-r1/work/binutils-2.29.1/bfd/elf32-sh.c:5174 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.29.1 p3) 2.29.1 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.29.1-r1/work/binutils-2.29.1/bfd/elf32-sh.c:5176 ... The trigger issue here is likely glibc's lack of support gcc built as --enable-default-pie but binutils ld error messages are not informative enough to understand what is wrong with the code. It's caused by BFD_ASSERT calls at: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf32-sh.c;h=9fa363615ddbb7629628b7fe500df93d0a27a8b0;hb=HEAD#l5141 I suggest changing calls like BFD_ASSERT ((insn & 0xff00) == 0xd000); to something like if ((insn & 0xff00) != 0xd000) _bfd_error_handler /* xgettext:c-format */ (_("%B(%A+%#Lx): unexpected instruction %04X (expected 0xd0??, ?)"), input_bfd, input_section, offset, insn); That way error message would be: ld/ld-new: libc.a(sched_yield.o)(.text+0x3a): unexpected instruction A005 (expected 0xd0??, mov.l) ld/ld-new: libc.a(sched_yield.o)(.text+0x3c): unexpected instruction E0FF (expected 0x0?12, stc) ld/ld-new: libc.a(sched_yield.o)(.text+0x3e): unexpected instruction 0009 (expected 0x0?ce, mov.l) It will help tweaking glibc.
Hi Sergei, Is there any chance that you could upload a reproducible testcase (object files + libraries + linker command line). This would make investigating the problem a lot easier. Cheers Nick
I'm afraid I can't reproduce it on current toolchain versions as is (something was fixed): gcc-8.1.0, binutils-2.30, glibc-2.27 I'll try to craft relocations to point to invalid instructions to trigger the same uninformative assertion failures.
Created attachment 11150 [details] binutils-gdb-sh4-better-errors.patch
Created attachment 11151 [details] bug.S
Managed to craft an object file to trigger needed asserts. As a bonus the test also causes out-of-bounds read access in ld and causes SIGSEGV: # cat bug.S # trying to trigger BFD_ASSERTs to make errors better: # https://sourceware.org/PR22706 # originally was found on toolchain that hits those asserts # and makes failures hard to discover .text .globl _start _start: .word 0 .word 0 .word 0 .globl bar .hidden bar bar: .word 0 .word 0 .word 0 .reloc _start, R_SH_TLS_LE_32, bar-5 .reloc _start, R_SH_TLS_IE_32, bar-5 .reloc _start, R_SH_TLS_GD_32, bar-5 Triggering (already patched binutils to produce nicer failures): $ sh4-unknown-linux-gnu-as bug.S -o bug.o $ sh4-unknown-linux-gnu-ld -m shlelf_linux -dynamic-linker /lib/ld-linux.so.2 -o bug.elf bug.o sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5156 sh4-unknown-linux-gnu-ld: bug.o(.text+0xfffffffffffffff6): unexpected instruction 0000 (expected 0xd0??, mov.l) sh4-unknown-linux-gnu-ld: bug.o(.text+0xfffffffffffffff8): unexpected instruction 0021 (expected 0x0?12, stc) sh4-unknown-linux-gnu-ld: bug.o(.text+0xfffffffffffffffa): unexpected instruction 0000 (expected 0x0?ce, mov.l) sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5115 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5126 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5128 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5130 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5132 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5134 sh4-unknown-linux-gnu-ld: BFD (Gentoo 2.30 p3) 2.30.0 assertion fail /tmp/portage-tmpdir/portage/cross-sh4-unknown-linux-gnu/binutils-2.30-r3/work/binutils-2.30/bfd/elf32-sh.c:5136 free(): invalid size ./do.sh: line 7: 17526 Aborted (core dumped) sh4-unknown-linux-gnu-ld -m shlelf_linux -dynamic-linker /lib/ld-linux.so.2 -o bug.elf bug.o valgrind suggests SIGSEGV might be related to out-of-bounds write: ==22276== Invalid read of size 2 ==22276== at 0x4E790A0: bfd_getl16 (libbfd.c:505) ==22276== by 0x4E91634: sh_elf_relocate_section (elf32-sh.c:5159) ==22276== by 0x4EB870F: elf_link_input_bfd (elflink.c:10715) ==22276== by 0x4EBA25E: bfd_elf_final_link (elflink.c:12033) ==22276== by 0x1294CE: ldwrite (ldwrite.c:581) ==22276== by 0x11202F: main (ldmain.c:456) ==22276== Address 0x596b806 is 10 bytes before a block of size 12 alloc'd ==22276== at 0x4C2CE6F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==22276== by 0x4E78E81: bfd_malloc (libbfd.c:193) ==22276== by 0x4EB9DE0: bfd_elf_final_link (elflink.c:11910) ==22276== by 0x1294CE: ldwrite (ldwrite.c:581) ==22276== by 0x11202F: main (ldmain.c:456)
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a05b9f5e1eb8f01eea23eff3902fa57f1f28a4e1 commit a05b9f5e1eb8f01eea23eff3902fa57f1f28a4e1 Author: Nick Clifton <nickc@redhat.com> Date: Mon Jul 30 13:58:15 2018 +0100 Prevent a seg-fault in the linker when trying to process SH object files with bogus relocs. PR 22706 * elf32-sh.c (sh_elf_relocate_section): When processing translation relocs, fail if the relocation offset is too small. Replace BFD_ASSERTs with more helpful error messages.
Hi Sergei, Thanks for the bug reproducer and the error message patch. The problem happens because the relocs are intended to modify a specific code sequence, but they are being applied to the wrong code. So I have extended your error message patch to replace some more of the assertions with not just error messages, but also early failures so that the code does not go on to process the relocs incorrectly and then try to write to the wrong location. Cheers Nick