From 48580982ef41907a45cda259a63d9e6878cbbea3 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 22 Jun 2017 05:50:20 -0700 Subject: [PATCH] x86: Support Intel Shadow Stack with SHSTK property To support Intel Shadow Stack (SHSTK) 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_SHSTK (1U << 1) is added to GNU program properties to indicate that all executable sections are compatible with SHSTK where return address popped from shadow stack always matches return address popped from normal stack. GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on output only if it is set on all relocatable inputs. bfd/ * elf32-i386.c (elf_i386_merge_gnu_properties): If info->shstk is set, turn on GNU_PROPERTY_X86_FEATURE_1_SHSTK. (elf_i386_link_setup_gnu_properties): If info->shstk is set, turn on GNU_PROPERTY_X86_FEATURE_1_IBT. * elf64-x86-64.c (elf_x86_64_merge_gnu_properties): If info->shstk is set, turn on GNU_PROPERTY_X86_FEATURE_1_SHSTK. (elf_x86_64_link_setup_gnu_properties): If info->shstk is set, turn on GNU_PROPERTY_X86_FEATURE_1_IBT. binutils/ * readelf.c (decode_x86_feature): Decode GNU_PROPERTY_X86_FEATURE_1_SHSTK. * testsuite/binutils-all/i386/shstk.d: New file. * testsuite/binutils-all/i386/shstk.s: Likewise. * testsuite/binutils-all/x86-64/shstk-x32.d: Likewise. * testsuite/binutils-all/x86-64/shstk.d: Likewise. * testsuite/binutils-all/x86-64/shstk.s: Likewise. include/ * bfdlink.h (bfd_link_info): Add shstk. * elf/common.h (GNU_PROPERTY_X86_FEATURE_1_SHSTK): New. ld/ * NEWS: Mention -z shstk and GNU_PROPERTY_X86_FEATURE_1_SHSTK. * emulparams/cet.sh (PARSE_AND_LIST_OPTIONS_CET): Add "-z shstk". (PARSE_AND_LIST_ARGS_CASE_Z_CET): Support "-z shstk". * ld.texinfo: Document -z shstk. * testsuite/ld-i386/i386.exp: Run SHSTK tests. * testsuite/ld-x86-64/x86-64.exp: Likewise. * testsuite/ld-i386/property-x86-shstk.s: New file. * testsuite/ld-i386/property-x86-shstk1a.d: Likewise. * testsuite/ld-i386/property-x86-shstk1b.d: Likewise. * testsuite/ld-i386/property-x86-shstk2.d: Likewise. * testsuite/ld-i386/property-x86-shstk3a.d: Likewise. * testsuite/ld-i386/property-x86-shstk3b.d: Likewise. * testsuite/ld-i386/property-x86-shstk4.d: Likewise. * testsuite/ld-i386/property-x86-shstk5.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk.s: Likewise. * testsuite/ld-x86-64/property-x86-shstk1a-x32.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk1a.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk1b-x32.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk1b.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk2-x32.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk2.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk3a-x32.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk3a.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk3b-x32.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk3b.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk4-x32.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk4.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk5-x32.d: Likewise. * testsuite/ld-x86-64/property-x86-shstk5.d: Likewise. --- bfd/ChangeLog | 11 +++++++ bfd/elf32-i386.c | 18 ++++++++--- bfd/elf64-x86-64.c | 18 ++++++++--- binutils/ChangeLog | 10 ++++++ binutils/readelf.c | 11 +++++++ binutils/testsuite/binutils-all/i386/shstk.d | 9 ++++++ binutils/testsuite/binutils-all/i386/shstk.s | 27 ++++++++++++++++ .../testsuite/binutils-all/x86-64/shstk-x32.d | 10 ++++++ .../testsuite/binutils-all/x86-64/shstk.d | 9 ++++++ .../testsuite/binutils-all/x86-64/shstk.s | 27 ++++++++++++++++ include/ChangeLog | 5 +++ include/bfdlink.h | 3 ++ include/elf/common.h | 1 + ld/ChangeLog | 32 +++++++++++++++++++ ld/NEWS | 7 ++++ ld/emulparams/cet.sh | 5 ++- ld/ld.texinfo | 5 +++ ld/testsuite/ld-i386/i386.exp | 7 ++++ ld/testsuite/ld-i386/property-x86-shstk.s | 27 ++++++++++++++++ ld/testsuite/ld-i386/property-x86-shstk1a.d | 6 ++++ ld/testsuite/ld-i386/property-x86-shstk1b.d | 6 ++++ ld/testsuite/ld-i386/property-x86-shstk2.d | 9 ++++++ ld/testsuite/ld-i386/property-x86-shstk3a.d | 11 +++++++ ld/testsuite/ld-i386/property-x86-shstk3b.d | 11 +++++++ ld/testsuite/ld-i386/property-x86-shstk4.d | 9 ++++++ ld/testsuite/ld-i386/property-x86-shstk5.d | 9 ++++++ ld/testsuite/ld-x86-64/property-x86-shstk.s | 27 ++++++++++++++++ .../ld-x86-64/property-x86-shstk1a-x32.d | 6 ++++ ld/testsuite/ld-x86-64/property-x86-shstk1a.d | 6 ++++ .../ld-x86-64/property-x86-shstk1b-x32.d | 6 ++++ ld/testsuite/ld-x86-64/property-x86-shstk1b.d | 6 ++++ .../ld-x86-64/property-x86-shstk2-x32.d | 9 ++++++ ld/testsuite/ld-x86-64/property-x86-shstk2.d | 9 ++++++ .../ld-x86-64/property-x86-shstk3a-x32.d | 11 +++++++ ld/testsuite/ld-x86-64/property-x86-shstk3a.d | 11 +++++++ .../ld-x86-64/property-x86-shstk3b-x32.d | 11 +++++++ ld/testsuite/ld-x86-64/property-x86-shstk3b.d | 11 +++++++ .../ld-x86-64/property-x86-shstk4-x32.d | 9 ++++++ ld/testsuite/ld-x86-64/property-x86-shstk4.d | 9 ++++++ .../ld-x86-64/property-x86-shstk5-x32.d | 9 ++++++ ld/testsuite/ld-x86-64/property-x86-shstk5.d | 9 ++++++ ld/testsuite/ld-x86-64/x86-64.exp | 14 ++++++++ 42 files changed, 457 insertions(+), 9 deletions(-) create mode 100644 binutils/testsuite/binutils-all/i386/shstk.d create mode 100644 binutils/testsuite/binutils-all/i386/shstk.s create mode 100644 binutils/testsuite/binutils-all/x86-64/shstk-x32.d create mode 100644 binutils/testsuite/binutils-all/x86-64/shstk.d create mode 100644 binutils/testsuite/binutils-all/x86-64/shstk.s create mode 100644 ld/testsuite/ld-i386/property-x86-shstk.s create mode 100644 ld/testsuite/ld-i386/property-x86-shstk1a.d create mode 100644 ld/testsuite/ld-i386/property-x86-shstk1b.d create mode 100644 ld/testsuite/ld-i386/property-x86-shstk2.d create mode 100644 ld/testsuite/ld-i386/property-x86-shstk3a.d create mode 100644 ld/testsuite/ld-i386/property-x86-shstk3b.d create mode 100644 ld/testsuite/ld-i386/property-x86-shstk4.d create mode 100644 ld/testsuite/ld-i386/property-x86-shstk5.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk.s create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk1a-x32.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk1a.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk1b-x32.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk1b.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk2-x32.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk2.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk3a-x32.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk3a.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk3b-x32.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk3b.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk4-x32.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk4.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk5-x32.d create mode 100644 ld/testsuite/ld-x86-64/property-x86-shstk5.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ac13db32788..647af617a83 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2017-06-22 H.J. Lu + + * elf32-i386.c (elf_i386_merge_gnu_properties): If info->shstk + is set, turn on GNU_PROPERTY_X86_FEATURE_1_SHSTK. + (elf_i386_link_setup_gnu_properties): If info->shstk is set, + turn on GNU_PROPERTY_X86_FEATURE_1_IBT. + * elf64-x86-64.c (elf_x86_64_merge_gnu_properties): If + info->shstk is set, turn on GNU_PROPERTY_X86_FEATURE_1_SHSTK. + (elf_x86_64_link_setup_gnu_properties): If info->shstk is set, + turn on GNU_PROPERTY_X86_FEATURE_1_IBT. + 2017-06-22 H.J. Lu * elf32-i386.c (elf_i386_lazy_ibt_plt0_entry): New. diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index d6628165481..ee8219cbbe4 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -6751,8 +6751,11 @@ elf_i386_merge_gnu_properties (struct bfd_link_info *info, features = 0; if (info->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; + if (info->shstk) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; number = aprop->u.number; - /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ aprop->u.number = (number & bprop->u.number) | features; updated = number != (unsigned int) aprop->u.number; /* Remove the property if all feature bits are cleared. */ @@ -6764,9 +6767,12 @@ elf_i386_merge_gnu_properties (struct bfd_link_info *info, features = 0; if (info->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; + if (info->shstk) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; if (features) { - /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ if (aprop != NULL) { number = aprop->u.number; @@ -6813,9 +6819,12 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) features = 0; if (info->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; + if (info->shstk) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; if (features) { - /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ bfd *ebfd = NULL; elf_property *prop; @@ -6833,7 +6842,8 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) prop = _bfd_elf_get_property (pbfd, GNU_PROPERTY_X86_FEATURE_1_AND, 4); - /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ prop->u.number |= features; prop->pr_kind = property_number; break; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 1f8e6d0ebde..1a9bebe668f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -7286,8 +7286,11 @@ elf_x86_64_merge_gnu_properties (struct bfd_link_info *info, features = 0; if (info->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; + if (info->shstk) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; number = aprop->u.number; - /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ aprop->u.number = (number & bprop->u.number) | features; updated = number != (unsigned int) aprop->u.number; /* Remove the property if all feature bits are cleared. */ @@ -7299,9 +7302,12 @@ elf_x86_64_merge_gnu_properties (struct bfd_link_info *info, features = 0; if (info->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; + if (info->shstk) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; if (features) { - /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ if (aprop != NULL) { number = aprop->u.number; @@ -7348,9 +7354,12 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info) features = 0; if (info->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; + if (info->shstk) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; if (features) { - /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ bfd *ebfd = NULL; elf_property *prop; @@ -7368,7 +7377,8 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info) prop = _bfd_elf_get_property (pbfd, GNU_PROPERTY_X86_FEATURE_1_AND, 4); - /* Add GNU_PROPERTY_X86_FEATURE_1_IBT. */ + /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and + GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ prop->u.number |= features; prop->pr_kind = property_number; break; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 3870711754e..484632addb5 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2017-06-22 H.J. Lu + + * readelf.c (decode_x86_feature): Decode + GNU_PROPERTY_X86_FEATURE_1_SHSTK. + * testsuite/binutils-all/i386/shstk.d: New file. + * testsuite/binutils-all/i386/shstk.s: Likewise. + * testsuite/binutils-all/x86-64/shstk-x32.d: Likewise. + * testsuite/binutils-all/x86-64/shstk.d: Likewise. + * testsuite/binutils-all/x86-64/shstk.s: Likewise. + 2017-06-22 H.J. Lu * readelf.c (decode_x86_feature): New. diff --git a/binutils/readelf.c b/binutils/readelf.c index 50354c1bd22..d23a020c2e7 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -16358,6 +16358,17 @@ decode_x86_feature (unsigned int type, unsigned int bitmask) abort (); } break; + case GNU_PROPERTY_X86_FEATURE_1_SHSTK: + switch (type) + { + case GNU_PROPERTY_X86_FEATURE_1_AND: + printf ("SHSTK"); + break; + default: + /* This should never happen. */ + abort (); + } + break; default: printf (_(""), bit); break; diff --git a/binutils/testsuite/binutils-all/i386/shstk.d b/binutils/testsuite/binutils-all/i386/shstk.d new file mode 100644 index 00000000000..933704cf913 --- /dev/null +++ b/binutils/testsuite/binutils-all/i386/shstk.d @@ -0,0 +1,9 @@ +#PROG: objcopy +#as: --32 +#objcopy: +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/binutils/testsuite/binutils-all/i386/shstk.s b/binutils/testsuite/binutils-all/i386/shstk.s new file mode 100644 index 00000000000..4c3218aa18f --- /dev/null +++ b/binutils/testsuite/binutils-all/i386/shstk.s @@ -0,0 +1,27 @@ + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +2: .long 0xc0000002 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 +4: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +5: diff --git a/binutils/testsuite/binutils-all/x86-64/shstk-x32.d b/binutils/testsuite/binutils-all/x86-64/shstk-x32.d new file mode 100644 index 00000000000..1dfc4fd0c89 --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/shstk-x32.d @@ -0,0 +1,10 @@ +#source: shstk.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: SHSTK diff --git a/binutils/testsuite/binutils-all/x86-64/shstk.d b/binutils/testsuite/binutils-all/x86-64/shstk.d new file mode 100644 index 00000000000..1f131b8c66c --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/shstk.d @@ -0,0 +1,9 @@ +#PROG: objcopy +#as: --64 -defsym __64_bit__=1 +#objcopy: +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/binutils/testsuite/binutils-all/x86-64/shstk.s b/binutils/testsuite/binutils-all/x86-64/shstk.s new file mode 100644 index 00000000000..4c3218aa18f --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/shstk.s @@ -0,0 +1,27 @@ + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +2: .long 0xc0000002 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 +4: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +5: diff --git a/include/ChangeLog b/include/ChangeLog index 4858699a7ee..d8730deab11 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2017-06-22 H.J. Lu + + * bfdlink.h (bfd_link_info): Add shstk. + * elf/common.h (GNU_PROPERTY_X86_FEATURE_1_SHSTK): New. + 2017-06-22 H.J. Lu * bfdlink.h (bfd_link_info): Add ibtplt and ibt. diff --git a/include/bfdlink.h b/include/bfdlink.h index 3b4dce9ca61..e7c7836f7fa 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -477,6 +477,9 @@ struct bfd_link_info /* TRUE if GNU_PROPERTY_X86_FEATURE_1_IBT should be generated. */ unsigned int ibt: 1; + /* TRUE if GNU_PROPERTY_X86_FEATURE_1_SHSTK should be generated. */ + unsigned int shstk: 1; + /* TRUE if generation of .interp/PT_INTERP should be suppressed. */ unsigned int nointerp: 1; diff --git a/include/elf/common.h b/include/elf/common.h index e638ba09ae6..8ca14bcbea7 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -731,6 +731,7 @@ #define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17) #define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0) +#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1) /* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG). */ #define GNU_ABI_TAG_LINUX 0 diff --git a/ld/ChangeLog b/ld/ChangeLog index b3567e112ec..bdc5853a7aa 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,35 @@ +2017-06-22 H.J. Lu + + * NEWS: Mention -z shstk and GNU_PROPERTY_X86_FEATURE_1_SHSTK. + * emulparams/cet.sh (PARSE_AND_LIST_OPTIONS_CET): Add "-z shstk". + (PARSE_AND_LIST_ARGS_CASE_Z_CET): Support "-z shstk". + * ld.texinfo: Document -z shstk. + * testsuite/ld-i386/i386.exp: Run SHSTK tests. + * testsuite/ld-x86-64/x86-64.exp: Likewise. + * testsuite/ld-i386/property-x86-shstk.s: New file. + * testsuite/ld-i386/property-x86-shstk1a.d: Likewise. + * testsuite/ld-i386/property-x86-shstk1b.d: Likewise. + * testsuite/ld-i386/property-x86-shstk2.d: Likewise. + * testsuite/ld-i386/property-x86-shstk3a.d: Likewise. + * testsuite/ld-i386/property-x86-shstk3b.d: Likewise. + * testsuite/ld-i386/property-x86-shstk4.d: Likewise. + * testsuite/ld-i386/property-x86-shstk5.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk.s: Likewise. + * testsuite/ld-x86-64/property-x86-shstk1a-x32.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk1a.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk1b-x32.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk1b.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk2-x32.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk2.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk3a-x32.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk3a.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk3b-x32.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk3b.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk4-x32.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk4.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk5-x32.d: Likewise. + * testsuite/ld-x86-64/property-x86-shstk5.d: Likewise. + 2017-06-22 H.J. Lu * Makefile.am (ELF_X86_DEPS): Add $(srcdir)/emulparams/cet.sh. diff --git a/ld/NEWS b/ld/NEWS index b1158431465..e9ef7136ef4 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,6 +1,13 @@ -*- text -*- +* Support for -z shstk in the x86 ELF linker to generate + GNU_PROPERTY_X86_FEATURE_1_SHSTK in ELF GNU program properties. + +* Add support for GNU_PROPERTY_X86_FEATURE_1_SHSTK in ELF GNU program + properties in the x86 ELF linker. + * Add support for GNU_PROPERTY_X86_FEATURE_1_IBT in ELF GNU program + properties in the x86 ELF linker. * Support for -z ibtplt in the x86 ELF linker to generate IBT-enabled PLT. diff --git a/ld/emulparams/cet.sh b/ld/emulparams/cet.sh index 62ff105613f..1973413c900 100644 --- a/ld/emulparams/cet.sh +++ b/ld/emulparams/cet.sh @@ -1,13 +1,16 @@ 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")); + -z ibt Generate GNU_PROPERTY_X86_FEATURE_1_IBT\n\ + -z shstk Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK\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; + else if (strcmp (optarg, "shstk") == 0) + link_info.shstk = TRUE; ' PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_CET" diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 4f7873cd905..77b5d3eec12 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1270,6 +1270,11 @@ 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. +@item shstk +Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK in .note.gnu.property section +to indicate compatibility with Intel Shadow Stack. Supported for +Linux/i386 and Linux/x86_64. + @end table Other keywords are ignored for Solaris compatibility. diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index d30dc767036..1cecea4e38e 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -427,6 +427,13 @@ run_dump_test "property-x86-ibt3a" run_dump_test "property-x86-ibt3b" run_dump_test "property-x86-ibt4" run_dump_test "property-x86-ibt5" +run_dump_test "property-x86-shstk1a" +run_dump_test "property-x86-shstk1b" +run_dump_test "property-x86-shstk2" +run_dump_test "property-x86-shstk3a" +run_dump_test "property-x86-shstk3b" +run_dump_test "property-x86-shstk4" +run_dump_test "property-x86-shstk5" if { !([istarget "i?86-*-linux*"] || [istarget "i?86-*-gnu*"] diff --git a/ld/testsuite/ld-i386/property-x86-shstk.s b/ld/testsuite/ld-i386/property-x86-shstk.s new file mode 100644 index 00000000000..4c3218aa18f --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk.s @@ -0,0 +1,27 @@ + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +2: .long 0xc0000002 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 +4: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +5: diff --git a/ld/testsuite/ld-i386/property-x86-shstk1a.d b/ld/testsuite/ld-i386/property-x86-shstk1a.d new file mode 100644 index 00000000000..238cebeeade --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk1a.d @@ -0,0 +1,6 @@ +#source: property-x86-empty.s +#source: property-x86-shstk.s +#as: --32 +#ld: -r -melf_i386 +#readelf: -n + diff --git a/ld/testsuite/ld-i386/property-x86-shstk1b.d b/ld/testsuite/ld-i386/property-x86-shstk1b.d new file mode 100644 index 00000000000..faa2ea7b71d --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk1b.d @@ -0,0 +1,6 @@ +#source: property-x86-shstk.s +#source: property-x86-empty.s +#as: --32 +#ld: -r -melf_i386 +#readelf: -n + diff --git a/ld/testsuite/ld-i386/property-x86-shstk2.d b/ld/testsuite/ld-i386/property-x86-shstk2.d new file mode 100644 index 00000000000..b39fa58c599 --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk2.d @@ -0,0 +1,9 @@ +#source: property-x86-shstk.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: SHSTK diff --git a/ld/testsuite/ld-i386/property-x86-shstk3a.d b/ld/testsuite/ld-i386/property-x86-shstk3a.d new file mode 100644 index 00000000000..e261038f608 --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk3a.d @@ -0,0 +1,11 @@ +#source: property-x86-3.s +#source: property-x86-shstk.s +#as: --32 +#ld: -r -melf_i386 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: i486, 586, SSE2, SSE3 + x86 ISA needed: 586, SSE, SSE3, SSE4_1 diff --git a/ld/testsuite/ld-i386/property-x86-shstk3b.d b/ld/testsuite/ld-i386/property-x86-shstk3b.d new file mode 100644 index 00000000000..25f3d2361e6 --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk3b.d @@ -0,0 +1,11 @@ +#source: property-x86-shstk.s +#source: property-x86-3.s +#as: --32 +#ld: -r -melf_i386 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: i486, 586, SSE2, SSE3 + x86 ISA needed: 586, SSE, SSE3, SSE4_1 diff --git a/ld/testsuite/ld-i386/property-x86-shstk4.d b/ld/testsuite/ld-i386/property-x86-shstk4.d new file mode 100644 index 00000000000..d962eabb980 --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk4.d @@ -0,0 +1,9 @@ +#source: property-x86-empty.s +#as: --32 +#ld: -r -melf_i386 -z shstk +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/ld/testsuite/ld-i386/property-x86-shstk5.d b/ld/testsuite/ld-i386/property-x86-shstk5.d new file mode 100644 index 00000000000..6d6371f6537 --- /dev/null +++ b/ld/testsuite/ld-i386/property-x86-shstk5.d @@ -0,0 +1,9 @@ +#source: start.s +#as: --32 +#ld: -r -melf_i386 -z shstk +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk.s b/ld/testsuite/ld-x86-64/property-x86-shstk.s new file mode 100644 index 00000000000..4c3218aa18f --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk.s @@ -0,0 +1,27 @@ + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +2: .long 0xc0000002 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 +4: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +5: diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk1a-x32.d b/ld/testsuite/ld-x86-64/property-x86-shstk1a-x32.d new file mode 100644 index 00000000000..312d1ea1223 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk1a-x32.d @@ -0,0 +1,6 @@ +#source: property-x86-empty.s +#source: property-x86-shstk.s +#as: --x32 +#ld: -r -m elf32_x86_64 +#readelf: -n + diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk1a.d b/ld/testsuite/ld-x86-64/property-x86-shstk1a.d new file mode 100644 index 00000000000..39a996e22cb --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk1a.d @@ -0,0 +1,6 @@ +#source: property-x86-empty.s +#source: property-x86-shstk.s +#as: --64 -defsym __64_bit__=1 +#ld: -r -melf_x86_64 +#readelf: -n + diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk1b-x32.d b/ld/testsuite/ld-x86-64/property-x86-shstk1b-x32.d new file mode 100644 index 00000000000..9e91c5c7534 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk1b-x32.d @@ -0,0 +1,6 @@ +#source: property-x86-shstk.s +#source: property-x86-empty.s +#as: --x32 +#ld: -r -m elf32_x86_64 +#readelf: -n + diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk1b.d b/ld/testsuite/ld-x86-64/property-x86-shstk1b.d new file mode 100644 index 00000000000..a9b9e626a44 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk1b.d @@ -0,0 +1,6 @@ +#source: property-x86-shstk.s +#source: property-x86-empty.s +#as: --64 -defsym __64_bit__=1 +#ld: -r -melf_x86_64 +#readelf: -n + diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk2-x32.d b/ld/testsuite/ld-x86-64/property-x86-shstk2-x32.d new file mode 100644 index 00000000000..7155f3feac2 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk2-x32.d @@ -0,0 +1,9 @@ +#source: property-x86-shstk.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: SHSTK diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk2.d b/ld/testsuite/ld-x86-64/property-x86-shstk2.d new file mode 100644 index 00000000000..7fbafe82458 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk2.d @@ -0,0 +1,9 @@ +#source: property-x86-shstk.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: SHSTK diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk3a-x32.d b/ld/testsuite/ld-x86-64/property-x86-shstk3a-x32.d new file mode 100644 index 00000000000..819542d1811 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk3a-x32.d @@ -0,0 +1,11 @@ +#source: property-x86-3.s +#source: property-x86-shstk.s +#as: --x32 +#ld: -r -m elf32_x86_64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: i486, 586, SSE2, SSE3 diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk3a.d b/ld/testsuite/ld-x86-64/property-x86-shstk3a.d new file mode 100644 index 00000000000..4c5d0e0a18a --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk3a.d @@ -0,0 +1,11 @@ +#source: property-x86-3.s +#source: property-x86-shstk.s +#as: --64 -defsym __64_bit__=1 +#ld: -r -melf_x86_64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: i486, 586, SSE2, SSE3 diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk3b-x32.d b/ld/testsuite/ld-x86-64/property-x86-shstk3b-x32.d new file mode 100644 index 00000000000..ba181e0bc59 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk3b-x32.d @@ -0,0 +1,11 @@ +#source: property-x86-shstk.s +#source: property-x86-3.s +#as: --x32 +#ld: -r -m elf32_x86_64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: i486, 586, SSE2, SSE3 diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk3b.d b/ld/testsuite/ld-x86-64/property-x86-shstk3b.d new file mode 100644 index 00000000000..5216f385dd3 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk3b.d @@ -0,0 +1,11 @@ +#source: property-x86-shstk.s +#source: property-x86-3.s +#as: --64 -defsym __64_bit__=1 +#ld: -r -melf_x86_64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: i486, 586, SSE2, SSE3 diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk4-x32.d b/ld/testsuite/ld-x86-64/property-x86-shstk4-x32.d new file mode 100644 index 00000000000..61b78269471 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk4-x32.d @@ -0,0 +1,9 @@ +#source: property-x86-empty.s +#as: --x32 +#ld: -r -m elf32_x86_64 -z shstk +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk4.d b/ld/testsuite/ld-x86-64/property-x86-shstk4.d new file mode 100644 index 00000000000..c2a7b363a84 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk4.d @@ -0,0 +1,9 @@ +#source: property-x86-empty.s +#as: --64 -defsym __64_bit__=1 +#ld: -r -melf_x86_64 -z shstk +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk5-x32.d b/ld/testsuite/ld-x86-64/property-x86-shstk5-x32.d new file mode 100644 index 00000000000..83c6a6866c1 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk5-x32.d @@ -0,0 +1,9 @@ +#source: start.s +#as: --x32 +#ld: -r -m elf32_x86_64 -z shstk +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/ld/testsuite/ld-x86-64/property-x86-shstk5.d b/ld/testsuite/ld-x86-64/property-x86-shstk5.d new file mode 100644 index 00000000000..9a4b1861586 --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-shstk5.d @@ -0,0 +1,9 @@ +#source: start.s +#as: --64 -defsym __64_bit__=1 +#ld: -r -melf_x86_64 -z shstk +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 feature: SHSTK diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 6cde22ff58e..9b83e1c5ce8 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -349,6 +349,20 @@ 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" +run_dump_test "property-x86-shstk1a" +run_dump_test "property-x86-shstk1b" +run_dump_test "property-x86-shstk1a-x32" +run_dump_test "property-x86-shstk1b-x32" +run_dump_test "property-x86-shstk2" +run_dump_test "property-x86-shstk2-x32" +run_dump_test "property-x86-shstk3a" +run_dump_test "property-x86-shstk3b" +run_dump_test "property-x86-shstk3a-x32" +run_dump_test "property-x86-shstk3b-x32" +run_dump_test "property-x86-shstk4" +run_dump_test "property-x86-shstk4-x32" +run_dump_test "property-x86-shstk5" +run_dump_test "property-x86-shstk5-x32" if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} { return