Skip to content

Commit 9d3b453

Browse files
author
Alexander Ivchenko
committedMar 5, 2018
[x86][CET] Introduce _get_ssp, _inc_ssp intrinsics
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
1 parent 162d436 commit 9d3b453

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed
 

‎clang/lib/Headers/cetintrin.h

+20
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ static __inline__ void __DEFAULT_FN_ATTRS _incsspq(unsigned long long __a) {
4242
}
4343
#endif /* __x86_64__ */
4444

45+
#ifdef __x86_64__
46+
static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) {
47+
__builtin_ia32_incsspq(__a);
48+
}
49+
#else /* __x86_64__ */
50+
static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) {
51+
__builtin_ia32_incsspd((int)__a);
52+
}
53+
#endif /* __x86_64__ */
54+
4555
static __inline__ unsigned int __DEFAULT_FN_ATTRS _rdsspd(unsigned int __a) {
4656
return __builtin_ia32_rdsspd(__a);
4757
}
@@ -52,6 +62,16 @@ static __inline__ unsigned long long __DEFAULT_FN_ATTRS _rdsspq(unsigned long lo
5262
}
5363
#endif /* __x86_64__ */
5464

65+
#ifdef __x86_64__
66+
static __inline__ unsigned long long __DEFAULT_FN_ATTRS _get_ssp(void) {
67+
return __builtin_ia32_rdsspq(0);
68+
}
69+
#else /* __x86_64__ */
70+
static __inline__ unsigned int __DEFAULT_FN_ATTRS _get_ssp(void) {
71+
return __builtin_ia32_rdsspd(0);
72+
}
73+
#endif /* __x86_64__ */
74+
5575
static __inline__ void __DEFAULT_FN_ATTRS _saveprevssp() {
5676
__builtin_ia32_saveprevssp();
5777
}

‎clang/test/CodeGen/cetintrin.c

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s
2-
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64
1+
// 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
2+
// 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
33

44
#include <immintrin.h>
55

@@ -15,6 +15,20 @@ void test_incsspq(int a) {
1515
// X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}})
1616
_incsspq(a);
1717
}
18+
19+
void test_inc_ssp(unsigned int a) {
20+
// X86_64-LABEL: @test_inc_ssp
21+
// X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}})
22+
_inc_ssp(a);
23+
}
24+
#else
25+
26+
void test_inc_ssp(unsigned int a) {
27+
// I386-LABEL: @test_inc_ssp
28+
// I386: call void @llvm.x86.incsspd(i32 %{{[0-9]+}})
29+
_inc_ssp(a);
30+
}
31+
1832
#endif
1933

2034
unsigned int test_rdsspd(unsigned int a) {
@@ -29,6 +43,21 @@ unsigned long long test_rdsspq(unsigned long long a) {
2943
// X86_64: call i64 @llvm.x86.rdsspq(i64 %{{[a-z0-9.]+}})
3044
return _rdsspq(a);
3145
}
46+
47+
unsigned long long test_get_ssp(void) {
48+
// X86_64-LABEL: @test_get_ssp
49+
// X86_64: call i64 @llvm.x86.rdsspq(i64 0)
50+
return _get_ssp();
51+
}
52+
53+
#else
54+
55+
unsigned int test_get_ssp(void) {
56+
// I386-LABEL: @test_get_ssp
57+
// I386: call i32 @llvm.x86.rdsspd(i32 0)
58+
return _get_ssp();
59+
}
60+
3261
#endif
3362

3463
void test_saveprevssp() {

0 commit comments

Comments
 (0)
Please sign in to comment.