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] Remove .eh_frame zero terminators


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

commit 8deff86b8c66a2f2e7792d99748e6c40911e02f2
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Aug 31 19:39:14 2017 +0930

    Remove .eh_frame zero terminators
    
    The machinery to do this was there, but not enabled if the terminator
    was the only thing in the section.
    
    bfd/
    	* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Don't exit early
    	for a section containing just a terminator.  Allow multiple
    	terminators at end of section.
    	* elflink.c (bfd_elf_discard_info): Iterate over .eh_frame
    	sections when not adding alignment.  Assert on terminator in
    	the middle of FDEs.
    ld/
    	* testsuite/ld-elf/eh3.d: Update.
    	* testsuite/ld-elf/eh4.d: Update.
    
    (cherry picked from commit 9866ffe25a0fe73f5153f2720650baf0dd9cc828)

Diff:
---
 bfd/ChangeLog             |  9 ++++++++
 bfd/elf-eh-frame.c        | 20 +++++++----------
 bfd/elflink.c             | 57 ++++++++++++++++++++++-------------------------
 ld/ChangeLog              |  5 +++++
 ld/testsuite/ld-elf/eh3.d | 12 ++--------
 ld/testsuite/ld-elf/eh4.d |  4 +---
 6 files changed, 52 insertions(+), 55 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 268f187..6dce8cc 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,14 @@
 2017-08-31  Alan Modra  <amodra@gmail.com>
 
+	* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Don't exit early
+	for a section containing just a terminator.  Allow multiple
+	terminators at end of section.
+	* elflink.c (bfd_elf_discard_info): Iterate over .eh_frame
+	sections when not adding alignment.  Assert on terminator in
+	the middle of FDEs.
+
+2017-08-31  Alan Modra  <amodra@gmail.com>
+
 	PR 21441
 	PR 22048
 	* elflink.c (bfd_elf_discard_info): Don't pad embedded zero
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 7e0d63f..f0ede2d 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++;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index d02aff9..e852762 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13857,39 +13857,36 @@ 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.  If there is a terminator in the middle of
-	     FDEs, don't increase its size as that will write bogus
-	     data of whatever was after the terminator in the input
-	     file, to the output file.  */
-	  for (; i != NULL; i = i->map_tail.s)
-	    if (i->size != 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)
+	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)
 	      {
-		bfd_size_type size
-		  = (i->size + eh_alignment - 1) & -eh_alignment;
-		if (i->size != size)
-		  {
-		    i->size = size;
-		    changed = 1;
-		    eh_changed = 1;
-		  }
+		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 56ce18b..65641fc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2017-08-31  Alan Modra  <amodra@gmail.com>
+
+	* testsuite/ld-elf/eh3.d: Update.
+	* testsuite/ld-elf/eh4.d: Update.
+
 2017-08-14  Alan Modra  <amodra@gmail.com>
 
 	PR 21441
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


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