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/binutils-2_29-branch] Import patch from mainline to improve padding of .eh_frame sections.


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.

Diff:
---
 bfd/ChangeLog                         |  6 ++++++
 bfd/elf-eh-frame.c                    | 31 +++++++++----------------------
 bfd/elflink.c                         | 32 ++++++++++++++++++++++++++++++++
 ld/ChangeLog                          | 11 +++++++++++
 ld/testsuite/ld-elf/eh3.d             | 12 ++----------
 ld/testsuite/ld-elf/eh4.d             |  4 +---
 ld/testsuite/ld-x86-64/pr21038a-now.d |  8 ++------
 ld/testsuite/ld-x86-64/pr21038a.d     |  8 ++------
 8 files changed, 65 insertions(+), 47 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 226aea9..db9d0a9 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -60,6 +60,12 @@
 	(elfcore_grok_freebsd_prstatus): Add checks to make sure that
 	there is enough data present in the note.
 
+	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-09-04  Alan Modra  <amodra@gmail.com>
 
 	PR 22067
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 52ba9c6..cd81b60 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -619,15 +619,6 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
 
   REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
 
-  if (sec->size >= 4
-      && bfd_get_32 (abfd, ehbuf) == 0
-      && cookie->rel == cookie->relend)
-    {
-      /* Empty .eh_frame section.  */
-      free (ehbuf);
-      return;
-    }
-
   /* If .eh_frame section size doesn't fit into int, we cannot handle
      it (it would need to use 64-bit .eh_frame format anyway).  */
   REQUIRE (sec->size == (unsigned int) sec->size);
@@ -669,8 +660,11 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
   REQUIRE (sec_info);
 
   /* We need to have a "struct cie" for each CIE in this section.  */
-  local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
-  REQUIRE (local_cies);
+  if (num_cies)
+    {
+      local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
+      REQUIRE (local_cies);
+    }
 
   /* FIXME: octets_per_byte.  */
 #define ENSURE_NO_RELOCS(buf)				\
@@ -724,7 +718,9 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
       if (hdr_length == 0)
 	{
 	  /* A zero-length CIE should only be found at the end of
-	     the section.  */
+	     the section, but allow multiple terminators.  */
+	  while (skip_bytes (&buf, ehbuf + sec->size, 4))
+	    REQUIRE (bfd_get_32 (abfd, buf - 4) == 0);
 	  REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
 	  ENSURE_NO_RELOCS (buf);
 	  sec_info->count++;
@@ -1339,7 +1335,7 @@ offset_adjust (bfd_vma offset, const asection *sec)
   struct eh_frame_sec_info *sec_info
     = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
   unsigned int lo, hi, mid;
-  struct eh_cie_fde *ent;
+  struct eh_cie_fde *ent = NULL;
   bfd_signed_vma delta;
 
   lo = 0;
@@ -1594,16 +1590,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 736fb4c..301cf03 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13831,6 +13831,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)
 	{
@@ -13856,6 +13857,37 @@ 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;
+      /* 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)
+	if (i->size == 4)
+	  /* All but the last zero terminator should have been removed.  */
+	  BFD_FAIL ();
+	else
+	  {
+	    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 24d0ed2..e8ee459 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,14 @@
+2017-09-04  Nick Clifton  <nickc@redhat.com>
+
+	Import from mainline:
+
+	* 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.
+
 2017-09-01  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/22064
diff --git a/ld/testsuite/ld-elf/eh3.d b/ld/testsuite/ld-elf/eh3.d
index 3811341..6ac584a 100644
--- a/ld/testsuite/ld-elf/eh3.d
+++ b/ld/testsuite/ld-elf/eh3.d
@@ -23,20 +23,12 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+0018 0+0024 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
+0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
   DW_CFA_advance_loc: 8 to 0+400080
   DW_CFA_def_cfa_offset: 16
   DW_CFA_offset: r6 \(rbp\) at cfa-16
   DW_CFA_advance_loc: 8 to 0+400088
   DW_CFA_def_cfa_register: r6 \(rbp\)
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
-  DW_CFA_nop
 
-0+0040 ZERO terminator
+0+0038 ZERO terminator
 #pass
diff --git a/ld/testsuite/ld-elf/eh4.d b/ld/testsuite/ld-elf/eh4.d
index b5eec2f..6c1cb32 100644
--- a/ld/testsuite/ld-elf/eh4.d
+++ b/ld/testsuite/ld-elf/eh4.d
@@ -28,14 +28,12 @@ Contents of the .eh_frame section:
   DW_CFA_set_loc: 0+0417
   DW_CFA_def_cfa_offset: 80
 
-0+0048 0+0024 0+004c FDE cie=0+0000 pc=[0-9a-f]+\.\.[0-9a-f]+
+0+0048 0+002[04] 0+004c FDE cie=0+0000 pc=[0-9a-f]+\.\.[0-9a-f]+
   DW_CFA_def_cfa_offset: 16
   DW_CFA_advance_loc: [0-9a-f]+ to [0-9a-f]+
   DW_CFA_def_cfa_offset: 24
   DW_CFA_advance_loc: [0-9a-f]+ to [0-9a-f]+
   DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0;.*
-  DW_CFA_nop
 #...
-
 [0-9a-f]+ ZERO terminator
 #pass
diff --git a/ld/testsuite/ld-x86-64/pr21038a-now.d b/ld/testsuite/ld-x86-64/pr21038a-now.d
index ebc5128..1d5bec1 100644
--- a/ld/testsuite/ld-x86-64/pr21038a-now.d
+++ b/ld/testsuite/ld-x86-64/pr21038a-now.d
@@ -1,7 +1,7 @@
 #name: PR ld/21038 (.plt.got, -z now)
 #source: pr21038a.s
 #as: --64
-#ld: -z now -z bndplt -melf_x86_64 -shared -z relro --ld-generated-unwind-info
+#ld: -z now -z bndplt -melf_x86_64 -shared -z relro --ld-generated-unwind-info --hash-style=sysv
 #objdump: -dw -Wf
 
 .*: +file format .*
@@ -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 81b26cb..01770ec 100644
--- a/ld/testsuite/ld-x86-64/pr21038a.d
+++ b/ld/testsuite/ld-x86-64/pr21038a.d
@@ -1,6 +1,6 @@
 #name: PR ld/21038 (.plt.got)
 #as: --64
-#ld: -z bndplt -melf_x86_64 -shared -z relro --ld-generated-unwind-info
+#ld: -z bndplt -melf_x86_64 -shared -z relro --ld-generated-unwind-info --hash-style=sysv
 #objdump: -dw -Wf
 
 .*: +file format .*
@@ -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]