aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-03-25 05:02:17 -0700
committerH.J. Lu <hjl.tools@gmail.com>2018-03-25 05:02:32 -0700
commitbf54968b128a2133174d81c438d402ecfaf83042 (patch)
treefadfbd0205867e75b54346add9cb3e22eef3df4b /bfd/elf64-x86-64.c
parentb3ee71e749f3c93c51cd6fb3fed51ffd54243117 (diff)
downloadgdb-bf54968b128a2133174d81c438d402ecfaf83042.zip
gdb-bf54968b128a2133174d81c438d402ecfaf83042.tar.gz
gdb-bf54968b128a2133174d81c438d402ecfaf83042.tar.bz2
x86-64: Add ENDBR64 to the TLSDESC PLT entry
The TLSDESC entry in a lazy procedure linkage table is called indirectly with "callq *(%rax)". This patch adds an ENDBR64 to support indirect branch tracking in Intel CET. The TLSDESC PLT entry now looks like: 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) */ The BND prefix isn't needed since MPX isn't used for TLSDESC. bfd/ PR ld/23000 * elf64-x86-64.c (elf_x86_64_finish_dynamic_sections): Add ENDBR64 to the TLSDESC PLT entry. ld/ PR ld/23000 * testsuite/ld-x86-64/tlsdesc.pd: Updated.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index a964316..fcc8236 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -4411,15 +4411,23 @@ 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,
- htab->lazy_plt->plt0_entry,
- htab->lazy_plt->plt0_entry_size);
+ tlsdesc_plt_entry, LAZY_PLT_ENTRY_SIZE);
- /* Add offset for pushq GOT+8(%rip), since the
- instruction uses 6 bytes subtract this value. */
+ /* Add offset for pushq GOT+8(%rip), since ENDBR64 uses 4
+ bytes and the instruction uses 6 bytes, subtract these
+ values. */
bfd_put_32 (output_bfd,
(htab->elf.sgotplt->output_section->vma
+ htab->elf.sgotplt->output_offset
@@ -4427,14 +4435,13 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
- htab->elf.splt->output_section->vma
- htab->elf.splt->output_offset
- htab->tlsdesc_plt
- - 6),
+ - 4 - 6),
(htab->elf.splt->contents
+ htab->tlsdesc_plt
- + htab->lazy_plt->plt0_got1_offset));
- /* Add offset for the PC-relative instruction accessing
- GOT+TDG, where TDG stands for htab->tlsdesc_got,
- subtracting the offset to the end of that
- instruction. */
+ + 4 + 2));
+ /* Add offset for indirect branch via GOT+TDG, where TDG
+ stands for htab->tlsdesc_got, subtracting the offset
+ to the end of that instruction. */
bfd_put_32 (output_bfd,
(htab->elf.sgot->output_section->vma
+ htab->elf.sgot->output_offset
@@ -4442,10 +4449,9 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
- htab->elf.splt->output_section->vma
- htab->elf.splt->output_offset
- htab->tlsdesc_plt
- - htab->lazy_plt->plt0_got2_insn_end),
+ - 4 - 6 - 6),
(htab->elf.splt->contents
- + htab->tlsdesc_plt
- + htab->lazy_plt->plt0_got2_offset));
+ + htab->tlsdesc_plt + 4 + 6 + 2));
}
}