[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 6 05:21:24 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Matthew Levy (matthewlevy97)
<details>
<summary>Changes</summary>
The goal of this stack is to provide a metric to audit the deployed mitigations in a binary and where they are enabled at function level granularity. This will enable tracking of where we do and don't have mitigations, versus the current approach of tracking where flags are passed.
Two flags are added to control this behavior:
1) Compile time `-fmitigation-analysis` to generate the metadata pertaining to mitigation enablement/disablement
2) Link time `-enable-mitigation-analysis` to generate the output JSON when building with LTO
---
Patch is 30.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130103.diff
18 Files Affected:
- (modified) clang/include/clang/Basic/CodeGenOptions.def (+1)
- (modified) clang/include/clang/Driver/Options.td (+6)
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+10)
- (modified) clang/lib/CodeGen/CGClass.cpp (+3)
- (modified) clang/lib/CodeGen/CGDecl.cpp (+4)
- (modified) clang/lib/CodeGen/CGExpr.cpp (+5)
- (modified) clang/lib/CodeGen/CGExprCXX.cpp (+6)
- (modified) clang/lib/CodeGen/CMakeLists.txt (+1)
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+22)
- (added) clang/lib/CodeGen/MitigationTagging.cpp (+84)
- (added) clang/lib/CodeGen/MitigationTagging.h (+45)
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+3)
- (added) llvm/include/llvm/Analysis/MitigationAnalysis.h (+27)
- (modified) llvm/lib/Analysis/CMakeLists.txt (+1)
- (added) llvm/lib/Analysis/MitigationAnalysis.cpp (+304)
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1)
- (modified) llvm/lib/Passes/PassBuilderPipelines.cpp (+9)
- (modified) llvm/lib/Passes/PassRegistry.def (+1)
``````````diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index a7f5f1abbb825..76a46ac3e592b 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable
CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled
CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled.
+CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled.
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined.
CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d0414aba35209..e50bb5c1c2cb4 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack",
CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse,
NegFlag<SetFalse, [], [ClangOption], "Wouldn't use segmented stack">,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use segmented stack">>;
+defm mitigation_analysis : BoolFOption<"mitigation-analysis",
+ CodeGenOpts<"MitigationAnalysis">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " mitigation analysis">>,
+ DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">;
def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
HelpText<"Enable stack protectors for all functions">;
defm stack_clash_protection : BoolFOption<"stack-clash-protection",
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index ab8f19b25fa66..4e180bb1a87cf 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -21,6 +21,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
+#include "MitigationTagging.h"
#include "PatternInit.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
@@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size,
switch (CGF.getLangOpts().getTrivialAutoVarInit()) {
case LangOptions::TrivialAutoVarInitKind::Uninitialized:
// Nothing to initialize.
+ AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT,
+ false);
return;
case LangOptions::TrivialAutoVarInitKind::Zero:
Byte = CGF.Builder.getInt8(0x00);
@@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size,
break;
}
}
+ AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true);
if (CGF.CGM.stopAutoInit())
return;
auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes);
@@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
AI->setAlignment(SuitableAlignmentInBytes);
if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized)
initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes);
+ else
+ AttachMitigationMetadataToFunction(*this, MitigationKey::AUTO_VAR_INIT,
+ false);
LangAS AAS = getASTAllocaAddressSpace();
LangAS EAS = E->getType()->getPointeeType().getAddressSpace();
if (AAS != EAS) {
@@ -4664,6 +4671,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
AI->setAlignment(AlignmentInBytes);
if (BuiltinID != Builtin::BI__builtin_alloca_with_align_uninitialized)
initializeAlloca(*this, AI, Size, AlignmentInBytes);
+ else
+ AttachMitigationMetadataToFunction(*this, MitigationKey::AUTO_VAR_INIT,
+ false);
LangAS AAS = getASTAllocaAddressSpace();
LangAS EAS = E->getType()->getPointeeType().getAddressSpace();
if (AAS != EAS) {
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index e54fd543f217b..6858cd35615d3 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -16,6 +16,7 @@
#include "CGDebugInfo.h"
#include "CGRecordLayout.h"
#include "CodeGenFunction.h"
+#include "MitigationTagging.h"
#include "TargetInfo.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
@@ -2847,6 +2848,8 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
Builder.CreateCall(CGM.getIntrinsic(IID), {VTable, TypeId});
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
}
+
+ AttachMitigationMetadataToFunction(*this, MitigationKey::CFI_VCALL, false);
}
void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 9cd5885aaae51..39f94b093b23c 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -20,6 +20,7 @@
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "EHScopeStack.h"
+#include "MitigationTagging.h"
#include "PatternInit.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
@@ -1974,6 +1975,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
? LangOptions::TrivialAutoVarInitKind::Uninitialized
: getContext().getLangOpts().getTrivialAutoVarInit());
+ AttachMitigationMetadataToFunction(
+ *this, MitigationKey::AUTO_VAR_INIT,
+ trivialAutoVarInit != LangOptions::TrivialAutoVarInitKind::Uninitialized);
auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
if (trivialAutoVarInit ==
LangOptions::TrivialAutoVarInitKind::Uninitialized)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 191912ca7d800..dda5ea63b93d1 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -22,6 +22,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
+#include "MitigationTagging.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
@@ -6091,6 +6092,10 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
// function pointer is a member of the bit set for the function type.
if (SanOpts.has(SanitizerKind::CFIICall) &&
(!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
+ AttachMitigationMetadataToFunction(
+ *this, MitigationKey::CFI_ICALL,
+ SanOpts.has(clang::SanitizerKind::CFIICall));
+
SanitizerScope SanScope(this);
EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index d4e14f4574b87..9ae192d60ca91 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -16,6 +16,7 @@
#include "CGObjCRuntime.h"
#include "CodeGenFunction.h"
#include "ConstantEmitter.h"
+#include "MitigationTagging.h"
#include "TargetInfo.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/CodeGen/CGFunctionInfo.h"
@@ -416,6 +417,11 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
std::tie(VTable, RD) = CGM.getCXXABI().LoadVTablePtr(
*this, This.getAddress(), CalleeDecl->getParent());
EmitVTablePtrCheckForCall(RD, VTable, CFITCK_NVCall, CE->getBeginLoc());
+ AttachMitigationMetadataToFunction(*this, MitigationKey::CFI_NVCALL,
+ true);
+ } else if (MD->getParent()->isDynamicClass()) {
+ AttachMitigationMetadataToFunction(*this, MitigationKey::CFI_NVCALL,
+ false);
}
if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index 05ab6671453f8..56b98742d35af 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -110,6 +110,7 @@ add_clang_library(clangCodeGen
LinkInModulesPass.cpp
MacroPPCallbacks.cpp
MicrosoftCXXABI.cpp
+ MitigationTagging.cpp
ModuleBuilder.cpp
ObjectFilePCHContainerWriter.cpp
PatternInit.cpp
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index cec8f1233b663..f8c65a21b0783 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -26,6 +26,7 @@
#include "CodeGenPGO.h"
#include "ConstantEmitter.h"
#include "CoverageMappingGen.h"
+#include "MitigationTagging.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
@@ -2490,6 +2491,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
if ((!D || !D->hasAttr<NoUwtableAttr>()) && CodeGenOpts.UnwindTables)
B.addUWTableAttr(llvm::UWTableKind(CodeGenOpts.UnwindTables));
+ AttachMitigationMetadataToFunction(*F, MitigationKey::STACK_CLASH_PROTECTION,
+ CodeGenOpts.StackClashProtector);
if (CodeGenOpts.StackClashProtector)
B.addAttribute("probe-stack", "inline-asm");
@@ -2512,6 +2515,25 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPReq))
B.addAttribute(llvm::Attribute::StackProtectReq);
+ bool noStackProtectionAttr = D && D->hasAttr<NoStackProtectorAttr>();
+ AttachMitigationMetadataToFunction(
+ *F, MitigationKey::STACK_PROTECTOR,
+ !noStackProtectionAttr &&
+ (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPOn) ||
+ isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPStrong) ||
+ isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPReq)));
+
+ AttachMitigationMetadataToFunction(
+ *F, MitigationKey::STACK_PROTECTOR_STRONG,
+ !noStackProtectionAttr &&
+ (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPStrong) ||
+ isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPReq)));
+
+ AttachMitigationMetadataToFunction(
+ *F, MitigationKey::STACK_PROTECTOR_ALL,
+ !noStackProtectionAttr &&
+ isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPReq));
+
if (!D) {
// Non-entry HLSL functions must always be inlined.
if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline))
diff --git a/clang/lib/CodeGen/MitigationTagging.cpp b/clang/lib/CodeGen/MitigationTagging.cpp
new file mode 100644
index 0000000000000..d247dcab84059
--- /dev/null
+++ b/clang/lib/CodeGen/MitigationTagging.cpp
@@ -0,0 +1,84 @@
+//===--- MitigationTagging.cpp - Emit LLVM Code from ASTs for a Module ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This enables tagging functions with metadata to indicate mitigations are
+// applied to them.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MitigationTagging.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace CodeGen {
+
+inline static std::string
+MitigationKeyToString(enum MitigationKey key) noexcept {
+ switch (key) {
+ case MitigationKey::AUTO_VAR_INIT:
+ return "auto-var-init";
+ case MitigationKey::STACK_CLASH_PROTECTION:
+ return "stack-clash-protection";
+ case MitigationKey::STACK_PROTECTOR:
+ return "stack-protector";
+ case MitigationKey::STACK_PROTECTOR_STRONG:
+ return "stack-protector-strong";
+ case MitigationKey::STACK_PROTECTOR_ALL:
+ return "stack-protector-all";
+ case MitigationKey::CFI_VCALL:
+ return "cfi-vcall";
+ case MitigationKey::CFI_ICALL:
+ return "cfi-icall";
+ case MitigationKey::CFI_NVCALL:
+ return "cfi-nvcall";
+ }
+}
+
+void AttachMitigationMetadataToFunction(llvm::Function &F,
+ enum MitigationKey key, bool enabled) {
+ llvm::LLVMContext &Context = F.getContext();
+
+ unsigned kindID = Context.getMDKindID("security_mitigations");
+
+ llvm::Metadata *ValueMD = llvm::ConstantAsMetadata::get(
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(Context), enabled));
+ llvm::MDString *KeyMD =
+ llvm::MDString::get(Context, MitigationKeyToString(key));
+
+ llvm::MDNode *NewMD = llvm::MDNode::get(Context, {KeyMD, ValueMD});
+ llvm::MDNode *ExistingMD = F.getMetadata(kindID);
+
+ if (ExistingMD) {
+ std::vector<llvm::Metadata *> MDs;
+ for (unsigned i = 0, e = ExistingMD->getNumOperands(); i != e; ++i) {
+ MDs.push_back(ExistingMD->getOperand(i));
+ }
+ MDs.push_back(NewMD);
+
+ llvm::MDNode *CombinedMD = llvm::MDNode::get(Context, MDs);
+ F.setMetadata(kindID, CombinedMD);
+ } else {
+ F.setMetadata(kindID, NewMD);
+ }
+}
+
+void AttachMitigationMetadataToFunction(CodeGenFunction &CGF,
+ enum MitigationKey key, bool enabled) {
+ if (!CGF.CGM.getCodeGenOpts().MitigationAnalysis) {
+ return;
+ }
+ AttachMitigationMetadataToFunction(*(CGF.CurFn), key, enabled);
+}
+
+} // namespace CodeGen
+} // namespace clang
diff --git a/clang/lib/CodeGen/MitigationTagging.h b/clang/lib/CodeGen/MitigationTagging.h
new file mode 100644
index 0000000000000..fa80f63439734
--- /dev/null
+++ b/clang/lib/CodeGen/MitigationTagging.h
@@ -0,0 +1,45 @@
+//===--- MitigationTagging.h - Emit LLVM Code from ASTs for a Module ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This enables tagging functions with metadata to indicate mitigations are
+// applied to them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_MITIGATIONTAGGING_H
+#define LLVM_CLANG_LIB_CODEGEN_MITIGATIONTAGGING_H
+
+#include "CodeGenFunction.h"
+#include "llvm/IR/Function.h"
+
+namespace clang {
+namespace CodeGen {
+
+enum class MitigationKey {
+ AUTO_VAR_INIT,
+
+ STACK_CLASH_PROTECTION,
+
+ STACK_PROTECTOR,
+ STACK_PROTECTOR_STRONG,
+ STACK_PROTECTOR_ALL,
+
+ CFI_VCALL,
+ CFI_ICALL,
+ CFI_NVCALL,
+};
+
+void AttachMitigationMetadataToFunction(llvm::Function &F,
+ enum MitigationKey key, bool enabled);
+void AttachMitigationMetadataToFunction(CodeGenFunction &CGF,
+ enum MitigationKey key, bool enabled);
+
+} // namespace CodeGen
+} // namespace clang
+
+#endif
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 4ebbd241d2f0b..b1d960c41a274 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7033,6 +7033,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
RenderSCPOptions(TC, Args, CmdArgs);
RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
+ Args.addOptInFlag(CmdArgs, options::OPT_fmitigation_analysis,
+ options::OPT_fno_mitigation_analysis);
+
Args.AddLastArg(CmdArgs, options::OPT_fswift_async_fp_EQ);
Args.addOptInFlag(CmdArgs, options::OPT_mstackrealign,
diff --git a/llvm/include/llvm/Analysis/MitigationAnalysis.h b/llvm/include/llvm/Analysis/MitigationAnalysis.h
new file mode 100644
index 0000000000000..c32f55f79fdb9
--- /dev/null
+++ b/llvm/include/llvm/Analysis/MitigationAnalysis.h
@@ -0,0 +1,27 @@
+#ifndef LLVM_ANALYSIS_MITIGATIONANALYSIS_H
+#define LLVM_ANALYSIS_MITIGATIONANALYSIS_H
+
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class MitigationAnalysis : public AnalysisInfoMixin<MitigationAnalysis> {
+ friend AnalysisInfoMixin<MitigationAnalysis>;
+ static AnalysisKey Key;
+
+ static constexpr const char *kMitigationAnalysisDebugType =
+ "mitigation_analysis";
+
+public:
+ using Result = PreservedAnalyses;
+ Result run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_MITIGATIONANALYSIS_H
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index a44f6c6a135ef..662e170c3c247 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -103,6 +103,7 @@ add_llvm_component_library(LLVMAnalysis
MemoryProfileInfo.cpp
MemorySSA.cpp
MemorySSAUpdater.cpp
+ MitigationAnalysis.cpp
ModelUnderTrainingRunner.cpp
ModuleDebugInfoPrinter.cpp
ModuleSummaryAnalysis.cpp
diff --git a/llvm/lib/Analysis/MitigationAnalysis.cpp b/llvm/lib/Analysis/MitigationAnalysis.cpp
new file mode 100644
index 0000000000000..08cbd3ae9ce48
--- /dev/null
+++ b/llvm/lib/Analysis/MitigationAnalysis.cpp
@@ -0,0 +1,304 @@
+#include "llvm/Analysis/MitigationAnalysis.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+#include <unordered_map>
+
+using namespace llvm;
+
+AnalysisKey MitigationAnalysis::Key;
+
+// Add a command line flag for the module name
+static cl::opt<std::string>
+ ClOutputModuleName("mitigation-analysis-dso-name", cl::Optional,
+ cl::desc("DSO name for the module"),
+ cl::init("unknown"));
+
+enum class MitigationState { Ineligible, EligibleDisabled, EligibleEnabled };
+
+static const std::unordered_map<MitigationState, std::string> mapStateToString =
+ {
+ {MitigationState::Ineligible, "N/A"},
+ {MitigationState::EligibleDisabled, "Disabled"},
+ {MitigationState::EligibleEnabled, "Enabled"},
+};
+
+struct MitigationInfo {
+ MitigationState auto_var_init = MitigationState::Ineligible;
+ MitigationState cfi_icall = MitigationState::Ineligible;
+ MitigationState cfi_vcall = MitigationState::Ineligible;
+ MitigationState cfi_nvcall = MitigationState::Ineligible;
+ MitigationState stack_clash_protection = MitigationState::Ineligible;
+ MitigationState stack_protector = MitigationState::Ineligible;
+ MitigationState stack_protector_strong = MitigationState::Ineligible;
+ MitigationState stack_protector_all = MitigationState::Ineligible;
+ MitigationState libcpp_hardening_mode = MitigationState::Ineligible;
+ std::string source_mapping = "(unknown)";
+ std::string type_signature = "??";
+ uint64_t type_id = 0;
+ std::string function;
+ std::string gmodule;
+};
+
+/// Convert an integer value (0 or 1) to the appropriate MitigationState.
+static inline MitigationState valToState(int value) {
+ switch (value) {
+ case 0:
+ return MitigationState::EligibleDisabled;
+ case 1:
+ return MitigationState::EligibleEnabled;
+ default:
+ return MitigationState::Ineligible;
+ }
+}
+
+/// Print out fields in MitigationInfo for debugging/verification purposes.
+#ifndef NDEBUG
+static void printInfo(const MitigationInfo &info) {
+ dbgs() << "module: " << info.gmodule << "\n";
+ dbgs() << "function: " << info.function << "\n";
+ dbgs() << "source_location: " << info.source_mapping << "\n";
+ dbgs() << "auto-var-init: " << mapStateToString.at(info.auto_var_init)
+ << "\n";
+ dbgs() << "cfi-icall: " << mapStateToString.at(info.cfi_icall) << "\n";
+ dbgs() << "cfi-vcall: " << mapStateToString.at(info.cfi_vcall) << "\n";
+ dbgs() << "cfi-nvcall: " << mapStateToString.at(info.cfi_nv...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/130103
More information about the cfe-commits
mailing list