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] ehdr_start twiddles


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

commit 772758ac42a5717d2c2043cc36aa6600c2bfc120
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Aug 24 17:37:53 2018 +0930

    ehdr_start twiddles
    
    We force __ehdr_start to defined in before_allocation, then restore
    the type and a union after dynamic symbols have been allocated.
    The union contains a number of structs, all starting with a "next"
    pointer, and various fields depending on the symbol type.  The old
    code restored the entire union, but it isn't necessary to restore the
    "next" pointer, and in fact it could be wrong if __ehdr_start happened
    to be last on the list and some symbols were added before restoring.
    
    	* emultempl/elf32.em (before_allocation): Don't restore
    	__ehdr_start u.*.next pointer.

Diff:
---
 ld/ChangeLog          |  5 +++++
 ld/emultempl/elf32.em | 28 ++++++++++++++++------------
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 4b33f72..c2d47fd 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-24  Alan Modra  <amodra@gmail.com>
+
+	* emultempl/elf32.em (before_allocation): Don't restore
+	__ehdr_start u.*.next pointer.
+
 2018-08-23  Alan Modra  <amodra@gmail.com>
 
 	PR 23566
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index eac4ba7..ad31a62 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1689,12 +1689,11 @@ gld${EMULATION_NAME}_before_allocation (void)
   const char *rpath;
   asection *sinterp;
   bfd *abfd;
-  struct elf_link_hash_entry *ehdr_start = NULL;
-  struct bfd_link_hash_entry ehdr_start_save;
+  struct bfd_link_hash_entry *ehdr_start = NULL;
+  unsigned char ehdr_start_save_type = 0;
+  char ehdr_start_save_u[sizeof ehdr_start->u
+			 - sizeof ehdr_start->u.def.next] = "";
 
-  /* The memset is here only to silence brain-dead compiler warnings
-     that the variable may be used uninitialized.  */
-  memset (&ehdr_start_save, 0, sizeof ehdr_start_save);
   if (is_elf_hash_table (link_info.hash))
     {
       _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
@@ -1725,11 +1724,14 @@ gld${EMULATION_NAME}_before_allocation (void)
 		 we most likely will need dynamic relocations for
 		 __ehdr_start if we are building a PIE or shared
 		 library.  */
-	      ehdr_start = h;
-	      ehdr_start_save = h->root;
-	      h->root.type = bfd_link_hash_defined;
-	      h->root.u.def.section = bfd_abs_section_ptr;
-	      h->root.u.def.value = 0;
+	      ehdr_start = &h->root;
+	      ehdr_start_save_type = ehdr_start->type;
+	      memcpy (ehdr_start_save_u,
+		      (char *) &ehdr_start->u + sizeof ehdr_start->u.def.next,
+		      sizeof ehdr_start_save_u);
+	      ehdr_start->type = bfd_link_hash_defined;
+	      ehdr_start->u.def.section = bfd_abs_section_ptr;
+	      ehdr_start->u.def.value = 0;
 	    }
 	}
 
@@ -1848,8 +1850,10 @@ ${ELF_INTERPRETER_SET_DEFAULT}
     {
       /* If we twiddled __ehdr_start to defined earlier, put it back
 	 as it was.  */
-      ehdr_start->root.type = ehdr_start_save.type;
-      ehdr_start->root.u = ehdr_start_save.u;
+      ehdr_start->type = ehdr_start_save_type;
+      memcpy ((char *) &ehdr_start->u + sizeof ehdr_start->u.def.next,
+	      ehdr_start_save_u,
+	      sizeof ehdr_start_save_u);
     }
 }


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