forked from OSchip/llvm-project
[X86][CET] Changing -fcf-protection behavior to comply with gcc (LLVM part)
This patch aims to match the changes introduced in gcc by https://gcc.gnu.org/ml/gcc-cvs/2018-04/msg00534.html. The IBT feature definition is removed, with the IBT instructions being freely available on all X86 targets. The shadow stack instructions are also being made freely available, and the use of all these CET instructions is controlled by the module flags derived from the -fcf-protection clang option. The hasSHSTK option remains since clang uses it to determine availability of shadow stack instruction intrinsics, but it is no longer directly used. Comes with a clang patch (D46881). Patch by mike.dvoretsky Differential Revision: https://reviews.llvm.org/D46882 llvm-svn: 332705
This commit is contained in:
parent
0fb8c877c4
commit
5c54742da4
|
@ -1264,8 +1264,6 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
|
||||||
Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
|
Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
|
||||||
Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
|
Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
|
||||||
|
|
||||||
Features["ibt"] = HasLeaf7 && ((EDX >> 20) & 1);
|
|
||||||
|
|
||||||
// There are two CPUID leafs which information associated with the pconfig
|
// There are two CPUID leafs which information associated with the pconfig
|
||||||
// instruction:
|
// instruction:
|
||||||
// EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
|
// EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
|
||||||
|
|
|
@ -218,8 +218,6 @@ def FeatureSHA : SubtargetFeature<"sha", "HasSHA", "true",
|
||||||
[FeatureSSE2]>;
|
[FeatureSSE2]>;
|
||||||
def FeatureSHSTK : SubtargetFeature<"shstk", "HasSHSTK", "true",
|
def FeatureSHSTK : SubtargetFeature<"shstk", "HasSHSTK", "true",
|
||||||
"Support CET Shadow-Stack instructions">;
|
"Support CET Shadow-Stack instructions">;
|
||||||
def FeatureIBT : SubtargetFeature<"ibt", "HasIBT", "true",
|
|
||||||
"Support CET Indirect-Branch-Tracking instructions">;
|
|
||||||
def FeaturePRFCHW : SubtargetFeature<"prfchw", "HasPRFCHW", "true",
|
def FeaturePRFCHW : SubtargetFeature<"prfchw", "HasPRFCHW", "true",
|
||||||
"Support PRFCHW instructions">;
|
"Support PRFCHW instructions">;
|
||||||
def FeatureRDSEED : SubtargetFeature<"rdseed", "HasRDSEED", "true",
|
def FeatureRDSEED : SubtargetFeature<"rdseed", "HasRDSEED", "true",
|
||||||
|
|
|
@ -89,10 +89,6 @@ bool X86IndirectBranchTrackingPass::addENDBR(MachineBasicBlock &MBB) const {
|
||||||
bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {
|
bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {
|
||||||
const X86Subtarget &SubTarget = MF.getSubtarget<X86Subtarget>();
|
const X86Subtarget &SubTarget = MF.getSubtarget<X86Subtarget>();
|
||||||
|
|
||||||
// Make sure that the target supports IBT instruction.
|
|
||||||
if (!SubTarget.hasIBT())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check that the cf-protection-branch is enabled.
|
// Check that the cf-protection-branch is enabled.
|
||||||
Metadata *isCFProtectionSupported =
|
Metadata *isCFProtectionSupported =
|
||||||
MF.getMMI().getModule()->getModuleFlag("cf-protection-branch");
|
MF.getMMI().getModule()->getModuleFlag("cf-protection-branch");
|
||||||
|
|
|
@ -141,7 +141,8 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
|
||||||
[(brind (loadi64 addr:$dst))]>, Requires<[In64BitMode]>,
|
[(brind (loadi64 addr:$dst))]>, Requires<[In64BitMode]>,
|
||||||
Sched<[WriteJumpLd]>;
|
Sched<[WriteJumpLd]>;
|
||||||
|
|
||||||
let isCodeGenOnly = 1, Predicates = [HasIBT] in {
|
// Non-tracking jumps for IBT, use with caution.
|
||||||
|
let isCodeGenOnly = 1 in {
|
||||||
def JMP16r_NT : I<0xFF, MRM4r, (outs), (ins GR16 : $dst), "jmp{w}\t{*}$dst",
|
def JMP16r_NT : I<0xFF, MRM4r, (outs), (ins GR16 : $dst), "jmp{w}\t{*}$dst",
|
||||||
[(X86NoTrackBrind GR16 : $dst)]>, Requires<[Not64BitMode]>,
|
[(X86NoTrackBrind GR16 : $dst)]>, Requires<[Not64BitMode]>,
|
||||||
OpSize16, Sched<[WriteJump]>, NOTRACK;
|
OpSize16, Sched<[WriteJump]>, NOTRACK;
|
||||||
|
@ -228,7 +229,8 @@ let isCall = 1 in
|
||||||
Requires<[Not64BitMode,FavorMemIndirectCall,NotUseRetpoline]>,
|
Requires<[Not64BitMode,FavorMemIndirectCall,NotUseRetpoline]>,
|
||||||
Sched<[WriteJumpLd]>;
|
Sched<[WriteJumpLd]>;
|
||||||
|
|
||||||
let isCodeGenOnly = 1, Predicates = [HasIBT] in {
|
// Non-tracking calls for IBT, use with caution.
|
||||||
|
let isCodeGenOnly = 1 in {
|
||||||
def CALL16r_NT : I<0xFF, MRM2r, (outs), (ins GR16 : $dst),
|
def CALL16r_NT : I<0xFF, MRM2r, (outs), (ins GR16 : $dst),
|
||||||
"call{w}\t{*}$dst",[(X86NoTrackCall GR16 : $dst)]>,
|
"call{w}\t{*}$dst",[(X86NoTrackCall GR16 : $dst)]>,
|
||||||
OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>, NOTRACK;
|
OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>, NOTRACK;
|
||||||
|
@ -324,7 +326,8 @@ let isCall = 1, Uses = [RSP, SSP], SchedRW = [WriteJump] in {
|
||||||
Requires<[In64BitMode,FavorMemIndirectCall,
|
Requires<[In64BitMode,FavorMemIndirectCall,
|
||||||
NotUseRetpoline]>;
|
NotUseRetpoline]>;
|
||||||
|
|
||||||
let isCodeGenOnly = 1, Predicates = [HasIBT] in{
|
// Non-tracking calls for IBT, use with caution.
|
||||||
|
let isCodeGenOnly = 1 in {
|
||||||
def CALL64r_NT : I<0xFF, MRM2r, (outs), (ins GR64 : $dst),
|
def CALL64r_NT : I<0xFF, MRM2r, (outs), (ins GR64 : $dst),
|
||||||
"call{q}\t{*}$dst",[(X86NoTrackCall GR64 : $dst)]>,
|
"call{q}\t{*}$dst",[(X86NoTrackCall GR64 : $dst)]>,
|
||||||
Requires<[In64BitMode]>, NOTRACK;
|
Requires<[In64BitMode]>, NOTRACK;
|
||||||
|
|
|
@ -899,7 +899,6 @@ def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
|
||||||
def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
|
def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
|
||||||
def HasMPX : Predicate<"Subtarget->hasMPX()">;
|
def HasMPX : Predicate<"Subtarget->hasMPX()">;
|
||||||
def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
|
def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
|
||||||
def HasIBT : Predicate<"Subtarget->hasIBT()">;
|
|
||||||
def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
|
def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
|
||||||
def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
|
def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
|
||||||
def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">;
|
def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">;
|
||||||
|
|
|
@ -450,7 +450,8 @@ def WBNOINVD : I<0x09, RawFrm, (outs), (ins), "wbnoinvd",
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// CET instructions
|
// CET instructions
|
||||||
let SchedRW = [WriteSystem], Predicates = [HasSHSTK] in{
|
// Use with caution, availability is not predicated on features.
|
||||||
|
let SchedRW = [WriteSystem] in {
|
||||||
let Uses = [SSP] in {
|
let Uses = [SSP] in {
|
||||||
let Defs = [SSP] in {
|
let Defs = [SSP] in {
|
||||||
def INCSSPD : I<0xAE, MRM5r, (outs), (ins GR32:$src), "incsspd\t$src",
|
def INCSSPD : I<0xAE, MRM5r, (outs), (ins GR32:$src), "incsspd\t$src",
|
||||||
|
@ -500,12 +501,12 @@ let SchedRW = [WriteSystem], Predicates = [HasSHSTK] in{
|
||||||
"clrssbsy\t$src",
|
"clrssbsy\t$src",
|
||||||
[(int_x86_clrssbsy addr:$src)]>, XS;
|
[(int_x86_clrssbsy addr:$src)]>, XS;
|
||||||
} // Defs SSP
|
} // Defs SSP
|
||||||
} // SchedRW && HasSHSTK
|
} // SchedRW
|
||||||
|
|
||||||
let SchedRW = [WriteSystem], Predicates = [HasIBT] in {
|
let SchedRW = [WriteSystem] in {
|
||||||
def ENDBR64 : I<0x1E, MRM_FA, (outs), (ins), "endbr64", []>, XS;
|
def ENDBR64 : I<0x1E, MRM_FA, (outs), (ins), "endbr64", []>, XS;
|
||||||
def ENDBR32 : I<0x1E, MRM_FB, (outs), (ins), "endbr32", []>, XS;
|
def ENDBR32 : I<0x1E, MRM_FB, (outs), (ins), "endbr32", []>, XS;
|
||||||
} // SchedRW && HasIBT
|
} // SchedRW
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// XSAVE instructions
|
// XSAVE instructions
|
||||||
|
|
|
@ -322,7 +322,6 @@ void X86Subtarget::initializeEnvironment() {
|
||||||
HasPTWRITE = false;
|
HasPTWRITE = false;
|
||||||
HasMPX = false;
|
HasMPX = false;
|
||||||
HasSHSTK = false;
|
HasSHSTK = false;
|
||||||
HasIBT = false;
|
|
||||||
HasSGX = false;
|
HasSGX = false;
|
||||||
HasPCONFIG = false;
|
HasPCONFIG = false;
|
||||||
HasCLFLUSHOPT = false;
|
HasCLFLUSHOPT = false;
|
||||||
|
|
|
@ -360,10 +360,6 @@ protected:
|
||||||
/// using Shadow Stack
|
/// using Shadow Stack
|
||||||
bool HasSHSTK;
|
bool HasSHSTK;
|
||||||
|
|
||||||
/// Processor supports CET IBT - Control-Flow Enforcement Technology
|
|
||||||
/// using Indirect Branch Tracking
|
|
||||||
bool HasIBT;
|
|
||||||
|
|
||||||
/// Processor has Software Guard Extensions
|
/// Processor has Software Guard Extensions
|
||||||
bool HasSGX;
|
bool HasSGX;
|
||||||
|
|
||||||
|
@ -641,7 +637,6 @@ public:
|
||||||
bool hasBITALG() const { return HasBITALG; }
|
bool hasBITALG() const { return HasBITALG; }
|
||||||
bool hasMPX() const { return HasMPX; }
|
bool hasMPX() const { return HasMPX; }
|
||||||
bool hasSHSTK() const { return HasSHSTK; }
|
bool hasSHSTK() const { return HasSHSTK; }
|
||||||
bool hasIBT() const { return HasIBT; }
|
|
||||||
bool hasCLFLUSHOPT() const { return HasCLFLUSHOPT; }
|
bool hasCLFLUSHOPT() const { return HasCLFLUSHOPT; }
|
||||||
bool hasCLWB() const { return HasCLWB; }
|
bool hasCLWB() const { return HasCLWB; }
|
||||||
bool hasWBNOINVD() const { return HasWBNOINVD; }
|
bool hasWBNOINVD() const { return HasWBNOINVD; }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+ibt < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86_64
|
; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86_64
|
||||||
; RUN: llc -mtriple=i386-unknown-unknown -mattr=+ibt < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86
|
; RUN: llc -mtriple=i386-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86
|
||||||
; RUN: llc -mtriple i386-windows-gnu -mattr=+ibt -exception-model sjlj < %s | FileCheck %s --check-prefix=SJLJ
|
; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj < %s | FileCheck %s --check-prefix=SJLJ
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Test1
|
;; Test1
|
||||||
|
@ -218,4 +218,4 @@ try.cont:
|
||||||
|
|
||||||
!llvm.module.flags = !{!0}
|
!llvm.module.flags = !{!0}
|
||||||
|
|
||||||
!0 = !{i32 4, !"cf-protection-branch", i32 1}
|
!0 = !{i32 4, !"cf-protection-branch", i32 1}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+ibt -x86-indirect-branch-tracking < %s | FileCheck %s
|
; RUN: llc -mtriple=x86_64-unknown-unknown -x86-indirect-branch-tracking < %s | FileCheck %s
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; This test verify the handling of ''nocf_check'' attribute by the backend. ;;
|
;; This test verify the handling of ''nocf_check'' attribute by the backend. ;;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
; RUN: llc < %s -mtriple=i386-apple-darwin -mattr=+shstk -mattr=+ibt | FileCheck %s
|
; RUN: llc < %s -mtriple=i386-apple-darwin -mattr=+shstk | FileCheck %s
|
||||||
|
|
||||||
define void @test_incsspd(i32 %a) local_unnamed_addr {
|
define void @test_incsspd(i32 %a) local_unnamed_addr {
|
||||||
; CHECK-LABEL: test_incsspd:
|
; CHECK-LABEL: test_incsspd:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+shstk -mattr=+ibt | FileCheck %s
|
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+shstk | FileCheck %s
|
||||||
|
|
||||||
define void @test_incsspd(i32 %a) local_unnamed_addr {
|
define void @test_incsspd(i32 %a) local_unnamed_addr {
|
||||||
; CHECK-LABEL: test_incsspd:
|
; CHECK-LABEL: test_incsspd:
|
||||||
|
|
|
@ -103,7 +103,7 @@ loopexit:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { uwtable "target-cpu"="skylake" "target-features"="+sse2,+cx16,+sahf,-tbm,-avx512ifma,-sha,-gfni,-fma4,-vpclmulqdq,+prfchw,+bmi2,-cldemote,+fsgsbase,+xsavec,+popcnt,+aes,-avx512bitalg,+xsaves,-avx512er,-avx512vnni,-avx512vpopcntdq,-clwb,-avx512f,-clzero,-pku,+mmx,-lwp,-rdpid,-xop,+rdseed,-waitpkg,-ibt,-sse4a,-avx512bw,+clflushopt,+xsave,-avx512vbmi2,-avx512vl,-avx512cd,+avx,-vaes,+rtm,+fma,+bmi,+rdrnd,-mwaitx,+sse4.1,+sse4.2,+avx2,-wbnoinvd,+sse,+lzcnt,+pclmul,-prefetchwt1,+f16c,+ssse3,+sgx,-shstk,+cmov,-avx512vbmi,+movbe,+xsaveopt,-avx512dq,+adx,-avx512pf,+sse3" }
|
attributes #0 = { uwtable "target-cpu"="skylake" "target-features"="+sse2,+cx16,+sahf,-tbm,-avx512ifma,-sha,-gfni,-fma4,-vpclmulqdq,+prfchw,+bmi2,-cldemote,+fsgsbase,+xsavec,+popcnt,+aes,-avx512bitalg,+xsaves,-avx512er,-avx512vnni,-avx512vpopcntdq,-clwb,-avx512f,-clzero,-pku,+mmx,-lwp,-rdpid,-xop,+rdseed,-waitpkg,-sse4a,-avx512bw,+clflushopt,+xsave,-avx512vbmi2,-avx512vl,-avx512cd,+avx,-vaes,+rtm,+fma,+bmi,+rdrnd,-mwaitx,+sse4.1,+sse4.2,+avx2,-wbnoinvd,+sse,+lzcnt,+pclmul,-prefetchwt1,+f16c,+ssse3,+sgx,-shstk,+cmov,-avx512vbmi,+movbe,+xsaveopt,-avx512dq,+adx,-avx512pf,+sse3" }
|
||||||
|
|
||||||
!0 = !{i32 0, i32 2147483646}
|
!0 = !{i32 0, i32 2147483646}
|
||||||
!1 = !{}
|
!1 = !{}
|
||||||
|
|
Loading…
Reference in New Issue