Bug 23046

Summary: gold crashes while linking armv7hl binaries built with clang 6.0 when using --icf=safe
Product: binutils Reporter: Bernhard Rosenkränzer <bero>
Component: goldAssignee: Cary Coutant <ccoutant>
Status: RESOLVED FIXED    
Severity: normal CC: ian
Priority: P2    
Version: 2.30   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed: 2018-04-14 00:00:00
Attachments: Object file triggering the crash
Object file still triggering the problem

Description Bernhard Rosenkränzer 2018-04-11 12:35:49 UTC
gold frequently crashes while linking armv7hl binaries built with clang 6.0 -- for example when building alsa-libs:

/usr/bin/ld -z relro -X --hash-style=gnu --build-id --enable-new-dtags --eh-frame-hdr -m armelf_linux_eabi -shared -o .libs/libasound.so.2.0.0 /usr/bin/../lib/gcc/armv7hl-mandriva-linux-gnueabihf/7.3.0/../../../../lib/crti.o /usr/bin/../lib/gcc/armv7hl-mandriva-linux-gnueabihf/7.3.0/crtbeginS.o -L/usr/bin/../lib/gcc/armv7hl-mandriva-linux-gnueabihf/7.3.0 -L/usr/bin/../lib/gcc/armv7hl-mandriva-linux-gnueabihf/7.3.0/../../../../lib -L/usr/bin/../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/bin/../lib/gcc/armv7hl-mandriva-linux-gnueabihf/7.3.0/../../.. -L/usr/bin/../lib -L/lib -L/usr/lib .libs/conf.o .libs/confmisc.o .libs/input.o .libs/output.o .libs/async.o .libs/error.o .libs/dlmisc.o .libs/socket.o .libs/shmarea.o .libs/userfile.o .libs/names.o --whole-archive control/.libs/libcontrol.a mixer/.libs/libmixer.a pcm/.libs/libpcm.a timer/.libs/libtimer.a rawmidi/.libs/librawmidi.a hwdep/.libs/libhwdep.a seq/.libs/libseq.a ucm/.libs/libucm.a topology/.libs/libtopology.a --no-whole-archive -lm -ldl -lpthread -lrt --version-script=Versions -Bsymbolic-functions --no-undefined -O2 -soname libasound.so.2 -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/armv7hl-mandriva-linux-gnueabihf/7.3.0/crtendS.o /usr/bin/../lib/gcc/armv7hl-mandriva-linux-gnueabihf/7.3.0/../../../../lib/crtn.o

Program received signal SIGSEGV, Segmentation fault.
---Type <return> to continue, or q <return> to quit---
0x000d4b60 in (anonymous namespace)::Target_arm<false>::gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Sized_relobj_file<32, false>*, unsigned int, unsigned int, unsigned char const*, unsigned int, gold::Output_section*, bool, unsigned int, unsigned char const*) ()
(gdb) bt
#0  0x000d4b60 in (anonymous namespace)::Target_arm<false>::gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Sized_relobj_file<32, false>*, unsigned int, unsigned int, unsigned char const*, unsigned int, gold::Output_section*, bool, unsigned int, unsigned char const*) ()
#1  0x0030e618 in gold::Sized_relobj_file<32, false>::do_gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Read_relocs_data*) ()
#2  0x000de4ac in (anonymous namespace)::Arm_relobj<false>::do_gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Read_relocs_data*) ()
#3  0x0030c6bc in gold::Gc_process_relocs::run(gold::Workqueue*) ()
#4  0x00366b30 in gold::Workqueue::find_and_run_task(int) ()
#5  0x0036738c in gold::Workqueue::process(int) ()
#6  0x00015260 in main ()
Comment 1 Bernhard Rosenkränzer 2018-04-11 12:38:48 UTC
Somewhat simplified (still from alsa-lib 1.1.6 sources):

$ ld -m armelf_linux_eabi -shared -o .libs/libasound.so.2.0.0 .libs/shmarea.o Segmentation fault (core dumped)
Comment 2 Bernhard Rosenkränzer 2018-04-11 12:40:02 UTC
Created attachment 10939 [details]
Object file triggering the crash
Comment 3 Bernhard Rosenkränzer 2018-04-11 12:42:29 UTC
Seems to be triggered by __attribute__((destructor)) on a function in shmarea.c

