x86: Support Intel IBT with IBT property and IBT-enable PLT

To support IBT in Intel Control-flow Enforcement Technology (CET)
instructions:

https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf

 #define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002

 #define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0)

are added to GNU program properties to indicate that all executable
sections are compatible with IBT when ENDBR instruction starts each
valid target where an indirect branch instruction can land.

GNU_PROPERTY_X86_FEATURE_1_IBT is set on output only if it is set on
all relocatable inputs.

The followings changes are made to the Procedure Linkage Table (PLT):

1. For 64-bit x86-64,  PLT is changed to

PLT0:  push       GOT[1]
       bnd jmp    *GOT[2]
       nop
...
PLTn:  endbr64
       push       namen_reloc_index
       bnd jmp    PLT0

together with the second PLT section:

PLTn:  endbr64
       bnd jmp   *GOT[namen_index]
       nop

BND prefix is also added so that IBT-enabled PLT is compatible with MPX.

2. For 32-bit x86-64 (x32) and i386,  PLT is changed to

PLT0:  push       GOT[1]
       jmp        *GOT[2]
       nop
...
PLTn:  endbr64                                 # endbr32 for i386.
       push       namen_reloc_index
       jmp        PLT0

together with the second PLT section:

PLTn:  endbr64                                 # endbr32 for i386.
       jmp       *GOT[namen_index]
       nop

BND prefix isn't used since MPX isn't supported on x32 and BND registers
aren't used in parameter passing on i386.

GOT is an array of addresses.  Initially, GOT[namen_index] is filled
with the address of the ENDBR instruction of the corresponding entry
in the first PLT section.  The function, namen, is called via the
ENDBR instruction in the second PLT entry.  GOT[namen_index] is updated
to the actual address of the function, namen, at run-time.

2 linker command line options are added:

1. -z ibtplt: Generate IBT-enabled PLT.
2. -z ibt: Generate GNU_PROPERTY_X86_FEATURE_1_IBT in GNU program
properties as well as IBT-enabled PLT.

bfd/

	* 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.

binutils/

	* 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.

include/

	* 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.

ld/

	* 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.
This commit is contained in:
H.J. Lu 2017-06-22 05:44:37 -07:00
parent f4906a9a74
commit ee2fdd6f36
93 changed files with 2967 additions and 76 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;
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;
}
/* 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;
}

View File

@ -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.

View File

@ -16337,6 +16337,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)
{
@ -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;
}

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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@

View File

@ -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.

View File

@ -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.

14
ld/emulparams/cet.sh Normal file
View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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"

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -0,0 +1,5 @@
#source: ibt-plt-3.s
#as: --32
#ld: -shared -m elf_i386 -z ibtplt
#readelf: -n

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -0,0 +1,6 @@
#source: property-x86-empty.s
#source: property-x86-ibt.s
#as: --32
#ld: -r -melf_i386
#readelf: -n

View File

@ -0,0 +1,6 @@
#source: property-x86-ibt.s
#source: property-x86-empty.s
#as: --32
#ld: -r -melf_i386
#readelf: -n

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
#source: ibt-plt-3.s
#as: --x32
#ld: -shared -m elf32_x86_64 -z ibtplt
#readelf: -n

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
#...
+\[[ 0-9]+\] \.plt\.sec +.*
#pass

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -0,0 +1,6 @@
#source: property-x86-empty.s
#source: property-x86-ibt.s
#as: --x32
#ld: -r -m elf32_x86_64
#readelf: -n

View File

@ -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

View File

@ -0,0 +1,6 @@
#source: property-x86-ibt.s
#source: property-x86-empty.s
#as: --x32
#ld: -r -m elf32_x86_64
#readelf: -n

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"