Bug 19002

Summary: .eh_frame error: "no .eh_frame_hdr table will be created" with gold
Product: binutils Reporter: Greg Masters <gregory.masters>
Component: goldAssignee: Cary Coutant <ccoutant>
Status: ASSIGNED ---    
Severity: normal CC: eugeni.stepanov, ian, martin.dorey
Priority: P2    
Version: 2.27   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: .cpp and .h files with a Makefile to reproduce

Description Greg Masters 2015-09-24 16:17:09 UTC
Created attachment 8628 [details]
.cpp and .h files with a Makefile to reproduce

Hi. I've attached a small example reproducer for the problem, but essentially, we're using gold to perform a partial link on some objects, then when it comes to the final link, we see an error and no .eh_frame_hdr created.

$ make
g++ -c T.cpp
g++ -c c1.cpp
g++ -c c2.cpp
gold -r -o c.so T.o c1.o c2.o
g++ -c main.cpp
g++ -o a.out c.so main.o
/usr/bin/ld: error in c.so(.eh_frame); no .eh_frame_hdr table will be created.

We're not seeing the problem if we use ld for the partial link instead, but we'd like to keep using gold for the substantial speed increase.

Any help would be appreciated.

$ ld.gold -v
GNU gold (GNU Binutils for Debian 2.25) 1.11
Comment 1 Martin Dorey 2015-11-25 17:44:07 UTC
Given Cary's blisteringly fast fix for Bug 19291 today, I wonder if there's something more we could do to help move this, our other gold issue, along.  Perhaps our reproducer didn't work for Cary?

I suppose it might help someone to find their way to the source of their pain to mention that our motivation is more than just cosmetic: we've found that libunwind's stack trace generation can be slow in the absence of .eh_frame_hdr.
Comment 2 Evgeniy Stepanov 2016-03-15 22:47:43 UTC
The same problem is present in the ToT gold.

A simpler test case. The input asm contains a single .init_array constructor in its own comdat.

$ cat 1.s
	.text
	.file	"1.ll"
	.section	.text.f,"axG",@progbits,f,comdat
	.p2align	4, 0x90
	.type	f,@function
f:                                      # @f
	.cfi_startproc
# BB#0:
	retq
.Lfunc_end0:
	.size	f, .Lfunc_end0-f
	.cfi_endproc

	.section	.init_array.0,"aGw",@init_array,f,comdat
	.p2align	3
	.quad	f

	.section	".note.GNU-stack","",@progbits

$ as 1.s -o 1.o
$ ld.gold -r -o full.o 1.o 1.o
$ ld.bfd -shared full.o -o libfull.so
ld: error in full.o(.eh_frame); no .eh_frame_hdr table will be created.

The resulting library has an empty (header-only) eh_frame_hdr:
 12 .eh_frame_hdr 00000008  00000000000006b0  00000000000006b0  000006b0  2**2

If ld.gold is used instead of ld.bfd in the second link, then there is no error message, but the same end result.
Comment 3 Sourceware Commits 2016-03-21 02:18:06 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

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

commit 698400bfb91b3476d98edcb6a4bf5e4abe1c14cc
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Sun Mar 20 19:15:56 2016 -0700

    Fix problem where gold cannot build .eh_frame_hdr from ld -r output.
    
    When running ld -r on objects that have comdat groups, when gold
    deduplicates a function in a comdat group, it removes the relocations
    from the EH information that referred to the dropped copy of the function.
    When running a final link using the result of the -r link, the missing
    relocation cause it to fail to recognize the FDE for the dropped
    function.
    
    This patch improves gold's FDE scanning to take into account the
    possibility that an FDE corresponds to a dropped function, and drops
    that FDE as well.
    
    Gnu ld, on the other hand, leaves the relocations in the ld -r output,
    but makes them R_NONE with an r_sym field of 0. This was sufficient to
    let both linkers recognize the FDE properly.
    
    With this fix, if you do an ld -r with gold, then do the final link with
    Gnu ld, the .eh_frame_hdr section will not be generated. To make it work
    with Gnu ld, we would have to leave the R_NONE relocations in, but I
    think it's better to drop the relocations entirely. I'd hope that if
    you're doing a -r link with gold, you'll also do the final link with
    gold.
    
    gold/
    	PR gold/19002
    	* ehframe.cc (Eh_frame::read_fde): Check for dropped functions.
    	* testsuite/Makefile.am (eh_test_2): New test.
    	* testsuite/Makefile.in: Regenerate.
    	* testsuite/eh_test_2.sh: New test script.
    	* testsuite/eh_test_a.cc (bar): Make it comdat.
    	* testsuite/eh_test_b.cc (bar): Add a duplicate copy.
Comment 4 Evgeniy Stepanov 2016-03-21 20:23:35 UTC
Thank you, Cary!
Comment 5 Cary Coutant 2016-03-21 20:57:54 UTC
Before I close this as fixed, I have a question: should gold also warn when it cannot build the .eh_frame_hdr section and --eh-frame-hdr is passed in? Would that be that useful?
Comment 6 Evgeniy Stepanov 2016-03-21 21:07:14 UTC
The bfd linker warning about not being able to build .eh_frame_hdr was very useful for me.
Comment 7 Greg Masters 2016-03-22 10:49:09 UTC
Thanks for the fix.

I agree, I think the warning would be useful.