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

See Also:
Host:
Target:
Build:
Last reconfirmed: 2016-09-27 00:00:00


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

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 UTC
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 UTC
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 UTC
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.

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

sysdeps/gnu/unwind-resume.c
sysdeps/arm/find_exidx.c
sysdeps/arm/aeabi_unwind_cpp_pr1.c

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 UTC
(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 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

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
    	elf_backend_update_relocs.
    	* 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
    	elf_backend_count_output_relocs.
    	* 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 UTC
I have applied Akihiko's patch, which is a much better way yo solve this problem.