This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH 1/2] x86: Support Intel IBT with IBT property and IBT-enable PLT
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Thu, 22 Jun 2017 05:53:06 -0700
- Subject: Re: [PATCH 1/2] x86: Support Intel IBT with IBT property and IBT-enable PLT
- Authentication-results: sourceware.org; auth=none
- References: <20170621195023.GA7041@gmail.com>
On Wed, Jun 21, 2017 at 12:50 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> 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.
I checked it in.
--
H.J.