Skip to content

Commit

Permalink
[x86][CET] Introduce _get_ssp, _inc_ssp intrinsics
Browse files Browse the repository at this point in the history
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

llvm-svn: 326689
  • Loading branch information
Alexander Ivchenko committed Mar 5, 2018
1 parent 162d436 commit 9d3b453
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
20 changes: 20 additions & 0 deletions clang/lib/Headers/cetintrin.h
Expand Up @@ -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);
}
Expand All @@ -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();
}
Expand Down
33 changes: 31 additions & 2 deletions clang/test/CodeGen/cetintrin.c
@@ -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>

Expand All @@ -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) {
Expand All @@ -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() {
Expand Down

0 comments on commit 9d3b453

Please sign in to comment.