]> granicus.if.org Git - clang/commitdiff
[x86][CET] Introduce _get_ssp, _inc_ssp intrinsics
authorAlexander Ivchenko <alexander.ivchenko@intel.com>
Mon, 5 Mar 2018 11:30:28 +0000 (11:30 +0000)
committerAlexander Ivchenko <alexander.ivchenko@intel.com>
Mon, 5 Mar 2018 11:30:28 +0000 (11:30 +0000)
Summary:
The _get_ssp intrinsic can be used to retrieve the
shadow stack pointer, independent of the current arch -- in
contract with the rdsspd and the rdsspq intrinsics.
Also, this intrinsic returns zero on CPUs which don't
support CET. The rdssp[d|q] instruction is decoded as nop,
essentially just returning the input operand, which is zero.
Example result of compilation:

```
xorl    %eax, %eax
movl    %eax, %ecx
rdsspq  %rcx         # NOP when CET is not supported
movq    %rcx, %rax   # return zero
```

Reviewers: craig.topper

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D43814

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326689 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/cetintrin.h
test/CodeGen/cetintrin.c

index 1256a3f63a1628a5681cfb92d271cf0e3f4f0547..b9e98017925f49c53ab3d73b827c186e60d03aba 100644 (file)
@@ -42,6 +42,16 @@ static __inline__ void __DEFAULT_FN_ATTRS _incsspq(unsigned long long __a) {
 }
 #endif /* __x86_64__ */
 
+#ifdef __x86_64__
+static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) {
+  __builtin_ia32_incsspq(__a);
+}
+#else /* __x86_64__ */
+static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) {
+  __builtin_ia32_incsspd((int)__a);
+}
+#endif /* __x86_64__ */
+
 static __inline__ unsigned int __DEFAULT_FN_ATTRS _rdsspd(unsigned int __a) {
   return __builtin_ia32_rdsspd(__a);
 }
@@ -52,6 +62,16 @@ static __inline__ unsigned long long __DEFAULT_FN_ATTRS _rdsspq(unsigned long lo
 }
 #endif /* __x86_64__ */
 
+#ifdef __x86_64__
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS _get_ssp(void) {
+  return __builtin_ia32_rdsspq(0);
+}
+#else /* __x86_64__ */
+static __inline__ unsigned int __DEFAULT_FN_ATTRS _get_ssp(void) {
+  return __builtin_ia32_rdsspd(0);
+}
+#endif /* __x86_64__ */
+
 static __inline__ void __DEFAULT_FN_ATTRS _saveprevssp() {
   __builtin_ia32_saveprevssp();
 }
index 085462a6626d810bfde8e6847154f1321c63dd40..4d2f87a4a3c601d025c0a4db8a5ed89a4912bcac 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s
-// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk  -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64
+// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=I386 --check-prefix=CHECK
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk  -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64  --check-prefix=CHECK
 
 #include <immintrin.h>
 
@@ -15,6 +15,20 @@ void test_incsspq(int a) {
   // X86_64:       call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}})
   _incsspq(a);
 }
+
+void test_inc_ssp(unsigned int a) {
+  // X86_64-LABEL: @test_inc_ssp
+  // X86_64:       call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}})
+  _inc_ssp(a);
+}
+#else
+
+void test_inc_ssp(unsigned int a) {
+  // I386-LABEL: @test_inc_ssp
+  // I386:       call void @llvm.x86.incsspd(i32 %{{[0-9]+}})
+  _inc_ssp(a);
+}
+
 #endif
 
 unsigned int test_rdsspd(unsigned int a) {
@@ -29,6 +43,21 @@ unsigned long long test_rdsspq(unsigned long long a) {
   // X86_64:       call i64 @llvm.x86.rdsspq(i64 %{{[a-z0-9.]+}})
   return _rdsspq(a);
 }
+
+unsigned long long test_get_ssp(void) {
+  // X86_64-LABEL: @test_get_ssp
+  // X86_64:       call i64 @llvm.x86.rdsspq(i64 0)
+  return _get_ssp();
+}
+
+#else
+
+unsigned int test_get_ssp(void) {
+  // I386-LABEL: @test_get_ssp
+  // I386:       call i32 @llvm.x86.rdsspd(i32 0)
+  return _get_ssp();
+}
+
 #endif
 
 void  test_saveprevssp() {