]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86-64: Add TLSDESC fields to elf_x86_lazy_plt_layout
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 28 May 2018 17:46:16 +0000 (10:46 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 28 May 2018 17:46:16 +0000 (10:46 -0700)
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.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elfxx-x86.h

index f190b9f3be042725e5d47fc58a7598cdf8f8afeb..5e1724b5f27013a803966968d37f8618acdba6ed 100644 (file)
@@ -1,3 +1,32 @@
+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
index 3dd709a10e446c06fa131cf15fbf97b4d0207306..49797dcbfaffd335a326e50a068dd456b74ad78d 100644 (file)
@@ -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 */
index e5a4dbcd519286f758626410e934b5c52836b592..4349561f3c313c300eb740742fcffc4c802139f3 100644 (file)
@@ -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 */
index 8f67c23a9fe40dfdec267f51effea91a91baf255..6a5609467d5e5c031264db7cc1cf563eb06e1ee6 100644 (file)
@@ -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;