[binutils-gdb] x86-64: Add TLSDESC fields to elf_x86_lazy_plt_layout

H.J.Lu hjl@sourceware.org
Mon May 28 17:56:00 GMT 2018


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

commit 92e68c1d65f844c0027f471a0c9e1722d781ef7d
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon May 28 10:46:16 2018 -0700

    x86-64: Add TLSDESC fields to elf_x86_lazy_plt_layout
    
    ENDBR64 is added to the special TLSDESC entry, which is similar to the
    PLT0 entry, in the x86-64 lazy procedure linkage table to support Intel
    CET.  The NaCl PLT is different from the normal PLT.  This patch adds
    plt_tlsdesc_entry, plt_tlsdesc_entry_size, plt_tlsdesc_got1_offset,
    plt_tlsdesc_got2_offset, plt_tlsdesc_got1_insn_end and
    plt_tlsdesc_got2_insn_end to elf_x86_lazy_plt_layout to support both
    normal and NaCl TLSDESC entries.  This fixed
    
    FAIL: TLS descriptor -fpic -shared transitions
    
    for x86_64-nacl.
    
    	* elf32-i386.c (elf_i386_lazy_plt): Add plt_tlsdesc_entry,
    	plt_tlsdesc_entry_size, plt_tlsdesc_got1_offset,
    	plt_tlsdesc_got2_offset, plt_tlsdesc_got1_insn_end and
    	plt_tlsdesc_got2_insn_end for TLSDESC entry.
    	(elf_i386_lazy_ibt_plt): Likewise.
    	(elf_i386_nacl_plt): Likewise.
    	* elf64-x86-64.c (tlsdesc_plt_entry): Moved and renamed to ...
    	(elf_x86_64_tlsdesc_plt_entry): This.
    	(elf_x86_64_lazy_plt): Add plt_tlsdesc_entry,
    	plt_tlsdesc_entry_size, plt_tlsdesc_got1_offset,
    	plt_tlsdesc_got2_offset, plt_tlsdesc_got1_insn_end and
    	plt_tlsdesc_got2_insn_end for TLSDESC entry.
    	(elf_x86_64_lazy_bnd_plt): Likewise.
    	(elf_x86_64_lazy_ibt_plt): Likewise.
    	(elf_x32_lazy_ibt_plt): Likewise.
    	(elf_x86_64_nacl_plt): Likewise.
    	(elf_x86_64_finish_dynamic_sections): Use plt_tlsdesc_entry,
    	plt_tlsdesc_entry_size, plt_tlsdesc_got1_offset,
    	plt_tlsdesc_got2_offset, plt_tlsdesc_got1_insn_end and
    	plt_tlsdesc_got2_insn_end to update TLSDESC entry.
    	* elfxx-x86.h (elf_x86_lazy_plt_layout): Update comments.
    	Add plt_tlsdesc_entry, plt_tlsdesc_entry_size,
    	plt_tlsdesc_got1_offset, plt_tlsdesc_got2_offset,
    	plt_tlsdesc_got1_insn_end and plt_tlsdesc_got2_insn_end.
    	(elf_x86_non_lazy_plt_layout): Update comments.
    	(elf_x86_plt_layout): Likewise.

Diff:
---
 bfd/ChangeLog      | 29 +++++++++++++++++++++++++++
 bfd/elf32-i386.c   | 18 +++++++++++++++++
 bfd/elf64-x86-64.c | 58 ++++++++++++++++++++++++++++++++++++++++++------------
 bfd/elfxx-x86.h    | 33 +++++++++++++++++++++----------
 4 files changed, 115 insertions(+), 23 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f190b9f..5e1724b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,34 @@
 2018-05-28  H.J. Lu  <hongjiu.lu@intel.com>
 
