Bug 20636 - [arm] ld crash when linking glibc unwind code
Summary: [arm] ld crash when linking glibc unwind code
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.28
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2016-09-26 16:35 IST by Szabolcs Nagy
Modified: 2016-09-28 10:53 IST (History)
1 user (show)

See Also:
Last reconfirmed: 2016-09-27 00:00:00

archive of 3 object files from glibc (22.70 KB, application/x-archive)
2016-09-26 16:35 IST, Szabolcs Nagy
Proposed patch (355 bytes, patch)
2016-09-27 12:03 IST, Nick Clifton
Details | Diff
testcase asm 1 (1.15 KB, text/plain)
2016-09-27 13:05 IST, Szabolcs Nagy
testcase asm 2 (829 bytes, text/plain)
2016-09-27 13:05 IST, Szabolcs Nagy
testcase asm 3 (403 bytes, text/plain)
2016-09-27 13:06 IST, Szabolcs Nagy

Note You need to log in before you can comment on or make changes to this bug.
Description Szabolcs Nagy 2016-09-26 16:35:47 IST
Created attachment 9522 [details]
archive of 3 object files from glibc

if i cross compile glibc trunk (version bb8081f57f23a3e1b28b1b7104f24d17da9a3d82) from x86_64 to arm then linking libc_pic.a into libc_pic.os crashes ld since binutils commit 5025eb7c0d87b01507116353b5d63b163d7add3d .

i attached a reduced archive file that only contains 3 object files from glibc that trigger the crash with

$ arm-none-linux-gnueabihf-ld -r -o bug.o --whole-archive libx.a
Segmentation fault (core dumped)
Comment 1 Szabolcs Nagy 2016-09-27 10:48:48 IST
during bfd_elf_final_link:

bfd/elflink.c:11409 bfd_elf_final_link
	first sets reldata->count to 2
bfd/elf32-arm.c:19031 elf32_arm_count_output_relocs
	counts 3 output relocs
bfd/elflink.c:2468 _bfd_elf_link_size_reloc_section
	allocates 3 entry for reldata->hdr.contents 
	allocates 2 entry for reldata->hash
bfd/elf32-arm.c:19336 emit_relocs
	sets reldata->count to 3
bfd/elflink.c:8406 elf_link_adjust_relocs
	assumes reldata->count (3) is the size of reldata->hashes

so either the hash allocation is incorrect in
_bfd_elf_link_size_reloc_section or the relocation
counting is wrong.
Comment 2 Nick Clifton 2016-09-27 12:03:17 IST
Hi Szabolcs,

  Thanks for the test case.  Is there any chance that we could get the assembler
sources for those files ?  (Or better yet, a reduced form of those sources that still reproduces the problem).  I am thinking about trying to create a linker testcase for this bug, which is why I would need the sources.

  I am currently testing the uploaded patch locally to see if it introduces any regressions.  In my opinion the patch is more of a workaround than a proper fix, but it is simple and clean, which gives me confidence that it will not break anything.

Comment 3 Nick Clifton 2016-09-27 12:03:40 IST
Created attachment 9526 [details]
Proposed patch
Comment 4 Szabolcs Nagy 2016-09-27 13:05:18 IST
Created attachment 9527 [details]
testcase asm 1
Comment 5 Szabolcs Nagy 2016-09-27 13:05:56 IST
Created attachment 9528 [details]
testcase asm 2
Comment 6 Szabolcs Nagy 2016-09-27 13:06:28 IST
Created attachment 9529 [details]
testcase asm 3
Comment 7 Szabolcs Nagy 2016-09-27 13:12:30 IST
attached the asm test cases, they are compiled from glibc sources


and an archive of the resulting objects triggers the crash with ld -r --whole-archive (order of objects in the archive seems to matter for some reason).
Comment 8 Szabolcs Nagy 2016-09-27 13:34:18 IST
(In reply to Szabolcs Nagy from comment #7)
> (order of objects in the archive seems to matter for some reason).

that's only because the out-of-bound reldata->hashes[2] entry happens to be 0 with some ordering which works out fine.
Comment 9 cvs-commit@gcc.gnu.org 2016-09-28 10:51:49 IST
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:


commit 9eaff8613893f063400fdae95bc382ab33685e3b
Author: Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
Date:   Wed Sep 28 11:50:41 2016 +0100

    Fix seg-fault in the linker introduced by the previous delta.
    	PR ld/20636
    	* elf-bfd.h (struct elf_backend_data): Delete
    	elf_backend_count_output_relocs callback and add
    	* elf32-arm.c (elf32_arm_count_output_relocs): Deleted.
    	(emit_relocs): Deleted.
    	(elf32_arm_emit_relocs): Deleted.
    	(elf_backend_emit_relocs): Updated not to use the old functions.
    	(elf32_arm_update_relocs): New function.
    	(elf_backend_update_relocs): New define.
    	* elflink.c (bfd_elf_final_link): Add additional_reloc_count to the
    	relocation count. Call elf_backend_emit_relocs.
    	(_bfd_elf_size_reloc_section): Do not call
    	* elfxx-target.h (elf_backend_count_output_relocs): Deleted.
    	(elf_backend_update_relocs): New define.
Comment 10 Nick Clifton 2016-09-28 10:53:36 IST
I have applied Akihiko's patch, which is a much better way yo solve this problem.