Created attachment 7737 [details] gcsec-1.s from GCC's testsuite GCC's gcc/testsuite/gcc.dg/special/gcsec-1.c fails on sparc-linux because it causes ld to segfault. This is reproducible both natively on sparc-linux and with cross toolchains hosted on x86_64-linux. Occurs with (at least) binutils 2.25 (HEAD), 2.24, and 2.23.2. Occurs with both 32 and 64-bit sparc targets. To reproduce natively on sparc-linux, do sth like: > gcc -m32 -c gcsec-1.s > ld -m elf32_sparc -static -relax -o a.out /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/sparcv9-brewer-linux/4.7.4/crtbeginT.o gcsec-1.o --gc-sections --start-group /usr/lib/libc.a /usr/lib/gcc/sparcv9-brewer-linux/4.7.4/libgcc.a /usr/lib/gcc/sparcv9-brewer-linux/4.7.4/libgcc_eh.a --end-group /usr/lib/gcc/sparcv9-brewer-linux/4.7.4/crtend.o /usr/lib/crtn.o Segmentation fault Running the above in gdb shows: Program received signal SIGSEGV, Segmentation fault. 0xf7f2ec2c in _bfd_sparc_elf_gc_sweep_hook (abfd=0x15ce98, info=0x9bc28 <link_info>, sec=0x16f418, relocs=<optimized out>) at elfxx-sparc.c:2003 2003 if (local_got_refcounts[r_symndx] > 0) Missing separate debuginfos, use: debuginfo-install glibc-2.17-2.bl17.bl.2.sparcv9 libgcc-4.7.4-10.bl17.bl.2.sparcv9 zlib-1.2.5-7.bl17.sparcv9 (gdb) list 1998 case R_SPARC_GOTDATA_OP_HIX22: 1999 case R_SPARC_GOTDATA_OP_LOX10: 2000 break; 2001 2002 default: 2003 if (local_got_refcounts[r_symndx] > 0) 2004 local_got_refcounts[r_symndx]--; 2005 break; 2006 } 2007 } (gdb) bt #0 0xf7f2ec2c in _bfd_sparc_elf_gc_sweep_hook (abfd=0x15ce98, info=0x9bc28 <link_info>, sec=0x16f418, relocs=<optimized out>) at elfxx-sparc.c:2003 #1 0xf7f5e264 in elf_gc_sweep (info=0x9bc28 <link_info>, abfd=0xa9618) at elflink.c:11936 #2 bfd_elf_gc_sections (abfd=0xa9618, info=0x9bc28 <link_info>) at elflink.c:12199 #3 0x00028e58 in lang_gc_sections () at ldlang.c:6401 #4 lang_process () at ldlang.c:6744 #5 0x00013b04 in main (argc=19, argv=0xffffd2b4) at ./ldmain.c:386 (gdb) print local_got_refcounts $1 = (bfd_signed_vma *) 0x0 Removing the --gc-sections option allows the link to succeed. To reproduce with a cross toolchain, do sth like: > sparc64-unknown-linux-gcc -m32 -c gcsec-1.s > sparc64-unknown-linux-ld -m elf32_sparc -static -relax -o a.out /home/mikpe/pkgs/linux-x86_64/cross-sparc64/usr/lib/crt1.o /home/mikpe/pkgs/linux-x86_64/cross-sparc64/usr/lib/crti.o /home/mikpe/pkgs/linux-x86_64/cross-sparc64/lib/gcc/sparc64-unknown-linux/4.8.3/32/crtbeginT.o gcsec-1.o --gc-sections --start-group /home/mikpe/pkgs/linux-x86_64/cross-sparc64/usr/lib/libc.a /home/mikpe/pkgs/linux-x86_64/cross-sparc64/lib/gcc/sparc64-unknown-linux/4.8.3/32/libgcc.a --end-group /home/mikpe/pkgs/linux-x86_64/cross-sparc64/lib/gcc/sparc64-unknown-linux/4.8.3/32/crtend.o /home/mikpe/pkgs/linux-x86_64/cross-sparc64/usr/lib/crtn.o Segmentation fault The cross toolchain was built with binutils-2.24, gcc-4.8.3, Linux 3.13 kernel headers, and glibc-2.19. I've tried to make the test case standalone, but simply stubbing out the references to libc makes the segfault go away.
Created attachment 7738 [details] proposed patch It seems that the majority of the elf backends in bfd do a NULL check before dereferencing local_got_refcounts in their gc_sweep_hook functions. I don't know if there's a fundamental reason why the sparc backend doesn't do a NULL check in this context, but adding a NULL check fixes this test case with no visible regressions (tested 2.25 HEAD, 2.24, and 2.23.2 in cross environments, tested 2.23.2 natively).
Created attachment 7739 [details] counter-proposal patch There shouldn't be any need to test local_got_refcounts for NULL, if gc_sweep_hook logic exactly matches check_relocs, and by inspection there's a typo that probably is the cause of this bug.
Thanks Alan, your patch also fixes the bug. Tested with crosses hosted on x86_64-linux, and natively on sparc64-linux: no regressions.
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "gdb and binutils". The branch, master has been updated via 7833fb7b8e4d0c75138ef715935a5040bc9b2e78 (commit) from 02eb0a49bceb35e4b0503e6ffc11e85151dbc571 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7833fb7b8e4d0c75138ef715935a5040bc9b2e78 commit 7833fb7b8e4d0c75138ef715935a5040bc9b2e78 Author: Alan Modra <amodra@gmail.com> Date: Tue Aug 5 10:49:54 2014 +0930 Fix PR17226, ld --gc-sections segfaults on sparc-linux PR ld/17226 * elfxx-sparc.c (_bfd_sparc_elf_gc_sweep_hook): Typo fix. ----------------------------------------------------------------------- Summary of changes: bfd/ChangeLog | 5 +++++ bfd/elfxx-sparc.c | 2 +- 2 files changed, 6 insertions(+), 1 deletions(-)
Fixed mainline.