+	* elf32-i386.c (elf_i386_lazy_plt): Add plt_tlsdesc_entry,
+	plt_tlsdesc_entry_size, plt_tlsdesc_got1_offset,
+	plt_tlsdesc_got2_offset, plt_tlsdesc_got1_insn_end and
+	plt_tlsdesc_got2_insn_end for TLSDESC entry.
+	(elf_i386_lazy_ibt_plt): Likewise.
+	(elf_i386_nacl_plt): Likewise.
+	* elf64-x86-64.c (tlsdesc_plt_entry): Moved and renamed to ...
+	(elf_x86_64_tlsdesc_plt_entry): This.
+	(elf_x86_64_lazy_plt): Add plt_tlsdesc_entry,
+	plt_tlsdesc_entry_size, plt_tlsdesc_got1_offset,
+	plt_tlsdesc_got2_offset, plt_tlsdesc_got1_insn_end and
+	plt_tlsdesc_got2_insn_end for TLSDESC entry.
+	(elf_x86_64_lazy_bnd_plt): Likewise.
+	(elf_x86_64_lazy_ibt_plt): Likewise.
+	(elf_x32_lazy_ibt_plt): Likewise.
+	(elf_x86_64_nacl_plt): Likewise.
+	(elf_x86_64_finish_dynamic_sections): Use plt_tlsdesc_entry,
+	plt_tlsdesc_entry_size, plt_tlsdesc_got1_offset,
+	plt_tlsdesc_got2_offset, plt_tlsdesc_got1_insn_end and
+	plt_tlsdesc_got2_insn_end to update TLSDESC entry.
+	* elfxx-x86.h (elf_x86_lazy_plt_layout): Update comments.
+	Add plt_tlsdesc_entry, plt_tlsdesc_entry_size,
+	plt_tlsdesc_got1_offset, plt_tlsdesc_got2_offset,
+	plt_tlsdesc_got1_insn_end and plt_tlsdesc_got2_insn_end.
+	(elf_x86_non_lazy_plt_layout): Update comments.
+	(elf_x86_plt_layout): Likewise.
+
+2018-05-28  H.J. Lu  <hongjiu.lu@intel.com>
+
 	PR ld/23238
 	* elf-s390-common.c (elf_s390_add_symbol_hook): Removed.
 	* elf32-arc.c (elf_arc_add_symbol_hook): Likewise.
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 3dd709a..49797dc 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -766,6 +766,12 @@ static const struct elf_x86_lazy_plt_layout elf_i386_lazy_plt =
     sizeof (elf_i386_lazy_plt0_entry),	/* plt0_entry_size */
     elf_i386_lazy_plt_entry,		/* plt_entry */
     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    NULL,				/* plt_tlsdesc_entry */
+    0,					/* plt_tlsdesc_entry_size*/
+    0,					/* plt_tlsdesc_got1_offset */
+    0,					/* plt_tlsdesc_got2_offset */
+    0,					/* plt_tlsdesc_got1_insn_end */
+    0,					/* plt_tlsdesc_got2_insn_end */
     2,					/* plt0_got1_offset */
     8,					/* plt0_got2_offset */
     0,					/* plt0_got2_insn_end */
@@ -798,6 +804,12 @@ static const struct elf_x86_lazy_plt_layout elf_i386_lazy_ibt_plt =
     sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */
     elf_i386_lazy_ibt_plt_entry,	/* plt_entry */
     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    NULL,				/* plt_tlsdesc_entry */
+    0,					/* plt_tlsdesc_entry_size*/
+    0,					/* plt_tlsdesc_got1_offset */
+    0,					/* plt_tlsdesc_got2_offset */
+    0,					/* plt_tlsdesc_got1_insn_end */
+    0,					/* plt_tlsdesc_got2_insn_end */
     2,					/* plt0_got1_offset */
     8,					/* plt0_got2_offset */
     0,					/* plt0_got2_insn_end */
@@ -4728,6 +4740,12 @@ static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt =
     sizeof (elf_i386_nacl_plt0_entry),	/* plt0_entry_size */
     elf_i386_nacl_plt_entry,		/* plt_entry */
     NACL_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    NULL,				/* plt_tlsdesc_entry */
+    0,					/* plt_tlsdesc_entry_size*/
+    0,					/* plt_tlsdesc_got1_offset */
+    0,					/* plt_tlsdesc_got2_offset */
+    0,					/* plt_tlsdesc_got1_insn_end */
+    0,					/* plt_tlsdesc_got2_insn_end */
     2,					/* plt0_got1_offset */
     8,					/* plt0_got2_offset */
     0,					/* plt0_got2_insn_end */
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index e5a4dbc..4349561 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -660,6 +660,14 @@ static const bfd_byte elf_x32_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
   0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1)  */
 };
 
+/* The TLSDESC entry in a lazy procedure linkage table.  */
+static const bfd_byte elf_x86_64_tlsdesc_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+  0xf3, 0x0f, 0x1e, 0xfa,	     /* endbr64		       */
+  0xff, 0x35, 8, 0, 0, 0,	     /* pushq GOT+8(%rip)	*/
+  0xff, 0x25, 16, 0, 0, 0	     /* jmpq *GOT+TDG(%rip)	*/
+};
+
 /* .eh_frame covering the lazy .plt section.  */
 
 static const bfd_byte elf_x86_64_eh_frame_lazy_plt[] =
@@ -834,6 +842,12 @@ static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt =
     LAZY_PLT_ENTRY_SIZE,		/* plt0_entry_size */
     elf_x86_64_lazy_plt_entry,		/* plt_entry */
     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    elf_x86_64_tlsdesc_plt_entry,	/* plt_tlsdesc_entry */
