Bug 21180

Summary: ld segfault for microblaze when --gc-sections is used
Product: binutils Reporter: wbx
Component: ldAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: nickc
Priority: P2    
Version: 2.29   
Target Milestone: ---   
Host: x86_64 Target: microblaze
Build: x86_64 Last reconfirmed:
Attachments: Proposed patch

Description wbx 2017-02-18 07:48:47 UTC
The buildroot autobuilders found two packages which are failing to compile for microblaze, because ld segfaults. This happens with binutils 2.26.1, but can be reproduced with binutils git from today.

The packages are nss and kmod (when python support is enabled).

Backtrace for nss with binutils 2.26.1:
gdb ./output/host/usr/bin/microblazeel-linux-ld.bfd ./output/build/libnss-3.27.2/nss/lib/freebl/core
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./output/host/usr/bin/microblazeel-linux-ld.bfd...(no debugging symbols found)...done.

warning: core file may not match specified executable file.
[New LWP 7756]
Core was generated by `/home/wbx/buildroot/output/host/usr/lib/gcc/microblazeel-buildroot-linux-uclibc'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000000000043b4a4 in microblaze_elf_finish_dynamic_symbol ()
(gdb) bt
#0  0x000000000043b4a4 in microblaze_elf_finish_dynamic_symbol ()
#1  0x0000000000453e94 in elf_link_output_extsym ()
#2  0x000000000042d591 in bfd_hash_traverse ()
#3  0x00000000004628ba in bfd_elf_final_link ()
#4  0x0000000000418966 in ldwrite ()
#5  0x00000000004038c9 in main ()
(gdb) info reg
rax            0xe8fac	954284
rbx            0x15f1220	23007776
rcx            0x70c680	7390848
rdx            0x18025d8	25175512
rsi            0x9c	156
rdi            0x0	0
rbp            0x15f3600	0x15f3600
rsp            0x7ffd7257eb40	0x7ffd7257eb40
r8             0x8040	32832
r9             0x99d64	630116
r10            0x1	1
r11            0x1	1
r12            0x16022c8	23077576
r13            0x16023f8	23077880
r14            0x17ac6f8	24823544
r15            0x706880	7366784
rip            0x43b4a4	0x43b4a4 <microblaze_elf_finish_dynamic_symbol+1012>
eflags         0x10246	[ PF ZF IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) disassemble 
...
   0x000000000043b48a <+986>:	callq  0x42a0b0 <bfd_assert>
   0x000000000043b48f <+991>:	jmpq   0x43b13f <microblaze_elf_finish_dynamic_symbol+143>
   0x000000000043b494 <+996>:	nopl   0x0(%rax)
   0x000000000043b498 <+1000>:	mov    0x28(%r14),%rdx
   0x000000000043b49c <+1004>:	mov    0x30(%r14),%rsi
   0x000000000043b4a0 <+1008>:	mov    0x68(%rdx),%rdi
---Type <return> to continue, or q <return> to quit---
=> 0x000000000043b4a4 <+1012>:	add    0x28(%rdi),%rsi
   0x000000000043b4a8 <+1016>:	add    0x60(%rdx),%rsi
   0x000000000043b4ac <+1020>:	mov    0x88(%r12),%edx
   0x000000000043b4b4 <+1028>:	lea    0x1(%rdx),%edi
   0x000000000043b4b7 <+1031>:	mov    %edi,0x88(%r12)
   0x000000000043b4bf <+1039>:	mov    0xb0(%r12),%rdi
   0x000000000043b4c7 <+1047>:	mov    %rax,0x30(%rsp)
   0x000000000043b4cc <+1052>:	movq   $0x10,0x38(%rsp)
   0x000000000043b4d5 <+1061>:	mov    %edx,%eax
   0x000000000043b4d7 <+1063>:	mov    %rsi,0x40(%rsp)
   0x000000000043b4dc <+1068>:	jmpq   0x43b349 <microblaze_elf_finish_dynamic_symbol+665>
   0x000000000043b4e1 <+1073>:	nopl   0x0(%rax)
   0x000000000043b4e8 <+1080>:	mov    $0xc92,%esi
   0x000000000043b4ed <+1085>:	mov    $0x4de331,%edi
   0x000000000043b4f2 <+1090>:	callq  0x42a0b0 <bfd_assert>

   0x000000000043b48a <+986>:	callq  0x42a0b0 <bfd_assert>
   0x000000000043b48f <+991>:	jmpq   0x43b13f <microblaze_elf_finish_dynamic_symbol+143>
   0x000000000043b494 <+996>:	nopl   0x0(%rax)
   0x000000000043b498 <+1000>:	mov    0x28(%r14),%rdx
   0x000000000043b49c <+1004>:	mov    0x30(%r14),%rsi
   0x000000000043b4a0 <+1008>:	mov    0x68(%rdx),%rdi
---Type <return> to continue, or q <return> to quit---
=> 0x000000000043b4a4 <+1012>:	add    0x28(%rdi),%rsi
   0x000000000043b4a8 <+1016>:	add    0x60(%rdx),%rsi
   0x000000000043b4ac <+1020>:	mov    0x88(%r12),%edx
   0x000000000043b4b4 <+1028>:	lea    0x1(%rdx),%edi
   0x000000000043b4b7 <+1031>:	mov    %edi,0x88(%r12)
   0x000000000043b4bf <+1039>:	mov    0xb0(%r12),%rdi
   0x000000000043b4c7 <+1047>:	mov    %rax,0x30(%rsp)
   0x000000000043b4cc <+1052>:	movq   $0x10,0x38(%rsp)
   0x000000000043b4d5 <+1061>:	mov    %edx,%eax
   0x000000000043b4d7 <+1063>:	mov    %rsi,0x40(%rsp)
   0x000000000043b4dc <+1068>:	jmpq   0x43b349 <microblaze_elf_finish_dynamic_symbol+665>
   0x000000000043b4e1 <+1073>:	nopl   0x0(%rax)
   0x000000000043b4e8 <+1080>:	mov    $0xc92,%esi
   0x000000000043b4ed <+1085>:	mov    $0x4de331,%edi
   0x000000000043b4f2 <+1090>:	callq  0x42a0b0 <bfd_assert>
...

Removing --gc-sections from LDFLAGS/CFLAGS let the linking work.
Comment 1 Nick Clifton 2017-02-22 12:45:37 UTC
Would it be possible for you to provide us with a testcase that demonstrates
this problem ?  I do not have access to a microblaze system so I cannot just
download and build nss.

Also - is an assertion being triggered, and if so, what is the message and
line number associated with the assertion failure ?
Comment 2 wbx 2017-02-22 19:39:42 UTC
You don't need microblaze hardware, the problem appear while cross-compiling from x86_64 to microblaze. The segfault happens without any assertion failure while trying to cross-compile libnss or kmod.

You can reproduce using for example Buildroot or OpenADK buildsystem targeting 
Qemu system for microblaze.

git clone git://buildroot.org/buildroot 
cd buildroot
git revert fceb1afd5dda45cf180f22877a6ab0e51d1b3dac
make qemu_microblazeel_mmu_defconfig
make menuconfig
--> choose Target Packages - Libraries - Crypto - libnss
make V=1

Wait a while for the segfault happening.
Comment 3 Nick Clifton 2017-02-23 10:43:04 UTC
Created attachment 9849 [details]
Proposed patch

Thanks - I can reproduce the problem now.

Please could you try out the uploaded patch and let me know if it works - and if the resulting library actually executes properly...

The patch is more of a workaround than a fix, since it ends up creating a redundant entry in the GOT table.  But I believe in keeping things simple, so if
it works I am happy to apply it as is.

Cheers
  Nick
Comment 4 wbx 2017-02-25 01:26:57 UTC
Works for me. No segfaults anymore, certutil application inside libnss shows no problems.

Thanks for the bugfix,
 Waldemar
Comment 5 Sourceware Commits 2017-02-27 11:34:22 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bd757ca7bf5886a4025ca02093fca1b8c5ce11a2

commit bd757ca7bf5886a4025ca02093fca1b8c5ce11a2
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Feb 27 11:33:05 2017 +0000

    Fix segfault in microblaze linker when garbage collection removes a symbol scheduled for a slot in the PLT.
    
    	PR ld/21180
    	* elf32-microblaze.c (microblaze_elf_finish_dynamic_symbol): Avoid
    	generating a seg-fault when encountering a symbol that has been
    	deleted by garbage collection.
Comment 6 Nick Clifton 2017-02-27 11:35:11 UTC
Patch applied.