Bug 18867

Summary: ld reloc sorting causes glibc to crash on alpha
Product: binutils Reporter: Mike Frysinger <vapier>
Component: ldAssignee: Alan Modra <amodra>
Status: RESOLVED FIXED    
Severity: normal CC: rth
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Host: Target: alphaev68-unknown-linux-gnu
Build: Last reconfirmed:
Bug Depends on: 17666    
Bug Blocks:    

Description Mike Frysinger 2015-08-25 21:02:07 UTC
we noticed that binutils-2.25.1 causes glibc to segfault when exiting:

we tracked it back to this commit:
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=53df40a43c968f4d97754226d62775d1fe665459

and current master also breaks (going back to the original commit):
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=28dbcedc7b1282b93c3f25c4e42ae71b44e8e2a8

if i take current master and force sort=false (the equiv of defining sort_relocs_p for the alpha backend and having it always return false), then glibc links & runs just fine.

i don't know if we should disable sorting for the alpha backend all the time, or if there's a change to reloc processing in glibc that we can make.
Comment 1 Alan Modra 2015-08-26 01:50:27 UTC
I see from the alpha backend binutils code that some relocs are expected in certain order.  That means I can't use qsort, which is unstable.

Argh!  In fact, even on powerpc we have marker relocs at the same r_offset as other relocs, eg. on __tls_get_addr calls, and they're expected in a certain order or TLS optimisation will be disabled.

I need to change that qsort to a stable sort.
Comment 2 Sourceware Commits 2015-08-26 14:05:23 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 0e28778672160ee57d12fcc4f0e631122088fe69
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Aug 26 17:32:08 2015 +0930

    Use stable sort for ld -r relocs
    
    A number of targets emit multiple relocs at a given r_offset, and
    depend on those relocs staying in their original order.
    
    	PR 18867
    	* elflink.c (cmp_ext32l_r_offset, cmp_ext32b_r_offset): Delete.
    	(cmp_ext64l_r_offset, cmp_ext64b_r_offset): Delete.
    	(ext32l_r_offset, ext32b_r_offset, ext64l_r_offset, ext64b_r_offset):
    	New functions.
    	(elf_link_adjust_relocs): Use an insertion sort to sort relocs.
Comment 3 Alan Modra 2015-08-27 01:33:49 UTC
Forgot to add the pr number to commit message, so adding info by hand from
https://sourceware.org/ml/binutils-cvs/2015-08/msg00192.html

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

commit 6fc5bb5718b72250cffb9c09110515971f72e116
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Aug 27 10:54:28 2015 +0930

    Don't sort ld -r output relocs on alpha
    
    LITERAL/LITUSE relocs must be kept together.
    
    	* elf64-alpha.c (elf64_alpha_sort_relocs_p): New function.
    	(elf_backend_sort_relocs_p): Define.
Comment 4 Mike Frysinger 2015-08-27 03:25:44 UTC
(In reply to Alan Modra from comment #3)

thanks, i can confirm master is working again now
Comment 5 Sourceware Commits 2015-08-27 14:04:49 UTC
The binutils-2_25-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 5fc980cc8be61203db24756e17d87f24c174f1ac
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Aug 26 17:32:08 2015 +0930

    Use stable sort for ld -r relocs
    
    A number of targets emit multiple relocs at a given r_offset, and
    depend on those relocs staying in their original order.
    
    	PR 18867
    	* elflink.c (cmp_ext32l_r_offset, cmp_ext32b_r_offset): Delete.
    	(cmp_ext64l_r_offset, cmp_ext64b_r_offset): Delete.
    	(ext32l_r_offset, ext32b_r_offset, ext64l_r_offset, ext64b_r_offset):
    	New functions.
    	(elf_link_adjust_relocs): Use an insertion sort to sort relocs.
Comment 6 Sourceware Commits 2015-08-27 14:04:54 UTC
The binutils-2_25-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 00b2b5c400e542a436b66989841a2f3b81181e91
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Aug 27 10:54:28 2015 +0930

    Don't sort ld -r output relocs on alpha
    
    LITERAL/LITUSE relocs must be kept together.
    
    	PR 18867
    	* elf64-alpha.c (elf64_alpha_sort_relocs_p): New function.
    	(elf_backend_sort_relocs_p): Define.
Comment 7 Sourceware Commits 2015-09-16 12:25:38 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit bca6d0e3195217576b39fa1205469e1d578b386a
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Sep 16 18:07:03 2015 +0930

    Fix slowdown in ld -r for most common case of out-of-order relocs
    
    I chose insertion sort since relocs are mostly sorted, but there is a
    common case we can handle better;  A run of relocs put out of order
    due to not linking input files in order.
    
    	PR 18867
    	* elflink.c (elf_link_adjust_relocs): Modify insertion sort to
    	insert a run.  Return status in case of malloc failure.
    	Adjust callers.
Comment 8 Sourceware Commits 2015-09-18 03:15:07 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit b29b8669ad250df649a0f02c5575e7163a2cd9e4
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Sep 17 12:53:29 2015 +0930

    Remove one unnecessary iteration in insertion sort
    
    	PR 18867
    	* elflink.c (elf_link_adjust_relocs): Correct start of insertion
    	sort main loop.
Comment 9 Sourceware Commits 2015-09-18 03:18:46 UTC
The binutils-2_25-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 9ad9e2c6fb404bdeb7489cab654575764ac6f791
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Sep 16 18:07:03 2015 +0930

    Fix slowdown in ld -r for most common case of out-of-order relocs
    
    I chose insertion sort since relocs are mostly sorted, but there is a
    common case we can handle better;  A run of relocs put out of order
    due to not linking input files in order.
    
    	PR 18867
    	* elflink.c (elf_link_adjust_relocs): Modify insertion sort to
    	insert a run.  Return status in case of malloc failure.
    	Adjust callers.
Comment 10 Sourceware Commits 2015-09-18 03:18:51 UTC
The binutils-2_25-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 352d25d9bb6dff7b30d1c6a4f4c6192572c8e817
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Sep 17 12:53:29 2015 +0930

    Remove one unnecessary iteration in insertion sort
    
    	PR 18867
    	* elflink.c (elf_link_adjust_relocs): Correct start of insertion
    	sort main loop.