+    LAZY_PLT_ENTRY_SIZE,		/* plt_tlsdesc_entry_size */
+    6,					/* plt_tlsdesc_got1_offset */
+    12,					/* plt_tlsdesc_got2_offset */
+    10,					/* plt_tlsdesc_got1_insn_end */
+    16,					/* plt_tlsdesc_got2_insn_end */
     2,					/* plt0_got1_offset */
     8,					/* plt0_got2_offset */
     12,					/* plt0_got2_insn_end */
@@ -866,6 +880,12 @@ static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt =
     LAZY_PLT_ENTRY_SIZE,		/* plt0_entry_size */
     elf_x86_64_lazy_bnd_plt_entry,	/* plt_entry */
     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    elf_x86_64_tlsdesc_plt_entry,	/* plt_tlsdesc_entry */
+    LAZY_PLT_ENTRY_SIZE,		/* plt_tlsdesc_entry_size */
+    6,					/* plt_tlsdesc_got1_offset */
+    12,					/* plt_tlsdesc_got2_offset */
+    10,					/* plt_tlsdesc_got1_insn_end */
+    16,					/* plt_tlsdesc_got2_insn_end */
     2,					/* plt0_got1_offset */
     1+8,				/* plt0_got2_offset */
     1+12,				/* plt0_got2_insn_end */
@@ -898,6 +918,12 @@ static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt =
     LAZY_PLT_ENTRY_SIZE,		/* plt0_entry_size */
     elf_x86_64_lazy_ibt_plt_entry,	/* plt_entry */
     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    elf_x86_64_tlsdesc_plt_entry,	/* plt_tlsdesc_entry */
+    LAZY_PLT_ENTRY_SIZE,		/* plt_tlsdesc_entry_size */
+    6,					/* plt_tlsdesc_got1_offset */
+    12,					/* plt_tlsdesc_got2_offset */
+    10,					/* plt_tlsdesc_got1_insn_end */
+    16,					/* plt_tlsdesc_got2_insn_end */
     2,					/* plt0_got1_offset */
     1+8,				/* plt0_got2_offset */
     1+12,				/* plt0_got2_insn_end */
@@ -919,6 +945,12 @@ static const struct elf_x86_lazy_plt_layout elf_x32_lazy_ibt_plt =
     LAZY_PLT_ENTRY_SIZE,		/* plt0_entry_size */
     elf_x32_lazy_ibt_plt_entry,		/* plt_entry */
     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    elf_x86_64_tlsdesc_plt_entry,	/* plt_tlsdesc_entry */
+    LAZY_PLT_ENTRY_SIZE,		/* plt_tlsdesc_entry_size */
+    6,					/* plt_tlsdesc_got1_offset */
+    12,					/* plt_tlsdesc_got2_offset */
+    10,					/* plt_tlsdesc_got1_insn_end */
+    16,					/* plt_tlsdesc_got2_insn_end */
     2,					/* plt0_got1_offset */
     8,					/* plt0_got2_offset */
     12,					/* plt0_got2_insn_end */
@@ -4417,19 +4449,12 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
 
       if (htab->tlsdesc_plt)
 	{
-	  /* The TLSDESC entry in a lazy procedure linkage table.  */
-	  static const bfd_byte tlsdesc_plt_entry[LAZY_PLT_ENTRY_SIZE] =
-	    {
-	      0xf3, 0x0f, 0x1e, 0xfa,	/* endbr64		*/
-	      0xff, 0x35, 8, 0, 0, 0,	/* pushq GOT+8(%rip)	*/
-	      0xff, 0x25, 16, 0, 0, 0	/* jmpq *GOT+TDG(%rip)	*/
-	    };
-
 	  bfd_put_64 (output_bfd, (bfd_vma) 0,
 		      htab->elf.sgot->contents + htab->tlsdesc_got);
 
 	  memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
-		  tlsdesc_plt_entry, LAZY_PLT_ENTRY_SIZE);
+		  htab->lazy_plt->plt_tlsdesc_entry,
+		  htab->lazy_plt->plt_tlsdesc_entry_size);
 
 	  /* Add offset for pushq GOT+8(%rip), since ENDBR64 uses 4
 	     bytes and the instruction uses 6 bytes, subtract these
@@ -4441,10 +4466,10 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
 		       - htab->elf.splt->output_section->vma
 		       - htab->elf.splt->output_offset
 		       - htab->tlsdesc_plt
-		       - 4 - 6),
+		       - htab->lazy_plt->plt_tlsdesc_got1_insn_end),
 		      (htab->elf.splt->contents
 		       + htab->tlsdesc_plt
-		       + 4 + 2));
+		       + htab->lazy_plt->plt_tlsdesc_got1_offset));
 	  /* Add offset for indirect branch via GOT+TDG, where TDG
 	     stands for htab->tlsdesc_got, subtracting the offset
 	     to the end of that instruction.  */
