[binutils-gdb/binutils-2_30-branch] x86-64: Add TLSDESC fields to elf_x86_lazy_plt_layout
H.J.Lu
hjl@sourceware.org
Mon May 28 18:16:00 GMT 2018
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=32647affe56d7e2d611f474f241bb3b33ef66cfb
commit 32647affe56d7e2d611f474f241bb3b33ef66cfb
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.
(cherry picked from commit 92e68c1d65f844c0027f471a0c9e1722d781ef7d)
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 e7193e7..8a69c09 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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-22 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/23199
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 20e4c74..0c6d2e7 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -762,6 +762,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 */
@@ -794,6 +800,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 */
@@ -4715,6 +4727,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 a3feddb..619f402 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -656,6 +656,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[] =
@@ -830,6 +838,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 */
@@ -862,6 +876,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 */
@@ -894,6 +914,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 */
@@ -915,6 +941,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 */
@@ -4400,19 +4432,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
@@ -4424,10 +4449,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. */
@@ -4438,9 +4463,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));
}
}
@@ -5222,6 +5248,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 a7bd49e..2f49901 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -281,16 +281,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;
@@ -332,10 +346,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. */
@@ -354,9 +369,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