This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] PR21441, Unnecessary padding of .eh_frame section


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

commit 79a94a2ad1e6e2f227de07427481e4bb8be84504
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.

Diff:
---
 bfd/ChangeLog                         |  8 ++++++++
 bfd/elf-eh-frame.c                    |  9 ---------
 bfd/elflink.c                         | 29 +++++++++++++++++++++++++++++
 ld/ChangeLog                          |  6 ++++++
 ld/testsuite/ld-x86-64/pr21038a-now.d |  6 +-----
 ld/testsuite/ld-x86-64/pr21038a.d     |  6 +-----
 6 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 356d19b..876461e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2017-08-14  Alan Modra  <amodra@gmail.com>
+
+	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.
+
 2017-08-11  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR binutils/21943
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 52ba9c6..7e0d63f 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -1594,16 +1594,7 @@ _bfd_elf_discard_section_eh_frame
 	offset += size_of_output_cie_fde (ent);
       }
 
-  /* Pad the last FDE out to the output section alignment if there are
-     following sections, in order to ensure no padding between this
-     section and the next.  (Relies on the output section alignment
-     being the maximum of all input sections alignments, which is the
-     case unless someone is overriding alignment via scripts.)  */
   eh_alignment = 4;
-  if (sec->map_head.s != NULL
-      && (sec->map_head.s->size != 4
-	  || sec->map_head.s->map_head.s != NULL))
-    eh_alignment = 1 << sec->output_section->alignment_power;
   offset = (offset + eh_alignment - 1) & -eh_alignment;
   sec->rawsize = sec->size;
   sec->size = offset;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 424de21..f9886dc 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13836,6 +13836,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
     {
       asection *i;
       int eh_changed = 0;
+      unsigned int eh_alignment;
 
       for (i = o->map_head.s; i != NULL; i = i->map_head.s)
 	{
@@ -13861,6 +13862,34 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 
 	  fini_reloc_cookie_for_section (&cookie, i);
 	}
+      eh_alignment = 1 << o->alignment_power;
+      if (eh_alignment > 4)
+	{
+	  /* Skip over zero terminator, and prevent empty sections
+	     from adding alignment padding at the end.  */
+	  for (i = o->map_tail.s; i != NULL; i = i->map_tail.s)
+	    if (i->size == 0)
+	      i->flags |= SEC_EXCLUDE;
+	    else if (i->size > 4)
+	      break;
+	  /* The last non-empty eh_frame section doesn't need padding.  */
+	  if (i != NULL)
+	    i = i->map_tail.s;
+	  /* Any prior sections must pad the last FDE out to the
+	     output section alignment.  Otherwise we might have zero
+	     padding between sections, which would be seen as a
+	     terminator.  */
+	  for (; i != NULL; i = i->map_tail.s)
+	    {
+	      bfd_size_type size = (i->size + eh_alignment - 1) & -eh_alignment;
+	      if (i->size != size)
+		{
+		  i->size = size;
+		  changed = 1;
+		  eh_changed = 1;
+		}
+	    }
+	}
       if (eh_changed)
 	elf_link_hash_traverse (elf_hash_table (info),
 				_bfd_elf_adjust_eh_frame_global_symbol, NULL);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index aad3249..1b0746a 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,9 @@
+2017-08-14  Alan Modra  <amodra@gmail.com>
+
+	PR 21441
+	* testsuite/ld-x86-64/pr21038a.d: Adjust.
+	* testsuite/ld-x86-64/pr21038a-now.d: Adjust.
+
 2017-08-13  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* testsuite/ld-i386/i386.exp: Run pr21884-nacl.
diff --git a/ld/testsuite/ld-x86-64/pr21038a-now.d b/ld/testsuite/ld-x86-64/pr21038a-now.d
index fb4ad8f..1d5bec1 100644
--- a/ld/testsuite/ld-x86-64/pr21038a-now.d
+++ b/ld/testsuite/ld-x86-64/pr21038a-now.d
@@ -41,11 +41,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
diff --git a/ld/testsuite/ld-x86-64/pr21038a.d b/ld/testsuite/ld-x86-64/pr21038a.d
index 2ed962a..01770ec 100644
--- a/ld/testsuite/ld-x86-64/pr21038a.d
+++ b/ld/testsuite/ld-x86-64/pr21038a.d
@@ -40,11 +40,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
+0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]