aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog54
-rw-r--r--bfd/elf32-i386.c556
-rw-r--r--bfd/elf64-x86-64.c454
-rw-r--r--binutils/ChangeLog16
-rw-r--r--binutils/readelf.c38
-rw-r--r--binutils/testsuite/binutils-all/i386/empty.d9
-rw-r--r--binutils/testsuite/binutils-all/i386/empty.s27
-rw-r--r--binutils/testsuite/binutils-all/i386/ibt.d9
-rw-r--r--binutils/testsuite/binutils-all/i386/ibt.s27
-rw-r--r--binutils/testsuite/binutils-all/x86-64/empty-x32.d10
-rw-r--r--binutils/testsuite/binutils-all/x86-64/empty.d9
-rw-r--r--binutils/testsuite/binutils-all/x86-64/empty.s27
-rw-r--r--binutils/testsuite/binutils-all/x86-64/ibt-x32.d10
-rw-r--r--binutils/testsuite/binutils-all/x86-64/ibt.d9
-rw-r--r--binutils/testsuite/binutils-all/x86-64/ibt.s27
-rw-r--r--include/ChangeLog6
-rw-r--r--include/bfdlink.h6
-rw-r--r--include/elf/common.h3
-rw-r--r--ld/ChangeLog79
-rw-r--r--ld/Makefile.am3
-rw-r--r--ld/Makefile.in3
-rw-r--r--ld/NEWS9
-rw-r--r--ld/emulparams/cet.sh14
-rw-r--r--ld/emulparams/elf32_x86_64.sh2
-rw-r--r--ld/emulparams/elf_i386.sh2
-rw-r--r--ld/emulparams/elf_x86_64.sh1
-rw-r--r--ld/ld.texinfo9
-rw-r--r--ld/testsuite/ld-i386/i386.exp78
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-1.d51
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-1.s54
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-2.s54
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-2a.d52
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-2b.d9
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-2c.d52
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-2d.d9
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-3.s38
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-3a.d52
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-3b.d5
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-3c.d52
-rw-r--r--ld/testsuite/ld-i386/ibt-plt-3d.d9
-rw-r--r--ld/testsuite/ld-i386/plt-main-ibt.dd7
-rw-r--r--ld/testsuite/ld-i386/plt-pie-ibt.dd7
-rw-r--r--ld/testsuite/ld-i386/property-x86-empty.s27
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt.s27
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt1a.d6
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt1b.d6
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt2.d9
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt3a.d11
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt3b.d11
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt4.d9
-rw-r--r--ld/testsuite/ld-i386/property-x86-ibt5.d9
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-1-x32.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-1.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-1.s45
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2.s45
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2a.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2b-x32.d9
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2b.d9
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2c-x32.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2c.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2d-x32.d9
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-2d.d9
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3.s17
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3a.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3b-x32.d5
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3b.d5
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3c-x32.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3c.d43
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3d-x32.d10
-rw-r--r--ld/testsuite/ld-x86-64/ibt-plt-3d.d10
-rw-r--r--ld/testsuite/ld-x86-64/plt-main-ibt-now.rd3
-rw-r--r--ld/testsuite/ld-x86-64/plt-main-ibt-x32.dd7
-rw-r--r--ld/testsuite/ld-x86-64/plt-main-ibt.dd7
-rw-r--r--ld/testsuite/ld-x86-64/pr21481b.S4
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-empty.s27
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt.s27
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d6
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt1a.d6
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt1b-x32.d6
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt1b.d6
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt2-x32.d9
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt2.d9
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt3a-x32.d11
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt3a.d11
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt3b-x32.d11
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt3b.d11
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt4-x32.d9
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt4.d9
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt5-x32.d9
-rw-r--r--ld/testsuite/ld-x86-64/property-x86-ibt5.d9
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp182
93 files changed, 2968 insertions, 77 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 57a07a5..ac13db3 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,57 @@
+2017-06-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_lazy_ibt_plt0_entry): New.
+ (elf_i386_lazy_ibt_plt_entry): Likewise.
+ (elf_i386_pic_lazy_ibt_plt0_entry): Likewise.
+ (elf_i386_non_lazy_ibt_plt_entry): Likewise.
+ (elf_i386_pic_non_lazy_ibt_plt_entry): Likewise.
+ (elf_i386_eh_frame_lazy_ibt_plt): Likewise.
+ (elf_i386_lazy_plt_layout): Likewise.
+ (elf_i386_non_lazy_plt_layout): Likewise.
+ (elf_i386_link_hash_entry): Add plt_second.
+ (elf_i386_link_hash_table): Add plt_second and
+ plt_second_eh_frame.
+ (elf_i386_allocate_dynrelocs): Use the second PLT if needed.
+ (elf_i386_size_dynamic_sections): Use .plt.got unwind info for
+ the second PLT. Check the second PLT.
+ (elf_i386_relocate_section): Use the second PLT to resolve
+ PLT reference if needed.
+ (elf_i386_finish_dynamic_symbol): Fill and use the second PLT if
+ needed.
+ (elf_i386_finish_dynamic_sections): Set sh_entsize on the
+ second PLT. Generate unwind info for the second PLT.
+ (elf_i386_plt_type): Add plt_second.
+ (elf_i386_get_synthetic_symtab): Support the second PLT.
+ (elf_i386_parse_gnu_properties): Support
+ GNU_PROPERTY_X86_FEATURE_1_AND.
+ (elf_i386_merge_gnu_properties): Support
+ GNU_PROPERTY_X86_FEATURE_1_AND. If info->ibt is set, turn
+ on GNU_PROPERTY_X86_FEATURE_1_IBT
+ (elf_i386_link_setup_gnu_properties): If info->ibt is set,
+ turn on GNU_PROPERTY_X86_FEATURE_1_IBT. Use IBT-enabled PLT
+ for info->ibtplt, info->ibt or GNU_PROPERTY_X86_FEATURE_1_IBT
+ is set on all relocatable inputs.
+ * elf64-x86-64.c (elf_x86_64_lazy_ibt_plt_entry): New.
+ (elf_x32_lazy_ibt_plt_entry): Likewise.
+ (elf_x86_64_non_lazy_ibt_plt_entry): Likewise.
+ (elf_x32_non_lazy_ibt_plt_entry): Likewise.
+ (elf_x86_64_eh_frame_lazy_ibt_plt): Likewise.
+ (elf_x32_eh_frame_lazy_ibt_plt): Likewise.
+ (elf_x86_64_lazy_ibt_plt): Likewise.
+ (elf_x32_lazy_ibt_plt): Likewise.
+ (elf_x86_64_non_lazy_ibt_plt): Likewise.
+ (elf_x32_non_lazy_ibt_plt): Likewise.
+ (elf_x86_64_get_synthetic_symtab): Support the second PLT.
+ (elf_x86_64_parse_gnu_properties): Support
+ GNU_PROPERTY_X86_FEATURE_1_AND.
+ (elf_x86_64_merge_gnu_properties): Support
+ GNU_PROPERTY_X86_FEATURE_1_AND. If info->ibt is set, turn
+ on GNU_PROPERTY_X86_FEATURE_1_IBT
+ (elf_x86_64_link_setup_gnu_properties): If info->ibt is set,
+ turn on GNU_PROPERTY_X86_FEATURE_1_IBT. Use IBT-enabled PLT
+ for info->ibtplt, info->ibt or GNU_PROPERTY_X86_FEATURE_1_IBT
+ is set on all relocatable inputs.
+
2017-06-22 Nick Clifton <nickc@redhat.com>
PR binutils/21649
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 6636551..d662816 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -617,6 +617,60 @@ static const bfd_byte elf_i386_pic_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
0x66, 0x90 /* xchg %ax,%ax */
};
+/* The first entry in an absolute IBT-enabled lazy procedure linkage
+ table looks like this. */
+
+static const bfd_byte elf_i386_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xff, 0x35, 0, 0, 0, 0, /* pushl GOT[1] */
+ 0xff, 0x25, 0, 0, 0, 0, /* jmp *GOT[2] */
+ 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
+};
+
+/* Subsequent entries for an absolute IBT-enabled lazy procedure linkage
+ table look like this. Subsequent entries for a PIC IBT-enabled lazy
+ procedure linkage table are the same. */
+
+static const bfd_byte elf_i386_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
+ 0x68, 0, 0, 0, 0, /* pushl immediate */
+ 0xe9, 0, 0, 0, 0, /* jmp relative */
+ 0x66, 0x90 /* xchg %ax,%ax */
+};
+
+/* The first entry in a PIC IBT-enabled lazy procedure linkage table
+ look like. */
+
+static const bfd_byte elf_i386_pic_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
+ 0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
+ 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
+};
+
+/* Entries for branches with IBT-enabled in the absolute non-lazey
+ procedure linkage table look like this. They have the same size
+ as the lazy PLT entry. */
+
+static const bfd_byte elf_i386_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
+ 0xff, 0x25, 0, 0, 0, 0, /* jmp *name@GOT */
+ 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
+};
+
+/* Entries for branches with IBT-enabled in the PIC non-lazey procedure
+ linkage table look like this. They have the same size as the lazy
+ PLT entry. */
+
+static const bfd_byte elf_i386_pic_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
+ 0xff, 0xa3, 0, 0, 0, 0, /* jmp *name@GOT(%ebx) */
+ 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
+};
+
/* .eh_frame covering the lazy .plt section. */
static const bfd_byte elf_i386_eh_frame_lazy_plt[] =
@@ -656,6 +710,41 @@ static const bfd_byte elf_i386_eh_frame_lazy_plt[] =
DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
};
+/* .eh_frame covering the lazy .plt section with IBT-enabled. */
+
+static const bfd_byte elf_i386_eh_frame_lazy_ibt_plt[] =
+{
+ PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
+ 0, 0, 0, 0, /* CIE ID */
+ 1, /* CIE version */
+ 'z', 'R', 0, /* Augmentation string */
+ 1, /* Code alignment factor */
+ 0x7c, /* Data alignment factor */
+ 8, /* Return address column */
+ 1, /* Augmentation size */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+ DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
+ DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
+ DW_CFA_nop, DW_CFA_nop,
+
+ PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+ PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+ 0, 0, 0, 0, /* R_386_PC32 .plt goes here */
+ 0, 0, 0, 0, /* .plt size goes here */
+ 0, /* Augmentation size */
+ DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */
+ DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+ DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */
+ DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
+ DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
+ 11, /* Block length */
+ DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */
+ DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */
+ DW_OP_lit15, DW_OP_and, DW_OP_lit9, DW_OP_ge,
+ DW_OP_lit2, DW_OP_shl, DW_OP_plus,
+ DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
+};
+
/* .eh_frame covering the non-lazy .plt section. */
static const bfd_byte elf_i386_eh_frame_non_lazy_plt[] =
@@ -786,6 +875,34 @@ static const struct elf_i386_non_lazy_plt_layout elf_i386_non_lazy_plt =
elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
};
+
+static const struct elf_i386_lazy_plt_layout elf_i386_lazy_ibt_plt =
+ {
+ elf_i386_lazy_ibt_plt0_entry, /* plt0_entry */
+ sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */
+ 2, /* plt0_got1_offset */
+ 8, /* plt0_got2_offset */
+ elf_i386_lazy_ibt_plt_entry, /* plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 4+2, /* plt_got_offset */
+ 4+1, /* plt_reloc_offset */
+ 4+6, /* plt_plt_offset */
+ 0, /* plt_lazy_offset */
+ elf_i386_pic_lazy_ibt_plt0_entry, /* pic_plt0_entry */
+ elf_i386_lazy_ibt_plt_entry, /* pic_plt_entry */
+ elf_i386_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
+ sizeof (elf_i386_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
+ };
+
+static const struct elf_i386_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt =
+ {
+ elf_i386_non_lazy_ibt_plt_entry, /* plt_entry */
+ elf_i386_pic_non_lazy_ibt_plt_entry,/* pic_plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 4+2, /* plt_got_offset */
+ elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
+ sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
+ };
/* On VxWorks, the .rel.plt.unloaded section has absolute relocations
@@ -889,6 +1006,9 @@ struct elf_i386_link_hash_entry
GOT and PLT relocations against the same function. */
union gotplt_union plt_got;
+ /* Information about the second PLT entry. */
+ union gotplt_union plt_second;
+
/* Offset of the GOTPLT entry reserved for the TLS descriptor,
starting at the end of the jump table. */
bfd_vma tlsdesc_got;
@@ -937,6 +1057,8 @@ struct elf_i386_link_hash_table
/* Short-cuts to get to dynamic linker sections. */
asection *interp;
asection *plt_eh_frame;
+ asection *plt_second;
+ asection *plt_second_eh_frame;
asection *plt_got;
asection *plt_got_eh_frame;
@@ -2644,12 +2766,29 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
here if it is defined and referenced in a non-shared object. */
if (h->type == STT_GNU_IFUNC
&& h->def_regular)
- return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
- &htab->readonly_dynrelocs_against_ifunc,
- plt_entry_size,
- (htab->plt.has_plt0 *
+ {
+ if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
+ &htab->readonly_dynrelocs_against_ifunc,
+ plt_entry_size,
+ (htab->plt.has_plt0 *
plt_entry_size),
- 4, TRUE);
+ 4, TRUE))
+ {
+ asection *s = htab->plt_second;
+ if (h->plt.offset != (bfd_vma) -1 && s != NULL)
+ {
+ /* Use the second PLT section if it is created. */
+ eh->plt_second.offset = s->size;
+
+ /* Make room for this entry in the second PLT section. */
+ s->size += htab->non_lazy_plt->plt_entry_size;
+ }
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
/* Don't create the PLT entry if there are only function pointer
relocations which can be resolved at run-time. */
else if (htab->elf.dynamic_sections_created
@@ -2677,6 +2816,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
{
asection *s = htab->elf.splt;
+ asection *second_s = htab->plt_second;
asection *got_s = htab->plt_got;
/* If this is the first .plt entry, make room for the special
@@ -2688,7 +2828,11 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (use_plt_got)
eh->plt_got.offset = got_s->size;
else
- h->plt.offset = s->size;
+ {
+ h->plt.offset = s->size;
+ if (second_s)
+ eh->plt_second.offset = second_s->size;
+ }
/* If this symbol is not defined in a regular file, and we are
not generating a shared library, then set the symbol to this
@@ -2707,8 +2851,18 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
}
else
{
- h->root.u.def.section = s;
- h->root.u.def.value = h->plt.offset;
+ if (second_s)
+ {
+ /* We need to make a call to the entry of the
+ second PLT instead of regular PLT entry. */
+ h->root.u.def.section = second_s;
+ h->root.u.def.value = eh->plt_second.offset;
+ }
+ else
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
}
}
@@ -2718,6 +2872,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
else
{
s->size += plt_entry_size;
+ if (second_s)
+ second_s->size += htab->non_lazy_plt->plt_entry_size;
/* We also need to make an entry in the .got.plt section,
which will be placed in the .got section by the linker
@@ -3370,6 +3526,15 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
&& !bfd_is_abs_section (htab->plt_got->output_section))
htab->plt_got_eh_frame->size
= htab->non_lazy_plt->eh_frame_plt_size;
+
+ /* Unwind info for the second PLT and .plt.got sections are
+ identical. */
+ if (htab->plt_second_eh_frame != NULL
+ && htab->plt_second != NULL
+ && htab->plt_second->size != 0
+ && !bfd_is_abs_section (htab->plt_second->output_section))
+ htab->plt_second_eh_frame->size
+ = htab->non_lazy_plt->eh_frame_plt_size;
}
/* We now have determined the sizes of the various dynamic sections.
@@ -3397,9 +3562,11 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
else if (s == htab->elf.sgotplt
|| s == htab->elf.iplt
|| s == htab->elf.igotplt
+ || s == htab->plt_second
|| s == htab->plt_got
|| s == htab->plt_eh_frame
|| s == htab->plt_got_eh_frame
+ || s == htab->plt_second_eh_frame
|| s == htab->elf.sdynbss
|| s == htab->elf.sdynrelro)
{
@@ -3472,6 +3639,17 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+ PLT_FDE_LEN_OFFSET));
}
+ if (htab->plt_second_eh_frame != NULL
+ && htab->plt_second_eh_frame->contents != NULL)
+ {
+ memcpy (htab->plt_second_eh_frame->contents,
+ htab->non_lazy_plt->eh_frame_plt,
+ htab->plt_second_eh_frame->size);
+ bfd_put_32 (dynobj, htab->plt_second->size,
+ (htab->plt_second_eh_frame->contents
+ + PLT_FDE_LEN_OFFSET));
+ }
+
if (htab->elf.dynamic_sections_created)
{
/* Add some entries to the .dynamic section. We fill in the
@@ -3903,13 +4081,15 @@ elf_i386_relocate_section (bfd *output_bfd,
continue;
}
+ eh = (struct elf_i386_link_hash_entry *) h;
+
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle
it here if it is defined in a non-shared object. */
if (h != NULL
&& h->type == STT_GNU_IFUNC
&& h->def_regular)
{
- asection *plt, *gotplt, *base_got;
+ asection *gotplt, *base_got;
bfd_vma plt_index;
const char *name;
@@ -3926,12 +4106,22 @@ elf_i386_relocate_section (bfd *output_bfd,
/* STT_GNU_IFUNC symbol must go through PLT. */
if (htab->elf.splt != NULL)
{
- plt = htab->elf.splt;
+ if (htab->plt_second != NULL)
+ {
+ resolved_plt = htab->plt_second;
+ plt_offset = eh->plt_second.offset;
+ }
+ else
+ {
+ resolved_plt = htab->elf.splt;
+ plt_offset = h->plt.offset;
+ }
gotplt = htab->elf.sgotplt;
}
else
{
- plt = htab->elf.iplt;
+ resolved_plt = htab->elf.iplt;
+ plt_offset = h->plt.offset;
gotplt = htab->elf.igotplt;
}
@@ -4031,8 +4221,8 @@ elf_i386_relocate_section (bfd *output_bfd,
goto bad_ifunc_reloc;
}
- relocation = (plt->output_section->vma
- + plt->output_offset + h->plt.offset);
+ relocation = (resolved_plt->output_section->vma
+ + resolved_plt->output_offset + plt_offset);
switch (r_type)
{
@@ -4126,7 +4316,6 @@ do_ifunc_pointer:
}
}
- eh = (struct elf_i386_link_hash_entry *) h;
resolved_to_zero = (eh != NULL
&& UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
eh->has_got_reloc,
@@ -4424,8 +4613,16 @@ disallow_got32:
if (h->plt.offset != (bfd_vma) -1)
{
- resolved_plt = htab->elf.splt;
- plt_offset = h->plt.offset;
+ if (htab->plt_second != NULL)
+ {
+ resolved_plt = htab->plt_second;
+ plt_offset = eh->plt_second.offset;
+ }
+ else
+ {
+ resolved_plt = htab->elf.splt;
+ plt_offset = h->plt.offset;
+ }
}
else
{
@@ -5258,6 +5455,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
const struct elf_i386_backend_data *abed;
struct elf_i386_link_hash_entry *eh;
bfd_boolean local_undefweak;
+ bfd_boolean use_plt_second;
htab = elf_i386_hash_table (info);
if (htab == NULL)
@@ -5266,6 +5464,9 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
abed = get_elf_i386_backend_data (output_bfd);
plt_entry_size = htab->plt.plt_entry_size;
+ /* Use the second PLT section only if there is .plt section. */
+ use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL;
+
eh = (struct elf_i386_link_hash_entry *) h;
if (eh->no_finish_dynamic_symbol)
abort ();
@@ -5279,11 +5480,11 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
if (h->plt.offset != (bfd_vma) -1)
{
- bfd_vma plt_index;
+ bfd_vma plt_index, plt_offset;
bfd_vma got_offset;
Elf_Internal_Rela rel;
bfd_byte *loc;
- asection *plt, *gotplt, *relplt;
+ asection *plt, *resolved_plt, *gotplt, *relplt;
/* When building a static executable, use .iplt, .igot.plt and
.rel.iplt sections for STT_GNU_IFUNC symbols. */
@@ -5340,13 +5541,33 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
the first slot. */
memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry,
plt_entry_size);
+
+ if (use_plt_second)
+ {
+ const bfd_byte *plt_entry;
+ if (bfd_link_pic (info))
+ plt_entry = htab->non_lazy_plt->pic_plt_entry;
+ else
+ plt_entry = htab->non_lazy_plt->plt_entry;
+ memcpy (htab->plt_second->contents + eh->plt_second.offset,
+ plt_entry, htab->non_lazy_plt->plt_entry_size);
+
+ resolved_plt = htab->plt_second;
+ plt_offset = eh->plt_second.offset;
+ }
+ else
+ {
+ resolved_plt = plt;
+ plt_offset = h->plt.offset;
+ }
+
if (! bfd_link_pic (info))
{
bfd_put_32 (output_bfd,
(gotplt->output_section->vma
+ gotplt->output_offset
+ got_offset),
- plt->contents + h->plt.offset
+ resolved_plt->contents + plt_offset
+ htab->plt.plt_got_offset);
if (abed->os == is_vxworks)
@@ -5370,8 +5591,8 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
loc = (htab->srelplt2->contents + reloc_index
* sizeof (Elf32_External_Rel));
- rel.r_offset = (htab->elf.splt->output_section->vma
- + htab->elf.splt->output_offset
+ rel.r_offset = (plt->output_section->vma
+ + plt->output_offset
+ h->plt.offset + 2),
rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
@@ -5389,7 +5610,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
else
{
bfd_put_32 (output_bfd, got_offset,
- plt->contents + h->plt.offset
+ resolved_plt->contents + plt_offset
+ htab->plt.plt_got_offset);
}
@@ -5577,6 +5798,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
else
{
asection *plt;
+ bfd_vma plt_offset;
if (!h->pointer_equality_needed)
abort ();
@@ -5584,10 +5806,19 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
/* For non-shared object, we can't use .got.plt, which
contains the real function addres if we need pointer
equality. We load the GOT entry with the PLT entry. */
- plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ if (htab->plt_second != NULL)
+ {
+ plt = htab->plt_second;
+ plt_offset = eh->plt_second.offset;
+ }
+ else
+ {
+ plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ plt_offset = h->plt.offset;
+ }
bfd_put_32 (output_bfd,
(plt->output_section->vma
- + plt->output_offset + h->plt.offset),
+ + plt->output_offset + plt_offset),
htab->elf.sgot->contents + h->got.offset);
return TRUE;
}
@@ -5868,6 +6099,10 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
if (htab->plt_got != NULL && htab->plt_got->size > 0)
elf_section_data (htab->plt_got->output_section)
->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
+
+ if (htab->plt_second != NULL && htab->plt_second->size > 0)
+ elf_section_data (htab->plt_second->output_section)
+ ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
}
/* Fill in the first three entries in the global offset table. */
@@ -5945,6 +6180,35 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
}
}
+ /* Adjust .eh_frame for the second PLT section. */
+ if (htab->plt_second_eh_frame != NULL
+ && htab->plt_second_eh_frame->contents != NULL)
+ {
+ if (htab->plt_second != NULL
+ && htab->plt_second->size != 0
+ && (htab->plt_second->flags & SEC_EXCLUDE) == 0
+ && htab->plt_second->output_section != NULL
+ && htab->plt_second_eh_frame->output_section != NULL)
+ {
+ bfd_vma plt_start = htab->plt_second->output_section->vma;
+ bfd_vma eh_frame_start
+ = (htab->plt_second_eh_frame->output_section->vma
+ + htab->plt_second_eh_frame->output_offset
+ + PLT_FDE_START_OFFSET);
+ bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
+ htab->plt_second_eh_frame->contents
+ + PLT_FDE_START_OFFSET);
+ }
+ if (htab->plt_second_eh_frame->sec_info_type
+ == SEC_INFO_TYPE_EH_FRAME)
+ {
+ if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+ htab->plt_second_eh_frame,
+ htab->plt_second_eh_frame->contents))
+ return FALSE;
+ }
+ }
+
if (htab->elf.sgot && htab->elf.sgot->size > 0)
elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
@@ -6005,6 +6269,7 @@ enum elf_i386_plt_type
plt_non_lazy = 0,
plt_lazy = 1 << 0,
plt_pic = 1 << 1,
+ plt_second = 1 << 2,
plt_unknown = -1
};
@@ -6042,6 +6307,8 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
arelent **dynrelbuf;
const struct elf_i386_lazy_plt_layout *lazy_plt;
const struct elf_i386_non_lazy_plt_layout *non_lazy_plt;
+ const struct elf_i386_lazy_plt_layout *lazy_ibt_plt;
+ const struct elf_i386_non_lazy_plt_layout *non_lazy_ibt_plt;
asection *plt;
bfd_vma got_addr;
char *names;
@@ -6050,6 +6317,7 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
{
{ ".plt", NULL, NULL, plt_unknown, 0, 0, 0 },
{ ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0 },
+ { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0 },
{ NULL, NULL, NULL, plt_non_lazy, 0, 0, 0 }
};
@@ -6078,10 +6346,14 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
non_lazy_plt = NULL;
/* Silence GCC 6. */
lazy_plt = NULL;
+ non_lazy_ibt_plt = NULL;
+ lazy_ibt_plt = NULL;
switch (get_elf_i386_backend_data (abfd)->os)
{
case is_normal:
non_lazy_plt = &elf_i386_non_lazy_plt;
+ lazy_ibt_plt = &elf_i386_lazy_ibt_plt;
+ non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt;
/* Fall through */
case is_vxworks:
lazy_plt = &elf_i386_lazy_plt;
@@ -6118,10 +6390,30 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
/* Match lazy PLT first. */
if (memcmp (plt_contents, lazy_plt->plt0_entry,
lazy_plt->plt0_got1_offset) == 0)
- plt_type = plt_lazy;
+ {
+ /* The fist entry in the lazy IBT PLT is the same as the
+ normal lazy PLT. */
+ if (lazy_ibt_plt != NULL
+ && (memcmp (plt_contents + lazy_ibt_plt->plt_entry_size,
+ lazy_ibt_plt->plt_entry,
+ lazy_ibt_plt->plt_got_offset) == 0))
+ plt_type = plt_lazy | plt_second;
+ else
+ plt_type = plt_lazy;
+ }
else if (memcmp (plt_contents, lazy_plt->pic_plt0_entry,
lazy_plt->plt0_got1_offset) == 0)
- plt_type = plt_lazy | plt_pic;
+ {
+ /* The fist entry in the PIC lazy IBT PLT is the same as
+ the normal PIC lazy PLT. */
+ if (lazy_ibt_plt != NULL
+ && (memcmp (plt_contents + lazy_ibt_plt->plt_entry_size,
+ lazy_ibt_plt->pic_plt_entry,
+ lazy_ibt_plt->plt_got_offset) == 0))
+ plt_type = plt_lazy | plt_pic | plt_second;
+ else
+ plt_type = plt_lazy | plt_pic;
+ }
}
if (non_lazy_plt != NULL
@@ -6136,6 +6428,27 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
plt_type = plt_pic;
}
+ if ((non_lazy_ibt_plt != NULL)
+ && (plt_type == plt_unknown || plt_type == plt_second))
+ {
+ if (memcmp (plt_contents,
+ non_lazy_ibt_plt->plt_entry,
+ non_lazy_ibt_plt->plt_got_offset) == 0)
+ {
+ /* Match IBT PLT. */
+ plt_type = plt_second;
+ non_lazy_plt = non_lazy_ibt_plt;
+ }
+ else if (memcmp (plt_contents,
+ non_lazy_ibt_plt->pic_plt_entry,
+ non_lazy_ibt_plt->plt_got_offset) == 0)
+ {
+ /* Match PIC IBT PLT. */
+ plt_type = plt_second | plt_pic;
+ non_lazy_plt = non_lazy_ibt_plt;
+ }
+ }
+
if (plt_type == plt_unknown)
continue;
@@ -6156,9 +6469,16 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
i = 0;
}
- n = plt->size / plts[j].plt_entry_size;
- plts[j].count = n;
- count += n - i;
+ /* Skip lazy PLT when the second PLT is used. */
+ if ((plt_type & (plt_lazy | plt_second))
+ == (plt_lazy | plt_second))
+ plts[j].count = 0;
+ else
+ {
+ n = plt->size / plts[j].plt_entry_size;
+ plts[j].count = n;
+ count += n - i;
+ }
plts[j].contents = plt_contents;
@@ -6363,12 +6683,15 @@ elf_i386_parse_gnu_properties (bfd *abfd, unsigned int type,
{
case GNU_PROPERTY_X86_ISA_1_USED:
case GNU_PROPERTY_X86_ISA_1_NEEDED:
+ case GNU_PROPERTY_X86_FEATURE_1_AND:
if (datasz != 4)
{
_bfd_error_handler
((type == GNU_PROPERTY_X86_ISA_1_USED
? _("error: %B: <corrupt x86 ISA used size: 0x%x>")
- : _("error: %B: <corrupt x86 ISA needed size: 0x%x>")),
+ : (type == GNU_PROPERTY_X86_ISA_1_NEEDED
+ ? _("error: %B: <corrupt x86 ISA needed size: 0x%x>")
+ : _("error: %B: <corrupt x86 feature size: 0x%x>"))),
abfd, datasz);
return property_corrupt;
}
@@ -6390,12 +6713,12 @@ elf_i386_parse_gnu_properties (bfd *abfd, unsigned int type,
should be merged with ABFD. */
static bfd_boolean
-elf_i386_merge_gnu_properties (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+elf_i386_merge_gnu_properties (struct bfd_link_info *info,
bfd *abfd ATTRIBUTE_UNUSED,
elf_property *aprop,
elf_property *bprop)
{
- unsigned int number;
+ unsigned int number, features;
bfd_boolean updated = FALSE;
unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
@@ -6417,6 +6740,53 @@ elf_i386_merge_gnu_properties (struct bfd_link_info *info ATTRIBUTE_UNUSED,
}
break;
+ case GNU_PROPERTY_X86_FEATURE_1_AND:
+ /* Only one of APROP and BPROP can be NULL:
+ 1. APROP & BPROP when both APROP and BPROP aren't NULL.
+ 2. If APROP is NULL, remove x86 feature.
+ 3. Otherwise, do nothing.
+ */
+ if (aprop != NULL && bprop != NULL)
+ {
+ features = 0;
+ if (info->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ number = aprop->u.number;
+ /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ aprop->u.number = (number & bprop->u.number) | features;
+ updated = number != (unsigned int) aprop->u.number;
+ /* Remove the property if all feature bits are cleared. */
+ if (aprop->u.number == 0)
+ aprop->pr_kind = property_remove;
+ }
+ else
+ {
+ features = 0;
+ if (info->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ if (features)
+ {
+ /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ if (aprop != NULL)
+ {
+ number = aprop->u.number;
+ aprop->u.number = number | features;
+ updated = number != (unsigned int) aprop->u.number;
+ }
+ else
+ {
+ bprop->u.number |= features;
+ updated = TRUE;
+ }
+ }
+ else if (aprop != NULL)
+ {
+ aprop->pr_kind = property_remove;
+ updated = TRUE;
+ }
+ }
+ break;
+
default:
/* Never should happen. */
abort ();
@@ -6432,11 +6802,72 @@ static bfd *
elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
{
bfd_boolean normal_target;
+ bfd_boolean lazy_plt;
asection *sec, *pltsec;
bfd *dynobj;
- unsigned int plt_alignment;
+ bfd_boolean use_ibt_plt;
+ unsigned int plt_alignment, features;
struct elf_i386_link_hash_table *htab;
- bfd *pbfd = _bfd_elf_link_setup_gnu_properties (info);
+ bfd *pbfd;
+
+ features = 0;
+ if (info->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ if (features)
+ {
+ /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ bfd *ebfd = NULL;
+ elf_property *prop;
+
+ for (pbfd = info->input_bfds;
+ pbfd != NULL;
+ pbfd = pbfd->link.next)
+ if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
+ && bfd_count_sections (pbfd) != 0)
+ {
+ ebfd = pbfd;
+
+ if (elf_properties (pbfd) != NULL)
+ {
+ /* Find a normal input file with GNU property note. */
+ prop = _bfd_elf_get_property (pbfd,
+ GNU_PROPERTY_X86_FEATURE_1_AND,
+ 4);
+ /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ prop->u.number |= features;
+ prop->pr_kind = property_number;
+ break;
+ }
+ }
+
+ if (pbfd == NULL && ebfd != NULL)
+ {
+ /* Create GNU_PROPERTY_X86_FEATURE_1_IBT if needed. */
+ prop = _bfd_elf_get_property (ebfd,
+ GNU_PROPERTY_X86_FEATURE_1_AND,
+ 4);
+ prop->u.number = features;
+ prop->pr_kind = property_number;
+
+ sec = bfd_make_section_with_flags (ebfd,
+ NOTE_GNU_PROPERTY_SECTION_NAME,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS
+ | SEC_DATA));
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
+
+ if (!bfd_set_section_alignment (ebfd, sec, 2))
+ goto error_alignment;
+
+ elf_section_type (sec) = SHT_NOTE;
+ }
+ }
+
+ pbfd = _bfd_elf_link_setup_gnu_properties (info);
if (bfd_link_relocatable (info))
return pbfd;
@@ -6445,6 +6876,26 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
if (htab == NULL)
return pbfd;
+ use_ibt_plt = info->ibtplt || info->ibt;
+ if (!use_ibt_plt && pbfd != NULL)
+ {
+ /* Check if GNU_PROPERTY_X86_FEATURE_1_IBT is on. */
+ elf_property_list *p;
+
+ /* The property list is sorted in order of type. */
+ for (p = elf_properties (pbfd); p; p = p->next)
+ {
+ if (GNU_PROPERTY_X86_FEATURE_1_AND == p->property.pr_type)
+ {
+ use_ibt_plt = !!(p->property.u.number
+ & GNU_PROPERTY_X86_FEATURE_1_IBT);
+ break;
+ }
+ else if (GNU_PROPERTY_X86_FEATURE_1_AND < p->property.pr_type)
+ break;
+ }
+ }
+
dynobj = htab->elf.dynobj;
/* Set htab->elf.dynobj here so that there is no need to check and
@@ -6476,8 +6927,16 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
switch (get_elf_i386_backend_data (info->output_bfd)->os)
{
case is_normal:
- htab->lazy_plt = &elf_i386_lazy_plt;
- htab->non_lazy_plt = &elf_i386_non_lazy_plt;
+ if (use_ibt_plt)
+ {
+ htab->lazy_plt = &elf_i386_lazy_ibt_plt;
+ htab->non_lazy_plt = &elf_i386_non_lazy_ibt_plt;
+ }
+ else
+ {
+ htab->lazy_plt = &elf_i386_lazy_plt;
+ htab->non_lazy_plt = &elf_i386_non_lazy_plt;
+ }
normal_target = TRUE;
break;
case is_vxworks:
@@ -6500,6 +6959,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
if (htab->non_lazy_plt != NULL
&& (!htab->plt.has_plt0 || pltsec == NULL))
{
+ lazy_plt = FALSE;
if (bfd_link_pic (info))
htab->plt.plt_entry
= htab->non_lazy_plt->pic_plt_entry;
@@ -6517,6 +6977,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
}
else
{
+ lazy_plt = TRUE;
if (bfd_link_pic (info))
{
htab->plt.plt0_entry
@@ -6605,6 +7066,29 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
goto error_alignment;
htab->plt_got = sec;
+
+ if (lazy_plt)
+ {
+ sec = NULL;
+
+ if (use_ibt_plt)
+ {
+ /* Create the second PLT for Intel IBT support. IBT
+ PLT is supported only for non-NaCl target and is
+ is needed only for lazy binding. */
+ sec = bfd_make_section_anyway_with_flags (dynobj,
+ ".plt.sec",
+ pltflags);
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F: failed to create IBT-enabled PLT section\n"));
+
+ if (!bfd_set_section_alignment (dynobj, sec,
+ plt_alignment))
+ goto error_alignment;
+ }
+
+ htab->plt_second = sec;
+ }
}
if (!info->no_ld_generated_unwind_info)
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index ab6f068..1f8e6d0 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -596,6 +596,32 @@ static const bfd_byte elf_x86_64_lazy_bnd_plt_entry[LAZY_PLT_ENTRY_SIZE] =
0x0f, 0x1f, 0x44, 0, 0 /* nopl 0(%rax,%rax,1) */
};
+/* The first entry in the IBT-enabled lazy procedure linkage table is the
+ the same as the lazy PLT with BND prefix so that bound registers are
+ preserved when control is passed to dynamic linker. Subsequent
+ entries for a IBT-enabled lazy procedure linkage table look like
+ this. */
+
+static const bfd_byte elf_x86_64_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0x68, 0, 0, 0, 0, /* pushq immediate */
+ 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */
+ 0x90 /* nop */
+};
+
+/* The first entry in the x32 IBT-enabled lazy procedure linkage table
+ is the the same as the normal lazy PLT. Subsequent entries for an
+ x32 IBT-enabled lazy procedure linkage table look like this. */
+
+static const bfd_byte elf_x32_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0x68, 0, 0, 0, 0, /* pushq immediate */
+ 0xe9, 0, 0, 0, 0, /* jmpq relative */
+ 0x66, 0x90 /* xchg %ax,%ax */
+};
+
/* Entries in the non-lazey procedure linkage table look like this. */
static const bfd_byte elf_x86_64_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
@@ -615,6 +641,30 @@ static const bfd_byte elf_x86_64_non_lazy_bnd_plt_entry[NON_LAZY_PLT_ENTRY_SIZE]
0x90 /* nop */
};
+/* Entries for branches with IBT-enabled in the non-lazey procedure
+ linkage table look like this. They have the same size as the lazy
+ PLT entry. */
+
+static const bfd_byte elf_x86_64_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
+ 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
+ 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopl 0x0(%rax,%rax,1) */
+};
+
+/* Entries for branches with IBT-enabled in the x32 non-lazey procedure
+ linkage table look like this. They have the same size as the lazy
+ PLT entry. */
+
+static const bfd_byte elf_x32_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+{
+ 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
+ 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
+ 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
+};
+
/* .eh_frame covering the lazy .plt section. */
static const bfd_byte elf_x86_64_eh_frame_lazy_plt[] =
@@ -689,6 +739,76 @@ static const bfd_byte elf_x86_64_eh_frame_lazy_bnd_plt[] =
DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
};
+/* .eh_frame covering the lazy .plt section with IBT-enabled. */
+
+static const bfd_byte elf_x86_64_eh_frame_lazy_ibt_plt[] =
+{
+ PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
+ 0, 0, 0, 0, /* CIE ID */
+ 1, /* CIE version */
+ 'z', 'R', 0, /* Augmentation string */
+ 1, /* Code alignment factor */
+ 0x78, /* Data alignment factor */
+ 16, /* Return address column */
+ 1, /* Augmentation size */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+ DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
+ DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
+ DW_CFA_nop, DW_CFA_nop,
+
+ PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+ PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+ 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
+ 0, 0, 0, 0, /* .plt size goes here */
+ 0, /* Augmentation size */
+ DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
+ DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+ DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
+ DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
+ DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
+ 11, /* Block length */
+ DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
+ DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
+ DW_OP_lit15, DW_OP_and, DW_OP_lit10, DW_OP_ge,
+ DW_OP_lit3, DW_OP_shl, DW_OP_plus,
+ DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
+};
+
+/* .eh_frame covering the x32 lazy .plt section with IBT-enabled. */
+
+static const bfd_byte elf_x32_eh_frame_lazy_ibt_plt[] =
+{
+ PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
+ 0, 0, 0, 0, /* CIE ID */
+ 1, /* CIE version */
+ 'z', 'R', 0, /* Augmentation string */
+ 1, /* Code alignment factor */
+ 0x78, /* Data alignment factor */
+ 16, /* Return address column */
+ 1, /* Augmentation size */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+ DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
+ DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
+ DW_CFA_nop, DW_CFA_nop,
+
+ PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+ PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+ 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
+ 0, 0, 0, 0, /* .plt size goes here */
+ 0, /* Augmentation size */
+ DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
+ DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+ DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
+ DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
+ DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
+ 11, /* Block length */
+ DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
+ DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
+ DW_OP_lit15, DW_OP_and, DW_OP_lit9, DW_OP_ge,
+ DW_OP_lit3, DW_OP_shl, DW_OP_plus,
+ DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
+};
+
/* .eh_frame covering the non-lazy .plt section. */
static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] =
@@ -862,6 +982,62 @@ static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt =
sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
};
+static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_ibt_plt =
+ {
+ elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */
+ elf_x86_64_lazy_ibt_plt_entry, /* plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 2, /* plt0_got1_offset */
+ 1+8, /* plt0_got2_offset */
+ 1+12, /* plt0_got2_insn_end */
+ 4+1+2, /* plt_got_offset */
+ 4+1, /* plt_reloc_offset */
+ 4+1+6, /* plt_plt_offset */
+ 4+1+6, /* plt_got_insn_size */
+ 4+1+5+5, /* plt_plt_insn_end */
+ 0, /* plt_lazy_offset */
+ elf_x86_64_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
+ sizeof (elf_x86_64_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
+ };
+
+static const struct elf_x86_64_lazy_plt_layout elf_x32_lazy_ibt_plt =
+ {
+ elf_x86_64_lazy_plt0_entry, /* plt0_entry */
+ elf_x32_lazy_ibt_plt_entry, /* plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 2, /* plt0_got1_offset */
+ 8, /* plt0_got2_offset */
+ 12, /* plt0_got2_insn_end */
+ 4+2, /* plt_got_offset */
+ 4+1, /* plt_reloc_offset */
+ 4+6, /* plt_plt_offset */
+ 4+6, /* plt_got_insn_size */
+ 4+5+5, /* plt_plt_insn_end */
+ 0, /* plt_lazy_offset */
+ elf_x32_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
+ sizeof (elf_x32_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
+ };
+
+static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt =
+ {
+ elf_x86_64_non_lazy_ibt_plt_entry, /* plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 4+1+2, /* plt_got_offset */
+ 4+1+6, /* plt_got_insn_size */
+ elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
+ sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
+ };
+
+static const struct elf_x86_64_non_lazy_plt_layout elf_x32_non_lazy_ibt_plt =
+ {
+ elf_x32_non_lazy_ibt_plt_entry, /* plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 4+2, /* plt_got_offset */
+ 4+6, /* plt_got_insn_size */
+ elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
+ sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
+ };
+
static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
{
is_normal /* os */
@@ -6508,6 +6684,8 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt;
const struct elf_x86_64_lazy_plt_layout *lazy_bnd_plt;
const struct elf_x86_64_non_lazy_plt_layout *non_lazy_bnd_plt;
+ const struct elf_x86_64_lazy_plt_layout *lazy_ibt_plt;
+ const struct elf_x86_64_non_lazy_plt_layout *non_lazy_ibt_plt;
asection *plt;
char *names;
enum elf_x86_64_plt_type plt_type;
@@ -6548,6 +6726,16 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
non_lazy_plt = &elf_x86_64_non_lazy_plt;
lazy_bnd_plt = &elf_x86_64_lazy_bnd_plt;
non_lazy_bnd_plt = &elf_x86_64_non_lazy_bnd_plt;
+ if (ABI_64_P (abfd))
+ {
+ lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt;
+ non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt;
+ }
+ else
+ {
+ lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
+ non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
+ }
}
else
{
@@ -6555,6 +6743,8 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
non_lazy_plt = NULL;
lazy_bnd_plt = NULL;
non_lazy_bnd_plt = NULL;
+ lazy_ibt_plt = NULL;
+ non_lazy_ibt_plt = NULL;
}
count = 0;
@@ -6593,7 +6783,14 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
lazy_bnd_plt->plt0_entry + 6, 3) == 0))
{
plt_type = plt_lazy | plt_second;
- lazy_plt = lazy_bnd_plt;
+ /* The fist entry in the lazy IBT PLT is the same as the
+ lazy BND PLT. */
+ if ((memcmp (plt_contents + lazy_ibt_plt->plt_entry_size,
+ lazy_ibt_plt->plt_entry,
+ lazy_ibt_plt->plt_got_offset) == 0))
+ lazy_plt = lazy_ibt_plt;
+ else
+ lazy_plt = lazy_bnd_plt;
}
}
@@ -6606,16 +6803,25 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
plt_type = plt_non_lazy;
}
- if (non_lazy_bnd_plt != NULL
- && (plt_type == plt_unknown || plt_type == plt_second))
+ if (plt_type == plt_unknown || plt_type == plt_second)
{
- /* Match BND PLT. */
- if (memcmp (plt_contents, non_lazy_bnd_plt->plt_entry,
- non_lazy_bnd_plt->plt_got_offset) == 0)
+ if (non_lazy_bnd_plt != NULL
+ && (memcmp (plt_contents, non_lazy_bnd_plt->plt_entry,
+ non_lazy_bnd_plt->plt_got_offset) == 0))
{
+ /* Match BND PLT. */
plt_type = plt_second;
non_lazy_plt = non_lazy_bnd_plt;
}
+ else if (non_lazy_ibt_plt != NULL
+ && (memcmp (plt_contents,
+ non_lazy_ibt_plt->plt_entry,
+ non_lazy_ibt_plt->plt_got_offset) == 0))
+ {
+ /* Match IBT PLT. */
+ plt_type = plt_second;
+ non_lazy_plt = non_lazy_ibt_plt;
+ }
}
if (plt_type == plt_unknown)
@@ -7012,12 +7218,15 @@ elf_x86_64_parse_gnu_properties (bfd *abfd, unsigned int type,
{
case GNU_PROPERTY_X86_ISA_1_USED:
case GNU_PROPERTY_X86_ISA_1_NEEDED:
+ case GNU_PROPERTY_X86_FEATURE_1_AND:
if (datasz != 4)
{
_bfd_error_handler
((type == GNU_PROPERTY_X86_ISA_1_USED
? _("error: %B: <corrupt x86 ISA used size: 0x%x>")
- : _("error: %B: <corrupt x86 ISA needed size: 0x%x>")),
+ : (type == GNU_PROPERTY_X86_ISA_1_NEEDED
+ ? _("error: %B: <corrupt x86 ISA needed size: 0x%x>")
+ : _("error: %B: <corrupt x86 feature size: 0x%x>"))),
abfd, datasz);
return property_corrupt;
}
@@ -7039,12 +7248,12 @@ elf_x86_64_parse_gnu_properties (bfd *abfd, unsigned int type,
should be merged with ABFD. */
static bfd_boolean
-elf_x86_64_merge_gnu_properties (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+elf_x86_64_merge_gnu_properties (struct bfd_link_info *info,
bfd *abfd ATTRIBUTE_UNUSED,
elf_property *aprop,
elf_property *bprop)
{
- unsigned int number;
+ unsigned int number, features;
bfd_boolean updated = FALSE;
unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
@@ -7066,6 +7275,53 @@ elf_x86_64_merge_gnu_properties (struct bfd_link_info *info ATTRIBUTE_UNUSED,
}
break;
+ case GNU_PROPERTY_X86_FEATURE_1_AND:
+ /* Only one of APROP and BPROP can be NULL:
+ 1. APROP & BPROP when both APROP and BPROP aren't NULL.
+ 2. If APROP is NULL, remove x86 feature.
+ 3. Otherwise, do nothing.
+ */
+ if (aprop != NULL && bprop != NULL)
+ {
+ features = 0;
+ if (info->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ number = aprop->u.number;
+ /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ aprop->u.number = (number & bprop->u.number) | features;
+ updated = number != (unsigned int) aprop->u.number;
+ /* Remove the property if all feature bits are cleared. */
+ if (aprop->u.number == 0)
+ aprop->pr_kind = property_remove;
+ }
+ else
+ {
+ features = 0;
+ if (info->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ if (features)
+ {
+ /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ if (aprop != NULL)
+ {
+ number = aprop->u.number;
+ aprop->u.number = number | features;
+ updated = number != (unsigned int) aprop->u.number;
+ }
+ else
+ {
+ bprop->u.number |= features;
+ updated = TRUE;
+ }
+ }
+ else if (aprop != NULL)
+ {
+ aprop->pr_kind = property_remove;
+ updated = TRUE;
+ }
+ }
+ break;
+
default:
/* Never should happen. */
abort ();
@@ -7084,9 +7340,69 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
bfd_boolean lazy_plt;
asection *sec, *pltsec;
bfd *dynobj;
- unsigned int plt_alignment;
+ bfd_boolean use_ibt_plt;
+ unsigned int plt_alignment, features;
struct elf_x86_64_link_hash_table *htab;
- bfd *pbfd = _bfd_elf_link_setup_gnu_properties (info);
+ bfd *pbfd;
+
+ features = 0;
+ if (info->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ if (features)
+ {
+ /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ bfd *ebfd = NULL;
+ elf_property *prop;
+
+ for (pbfd = info->input_bfds;
+ pbfd != NULL;
+ pbfd = pbfd->link.next)
+ if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
+ && bfd_count_sections (pbfd) != 0)
+ {
+ ebfd = pbfd;
+
+ if (elf_properties (pbfd) != NULL)
+ {
+ /* Find a normal input file with GNU property note. */
+ prop = _bfd_elf_get_property (pbfd,
+ GNU_PROPERTY_X86_FEATURE_1_AND,
+ 4);
+ /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ prop->u.number |= features;
+ prop->pr_kind = property_number;
+ break;
+ }
+ }
+
+ if (pbfd == NULL && ebfd != NULL)
+ {
+ /* Create GNU_PROPERTY_X86_FEATURE_1_IBT if needed. */
+ prop = _bfd_elf_get_property (ebfd,
+ GNU_PROPERTY_X86_FEATURE_1_AND,
+ 4);
+ prop->u.number = features;
+ prop->pr_kind = property_number;
+
+ sec = bfd_make_section_with_flags (ebfd,
+ NOTE_GNU_PROPERTY_SECTION_NAME,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS
+ | SEC_DATA));
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
+
+ if (!bfd_set_section_alignment (ebfd, sec, 2))
+ goto error_alignment;
+
+ elf_section_type (sec) = SHT_NOTE;
+ }
+ }
+
+ pbfd = _bfd_elf_link_setup_gnu_properties (info);
if (bfd_link_relocatable (info))
return pbfd;
@@ -7095,26 +7411,54 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
if (htab == NULL)
return pbfd;
+ use_ibt_plt = info->ibtplt || info->ibt;
+ if (!use_ibt_plt && pbfd != NULL)
+ {
+ /* Check if GNU_PROPERTY_X86_FEATURE_1_IBT is on. */
+ elf_property_list *p;
+
+ /* The property list is sorted in order of type. */
+ for (p = elf_properties (pbfd); p; p = p->next)
+ {
+ if (GNU_PROPERTY_X86_FEATURE_1_AND == p->property.pr_type)
+ {
+ use_ibt_plt = !!(p->property.u.number
+ & GNU_PROPERTY_X86_FEATURE_1_IBT);
+ break;
+ }
+ else if (GNU_PROPERTY_X86_FEATURE_1_AND < p->property.pr_type)
+ break;
+ }
+ }
+
dynobj = htab->elf.dynobj;
/* Set htab->elf.dynobj here so that there is no need to check and
set it in check_relocs. */
if (dynobj == NULL)
{
- bfd *abfd;
-
- /* Find a normal input file to hold linker created
- sections. */
- for (abfd = info->input_bfds;
- abfd != NULL;
- abfd = abfd->link.next)
- if ((abfd->flags
- & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
- {
- htab->elf.dynobj = abfd;
- dynobj = abfd;
- break;
- }
+ if (pbfd != NULL)
+ {
+ htab->elf.dynobj = pbfd;
+ dynobj = pbfd;
+ }
+ else
+ {
+ bfd *abfd;
+
+ /* Find a normal input file to hold linker created
+ sections. */
+ for (abfd = info->input_bfds;
+ abfd != NULL;
+ abfd = abfd->link.next)
+ if ((abfd->flags
+ & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
+ {
+ htab->elf.dynobj = abfd;
+ dynobj = abfd;
+ break;
+ }
+ }
}
/* Even when lazy binding is disabled by "-z now", the PLT0 entry may
@@ -7125,7 +7469,20 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
if (get_elf_x86_64_backend_data (info->output_bfd)->os
== is_normal)
{
- if (info->bndplt)
+ if (use_ibt_plt)
+ {
+ if (ABI_64_P (dynobj))
+ {
+ htab->lazy_plt = &elf_x86_64_lazy_ibt_plt;
+ htab->non_lazy_plt = &elf_x86_64_non_lazy_ibt_plt;
+ }
+ else
+ {
+ htab->lazy_plt = &elf_x32_lazy_ibt_plt;
+ htab->non_lazy_plt = &elf_x32_non_lazy_ibt_plt;
+ }
+ }
+ else if (info->bndplt)
{
htab->lazy_plt = &elf_x86_64_lazy_bnd_plt;
htab->non_lazy_plt = &elf_x86_64_non_lazy_bnd_plt;
@@ -7262,21 +7619,40 @@ error_alignment:
htab->plt_got = sec;
- /* MPX PLT is supported only for non-NaCl target in 64-bit
- mode and is needed only for lazy binding. */
- if (lazy_plt
- && info->bndplt && ABI_64_P (dynobj))
+ if (lazy_plt)
{
- /* Create the second PLT for Intel MPX support. */
- sec = bfd_make_section_anyway_with_flags (dynobj,
- ".plt.sec",
- pltflags);
- if (sec == NULL)
- info->callbacks->einfo (_("%F: failed to create BND PLT section\n"));
+ sec = NULL;
- if (!bfd_set_section_alignment (dynobj, sec,
- non_lazy_plt_alignment))
- goto error_alignment;
+ if (use_ibt_plt)
+ {
+ /* Create the second PLT for Intel IBT support. IBT
+ PLT is supported only for non-NaCl target and is
+ is needed only for lazy binding. */
+ sec = bfd_make_section_anyway_with_flags (dynobj,
+ ".plt.sec",
+ pltflags);
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F: failed to create IBT-enabled PLT section\n"));
+
+ if (!bfd_set_section_alignment (dynobj, sec,
+ plt_alignment))
+ goto error_alignment;
+ }
+ else if (info->bndplt && ABI_64_P (dynobj))
+ {
+ /* Create the second PLT for Intel MPX support. MPX
+ PLT is supported only for non-NaCl target in 64-bit
+ mode and is needed only for lazy binding. */
+ sec = bfd_make_section_anyway_with_flags (dynobj,
+ ".plt.sec",
+ pltflags);
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F: failed to create BND PLT section\n"));
+
+ if (!bfd_set_section_alignment (dynobj, sec,
+ non_lazy_plt_alignment))
+ goto error_alignment;
+ }
htab->plt_second = sec;
}
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index a9166de..3870711 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,19 @@
+2017-06-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * readelf.c (decode_x86_feature): New.
+ (print_gnu_property_note): Call decode_x86_feature on
+ GNU_PROPERTY_X86_FEATURE_1_AND.
+ * testsuite/binutils-all/i386/empty.d: New file.
+ * testsuite/binutils-all/i386/empty.s: Likewise.
+ * testsuite/binutils-all/i386/ibt.d: Likewise.
+ * testsuite/binutils-all/i386/ibt.s: Likewise.
+ * testsuite/binutils-all/x86-64/empty-x32.d: Likewise.
+ * testsuite/binutils-all/x86-64/empty.d: Likewise.
+ * testsuite/binutils-all/x86-64/empty.s: Likewise.
+ * testsuite/binutils-all/x86-64/ibt-x32.d: Likewise.
+ * testsuite/binutils-all/x86-64/ibt.d: Likewise.
+ * testsuite/binutils-all/x86-64/ibt.s: Likewise.
+
2017-06-21 H.J. Lu <hongjiu.lu@intel.com>
* dwarf.c (READ_ULEB): Use DWARF_VMA_FMT to report error.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index bb6bb79..50354c1 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -16338,6 +16338,36 @@ decode_x86_isa (unsigned int bitmask)
}
static void
+decode_x86_feature (unsigned int type, unsigned int bitmask)
+{
+ while (bitmask)
+ {
+ unsigned int bit = bitmask & (- bitmask);
+
+ bitmask &= ~ bit;
+ switch (bit)
+ {
+ case GNU_PROPERTY_X86_FEATURE_1_IBT:
+ switch (type)
+ {
+ case GNU_PROPERTY_X86_FEATURE_1_AND:
+ printf ("IBT");
+ break;
+ default:
+ /* This should never happen. */
+ abort ();
+ }
+ break;
+ default:
+ printf (_("<unknown: %x>"), bit);
+ break;
+ }
+ if (bitmask)
+ printf (", ");
+ }
+}
+
+static void
print_gnu_property_note (Elf_Internal_Note * pnote)
{
unsigned char * ptr = (unsigned char *) pnote->descdata;
@@ -16391,6 +16421,14 @@ print_gnu_property_note (Elf_Internal_Note * pnote)
decode_x86_isa (byte_get (ptr, 4));
goto next;
+ case GNU_PROPERTY_X86_FEATURE_1_AND:
+ printf ("x86 feature: ");
+ if (datasz != 4)
+ printf (_("<corrupt length: %#x> "), datasz);
+ else
+ decode_x86_feature (type, byte_get (ptr, 4));
+ goto next;
+
default:
break;
}
diff --git a/binutils/testsuite/binutils-all/i386/empty.d b/binutils/testsuite/binutils-all/i386/empty.d
new file mode 100644
index 0000000..5f4cc56
--- /dev/null
+++ b/binutils/testsuite/binutils-all/i386/empty.d
@@ -0,0 +1,9 @@
+#PROG: objcopy
+#as: --32
+#objcopy:
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature:
diff --git a/binutils/testsuite/binutils-all/i386/empty.s b/binutils/testsuite/binutils-all/i386/empty.s
new file mode 100644
index 0000000..6a6b517
--- /dev/null
+++ b/binutils/testsuite/binutils-all/i386/empty.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x0
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/binutils/testsuite/binutils-all/i386/ibt.d b/binutils/testsuite/binutils-all/i386/ibt.d
new file mode 100644
index 0000000..dfd7676
--- /dev/null
+++ b/binutils/testsuite/binutils-all/i386/ibt.d
@@ -0,0 +1,9 @@
+#PROG: objcopy
+#as: --32
+#objcopy:
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/binutils/testsuite/binutils-all/i386/ibt.s b/binutils/testsuite/binutils-all/i386/ibt.s
new file mode 100644
index 0000000..84ee964
--- /dev/null
+++ b/binutils/testsuite/binutils-all/i386/ibt.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/binutils/testsuite/binutils-all/x86-64/empty-x32.d b/binutils/testsuite/binutils-all/x86-64/empty-x32.d
new file mode 100644
index 0000000..4193818
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/empty-x32.d
@@ -0,0 +1,10 @@
+#source: empty.s
+#PROG: objcopy
+#as: --x32
+#objcopy:
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature:
diff --git a/binutils/testsuite/binutils-all/x86-64/empty.d b/binutils/testsuite/binutils-all/x86-64/empty.d
new file mode 100644
index 0000000..777efbb
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/empty.d
@@ -0,0 +1,9 @@
+#PROG: objcopy
+#as: --64 -defsym __64_bit__=1
+#objcopy:
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature:
diff --git a/binutils/testsuite/binutils-all/x86-64/empty.s b/binutils/testsuite/binutils-all/x86-64/empty.s
new file mode 100644
index 0000000..6a6b517
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/empty.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x0
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/binutils/testsuite/binutils-all/x86-64/ibt-x32.d b/binutils/testsuite/binutils-all/x86-64/ibt-x32.d
new file mode 100644
index 0000000..5be7c98
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/ibt-x32.d
@@ -0,0 +1,10 @@
+#source: ibt.s
+#PROG: objcopy
+#as: --x32
+#objcopy:
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/binutils/testsuite/binutils-all/x86-64/ibt.d b/binutils/testsuite/binutils-all/x86-64/ibt.d
new file mode 100644
index 0000000..7bedff5
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/ibt.d
@@ -0,0 +1,9 @@
+#PROG: objcopy
+#as: --64 -defsym __64_bit__=1
+#objcopy:
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/binutils/testsuite/binutils-all/x86-64/ibt.s b/binutils/testsuite/binutils-all/x86-64/ibt.s
new file mode 100644
index 0000000..84ee964
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/ibt.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/include/ChangeLog b/include/ChangeLog
index b48df091..4858699 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfdlink.h (bfd_link_info): Add ibtplt and ibt.
+ * elf/common.h (GNU_PROPERTY_X86_FEATURE_1_AND): New.
+ (GNU_PROPERTY_X86_FEATURE_1_IBT): Likewise.
+
2017-06-21 Thomas Preud'homme <thomas.preudhomme@arm.com>
* opcode/arm.h (FPU_ANY): New macro.
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 69232c4..3b4dce9 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -471,6 +471,12 @@ struct bfd_link_info
/* TRUE if BND prefix in PLT entries is always generated. */
unsigned int bndplt: 1;
+ /* TRUE if IBT-enabled PLT entries should be generated. */
+ unsigned int ibtplt: 1;
+
+ /* TRUE if GNU_PROPERTY_X86_FEATURE_1_IBT should be generated. */
+ unsigned int ibt: 1;
+
/* TRUE if generation of .interp/PT_INTERP should be suppressed. */
unsigned int nointerp: 1;
diff --git a/include/elf/common.h b/include/elf/common.h
index 484cb48..e638ba0 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -709,6 +709,7 @@
#define GNU_PROPERTY_X86_ISA_1_USED 0xc0000000
#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0000001
+#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002
#define GNU_PROPERTY_X86_ISA_1_486 (1U << 0)
#define GNU_PROPERTY_X86_ISA_1_586 (1U << 1)
@@ -729,6 +730,8 @@
#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16)
#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17)
+#define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0)
+
/* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG). */
#define GNU_ABI_TAG_LINUX 0
#define GNU_ABI_TAG_HURD 1
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 94af73d..b3567e1 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,82 @@
+2017-06-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (ELF_X86_DEPS): Add $(srcdir)/emulparams/cet.sh.
+ * Makefile.in: Regenerated.
+ * NEWS: Mention GNU_PROPERTY_X86_FEATURE_1_IBT, -z ibtplt
+ and -z ibt.
+ * emulparams/cet.sh: New file.
+ * testsuite/ld-i386/ibt-plt-1.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-1.s: Likewise.
+ * testsuite/ld-i386/ibt-plt-2.s: Likewise.
+ * testsuite/ld-i386/ibt-plt-2a.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-2b.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-2c.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-2d.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-3.s: Likewise.
+ * testsuite/ld-i386/ibt-plt-3a.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-3b.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-3c.d: Likewise.
+ * testsuite/ld-i386/ibt-plt-3d.d: Likewise.
+ * testsuite/ld-i386/plt-main-ibt.dd: Likewise.
+ * testsuite/ld-i386/plt-pie-ibt.dd: Likewise.
+ * testsuite/ld-i386/property-x86-empty.s: Likewise.
+ * testsuite/ld-i386/property-x86-ibt.s: Likewise.
+ * testsuite/ld-i386/property-x86-ibt1a.d: Likewise.
+ * testsuite/ld-i386/property-x86-ibt1b.d: Likewise.
+ * testsuite/ld-i386/property-x86-ibt2.d: Likewise.
+ * testsuite/ld-i386/property-x86-ibt3a.d: Likewise.
+ * testsuite/ld-i386/property-x86-ibt3b.d: Likewise.
+ * testsuite/ld-i386/property-x86-ibt4.d: Likewise.
+ * testsuite/ld-i386/property-x86-ibt5.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-1-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-1.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-1.s: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2.s: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2a-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2a.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2b-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2b.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2c-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2c.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2d-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-2d.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3.s: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3a-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3a.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3b-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3b.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3c-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3c.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3d-x32.d: Likewise.
+ * testsuite/ld-x86-64/ibt-plt-3d.d: Likewise.
+ * testsuite/ld-x86-64/plt-main-ibt-now.rd: Likewise.
+ * testsuite/ld-x86-64/plt-main-ibt-x32.dd: Likewise.
+ * testsuite/ld-x86-64/plt-main-ibt.dd: Likewise.
+ * testsuite/ld-x86-64/property-x86-empty.s: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt.s: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt1a-x32.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt1a.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt1b-x32.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt1b.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt2-x32.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt2.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt3a-x32.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt3a.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt3b-x32.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt3b.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt4-x32.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt4.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt5-x32.d: Likewise.
+ * testsuite/ld-x86-64/property-x86-ibt5.d: Likewise.
+ * emulparams/elf32_x86_64.sh: Source emulparams/cet.sh.
+ (TINY_READONLY_SECTION): Add .plt.sec.
+ * emulparams/elf_i386.sh: Likewise.
+ * emulparams/elf_x86_64.sh: Source emulparams/cet.sh.
+ * ld.texinfo: Document -z ibtplt and -z ibt.
+ * testsuite/ld-i386/i386.exp: Run IBT and IBT PLT tests.
+ * testsuite/ld-x86-64/x86-64.exp: Likewise.
+ * testsuite/ld-x86-64/pr21481b.S (check): Updated for x32.
+
2017-06-21 H.J. Lu <hongjiu.lu@intel.com>
PR ld/21090
diff --git a/ld/Makefile.am b/ld/Makefile.am
index b509e23..fcd4c36 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -677,7 +677,8 @@ ELF_X86_DEPS = $(ELF_DEPS) $(srcdir)/emulparams/plt_unwind.sh \
$(srcdir)/emulparams/extern_protected_data.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emulparams/reloc_overflow.sh \
- $(srcdir)/emulparams/call_nop.sh
+ $(srcdir)/emulparams/call_nop.sh \
+ $(srcdir)/emulparams/cet.sh
@TDIRS@
diff --git a/ld/Makefile.in b/ld/Makefile.in
index b69d6b8..5e66e02 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -932,7 +932,8 @@ ELF_X86_DEPS = $(ELF_DEPS) $(srcdir)/emulparams/plt_unwind.sh \
$(srcdir)/emulparams/extern_protected_data.sh \
$(srcdir)/emulparams/dynamic_undefined_weak.sh \
$(srcdir)/emulparams/reloc_overflow.sh \
- $(srcdir)/emulparams/call_nop.sh
+ $(srcdir)/emulparams/call_nop.sh \
+ $(srcdir)/emulparams/cet.sh
# We need this for automake to use YLWRAP.
diff --git a/ld/NEWS b/ld/NEWS
index 98055b5..b115843 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,14 @@
-*- text -*-
+* Add support for GNU_PROPERTY_X86_FEATURE_1_IBT in ELF GNU program
+
+* Support for -z ibtplt in the x86 ELF linker to generate IBT-enabled
+ PLT.
+
+* Support for -z ibt in the x86 ELF linker to generate IBT-enabled
+ PLT as well as GNU_PROPERTY_X86_FEATURE_1_IBT in ELF GNU program
+ properties.
+
* Add support for ELF SHF_GNU_MBIND and PT_GNU_MBIND_XXX.
* Add support for ELF GNU program properties.
diff --git a/ld/emulparams/cet.sh b/ld/emulparams/cet.sh
new file mode 100644
index 0000000..62ff105
--- /dev/null
+++ b/ld/emulparams/cet.sh
@@ -0,0 +1,14 @@
+PARSE_AND_LIST_OPTIONS_CET='
+ fprintf (file, _("\
+ -z ibtplt Generate IBT-enabled PLT entries\n\
+ -z ibt Generate GNU_PROPERTY_X86_FEATURE_1_IBT\n"));
+'
+PARSE_AND_LIST_ARGS_CASE_Z_CET='
+ else if (strcmp (optarg, "ibtplt") == 0)
+ link_info.ibtplt = TRUE;
+ else if (strcmp (optarg, "ibt") == 0)
+ link_info.ibt = TRUE;
+'
+
+PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_CET"
+PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_CET"
diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh
index 9b85239..06a0f3c 100644
--- a/ld/emulparams/elf32_x86_64.sh
+++ b/ld/emulparams/elf32_x86_64.sh
@@ -3,6 +3,7 @@
. ${srcdir}/emulparams/dynamic_undefined_weak.sh
. ${srcdir}/emulparams/reloc_overflow.sh
. ${srcdir}/emulparams/call_nop.sh
+. ${srcdir}/emulparams/cet.sh
SCRIPT_NAME=elf
ELFSIZE=32
OUTPUT_FORMAT="elf32-x86-64"
@@ -24,6 +25,7 @@ IREL_IN_PLT=
# Reuse TINY_READONLY_SECTION which is placed right after .plt section.
TINY_READONLY_SECTION="
.plt.got ${RELOCATING-0} : { *(.plt.got) }
+.plt.sec ${RELOCATING-0} : { *(.plt.sec) }
"
if [ "x${host}" = "x${target}" ]; then
diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh
index b08e661..6997d40 100644
--- a/ld/emulparams/elf_i386.sh
+++ b/ld/emulparams/elf_i386.sh
@@ -2,6 +2,7 @@
. ${srcdir}/emulparams/extern_protected_data.sh
. ${srcdir}/emulparams/dynamic_undefined_weak.sh
. ${srcdir}/emulparams/call_nop.sh
+. ${srcdir}/emulparams/cet.sh
SCRIPT_NAME=elf
OUTPUT_FORMAT="elf32-i386"
CHECK_RELOCS_AFTER_OPEN_INPUT=yes
@@ -20,6 +21,7 @@ IREL_IN_PLT=
# Reuse TINY_READONLY_SECTION which is placed right after .plt section.
TINY_READONLY_SECTION="
.plt.got ${RELOCATING-0} : { *(.plt.got) }
+.plt.sec ${RELOCATING-0} : { *(.plt.sec) }
"
# Linux modify the default library search path to first include
diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh
index ca6d06c..ad25526 100644
--- a/ld/emulparams/elf_x86_64.sh
+++ b/ld/emulparams/elf_x86_64.sh
@@ -3,6 +3,7 @@
. ${srcdir}/emulparams/dynamic_undefined_weak.sh
. ${srcdir}/emulparams/reloc_overflow.sh
. ${srcdir}/emulparams/call_nop.sh
+. ${srcdir}/emulparams/cet.sh
SCRIPT_NAME=elf
ELFSIZE=64
OUTPUT_FORMAT="elf64-x86-64"
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 44ad84b..4f7873c 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1261,6 +1261,15 @@ to a locally defined function, foo, via its GOT slot.
@option{call-nop=suffix-@var{byte}} generates @code{call foo @var{byte}}.
Supported for i386 and x86_64.
+@item ibtplt
+Generate Intel Indirect Branch Tracking (IBT) enabled PLT entries.
+Supported for Linux/i386 and Linux/x86_64.
+
+@item IBT
+Generate GNU_PROPERTY_X86_FEATURE_1_IBT in .note.gnu.property section
+to indicate compatibility with IBT. This also implies @option{ibtplt}.
+Supported for Linux/i386 and Linux/x86_64.
+
@end table
Other keywords are ignored for Solaris compatibility.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 2e3c224..d30dc76 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -420,6 +420,13 @@ run_dump_test "pr20515"
run_dump_test "property-x86-3"
run_dump_test "property-x86-4a"
run_dump_test "property-x86-4b"
+run_dump_test "property-x86-ibt1a"
+run_dump_test "property-x86-ibt1b"
+run_dump_test "property-x86-ibt2"
+run_dump_test "property-x86-ibt3a"
+run_dump_test "property-x86-ibt3b"
+run_dump_test "property-x86-ibt4"
+run_dump_test "property-x86-ibt5"
if { !([istarget "i?86-*-linux*"]
|| [istarget "i?86-*-gnu*"]
@@ -1100,6 +1107,8 @@ if { [isnative]
undefined_weak "-fPIE" "-pie -z nodynamic-undefined-weak"
}
+global NOPIE_LDFLAGS
+
# Must be native with the C compiler and working IFUNC support,
if { [isnative]
&& [check_ifunc_available]
@@ -1156,6 +1165,66 @@ if { [isnative]
"pass.out" \
] \
]
+
+ if { [istarget "i?86-*-linux*"] } {
+ run_cc_link_tests [list \
+ [list \
+ "Build pr21168.so with -z ibtplt" \
+ "-shared -Wl,-z,ibtplt" \
+ "" \
+ { pr21168b.S } \
+ "" \
+ "pr21168-ibt.so" \
+ ] \
+ [list \
+ "Build ifunc-1a with -z ibtplt" \
+ "-Wl,-z,ibtplt $NOPIE_LDFLAGS tmpdir/ifunc-1a.o \
+ tmpdir/ifunc-1b.o tmpdir/ifunc-1c.o tmpdir/ifunc-1d.o" \
+ "" \
+ { dummy.c } \
+ {{objdump {-dw} plt-main-ibt.dd}} \
+ "ifunc-1a-ibt" \
+ ] \
+ [list \
+ "Build ifunc-1a with PIE -z ibtplt" \
+ "-Wl,-z,ibtplt -pie tmpdir/ifunc-1a.o \
+ tmpdir/ifunc-1b.o tmpdir/ifunc-1c.o tmpdir/ifunc-1d.o" \
+ "" \
+ { dummy.c } \
+ {{objdump {-dw} plt-pie-ibt.dd}} \
+ "ifunc-1a-pie-ibt" \
+ ] \
+ ]
+
+ run_ld_link_exec_tests [list \
+ [list \
+ "Run ifunc-1a with -z ibtplt" \
+ "-Wl,-z,ibtplt $NOPIE_LDFLAGS tmpdir/ifunc-1a.o \
+ tmpdir/ifunc-1b.o tmpdir/ifunc-1c.o tmpdir/ifunc-1d.o" \
+ "" \
+ { dummy.c } \
+ "ifunc-1a-ibt" \
+ "pass.out" \
+ ] \
+ [list \
+ "Run ifunc-1a with PIE -z ibtplt" \
+ "-Wl,-z,ibtplt -pie tmpdir/ifunc-1a.o \
+ tmpdir/ifunc-1b.o tmpdir/ifunc-1c.o tmpdir/ifunc-1d.o" \
+ "" \
+ { dummy.c } \
+ "ifunc-1a-pie-ibt" \
+ "pass.out" \
+ ] \
+ [list \
+ "Run pr21168 with -z ibtplt" \
+ "tmpdir/pr21168a.o tmpdir/pr21168-ibt.so" \
+ "" \
+ { dummy.c } \
+ "pr21168-ibt" \
+ "pass.out" \
+ ] \
+ ]
+ }
}
if { !([istarget "i?86-*-linux*"]
@@ -1206,3 +1275,12 @@ run_ld_link_tests [list \
run_dump_test "pltgot-1"
run_dump_test "pltgot-2"
run_dump_test "pr20830"
+run_dump_test "ibt-plt-1"
+run_dump_test "ibt-plt-2a"
+run_dump_test "ibt-plt-2b"
+run_dump_test "ibt-plt-2c"
+run_dump_test "ibt-plt-2d"
+run_dump_test "ibt-plt-3a"
+run_dump_test "ibt-plt-3b"
+run_dump_test "ibt-plt-3c"
+run_dump_test "ibt-plt-3d"
diff --git a/ld/testsuite/ld-i386/ibt-plt-1.d b/ld/testsuite/ld-i386/ibt-plt-1.d
new file mode 100644
index 0000000..1c90591
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-1.d
@@ -0,0 +1,51 @@
+#as: --32
+#ld: -shared -m elf_i386
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1b0 <.plt>:
+ +[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\)
+ +[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\)
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%eax\)
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 00 00 00 00 push \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmp 1b0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 08 00 00 00 push \$0x8
+ +[a-f0-9]+: e9 d2 ff ff ff jmp 1b0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1e0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+0+1f0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 10 00 00 00 jmp \*0x10\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+Disassembly of section .text:
+
+0+200 <foo>:
+ +[a-f0-9]+: 53 push %ebx
+ +[a-f0-9]+: e8 18 00 00 00 call 21e <__x86.get_pc_thunk.bx>
+ +[a-f0-9]+: 81 c3 22 11 00 00 add \$0x1122,%ebx
+ +[a-f0-9]+: 83 ec 08 sub \$0x8,%esp
+ +[a-f0-9]+: e8 dc ff ff ff call 1f0 <bar2@plt>
+ +[a-f0-9]+: e8 c7 ff ff ff call 1e0 <bar1@plt>
+ +[a-f0-9]+: 83 c4 08 add \$0x8,%esp
+ +[a-f0-9]+: 5b pop %ebx
+ +[a-f0-9]+: c3 ret
+
+0+21e <__x86.get_pc_thunk.bx>:
+ +[a-f0-9]+: 8b 1c 24 mov \(%esp\),%ebx
+ +[a-f0-9]+: c3 ret
+#pass
diff --git a/ld/testsuite/ld-i386/ibt-plt-1.s b/ld/testsuite/ld-i386/ibt-plt-1.s
new file mode 100644
index 0000000..80e2311
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-1.s
@@ -0,0 +1,54 @@
+ .text
+ .p2align 4,,15
+ .globl foo
+ .type foo, @function
+foo:
+.LFB0:
+ .cfi_startproc
+ pushl %ebx
+ .cfi_def_cfa_offset 8
+ .cfi_offset 3, -8
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $8, %esp
+ .cfi_def_cfa_offset 16
+ call bar2@PLT
+ call bar1@PLT
+ addl $8, %esp
+ .cfi_def_cfa_offset 8
+ popl %ebx
+ .cfi_restore 3
+ .cfi_def_cfa_offset 4
+ ret
+ .cfi_endproc
+.LFE0:
+ .size foo, .-foo
+ .section .note.GNU-stack,"",@progbits
+
+ .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+.LFB1:
+ .cfi_startproc
+ movl (%esp), %ebx
+ ret
+ .cfi_endproc
+.LFE1:
+
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+ .p2align 2
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+ .p2align 2
+5:
diff --git a/ld/testsuite/ld-i386/ibt-plt-2.s b/ld/testsuite/ld-i386/ibt-plt-2.s
new file mode 100644
index 0000000..500fdd2
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-2.s
@@ -0,0 +1,54 @@
+ .text
+ .p2align 4,,15
+ .globl foo
+ .type foo, @function
+foo:
+.LFB0:
+ .cfi_startproc
+ pushl %ebx
+ .cfi_def_cfa_offset 8
+ .cfi_offset 3, -8
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $8, %esp
+ .cfi_def_cfa_offset 16
+ call bar2@PLT
+ call bar1@PLT
+ addl $8, %esp
+ .cfi_def_cfa_offset 8
+ popl %ebx
+ .cfi_restore 3
+ .cfi_def_cfa_offset 4
+ ret
+ .cfi_endproc
+.LFE0:
+ .size foo, .-foo
+ .section .note.GNU-stack,"",@progbits
+
+ .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+.LFB1:
+ .cfi_startproc
+ movl (%esp), %ebx
+ ret
+ .cfi_endproc
+.LFE1:
+
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+ .p2align 2
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x0
+4:
+ .p2align 2
+5:
diff --git a/ld/testsuite/ld-i386/ibt-plt-2a.d b/ld/testsuite/ld-i386/ibt-plt-2a.d
new file mode 100644
index 0000000..4881dea
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-2a.d
@@ -0,0 +1,52 @@
+#source: ibt-plt-2.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibtplt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1b0 <.plt>:
+ +[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\)
+ +[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\)
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%eax\)
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 00 00 00 00 push \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmp 1b0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 08 00 00 00 push \$0x8
+ +[a-f0-9]+: e9 d2 ff ff ff jmp 1b0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1e0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+0+1f0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 10 00 00 00 jmp \*0x10\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+Disassembly of section .text:
+
+0+200 <foo>:
+ +[a-f0-9]+: 53 push %ebx
+ +[a-f0-9]+: e8 18 00 00 00 call 21e <__x86.get_pc_thunk.bx>
+ +[a-f0-9]+: 81 c3 22 11 00 00 add \$0x1122,%ebx
+ +[a-f0-9]+: 83 ec 08 sub \$0x8,%esp
+ +[a-f0-9]+: e8 dc ff ff ff call 1f0 <bar2@plt>
+ +[a-f0-9]+: e8 c7 ff ff ff call 1e0 <bar1@plt>
+ +[a-f0-9]+: 83 c4 08 add \$0x8,%esp
+ +[a-f0-9]+: 5b pop %ebx
+ +[a-f0-9]+: c3 ret
+
+0+21e <__x86.get_pc_thunk.bx>:
+ +[a-f0-9]+: 8b 1c 24 mov \(%esp\),%ebx
+ +[a-f0-9]+: c3 ret
+#pass
diff --git a/ld/testsuite/ld-i386/ibt-plt-2b.d b/ld/testsuite/ld-i386/ibt-plt-2b.d
new file mode 100644
index 0000000..740b889
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-2b.d
@@ -0,0 +1,9 @@
+#source: ibt-plt-2.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibtplt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature:
diff --git a/ld/testsuite/ld-i386/ibt-plt-2c.d b/ld/testsuite/ld-i386/ibt-plt-2c.d
new file mode 100644
index 0000000..2ba1d78
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-2c.d
@@ -0,0 +1,52 @@
+#source: ibt-plt-2.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1b0 <.plt>:
+ +[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\)
+ +[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\)
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%eax\)
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 00 00 00 00 push \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmp 1b0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 08 00 00 00 push \$0x8
+ +[a-f0-9]+: e9 d2 ff ff ff jmp 1b0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1e0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+0+1f0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 10 00 00 00 jmp \*0x10\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+Disassembly of section .text:
+
+0+200 <foo>:
+ +[a-f0-9]+: 53 push %ebx
+ +[a-f0-9]+: e8 18 00 00 00 call 21e <__x86.get_pc_thunk.bx>
+ +[a-f0-9]+: 81 c3 22 11 00 00 add \$0x1122,%ebx
+ +[a-f0-9]+: 83 ec 08 sub \$0x8,%esp
+ +[a-f0-9]+: e8 dc ff ff ff call 1f0 <bar2@plt>
+ +[a-f0-9]+: e8 c7 ff ff ff call 1e0 <bar1@plt>
+ +[a-f0-9]+: 83 c4 08 add \$0x8,%esp
+ +[a-f0-9]+: 5b pop %ebx
+ +[a-f0-9]+: c3 ret
+
+0+21e <__x86.get_pc_thunk.bx>:
+ +[a-f0-9]+: 8b 1c 24 mov \(%esp\),%ebx
+ +[a-f0-9]+: c3 ret
+#pass
diff --git a/ld/testsuite/ld-i386/ibt-plt-2d.d b/ld/testsuite/ld-i386/ibt-plt-2d.d
new file mode 100644
index 0000000..3e02a62
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-2d.d
@@ -0,0 +1,9 @@
+#source: ibt-plt-2.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-i386/ibt-plt-3.s b/ld/testsuite/ld-i386/ibt-plt-3.s
new file mode 100644
index 0000000..b52f2e7
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-3.s
@@ -0,0 +1,38 @@
+ .text
+ .p2align 4,,15
+ .globl foo
+ .type foo, @function
+foo:
+.LFB0:
+ .cfi_startproc
+ pushl %ebx
+ .cfi_def_cfa_offset 8
+ .cfi_offset 3, -8
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $8, %esp
+ .cfi_def_cfa_offset 16
+ call bar2@PLT
+ call bar1@PLT
+ addl $8, %esp
+ .cfi_def_cfa_offset 8
+ popl %ebx
+ .cfi_restore 3
+ .cfi_def_cfa_offset 4
+ ret
+ .cfi_endproc
+.LFE0:
+ .size foo, .-foo
+ .section .note.GNU-stack,"",@progbits
+
+ .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+.LFB1:
+ .cfi_startproc
+ movl (%esp), %ebx
+ ret
+ .cfi_endproc
+.LFE1:
diff --git a/ld/testsuite/ld-i386/ibt-plt-3a.d b/ld/testsuite/ld-i386/ibt-plt-3a.d
new file mode 100644
index 0000000..c2ce3fd
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-3a.d
@@ -0,0 +1,52 @@
+#source: ibt-plt-3.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibtplt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+190 <.plt>:
+ +[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\)
+ +[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\)
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%eax\)
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 00 00 00 00 push \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmp 190 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 08 00 00 00 push \$0x8
+ +[a-f0-9]+: e9 d2 ff ff ff jmp 190 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1c0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+0+1d0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 10 00 00 00 jmp \*0x10\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+Disassembly of section .text:
+
+0+1e0 <foo>:
+ +[a-f0-9]+: 53 push %ebx
+ +[a-f0-9]+: e8 18 00 00 00 call 1fe <__x86.get_pc_thunk.bx>
+ +[a-f0-9]+: 81 c3 06 11 00 00 add \$0x1106,%ebx
+ +[a-f0-9]+: 83 ec 08 sub \$0x8,%esp
+ +[a-f0-9]+: e8 dc ff ff ff call 1d0 <bar2@plt>
+ +[a-f0-9]+: e8 c7 ff ff ff call 1c0 <bar1@plt>
+ +[a-f0-9]+: 83 c4 08 add \$0x8,%esp
+ +[a-f0-9]+: 5b pop %ebx
+ +[a-f0-9]+: c3 ret
+
+0+1fe <__x86.get_pc_thunk.bx>:
+ +[a-f0-9]+: 8b 1c 24 mov \(%esp\),%ebx
+ +[a-f0-9]+: c3 ret
+#pass
diff --git a/ld/testsuite/ld-i386/ibt-plt-3b.d b/ld/testsuite/ld-i386/ibt-plt-3b.d
new file mode 100644
index 0000000..d9b5be2
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-3b.d
@@ -0,0 +1,5 @@
+#source: ibt-plt-3.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibtplt
+#readelf: -n
+
diff --git a/ld/testsuite/ld-i386/ibt-plt-3c.d b/ld/testsuite/ld-i386/ibt-plt-3c.d
new file mode 100644
index 0000000..c2ce3fd
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-3c.d
@@ -0,0 +1,52 @@
+#source: ibt-plt-3.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibtplt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+190 <.plt>:
+ +[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\)
+ +[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\)
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%eax\)
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 00 00 00 00 push \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmp 190 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: 68 08 00 00 00 push \$0x8
+ +[a-f0-9]+: e9 d2 ff ff ff jmp 190 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1c0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+0+1d0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fb endbr32
+ +[a-f0-9]+: ff a3 10 00 00 00 jmp \*0x10\(%ebx\)
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%eax,%eax,1\)
+
+Disassembly of section .text:
+
+0+1e0 <foo>:
+ +[a-f0-9]+: 53 push %ebx
+ +[a-f0-9]+: e8 18 00 00 00 call 1fe <__x86.get_pc_thunk.bx>
+ +[a-f0-9]+: 81 c3 06 11 00 00 add \$0x1106,%ebx
+ +[a-f0-9]+: 83 ec 08 sub \$0x8,%esp
+ +[a-f0-9]+: e8 dc ff ff ff call 1d0 <bar2@plt>
+ +[a-f0-9]+: e8 c7 ff ff ff call 1c0 <bar1@plt>
+ +[a-f0-9]+: 83 c4 08 add \$0x8,%esp
+ +[a-f0-9]+: 5b pop %ebx
+ +[a-f0-9]+: c3 ret
+
+0+1fe <__x86.get_pc_thunk.bx>:
+ +[a-f0-9]+: 8b 1c 24 mov \(%esp\),%ebx
+ +[a-f0-9]+: c3 ret
+#pass
diff --git a/ld/testsuite/ld-i386/ibt-plt-3d.d b/ld/testsuite/ld-i386/ibt-plt-3d.d
new file mode 100644
index 0000000..3cf159a
--- /dev/null
+++ b/ld/testsuite/ld-i386/ibt-plt-3d.d
@@ -0,0 +1,9 @@
+#source: ibt-plt-3.s
+#as: --32
+#ld: -shared -m elf_i386 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-i386/plt-main-ibt.dd b/ld/testsuite/ld-i386/plt-main-ibt.dd
new file mode 100644
index 0000000..18240a2
--- /dev/null
+++ b/ld/testsuite/ld-i386/plt-main-ibt.dd
@@ -0,0 +1,7 @@
+#...
+Disassembly of section .plt.got:
+
+[a-f0-9]+ <[_a-z]+@plt>:
+[ ]*[a-f0-9]+: f3 0f 1e fb endbr32
+[ ]*[a-f0-9]+: ff 25 .. .. .. .. jmp +\*0x[a-f0-9]+
+#pass
diff --git a/ld/testsuite/ld-i386/plt-pie-ibt.dd b/ld/testsuite/ld-i386/plt-pie-ibt.dd
new file mode 100644
index 0000000..2dc016c
--- /dev/null
+++ b/ld/testsuite/ld-i386/plt-pie-ibt.dd
@@ -0,0 +1,7 @@
+#...
+Disassembly of section .plt.got:
+
+[a-f0-9]+ <[_a-z]+@plt>:
+[ ]*[a-f0-9]+: f3 0f 1e fb endbr32
+[ ]*[a-f0-9]+: ff a3 .. .. .. .. jmp +\*\-0x[a-f0-9]+\(%ebx\)
+#pass
diff --git a/ld/testsuite/ld-i386/property-x86-empty.s b/ld/testsuite/ld-i386/property-x86-empty.s
new file mode 100644
index 0000000..6a6b517
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-empty.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x0
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/ld/testsuite/ld-i386/property-x86-ibt.s b/ld/testsuite/ld-i386/property-x86-ibt.s
new file mode 100644
index 0000000..84ee964
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/ld/testsuite/ld-i386/property-x86-ibt1a.d b/ld/testsuite/ld-i386/property-x86-ibt1a.d
new file mode 100644
index 0000000..43b272f
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt1a.d
@@ -0,0 +1,6 @@
+#source: property-x86-empty.s
+#source: property-x86-ibt.s
+#as: --32
+#ld: -r -melf_i386
+#readelf: -n
+
diff --git a/ld/testsuite/ld-i386/property-x86-ibt1b.d b/ld/testsuite/ld-i386/property-x86-ibt1b.d
new file mode 100644
index 0000000..83bf411
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt1b.d
@@ -0,0 +1,6 @@
+#source: property-x86-ibt.s
+#source: property-x86-empty.s
+#as: --32
+#ld: -r -melf_i386
+#readelf: -n
+
diff --git a/ld/testsuite/ld-i386/property-x86-ibt2.d b/ld/testsuite/ld-i386/property-x86-ibt2.d
new file mode 100644
index 0000000..fbdf4c1
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt2.d
@@ -0,0 +1,9 @@
+#source: property-x86-ibt.s
+#as: --32
+#ld: -r -melf_i386
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-i386/property-x86-ibt3a.d b/ld/testsuite/ld-i386/property-x86-ibt3a.d
new file mode 100644
index 0000000..4bb35b0
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt3a.d
@@ -0,0 +1,11 @@
+#source: property-x86-3.s
+#source: property-x86-ibt.s
+#as: --32
+#ld: -r -melf_i386
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 ISA used: i486, 586, SSE2, SSE3
+ x86 ISA needed: 586, SSE, SSE3, SSE4_1
diff --git a/ld/testsuite/ld-i386/property-x86-ibt3b.d b/ld/testsuite/ld-i386/property-x86-ibt3b.d
new file mode 100644
index 0000000..418d58a
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt3b.d
@@ -0,0 +1,11 @@
+#source: property-x86-ibt.s
+#source: property-x86-3.s
+#as: --32
+#ld: -r -melf_i386
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 ISA used: i486, 586, SSE2, SSE3
+ x86 ISA needed: 586, SSE, SSE3, SSE4_1
diff --git a/ld/testsuite/ld-i386/property-x86-ibt4.d b/ld/testsuite/ld-i386/property-x86-ibt4.d
new file mode 100644
index 0000000..db14fb9
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt4.d
@@ -0,0 +1,9 @@
+#source: property-x86-empty.s
+#as: --32
+#ld: -r -melf_i386 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-i386/property-x86-ibt5.d b/ld/testsuite/ld-i386/property-x86-ibt5.d
new file mode 100644
index 0000000..652f660
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-ibt5.d
@@ -0,0 +1,9 @@
+#source: start.s
+#as: --32
+#ld: -r -melf_i386 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-1-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-1-x32.d
new file mode 100644
index 0000000..6147ab4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-1-x32.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-1.s
+#as: --x32
+#ld: -shared -m elf32_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1c0 <.plt>:
+ +[a-f0-9]+: ff 35 6a 01 20 00 pushq 0x20016a\(%rip\) # 200330 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: ff 25 6c 01 20 00 jmpq \*0x20016c\(%rip\) # 200338 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: e9 d2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1f0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 46 01 20 00 jmpq \*0x200146\(%rip\) # 200340 <bar1>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+0+200 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 3e 01 20 00 jmpq \*0x20013e\(%rip\) # 200348 <bar2>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+210 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 200 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 1f0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-1.d b/ld/testsuite/ld-x86-64/ibt-plt-1.d
new file mode 100644
index 0000000..dbec3ed
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-1.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-1.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+290 <.plt>:
+ +[a-f0-9]+: ff 35 ea 01 20 00 pushq 0x2001ea\(%rip\) # 200480 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: f2 ff 25 eb 01 20 00 bnd jmpq \*0x2001eb\(%rip\) # 200488 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: f2 e9 e1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: f2 e9 d1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+
+Disassembly of section .plt.sec:
+
+0+2c0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 c5 01 20 00 bnd jmpq \*0x2001c5\(%rip\) # 200490 <bar1>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+0+2d0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 bd 01 20 00 bnd jmpq \*0x2001bd\(%rip\) # 200498 <bar2>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+2e0 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 2d0 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 2c0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-1.s b/ld/testsuite/ld-x86-64/ibt-plt-1.s
new file mode 100644
index 0000000..2ddf3bb
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-1.s
@@ -0,0 +1,45 @@
+ .text
+ .p2align 4,,15
+ .globl foo
+ .type foo, @function
+foo:
+.LFB0:
+ .cfi_startproc
+ subq $8, %rsp
+ .cfi_def_cfa_offset 16
+ call bar2@PLT
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ jmp bar1@PLT
+ .cfi_endproc
+.LFE0:
+ .size foo, .-foo
+ .section .note.GNU-stack,"",@progbits
+
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2.s b/ld/testsuite/ld-x86-64/ibt-plt-2.s
new file mode 100644
index 0000000..e1ea540
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2.s
@@ -0,0 +1,45 @@
+ .text
+ .p2align 4,,15
+ .globl foo
+ .type foo, @function
+foo:
+.LFB0:
+ .cfi_startproc
+ subq $8, %rsp
+ .cfi_def_cfa_offset 16
+ call bar2@PLT
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ jmp bar1@PLT
+ .cfi_endproc
+.LFE0:
+ .size foo, .-foo
+ .section .note.GNU-stack,"",@progbits
+
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x0
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d
new file mode 100644
index 0000000..df9dc8e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-2.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibtplt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1c0 <.plt>:
+ +[a-f0-9]+: ff 35 6a 01 20 00 pushq 0x20016a\(%rip\) # 200330 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: ff 25 6c 01 20 00 jmpq \*0x20016c\(%rip\) # 200338 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: e9 d2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1f0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 46 01 20 00 jmpq \*0x200146\(%rip\) # 200340 <bar1>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+0+200 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 3e 01 20 00 jmpq \*0x20013e\(%rip\) # 200348 <bar2>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+210 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 200 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 1f0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2a.d b/ld/testsuite/ld-x86-64/ibt-plt-2a.d
new file mode 100644
index 0000000..0e4f424
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2a.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-2.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibtplt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+290 <.plt>:
+ +[a-f0-9]+: ff 35 ea 01 20 00 pushq 0x2001ea\(%rip\) # 200480 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: f2 ff 25 eb 01 20 00 bnd jmpq \*0x2001eb\(%rip\) # 200488 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: f2 e9 e1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: f2 e9 d1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+
+Disassembly of section .plt.sec:
+
+0+2c0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 c5 01 20 00 bnd jmpq \*0x2001c5\(%rip\) # 200490 <bar1>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+0+2d0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 bd 01 20 00 bnd jmpq \*0x2001bd\(%rip\) # 200498 <bar2>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+2e0 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 2d0 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 2c0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2b-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-2b-x32.d
new file mode 100644
index 0000000..e9e5638
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2b-x32.d
@@ -0,0 +1,9 @@
+#source: ibt-plt-2.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibtplt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature:
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2b.d b/ld/testsuite/ld-x86-64/ibt-plt-2b.d
new file mode 100644
index 0000000..604db82
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2b.d
@@ -0,0 +1,9 @@
+#source: ibt-plt-2.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibtplt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature:
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2c-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-2c-x32.d
new file mode 100644
index 0000000..e908804
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2c-x32.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-2.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1c0 <.plt>:
+ +[a-f0-9]+: ff 35 6a 01 20 00 pushq 0x20016a\(%rip\) # 200330 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: ff 25 6c 01 20 00 jmpq \*0x20016c\(%rip\) # 200338 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: e9 d2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1f0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 46 01 20 00 jmpq \*0x200146\(%rip\) # 200340 <bar1>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+0+200 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 3e 01 20 00 jmpq \*0x20013e\(%rip\) # 200348 <bar2>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+210 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 200 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 1f0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2c.d b/ld/testsuite/ld-x86-64/ibt-plt-2c.d
new file mode 100644
index 0000000..0ef1131
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2c.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-2.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+290 <.plt>:
+ +[a-f0-9]+: ff 35 ea 01 20 00 pushq 0x2001ea\(%rip\) # 200480 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: f2 ff 25 eb 01 20 00 bnd jmpq \*0x2001eb\(%rip\) # 200488 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: f2 e9 e1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: f2 e9 d1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+
+Disassembly of section .plt.sec:
+
+0+2c0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 c5 01 20 00 bnd jmpq \*0x2001c5\(%rip\) # 200490 <bar1>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+0+2d0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 bd 01 20 00 bnd jmpq \*0x2001bd\(%rip\) # 200498 <bar2>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+2e0 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 2d0 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 2c0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2d-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-2d-x32.d
new file mode 100644
index 0000000..b3be904
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2d-x32.d
@@ -0,0 +1,9 @@
+#source: ibt-plt-2.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2d.d b/ld/testsuite/ld-x86-64/ibt-plt-2d.d
new file mode 100644
index 0000000..7226b69
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-2d.d
@@ -0,0 +1,9 @@
+#source: ibt-plt-2.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3.s b/ld/testsuite/ld-x86-64/ibt-plt-3.s
new file mode 100644
index 0000000..299b023
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3.s
@@ -0,0 +1,17 @@
+ .text
+ .p2align 4,,15
+ .globl foo
+ .type foo, @function
+foo:
+.LFB0:
+ .cfi_startproc
+ subq $8, %rsp
+ .cfi_def_cfa_offset 16
+ call bar2@PLT
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ jmp bar1@PLT
+ .cfi_endproc
+.LFE0:
+ .size foo, .-foo
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d
new file mode 100644
index 0000000..0f7835d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-3.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibtplt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1a0 <.plt>:
+ +[a-f0-9]+: ff 35 52 01 20 00 pushq 0x200152\(%rip\) # 2002f8 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: ff 25 54 01 20 00 jmpq \*0x200154\(%rip\) # 200300 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmpq 1a0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: e9 d2 ff ff ff jmpq 1a0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1d0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 2e 01 20 00 jmpq \*0x20012e\(%rip\) # 200308 <bar1>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+0+1e0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 26 01 20 00 jmpq \*0x200126\(%rip\) # 200310 <bar2>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+1f0 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 1e0 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 1d0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3a.d b/ld/testsuite/ld-x86-64/ibt-plt-3a.d
new file mode 100644
index 0000000..b8f2ebc
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3a.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-3.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibtplt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+250 <.plt>:
+ +[a-f0-9]+: ff 35 ca 01 20 00 pushq 0x2001ca\(%rip\) # 200420 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: f2 ff 25 cb 01 20 00 bnd jmpq \*0x2001cb\(%rip\) # 200428 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: f2 e9 e1 ff ff ff bnd jmpq 250 <.plt>
+ +[a-f0-9]+: 90 nop
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: f2 e9 d1 ff ff ff bnd jmpq 250 <.plt>
+ +[a-f0-9]+: 90 nop
+
+Disassembly of section .plt.sec:
+
+0+280 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 a5 01 20 00 bnd jmpq \*0x2001a5\(%rip\) # 200430 <bar1>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+0+290 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 9d 01 20 00 bnd jmpq \*0x20019d\(%rip\) # 200438 <bar2>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+2a0 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 290 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 280 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3b-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-3b-x32.d
new file mode 100644
index 0000000..fb0a834
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3b-x32.d
@@ -0,0 +1,5 @@
+#source: ibt-plt-3.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibtplt
+#readelf: -n
+
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3b.d b/ld/testsuite/ld-x86-64/ibt-plt-3b.d
new file mode 100644
index 0000000..5a3843b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3b.d
@@ -0,0 +1,5 @@
+#source: ibt-plt-3.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibtplt
+#readelf: -n
+
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3c-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-3c-x32.d
new file mode 100644
index 0000000..234944d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3c-x32.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-3.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+1c0 <.plt>:
+ +[a-f0-9]+: ff 35 6a 01 20 00 pushq 0x20016a\(%rip\) # 200330 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: ff 25 6c 01 20 00 jmpq \*0x20016c\(%rip\) # 200338 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: e9 e2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: e9 d2 ff ff ff jmpq 1c0 <.plt>
+ +[a-f0-9]+: 66 90 xchg %ax,%ax
+
+Disassembly of section .plt.sec:
+
+0+1f0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 46 01 20 00 jmpq \*0x200146\(%rip\) # 200340 <bar1>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+0+200 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: ff 25 3e 01 20 00 jmpq \*0x20013e\(%rip\) # 200348 <bar2>
+ +[a-f0-9]+: 66 0f 1f 44 00 00 nopw 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+210 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 200 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 1f0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3c.d b/ld/testsuite/ld-x86-64/ibt-plt-3c.d
new file mode 100644
index 0000000..b299f22
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3c.d
@@ -0,0 +1,43 @@
+#source: ibt-plt-3.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibt
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .plt:
+
+0+290 <.plt>:
+ +[a-f0-9]+: ff 35 ea 01 20 00 pushq 0x2001ea\(%rip\) # 200480 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: f2 ff 25 eb 01 20 00 bnd jmpq \*0x2001eb\(%rip\) # 200488 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: f2 e9 e1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+ +[a-f0-9]+: f2 e9 d1 ff ff ff bnd jmpq 290 <.plt>
+ +[a-f0-9]+: 90 nop
+
+Disassembly of section .plt.sec:
+
+0+2c0 <bar1@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 c5 01 20 00 bnd jmpq \*0x2001c5\(%rip\) # 200490 <bar1>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+0+2d0 <bar2@plt>:
+ +[a-f0-9]+: f3 0f 1e fa endbr64
+ +[a-f0-9]+: f2 ff 25 bd 01 20 00 bnd jmpq \*0x2001bd\(%rip\) # 200498 <bar2>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+2e0 <foo>:
+ +[a-f0-9]+: 48 83 ec 08 sub \$0x8,%rsp
+ +[a-f0-9]+: e8 e7 ff ff ff callq 2d0 <bar2@plt>
+ +[a-f0-9]+: 48 83 c4 08 add \$0x8,%rsp
+ +[a-f0-9]+: e9 ce ff ff ff jmpq 2c0 <bar1@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3d-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-3d-x32.d
new file mode 100644
index 0000000..447e811
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3d-x32.d
@@ -0,0 +1,10 @@
+#source: ibt-plt-3.s
+#as: --x32
+#ld: -shared -m elf32_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
+
diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3d.d b/ld/testsuite/ld-x86-64/ibt-plt-3d.d
new file mode 100644
index 0000000..342626a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ibt-plt-3d.d
@@ -0,0 +1,10 @@
+#source: ibt-plt-3.s
+#as: --64 -defsym __64_bit__=1
+#ld: -shared -m elf_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
+
diff --git a/ld/testsuite/ld-x86-64/plt-main-ibt-now.rd b/ld/testsuite/ld-x86-64/plt-main-ibt-now.rd
new file mode 100644
index 0000000..2478c1f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/plt-main-ibt-now.rd
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] \.plt\.sec +.*
+#pass
diff --git a/ld/testsuite/ld-x86-64/plt-main-ibt-x32.dd b/ld/testsuite/ld-x86-64/plt-main-ibt-x32.dd
new file mode 100644
index 0000000..7b5e174
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/plt-main-ibt-x32.dd
@@ -0,0 +1,7 @@
+#...
+Disassembly of section .plt.got:
+
+[a-f0-9]+ <[_a-z]+@plt>:
+[ ]*[a-f0-9]+: f3 0f 1e fa endbr64
+[ ]*[a-f0-9]+: ff 25 .. .. 20 00 jmpq +\*0x20....\(%rip\) # ...... <[_a-z]+>
+#pass
diff --git a/ld/testsuite/ld-x86-64/plt-main-ibt.dd b/ld/testsuite/ld-x86-64/plt-main-ibt.dd
new file mode 100644
index 0000000..725f427
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/plt-main-ibt.dd
@@ -0,0 +1,7 @@
+#...
+Disassembly of section .plt.got:
+
+[a-f0-9]+ <[_a-z]+@plt>:
+[ ]*[a-f0-9]+: f3 0f 1e fa endbr64
+[ ]*[a-f0-9]+: f2 ff 25 .. .. 20 00 bnd jmpq \*0x20....\(%rip\) # ...... <[_a-z]+>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr21481b.S b/ld/testsuite/ld-x86-64/pr21481b.S
index 744d86a..583ec77 100644
--- a/ld/testsuite/ld-x86-64/pr21481b.S
+++ b/ld/testsuite/ld-x86-64/pr21481b.S
@@ -10,7 +10,11 @@ check:
cmpl $func1, %eax
jne .L3
movq func1_p@GOTPCREL(%rip), %rdx
+#ifdef __LP64__
cmpq %rax, (%rdx)
+#else
+ cmpl %eax, (%rdx)
+#endif
jne .L3
call *func1@GOTPCREL(%rip)
cmpl $1, %eax
diff --git a/ld/testsuite/ld-x86-64/property-x86-empty.s b/ld/testsuite/ld-x86-64/property-x86-empty.s
new file mode 100644
index 0000000..6a6b517
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-empty.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x0
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt.s b/ld/testsuite/ld-x86-64/property-x86-ibt.s
new file mode 100644
index 0000000..84ee964
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt.s
@@ -0,0 +1,27 @@
+ .section ".note.gnu.property", "a"
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+2: .long 0xc0000002 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+.ifdef __64_bit__
+ .p2align 3
+.else
+ .p2align 2
+.endif
+5:
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d
new file mode 100644
index 0000000..b215d79d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d
@@ -0,0 +1,6 @@
+#source: property-x86-empty.s
+#source: property-x86-ibt.s
+#as: --x32
+#ld: -r -m elf32_x86_64
+#readelf: -n
+
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt1a.d b/ld/testsuite/ld-x86-64/property-x86-ibt1a.d
new file mode 100644
index 0000000..50f220c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt1a.d
@@ -0,0 +1,6 @@
+#source: property-x86-empty.s
+#source: property-x86-ibt.s
+#as: --64 -defsym __64_bit__=1
+#ld: -r -melf_x86_64
+#readelf: -n
+
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt1b-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt1b-x32.d
new file mode 100644
index 0000000..7361cea
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt1b-x32.d
@@ -0,0 +1,6 @@
+#source: property-x86-ibt.s
+#source: property-x86-empty.s
+#as: --x32
+#ld: -r -m elf32_x86_64
+#readelf: -n
+
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt1b.d b/ld/testsuite/ld-x86-64/property-x86-ibt1b.d
new file mode 100644
index 0000000..7f47db7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt1b.d
@@ -0,0 +1,6 @@
+#source: property-x86-ibt.s
+#source: property-x86-empty.s
+#as: --64 -defsym __64_bit__=1
+#ld: -r -melf_x86_64
+#readelf: -n
+
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt2-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt2-x32.d
new file mode 100644
index 0000000..a0fb614
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt2-x32.d
@@ -0,0 +1,9 @@
+#source: property-x86-ibt.s
+#as: --x32
+#ld: -r -m elf32_x86_64
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt2.d b/ld/testsuite/ld-x86-64/property-x86-ibt2.d
new file mode 100644
index 0000000..be3df9c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt2.d
@@ -0,0 +1,9 @@
+#source: property-x86-ibt.s
+#as: --64 -defsym __64_bit__=1
+#ld: -r -melf_x86_64
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt3a-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt3a-x32.d
new file mode 100644
index 0000000..011426f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt3a-x32.d
@@ -0,0 +1,11 @@
+#source: property-x86-3.s
+#source: property-x86-ibt.s
+#as: --x32
+#ld: -r -m elf32_x86_64
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1
+ x86 ISA needed: i486, 586, SSE2, SSE3
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt3a.d b/ld/testsuite/ld-x86-64/property-x86-ibt3a.d
new file mode 100644
index 0000000..1b4229a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt3a.d
@@ -0,0 +1,11 @@
+#source: property-x86-3.s
+#source: property-x86-ibt.s
+#as: --64 -defsym __64_bit__=1
+#ld: -r -melf_x86_64
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1
+ x86 ISA needed: i486, 586, SSE2, SSE3
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt3b-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt3b-x32.d
new file mode 100644
index 0000000..290ed6a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt3b-x32.d
@@ -0,0 +1,11 @@
+#source: property-x86-ibt.s
+#source: property-x86-3.s
+#as: --x32
+#ld: -r -m elf32_x86_64
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1
+ x86 ISA needed: i486, 586, SSE2, SSE3
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt3b.d b/ld/testsuite/ld-x86-64/property-x86-ibt3b.d
new file mode 100644
index 0000000..1142e03
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt3b.d
@@ -0,0 +1,11 @@
+#source: property-x86-ibt.s
+#source: property-x86-3.s
+#as: --64 -defsym __64_bit__=1
+#ld: -r -melf_x86_64
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1
+ x86 ISA needed: i486, 586, SSE2, SSE3
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt4-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt4-x32.d
new file mode 100644
index 0000000..b96abbc
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt4-x32.d
@@ -0,0 +1,9 @@
+#source: property-x86-empty.s
+#as: --x32
+#ld: -r -m elf32_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt4.d b/ld/testsuite/ld-x86-64/property-x86-ibt4.d
new file mode 100644
index 0000000..3f61a76
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt4.d
@@ -0,0 +1,9 @@
+#source: property-x86-empty.s
+#as: --64 -defsym __64_bit__=1
+#ld: -r -melf_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt5-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt5-x32.d
new file mode 100644
index 0000000..5245d0b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt5-x32.d
@@ -0,0 +1,9 @@
+#source: start.s
+#as: --x32
+#ld: -r -m elf32_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt5.d b/ld/testsuite/ld-x86-64/property-x86-ibt5.d
new file mode 100644
index 0000000..ab74033
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-ibt5.d
@@ -0,0 +1,9 @@
+#source: start.s
+#as: --64 -defsym __64_bit__=1
+#ld: -r -melf_x86_64 -z ibt
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+ Owner Data size Description
+ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
+ Properties: x86 feature: IBT
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 21f408d..6cde22f 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -335,6 +335,20 @@ run_dump_test "property-x86-4b"
run_dump_test "property-x86-3-x32"
run_dump_test "property-x86-4a-x32"
run_dump_test "property-x86-4b-x32"
+run_dump_test "property-x86-ibt1a"
+run_dump_test "property-x86-ibt1b"
+run_dump_test "property-x86-ibt1a-x32"
+run_dump_test "property-x86-ibt1b-x32"
+run_dump_test "property-x86-ibt2"
+run_dump_test "property-x86-ibt2-x32"
+run_dump_test "property-x86-ibt3a"
+run_dump_test "property-x86-ibt3b"
+run_dump_test "property-x86-ibt3a-x32"
+run_dump_test "property-x86-ibt3b-x32"
+run_dump_test "property-x86-ibt4"
+run_dump_test "property-x86-ibt4-x32"
+run_dump_test "property-x86-ibt5"
+run_dump_test "property-x86-ibt5-x32"
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
return
@@ -1350,6 +1364,156 @@ if { [isnative] && [which $CC] != 0 } {
}
}
+ if { [istarget "x86_64-*-linux*"] } {
+ if { [istarget "x86_64-*-linux*-gnux32"] } {
+ set pltdump {{objdump {-drw} plt-main-ibt-x32.dd}}
+ set pltsecdump {{readelf {-SW} plt-main-ibt-now.rd} {objdump {-drw} plt-main-ibt-x32.dd}}
+ } else {
+ set pltdump {{objdump {-drw} plt-main-ibt.dd}}
+ set pltsecdump {{readelf {-SW} plt-main-ibt-now.rd} {objdump {-drw} plt-main-ibt.dd}}
+ }
+ run_cc_link_tests [list \
+ [list \
+ "Build plt-main with -z ibtplt" \
+ "tmpdir/plt-main1.o tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so -z ibtplt" \
+ "" \
+ { plt-main5.c } \
+ $pltdump \
+ "plt-main-ibt" \
+ ] \
+ [list \
+ "Build plt-main with PIE and -z ibtplt" \
+ "tmpdir/plt-main1.o tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so -z ibtplt -pie" \
+ "-fPIC" \
+ { plt-main5.c } \
+ $pltdump \
+ "plt-main-pie-ibt" \
+ ] \
+ [list \
+ "Build plt-main with -z ibtplt -z now" \
+ "tmpdir/plt-main1.o tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so -z ibtplt -z now" \
+ "" \
+ { plt-main5.c } \
+ $pltsecdump \
+ "plt-main-ibt-now" \
+ ] \
+ [list \
+ "Build plt-main with PIE and -z ibtplt -z now" \
+ "tmpdir/plt-main1.o tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so -z ibtplt -z now -pie" \
+ "-fPIC" \
+ { plt-main5.c } \
+ $pltsecdump \
+ "plt-main-pie-ibt-now" \
+ ] \
+ [list \
+ "Build libibtplt-lib.so with -z ibtplt" \
+ "-shared -z ibtplt" \
+ "-fPIC" \
+ { plt-main1.c plt-main2.c plt-main3.c plt-main4.c} \
+ $pltdump \
+ "libibtplt-lib.so" \
+ ] \
+ [list \
+ "Build libibtplt--now-lib.so with -z ibtplt -z now" \
+ "-shared -z ibtplt -z now" \
+ "-fPIC" \
+ { plt-main1.c plt-main2.c plt-main3.c plt-main4.c} \
+ $pltdump \
+ "libibtplt-now-lib.so" \
+ ] \
+ ]
+
+ run_ld_link_exec_tests [list \
+ [list \
+ "Run plt-main with -z ibtplt" \
+ "-Wl,--no-as-needed,-z,ibtplt tmpdir/plt-main1.o \
+ tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so" \
+ "" \
+ { plt-main5.c } \
+ "plt-main-ibt" \
+ "plt-main.out" \
+ ] \
+ [list \
+ "Run plt-main with PIE and -z ibtplt" \
+ "-Wl,--no-as-needed,-z,ibtplt -pie tmpdir/plt-main1.o \
+ tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so" \
+ "" \
+ { plt-main5.c } \
+ "plt-main-pie-ibt" \
+ "plt-main.out" \
+ "-fPIC" \
+ ] \
+ [list \
+ "Run plt-main with -z ibtplt -z now" \
+ "-Wl,--no-as-needed,-z,ibtplt,-z,now tmpdir/plt-main1.o \
+ tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so" \
+ "" \
+ { plt-main5.c } \
+ "plt-main-ibt-now" \
+ "plt-main.out" \
+ ] \
+ [list \
+ "Run plt-main with PIE and -z ibtplt -z now" \
+ "-Wl,--no-as-needed,-z,ibtplt,-z,now -pie tmpdir/plt-main1.o \
+ tmpdir/plt-main2.o tmpdir/plt-main3.o \
+ tmpdir/plt-main4.o tmpdir/libplt-lib.so" \
+ "" \
+ { plt-main5.c } \
+ "plt-main-pie-ibt-now" \
+ "plt-main.out" \
+ "-fPIC" \
+ ] \
+ [list \
+ "Run plt-main with libibtplt-lib.so -z ibtplt" \
+ "-Wl,--no-as-needed,-z,ibtplt tmpdir/libibtplt-lib.so \
+ tmpdir/libplt-lib.so" \
+ "" \
+ { plt-main5.c } \
+ "plt-main-ibt-lib" \
+ "plt-main.out" \
+ ] \
+ [list \
+ "Run plt-main with libibtplt-lib.so -z ibtplt -z now" \
+ "-Wl,--no-as-needed,-z,ibtplt,-z,now \
+ tmpdir/libibtplt-now-lib.so tmpdir/libplt-lib.so" \
+ "" \
+ { plt-main5.c } \
+ "plt-main-ibt-now-lib" \
+ "plt-main.out" \
+ ] \
+ ]
+
+ if { [check_ifunc_attribute_available] } {
+ run_ld_link_exec_tests [list \
+ [list \
+ "Run pr21481a" \
+ "$NOPIE_LDFLAGS -Wl,-z,ibtplt" \
+ "" \
+ { pr21481a.c pr21481b.S } \
+ "pr21481a" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+ "Run pr21481b" \
+ "$NOPIE_LDFLAGS -Wl,-z,ibtplt,-z,now" \
+ "" \
+ { pr21481a.c pr21481b.S } \
+ "pr21481b" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ ]
+ }
+ }
+
undefined_weak "$NOPIE_CFLAGS" "$NOPIE_LDFLAGS"
undefined_weak "-fPIE" ""
undefined_weak "-fPIE" "-pie"
@@ -1405,3 +1569,21 @@ run_dump_test "pr20830b-now"
run_dump_test "pr21038a-now"
run_dump_test "pr21038b-now"
run_dump_test "pr21038c-now"
+run_dump_test "ibt-plt-1"
+run_dump_test "ibt-plt-1-x32"
+run_dump_test "ibt-plt-2a"
+run_dump_test "ibt-plt-2b"
+run_dump_test "ibt-plt-2c"
+run_dump_test "ibt-plt-2d"
+run_dump_test "ibt-plt-2a-x32"
+run_dump_test "ibt-plt-2b-x32"
+run_dump_test "ibt-plt-2c-x32"
+run_dump_test "ibt-plt-2d-x32"
+run_dump_test "ibt-plt-3a"
+run_dump_test "ibt-plt-3b"
+run_dump_test "ibt-plt-3c"
+run_dump_test "ibt-plt-3d"
+run_dump_test "ibt-plt-3a-x32"
+run_dump_test "ibt-plt-3b-x32"
+run_dump_test "ibt-plt-3c-x32"
+run_dump_test "ibt-plt-3d-x32"