From: Alexander Ivchenko Date: Mon, 5 Mar 2018 11:30:28 +0000 (+0000) Subject: [x86][CET] Introduce _get_ssp, _inc_ssp intrinsics X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=26d4516ed3de4e70527ed6dd1b122ff03a3a7ba5;p=clang [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326689 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Headers/cetintrin.h b/lib/Headers/cetintrin.h index 1256a3f63a..b9e9801792 100644 --- a/lib/Headers/cetintrin.h +++ b/lib/Headers/cetintrin.h @@ -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(); } diff --git a/test/CodeGen/cetintrin.c b/test/CodeGen/cetintrin.c index 085462a662..4d2f87a4a3 100644 --- a/test/CodeGen/cetintrin.c +++ b/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 @@ -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() {