Source is here:
https://github.com/michaelwu/alsa-lib/blob/master/src/shmarea.c

Dropping __attribute__((destructor)) from line 97 "fixes" the problem (but of course doesn't result in a library doing its job)
Comment 4 Cary Coutant 2018-04-14 22:32:55 UTC
I can't reproduce the problem with the object file and command line that you provided. Even though your command line doesn't use --gc-sections, the backtrace you showed suggested that it was in use, but adding that option still doesn't trigger a crash.

Please provide more details if you're still seeing this problem with the latest version of gold.
Comment 5 Bernhard Rosenkränzer 2018-04-14 22:44:28 UTC
Forgot that I had a patch in there that enables some options by default...

With all flags adjusted for, the command I'm running is

armv7hl-openmandriva-linux-gnueabihf-ld -z relro -X --hash-style=gnu --build-id --enable-new-dtags --eh-frame-hdr -m armelf_linux_eabi --as-needed --icf=safe -O1 --warn-common --warn-execstack --warn-shared-textrel  -shared -o test.so.0 shmarea.o

And --icf=safe seems to be needed to trigger it.
Comment 6 Cary Coutant 2018-04-14 22:52:35 UTC
Thanks, I see the problem now. Fix on the way...
Comment 7 Cary Coutant 2018-04-14 22:58:58 UTC
Fixed on trunk.
Comment 8 Sourceware Commits 2018-04-14 22:58:59 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

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

commit aae8280935aab812c3666d1c5c0ea099e96927cc
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Sat Apr 14 15:58:07 2018 -0700

    Fix bug where --icf=safe triggers segfault when linking ARM.
    
    When checking a R_ARM_TARGET[12] relocation, we need a valid target
    pointer, but the garbage collection code was passing a NULL instead.
    
    gold/
    	PR gold/23046
    	* gc.h (gc_process_relocs): Pass target to
    	scan.global_reloc_may_be_function_pointer.
Comment 9 Bernhard Rosenkränzer 2018-04-19 15:25:39 UTC
After applying the patch on top of 2.30, I can still trigger this crash with --icf=safe with a different test case. Backtrace looks the same.

Program received signal SIGSEGV, Segmentation fault.
0x000d4b58 in (anonymous namespace)::Target_arm<false>::gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Sized_relobj_file<32, false>*, unsigned int, unsigned int, unsigned char const*, unsigned int, gold::Output_section*, bool, unsigned int, unsigned char const*) ()
(gdb) bt
#0  0x000d4b58 in (anonymous namespace)::Target_arm<false>::gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Sized_relobj_file<32, false>*, unsigned int, unsigned int, unsigned char const*, unsigned int, gold::Output_section*, bool, unsigned int, unsigned char const*) ()
#1  0x0030e638 in gold::Sized_relobj_file<32, false>::do_gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Read_relocs_data*) ()
#2  0x000de4bc in (anonymous namespace)::Arm_relobj<false>::do_gc_process_relocs(gold::Symbol_table*, gold::Layout*, gold::Read_relocs_data*) ()
#3  0x0030c6dc in gold::Gc_process_relocs::run(gold::Workqueue*) ()
#4  0x00366b50 in gold::Workqueue::find_and_run_task(int) ()
#5  0x003673ac in gold::Workqueue::process(int) ()
#6  0x00015260 in main ()
Comment 10 Bernhard Rosenkränzer 2018-04-19 15:27:30 UTC
Created attachment 10962 [details]
Object file still triggering the problem
Comment 11 Sourceware Commits 2018-04-19 17:20:50 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

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

commit d83d54033545c0e7b668950b127753c88a33f950
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Thu Apr 19 10:20:08 2018 -0700

    Fix second bug where --icf=safe triggers segfault when linking ARM.
    
    When checking a R_ARM_TARGET[12] relocation, we need a valid target
    pointer, but the garbage collection code was passing a NULL instead.
    The previous fix for this bug fixed the call to
    scan.global_reloc_may_be_function_pointer, but missed the similar
    call to scan.local_reloc_may_be_function_pointer.
    
    gold/
    	PR gold/23046
    	* gc.h (gc_process_relocs): Pass target to
    	scan.local_reloc_may_be_function_pointer.
Comment 12 Cary Coutant 2018-04-19 17:39:00 UTC
Sorry, missed the call to scan.local_reloc_may_be_function_pointer.

Should be fixed now.