Bug 21441

Summary: Unnecessary padding of .eh_frame section
Product: binutils Reporter: H.J. Lu <hjl.tools>
Component: ldAssignee: Alan Modra <amodra>
Status: RESOLVED FIXED    
Severity: normal CC: amodra
Priority: P2    
Version: 2.29   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description H.J. Lu 2017-04-27 19:31:12 UTC
[hjl@gnu-6 eh-frame-1]$ cat foo.s
	.text
	.globl	foo
	.type	foo, %function
foo:
	.cfi_startproc
	.cfi_endproc
	.size	foo, .-foo
[hjl@gnu-6 eh-frame-1]$ cat bar.s
	.text
	.globl	bar
	.type	bar, %function
bar:
	.cfi_startproc
	.byte 0x90
	.cfi_endproc
	.size	bar, .-bar
[hjl@gnu-6 eh-frame-1]$ make
as   -o foo.o foo.s
as   -o bar.o bar.s
./ld -shared -o foo.so foo.o bar.o
./ld -shared -o bar.so bar.o foo.o
readelf -w foo.so > foo.eh
readelf -w bar.so > bar.eh
diff -up foo.eh bar.eh
--- foo.eh	2017-04-27 12:30:43.466685231 -0700
+++ bar.eh	2017-04-27 12:30:43.467685234 -0700
@@ -13,7 +13,11 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-00000018 0000000000000010 0000001c FDE cie=00000000 pc=0000000000000201..0000000000000202
+00000018 0000000000000014 0000001c FDE cie=00000000 pc=0000000000000201..0000000000000202
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
Makefile:6: recipe for target 'all' failed
make: *** [all] Error 1
[hjl@gnu-6 eh-frame-1]$
Comment 1 Alan Modra 2017-08-12 11:27:02 UTC
How did you manage to avoid "discarding zero address range FDE" (see elf-eh-frame.c) for foo.so?  If I use --traditional-format to avoid eh_frame editing then I see both foo.so and bar.so with the same size eh_frame.
Comment 2 H.J. Lu 2017-08-12 20:23:55 UTC
(In reply to Alan Modra from comment #1)
> How did you manage to avoid "discarding zero address range FDE" (see
> elf-eh-frame.c) for foo.so?  If I use --traditional-format to avoid eh_frame
> editing then I see both foo.so and bar.so with the same size eh_frame.

/* ('m' for map) Format info message and print on map.  */

void
minfo (const char *fmt, ...)
{
  if (config.map_file != NULL)
    {   

Since I didn't use -M map, there was no linker message.
Comment 3 Alan Modra 2017-08-12 23:15:57 UTC
My point was that elf-eh-frame.c discards the zero range FDE, and foo.so ends up with an empty .eh_frame.  Which is not what you reported.
Comment 4 Alan Modra 2017-08-12 23:21:45 UTC
Also, your foo.eh shows a range of 1 for the FDE.  How did that happen?
Comment 5 H.J. Lu 2017-08-13 00:51:43 UTC
(In reply to Alan Modra from comment #4)
> Also, your foo.eh shows a range of 1 for the FDE.  How did that happen?

foo.so and bar.so have very similar contents.
Both are built from foo.o and bar.o, but with
different orders.
Comment 6 Alan Modra 2017-08-13 01:06:56 UTC
Silly me.  I didn't follow the recipe, just build foo.so from foo.o and bar.so from bar.o.
Comment 7 Alan Modra 2017-08-16 08:27:35 UTC
The master branch has been updated by Alan Modra <address@hidden>:

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

commit 79a94a2ad1e6e2f227de07427481e4bb8be84504
Author: Alan Modra <address@hidden>
Date:   Mon Aug 14 09:25:17 2017 +0930

    PR21441, Unnecessary padding of .eh_frame section

    Until all .eh_frame sections have been edited we don't know their
    sizes.  So it isn't possible to properly decide whether a non-empty
    .eh_frame section follows a given section until editing is complete.

    bfd/
        PR 21441
        * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't add
        alignment padding here.
        * elflink.c (bfd_elf_discard_info): Add .eh_frame padding here
        in a reverse pass over sections.
    ld/
        PR 21441
        * testsuite/ld-x86-64/pr21038a.d: Adjust.
        * testsuite/ld-x86-64/pr21038a-now.d: Adjust.
Comment 8 Sourceware Commits 2017-08-31 03:58:27 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit af471f828cc74d65b50a7531ba2c69522266cfe9
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Aug 31 12:48:37 2017 +0930

    PR22048, Incorrect .eh_frame section in libc.so
    
    	PR 21441
    	PR 22048
    	* elflink.c (bfd_elf_discard_info): Don't pad embedded zero
    	terminators.
Comment 9 Sourceware Commits 2017-09-04 16:30:55 UTC
The binutils-2_29-branch branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit 35e01275b59ac867d342379d457e732b5acda6a3
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Sep 4 17:28:17 2017 +0100

    Import patch from mainline to improve padding of .eh_frame sections.
    
    	PR 21441
    bfd	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't add
    	alignment padding here.
    	* elflink.c (bfd_elf_discard_info): Add .eh_frame padding here
    	in a reverse pass over sections.
    
    ld	* testsuite/ld-elf/eh3.d: Update.
    	* testsuite/ld-elf/eh4.d: Update.
    	PR 21441
    	* testsuite/ld-x86-64/pr21038a.d: Adjust.
    	* testsuite/ld-x86-64/pr21038a-now.d: Adjust.
Comment 10 Sourceware Commits 2017-09-19 05:08:32 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 25516cc573ff3551a7ac0538e1d3de5811c7199e
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Sep 19 13:22:49 2017 +0930

    PowerPC64 stubs don't match calculated size
    
    After the PR 21411 fix, the linker generated .eh_frame for ppc64 glink
    can be edited by the generic code.  The sequence of events goes
    something like:
    1) Some object file adds .eh_frame aligned to 8, making the output
       .eh_frame aligned to at least 8, so linker generated .eh_frame FDE
       is padded to an 8 byte boundary.
    2) All .eh_frame past the glink .eh_frame is garbage collected.
    3) Generic code detects that last FDE (the glink .eh_frame) doesn't
       need to be padded to an 8 byte boundary, reducing size from 88 to
       84.
    4) elf64-ppc.c check fails.
    
    	PR 21441
    	* elf64-ppc.c (ppc64_elf_build_stubs): Don't check glink_eh_frame
    	size.
