Author: Stefan Pintilie Date: 2021-02-18T12:15:50Z New Revision: b80357d46e229ace904a8580e0a93e3f9b91720b
URL: https://github.com/llvm/llvm-project/commit/b80357d46e229ace904a8580e0a93e3f9b91720b DIFF: https://github.com/llvm/llvm-project/commit/b80357d46e229ace904a8580e0a93e3f9b91720b.diff LOG: [PowerPC] Add option for ROP Protection Added -mrop-protection for Power PC to turn on codegen that provides some protection from ROP attacks. The option is off by default and can be turned on for Power 8, Power 9 and Power 10. This patch is for the option only. The feature will be implemented by a later patch. Reviewed By: amyk Differential Revision: https://reviews.llvm.org/D96512 Added: clang/test/Driver/ppc-mrop-protection-support-check.c Modified: clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/PPC.cpp clang/lib/Basic/Targets/PPC.h clang/test/Preprocessor/init-ppc64.c llvm/lib/Target/PowerPC/PPC.td llvm/lib/Target/PowerPC/PPCSubtarget.cpp llvm/lib/Target/PowerPC/PPCSubtarget.h llvm/test/CodeGen/PowerPC/future-check-features.ll Removed: ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 635af48cc051..0e09958b36e1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3181,6 +3181,8 @@ def mno_longcall : Flag<["-"], "mno-longcall">, Group<m_ppc_Features_Group>; def mmma: Flag<["-"], "mmma">, Group<m_ppc_Features_Group>; def mno_mma: Flag<["-"], "mno-mma">, Group<m_ppc_Features_Group>; +def mrop_protection : Flag<["-"], "mrop-protection">, + Group<m_ppc_Features_Group>; def maix_struct_return : Flag<["-"], "maix-struct-return">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Return all structs in memory (PPC32 only)">; diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index ff09c0fa2a23..73ecc05f2015 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -66,6 +66,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, PairedVectorMemops = true; } else if (Feature == "+mma") { HasMMA = true; + } else if (Feature == "+rop-protection") { + HasROPProtection = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -193,6 +195,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__POWER9_VECTOR__"); if (HasMMA) Builder.defineMacro("__MMA__"); + if (HasROPProtection) + Builder.defineMacro("__ROP_PROTECTION__"); if (HasP10Vector) Builder.defineMacro("__POWER10_VECTOR__"); @@ -319,6 +323,9 @@ bool PPCTargetInfo::initFeatureMap( .Case("pwr8", true) .Default(false); + // ROP Protection is off by default. + Features["rop-protection"] = false; + Features["spe"] = llvm::StringSwitch<bool>(CPU) .Case("8548", true) .Case("e500", true) @@ -355,6 +362,13 @@ bool PPCTargetInfo::initFeatureMap( return false; } + if (!(ArchDefs & ArchDefinePwr8) && + llvm::find(FeaturesVec, "+rop-protection") != FeaturesVec.end()) { + // We can turn on ROP Protection on Power 8 and above. + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protection" << CPU; + return false; + } + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -393,6 +407,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("pcrelative-memops", HasPCRelativeMemops) .Case("spe", HasSPE) .Case("mma", HasMMA) + .Case("rop-protection", HasROPProtection) .Default(false); } diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 56c8f33ef221..d3bff015760f 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -59,6 +59,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // Target cpu features. bool HasAltivec = false; bool HasMMA = false; + bool HasROPProtection = false; bool HasVSX = false; bool HasP8Vector = false; bool HasP8Crypto = false; diff --git a/clang/test/Driver/ppc-mrop-protection-support-check.c b/clang/test/Driver/ppc-mrop-protection-support-check.c new file mode 100644 index 000000000000..c2761d21c9d1 --- /dev/null +++ b/clang/test/Driver/ppc-mrop-protection-support-check.c @@ -0,0 +1,26 @@ +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr10 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power10 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr9 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power9 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr8 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power8 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=HASROP + +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=pwr7 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=NOROP +// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \ +// RUN: -mcpu=power7 -mrop-protection %s 2>&1 | FileCheck %s --check-prefix=NOROP + +#ifdef __ROP_PROTECTION__ +static_assert(false, "ROP Protection enabled"); +#endif + +// HASROP: ROP Protection enabled +// HASROP-NOT: option '-mrop-protection' cannot be specified with +// NOROP: option '-mrop-protection' cannot be specified with + diff --git a/clang/test/Preprocessor/init-ppc64.c b/clang/test/Preprocessor/init-ppc64.c index 120f1b3dba6a..163e86b919bc 100644 --- a/clang/test/Preprocessor/init-ppc64.c +++ b/clang/test/Preprocessor/init-ppc64.c @@ -566,6 +566,7 @@ // PPCPWR8-NOT:#define _ARCH_PWR6X 1 // PPCPWR8:#define _ARCH_PWR7 1 // PPCPWR8:#define _ARCH_PWR8 1 +// PPCPWR8-NOT:#define __ROP_PROTECTION__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER8 %s // @@ -583,6 +584,7 @@ // PPCPOWER8-NOT:#define _ARCH_PWR6X 1 // PPCPOWER8:#define _ARCH_PWR7 1 // PPCPOWER8:#define _ARCH_PWR8 1 +// PPCPOWER8-NOT:#define __ROP_PROTECTION__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr9 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPWR9 %s // @@ -597,6 +599,7 @@ // PPCPWR9-NOT:#define _ARCH_PWR6X 1 // PPCPWR9:#define _ARCH_PWR7 1 // PPCPWR9:#define _ARCH_PWR9 1 +// PPCPWR9-NOT:#define __ROP_PROTECTION__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER9 %s // @@ -611,6 +614,7 @@ // PPCPOWER9-NOT:#define _ARCH_PWR6X 1 // PPCPOWER9:#define _ARCH_PWR7 1 // PPCPOWER9:#define _ARCH_PWR9 1 +// PPCPOWER9-NOT:#define __ROP_PROTECTION__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr10 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER10 %s // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER10 %s @@ -629,6 +633,7 @@ // PPCPOWER10:#define _ARCH_PWR8 1 // PPCPOWER10:#define _ARCH_PWR9 1 // PPCPOWER10:#define __MMA__ 1 +// PPCPOWER10-NOT:#define __ROP_PROTECTION__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu future -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCFUTURE %s // @@ -647,10 +652,16 @@ // PPCFUTURE:#define _ARCH_PWR9 1 // PPCFUTURE:#define _ARCH_PWR_FUTURE 1 // PPCFUTURE:#define __MMA__ 1 +// PPCFUTURE-NOT:#define __ROP_PROTECTION__ 1 // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +mma -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-MMA %s // PPC-MMA:#define __MMA__ 1 // +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protection -target-cpu power10 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protection -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +rop-protection -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-ROP %s +// PPC-ROP:#define __ROP_PROTECTION__ 1 +// // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s // PPC-FLOAT128:#define __FLOAT128__ 1 // diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td index 1e6ded231585..c2840ebc5342 100644 --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -252,6 +252,9 @@ def FeatureMMA : SubtargetFeature<"mma", "HasMMA", "true", "Enable MMA instructions", [FeatureP8Vector, FeatureP9Altivec, FeaturePairedVectorMemops]>; +def FeatureROPProtection : + SubtargetFeature<"rop-protection", "HasROPProtection", "false", + "Add ROP protection">; def FeaturePredictableSelectIsExpensive : SubtargetFeature<"predictable-select-expensive", @@ -320,7 +323,8 @@ def ProcessorFeatures { FeatureDirectMove, FeatureICBT, FeaturePartwordAtomic, - FeaturePredictableSelectIsExpensive + FeaturePredictableSelectIsExpensive, + FeatureROPProtection ]; list<SubtargetFeature> P8SpecificFeatures = [FeatureAddiLoadFusion, diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp index d31195f67ef1..bf98ea8a01d0 100644 --- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -87,6 +87,7 @@ void PPCSubtarget::initializeEnvironment() { HasP9Vector = false; HasP9Altivec = false; HasMMA = false; + HasROPProtection = false; HasP10Vector = false; HasPrefixInstrs = false; HasPCRelativeMemops = false; diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h index 50d89390d5bc..04eb4a2f3da7 100644 --- a/llvm/lib/Target/PowerPC/PPCSubtarget.h +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h @@ -112,6 +112,7 @@ class PPCSubtarget : public PPCGenSubtargetInfo { bool HasPrefixInstrs; bool HasPCRelativeMemops; bool HasMMA; + bool HasROPProtection; bool HasFCPSGN; bool HasFSQRT; bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES; @@ -273,6 +274,7 @@ class PPCSubtarget : public PPCGenSubtargetInfo { bool hasPrefixInstrs() const { return HasPrefixInstrs; } bool hasPCRelativeMemops() const { return HasPCRelativeMemops; } bool hasMMA() const { return HasMMA; } + bool hasROPProtection() const { return HasROPProtection; } bool pairedVectorMemops() const { return PairedVectorMemops; } bool hasMFOCRF() const { return HasMFOCRF; } bool hasISEL() const { return HasISEL; } diff --git a/llvm/test/CodeGen/PowerPC/future-check-features.ll b/llvm/test/CodeGen/PowerPC/future-check-features.ll index ce4305ac44c2..aaae1089ea01 100644 --- a/llvm/test/CodeGen/PowerPC/future-check-features.ll +++ b/llvm/test/CodeGen/PowerPC/future-check-features.ll @@ -1,7 +1,7 @@ -; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma \ +; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma,rop-protection \ ; RUN: -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown \ ; RUN: -ppc-asm-full-reg-names %s -o - 2>&1 | FileCheck %s -; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma \ +; RUN: llc -mattr=pcrelative-memops,prefix-instrs,paired-vector-memops,mma,rop-protection \ ; RUN: -verify-machineinstrs -mtriple=powerpc64-unknown-unknown \ ; RUN: -ppc-asm-full-reg-names %s -o - 2>&1 | FileCheck %s _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits