summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-06-22 05:50:20 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-06-30 04:05:41 -0700
commit68ca21b238e2260f34371eb1db0f2d15eec20ce8 (patch)
tree814bd1fe9516bb54f23ba9212f993df6e3c51ccd
parentef8fd36474ed6afbcaafaf9bc05a29d9e45b0531 (diff)
downloadbinutils-gdb-68ca21b238e2260f34371eb1db0f2d15eec20ce8.tar.gz
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. include/ * bfdlink.h (bfd_link_info): Add shstk. * elf/common.h (GNU_PROPERTY_X86_FEATURE_1_SHSTK): New. (cherry picked from commit 48580982ef41907a45cda259a63d9e6878cbbea3)
-rw-r--r--bfd/elf32-i386.c18
-rw-r--r--bfd/elf64-x86-64.c18
-rw-r--r--include/bfdlink.h3
-rw-r--r--include/elf/common.h1
4 files changed, 32 insertions, 8 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 1a316e32812..af6f13cbecd 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -6740,8 +6740,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. */
@@ -6753,9 +6756,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;
@@ -6802,9 +6808,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;
@@ -6822,7 +6831,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 4a25f0a79c3..2e10ad1bd9a 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -7267,8 +7267,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. */
@@ -7280,9 +7283,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;
@@ -7329,9 +7335,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;
@@ -7349,7 +7358,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/include/bfdlink.h b/include/bfdlink.h
index 72cf9b198fa..d201d2b0a42 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -473,6 +473,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