Comment 11 Sourceware Commits 2017-09-19 07:15:18 UTC
The binutils-2_29-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 8fd7cca5b0ed5a2f2099428586359f5cdff2063d
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Aug 14 09:25:17 2017 +0930

    PR21441, Unnecessary padding of .eh_frame section
    
    Until all .eh_frame sections have been edited we don't know their
    sizes.  So it isn't possible to properly decide whether a non-empty
    .eh_frame section follows a given section until editing is complete.
    
    bfd/
    	PR 21441
    	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't add
    	alignment padding here.
    	* elflink.c (bfd_elf_discard_info): Add .eh_frame padding here
    	in a reverse pass over sections.
    ld/
    	PR 21441
    	* testsuite/ld-x86-64/pr21038a.d: Adjust.
    	* testsuite/ld-x86-64/pr21038a-now.d: Adjust.
    
    (cherry picked from commit 79a94a2ad1e6e2f227de07427481e4bb8be84504)
Comment 12 Sourceware Commits 2017-09-19 07:15:19 UTC
The binutils-2_29-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 3bf3f89d9d6f3a09def722d010695c35bffb4a48
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Aug 31 12:48:37 2017 +0930

    PR22048, Incorrect .eh_frame section in libc.so
    
    	PR 21441
    	PR 22048
    	* elflink.c (bfd_elf_discard_info): Don't pad embedded zero
    	terminators.
    
    (cherry picked from commit af471f828cc74d65b50a7531ba2c69522266cfe9)
Comment 13 Sourceware Commits 2017-09-19 07:15:59 UTC
The binutils-2_29-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 910201669dca1cb57c583e0d63d1369388a3375d
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Sep 19 13:22:49 2017 +0930

    PowerPC64 stubs don't match calculated size
    
    After the PR 21411 fix, the linker generated .eh_frame for ppc64 glink
    can be edited by the generic code.  The sequence of events goes
    something like:
    1) Some object file adds .eh_frame aligned to 8, making the output
       .eh_frame aligned to at least 8, so linker generated .eh_frame FDE
       is padded to an 8 byte boundary.
    2) All .eh_frame past the glink .eh_frame is garbage collected.
    3) Generic code detects that last FDE (the glink .eh_frame) doesn't
       need to be padded to an 8 byte boundary, reducing size from 88 to
       84.
    4) elf64-ppc.c check fails.
    
    	PR 21441
    	* elf64-ppc.c (ppc64_elf_build_stubs): Don't check glink_eh_frame
    	size.
    
    (cherry picked from commit 25516cc573ff3551a7ac0538e1d3de5811c7199e)