llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Daniel Paoliello (dpaoliello)

<details>
<summary>Changes</summary>

Currently the `cfguard` module flag can be set to 1 (emit tables only, no 
checks) or 2 (emit tables and checks).

This change formalizes that definition by moving these values into an enum, 
instead of just having them documented in comments.

Split out from #<!-- -->176276

---
Full diff: https://github.com/llvm/llvm-project/pull/176461.diff


8 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+6-2) 
- (modified) llvm/include/llvm/IR/Module.h (+3) 
- (modified) llvm/include/llvm/Support/CodeGen.h (+10) 
- (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/CFGuardLongjmp.cpp (+2-1) 
- (modified) llvm/lib/IR/Module.cpp (+7) 
- (modified) llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp (+4-5) 
- (modified) llvm/lib/Transforms/CFGuard/CFGuard.cpp (+4-6) 


``````````diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 614bca627e03c..c22daca9863f1 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1123,10 +1123,14 @@ void CodeGenModule::Release() {
   }
   if (CodeGenOpts.ControlFlowGuard) {
     // Function ID tables and checks for Control Flow Guard (cfguard=2).
-    getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 2);
+    getModule().addModuleFlag(
+        llvm::Module::Warning, "cfguard",
+        static_cast<unsigned>(llvm::ControlFlowGuardMode::Enabled));
   } else if (CodeGenOpts.ControlFlowGuardNoChecks) {
     // Function ID tables for Control Flow Guard (cfguard=1).
-    getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1);
+    getModule().addModuleFlag(
+        llvm::Module::Warning, "cfguard",
+        static_cast<unsigned>(llvm::ControlFlowGuardMode::TableOnly));
   }
   if (CodeGenOpts.EHContGuard) {
     // Function ID tables for EH Continuation Guard.
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index ac6c20b81d68c..7156a83c9f3cc 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -1056,6 +1056,9 @@ class LLVM_ABI Module {
   /// Get how unwind v2 (epilog) information should be generated for x64
   /// Windows.
   WinX64EHUnwindV2Mode getWinX64EHUnwindV2Mode() const;
+
+  /// Gets the Control Flow Guard mode.
+  ControlFlowGuardMode getControlFlowGuardMode() const;
 };
 
 /// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the
diff --git a/llvm/include/llvm/Support/CodeGen.h 
b/llvm/include/llvm/Support/CodeGen.h
index 848796ef574f8..65d262a087378 100644
--- a/llvm/include/llvm/Support/CodeGen.h
+++ b/llvm/include/llvm/Support/CodeGen.h
@@ -173,6 +173,16 @@ namespace llvm {
     Required = 2,
   };
 
+  enum class ControlFlowGuardMode {
+    // Don't enable Control Flow Guard.
+    Disabled = 0,
+    // Emit the Control Flow Guard tables in the binary, but don't emit any
+    // checks.
+    TableOnly = 1,
+    // Enable Control Flow Guard checks and emit the tables.
+    Enabled = 2,
+  };
+
   } // namespace llvm
 
 #endif
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp 
b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d96294e06d579..5990c2a2ba26a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -665,7 +665,7 @@ bool AsmPrinter::doInitialization(Module &M) {
     Handlers.push_back(std::unique_ptr<EHStreamer>(ES));
 
   // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2).
-  if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard")))
+  if (M.getControlFlowGuardMode() != ControlFlowGuardMode::Disabled)
     EHHandlers.push_back(std::make_unique<WinCFGuard>(this));
 
   for (auto &Handler : Handlers)
@@ -5088,7 +5088,7 @@ void AsmPrinter::emitCOFFFeatureSymbol(Module &M) {
     Feat00Value |= COFF::Feat00Flags::SafeSEH;
   }
 
-  if (M.getModuleFlag("cfguard")) {
+  if (M.getControlFlowGuardMode() != ControlFlowGuardMode::Disabled) {
     // Object is CFG-aware.
     Feat00Value |= COFF::Feat00Flags::GuardCF;
   }
diff --git a/llvm/lib/CodeGen/CFGuardLongjmp.cpp 
b/llvm/lib/CodeGen/CFGuardLongjmp.cpp
index 04de011400568..639d0537c2cc1 100644
--- a/llvm/lib/CodeGen/CFGuardLongjmp.cpp
+++ b/llvm/lib/CodeGen/CFGuardLongjmp.cpp
@@ -62,7 +62,8 @@ FunctionPass *llvm::createCFGuardLongjmpPass() { return new 
CFGuardLongjmp(); }
 bool CFGuardLongjmp::runOnMachineFunction(MachineFunction &MF) {
 
   // Skip modules for which the cfguard flag is not set.
-  if (!MF.getFunction().getParent()->getModuleFlag("cfguard"))
+  if (MF.getFunction().getParent()->getControlFlowGuardMode() ==
+      ControlFlowGuardMode::Disabled)
     return false;
 
   // Skip functions that do not have calls to _setjmp.
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 7360d0fa1f86a..11dc68e0e4751 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -940,3 +940,10 @@ WinX64EHUnwindV2Mode Module::getWinX64EHUnwindV2Mode() 
const {
     return static_cast<WinX64EHUnwindV2Mode>(CI->getZExtValue());
   return WinX64EHUnwindV2Mode::Disabled;
 }
+
+ControlFlowGuardMode Module::getControlFlowGuardMode() const {
+  Metadata *MD = getModuleFlag("cfguard");
+  if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
+    return static_cast<ControlFlowGuardMode>(CI->getZExtValue());
+  return ControlFlowGuardMode::Disabled;
+}
diff --git a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp 
b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
index d0c4b1b9f83fd..c27a693ceecc1 100644
--- a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
@@ -75,7 +75,7 @@ class AArch64Arm64ECCallLowering : public ModulePass {
   bool runOnModule(Module &M) override;
 
 private:
-  int cfguard_module_flag = 0;
+  ControlFlowGuardMode CFGuardModuleFlag = ControlFlowGuardMode::Disabled;
   FunctionType *GuardFnType = nullptr;
   FunctionType *DispatchFnType = nullptr;
   Constant *GuardFnCFGlobal = nullptr;
@@ -758,7 +758,8 @@ void AArch64Arm64ECCallLowering::lowerCall(CallBase *CB) {
 
   // Load the global symbol as a pointer to the check function.
   Value *GuardFn;
-  if (cfguard_module_flag == 2 && !CB->hasFnAttr("guard_nocf"))
+  if ((CFGuardModuleFlag == ControlFlowGuardMode::Enabled) &&
+      !CB->hasFnAttr("guard_nocf"))
     GuardFn = GuardFnCFGlobal;
   else
     GuardFn = GuardFnGlobal;
@@ -794,9 +795,7 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
   M = &Mod;
 
   // Check if this module has the cfguard flag and read its value.
-  if (auto *MD =
-          mdconst::extract_or_null<ConstantInt>(M->getModuleFlag("cfguard")))
-    cfguard_module_flag = MD->getZExtValue();
+  CFGuardModuleFlag = M->getControlFlowGuardMode();
 
   PtrTy = PointerType::getUnqual(M->getContext());
   I64Ty = Type::getInt64Ty(M->getContext());
diff --git a/llvm/lib/Transforms/CFGuard/CFGuard.cpp 
b/llvm/lib/Transforms/CFGuard/CFGuard.cpp
index 5c2d9ddaa76db..1553dcc8b197b 100644
--- a/llvm/lib/Transforms/CFGuard/CFGuard.cpp
+++ b/llvm/lib/Transforms/CFGuard/CFGuard.cpp
@@ -147,7 +147,7 @@ class CFGuardImpl {
 
 private:
   // Only add checks if the module has the cfguard=2 flag.
-  int CFGuardModuleFlag = 0;
+  ControlFlowGuardMode CFGuardModuleFlag = ControlFlowGuardMode::Disabled;
   StringRef GuardFnName;
   Mechanism GuardMechanism = Mechanism::Check;
   FunctionType *GuardFnType = nullptr;
@@ -233,12 +233,10 @@ void CFGuardImpl::insertCFGuardDispatch(CallBase *CB) {
 
 bool CFGuardImpl::doInitialization(Module &M) {
   // Check if this module has the cfguard flag and read its value.
-  if (auto *MD =
-          mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard")))
-    CFGuardModuleFlag = MD->getZExtValue();
+  CFGuardModuleFlag = M.getControlFlowGuardMode();
 
   // Skip modules for which CFGuard checks have been disabled.
-  if (CFGuardModuleFlag != 2)
+  if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled)
     return false;
 
   // Set up prototypes for the guard check and dispatch functions.
@@ -260,7 +258,7 @@ bool CFGuardImpl::doInitialization(Module &M) {
 
 bool CFGuardImpl::runOnFunction(Function &F) {
   // Skip modules for which CFGuard checks have been disabled.
-  if (CFGuardModuleFlag != 2)
+  if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled)
     return false;
 
   SmallVector<CallBase *, 8> IndirectCalls;

``````````

</details>


https://github.com/llvm/llvm-project/pull/176461
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to