@@ -4455,9 +4480,10 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
 		       - htab->elf.splt->output_section->vma
 		       - htab->elf.splt->output_offset
 		       - htab->tlsdesc_plt
-		       - 4 - 6 - 6),
+		       - htab->lazy_plt->plt_tlsdesc_got2_insn_end),
 		      (htab->elf.splt->contents
-		       + htab->tlsdesc_plt + 4 + 6 + 2));
+		       + htab->tlsdesc_plt
+		       + htab->lazy_plt->plt_tlsdesc_got2_offset));
 	}
     }
 
@@ -5246,6 +5272,12 @@ static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt =
     NACL_PLT_ENTRY_SIZE,		     /* plt0_entry_size */
     elf_x86_64_nacl_plt_entry,		     /* plt_entry */
     NACL_PLT_ENTRY_SIZE,		     /* plt_entry_size */
+    elf_x86_64_nacl_plt0_entry,		     /* plt_tlsdesc_entry */
+    NACL_PLT_ENTRY_SIZE,		     /* plt_tlsdesc_entry_size */
+    2,					     /* plt_tlsdesc_got1_offset */
+    9,					     /* plt_tlsdesc_got2_offset */
+    6,					     /* plt_tlsdesc_got1_insn_end */
+    13,					     /* plt_tlsdesc_got2_insn_end */
     2,					     /* plt0_got1_offset */
     9,					     /* plt0_got2_offset */
     13,					     /* plt0_got2_insn_end */
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 8f67c23..6a56094 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -285,16 +285,30 @@ struct elf_x86_link_hash_entry
 
 struct elf_x86_lazy_plt_layout
 {
-  /* The first entry in an absolute lazy procedure linkage table looks
-     like this.  */
+  /* The first entry in a lazy procedure linkage table looks like this.  */
   const bfd_byte *plt0_entry;
   unsigned int plt0_entry_size;		 /* Size of PLT0 entry.  */
 
-  /* Later entries in an absolute lazy procedure linkage table look
-     like this.  */
+  /* Later entries in a lazy procedure linkage table look like this.  */
   const bfd_byte *plt_entry;
   unsigned int plt_entry_size;		/* Size of each PLT entry.  */
 
+  /* The TLSDESC entry in a lazy procedure linkage table looks like
+     this.  This is for x86-64 only.  */
+  const bfd_byte *plt_tlsdesc_entry;
+  unsigned int plt_tlsdesc_entry_size;	 /* Size of TLSDESC entry.  */
+
+  /* Offsets into the TLSDESC entry that are to be replaced with
+     GOT+8 and GOT+TDG.  These are for x86-64 only.  */
+  unsigned int plt_tlsdesc_got1_offset;
+  unsigned int plt_tlsdesc_got2_offset;
+
+  /* Offset of the end of the PC-relative instructions containing
+     plt_tlsdesc_got1_offset and plt_tlsdesc_got2_offset.  These
+     are for x86-64 only.  */
+  unsigned int plt_tlsdesc_got1_insn_end;
+  unsigned int plt_tlsdesc_got2_insn_end;
+
   /* Offsets into plt0_entry that are to be replaced with GOT[1] and
      GOT[2].  */
   unsigned int plt0_got1_offset;
@@ -336,10 +350,11 @@ struct elf_x86_lazy_plt_layout
 
 struct elf_x86_non_lazy_plt_layout
 {
-  /* Entries in an absolute non-lazy procedure linkage table look like
-     this.  */
+  /* Entries in a non-lazy procedure linkage table look like this.  */
   const bfd_byte *plt_entry;
-  /* Entries in a PIC non-lazy procedure linkage table look like this.  */
+  /* Entries in a PIC non-lazy procedure linkage table look like this.
+     This is only used for i386 where absolute PLT and PIC PLT are
+     different.  */
   const bfd_byte *pic_plt_entry;
 
   unsigned int plt_entry_size;		/* Size of each PLT entry.  */
@@ -358,9 +373,7 @@ struct elf_x86_non_lazy_plt_layout
 
 struct elf_x86_plt_layout
 {
-  /* The first entry in a lazy procedure linkage table looks like this.
-     This is only used for i386 where absolute PLT0 and PIC PLT0 are
-     different.  */
+  /* The first entry in a lazy procedure linkage table looks like this.  */
   const bfd_byte *plt0_entry;
   /* Entries in a procedure linkage table look like this.  */
   const bfd_byte *plt_entry;



More information about the Binutils-cvs mailing list