aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-01-09 20:00:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-19 21:14:10 +0000
commitcdc20ff6a7f12464aed70d9b6e67ea07da9f0399 (patch)
tree0c2f259d41b6d1f146c344cb9cf2b15ea99d35bb /contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
parent7adf29b6244fe016ef869f287a66048195f9af29 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp97
1 files changed, 66 insertions, 31 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
index d4840d117110..232e5e2bb886 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
@@ -15,9 +15,11 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/CodeGen/ShadowStackGCLowering.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
@@ -50,7 +52,7 @@ using namespace llvm;
namespace {
-class ShadowStackGCLowering : public FunctionPass {
+class ShadowStackGCLoweringImpl {
/// RootChain - This is the global linked-list that contains the chain of GC
/// roots.
GlobalVariable *Head = nullptr;
@@ -64,13 +66,10 @@ class ShadowStackGCLowering : public FunctionPass {
std::vector<std::pair<CallInst *, AllocaInst *>> Roots;
public:
- static char ID;
-
- ShadowStackGCLowering();
+ ShadowStackGCLoweringImpl() = default;
- bool doInitialization(Module &M) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnFunction(Function &F) override;
+ bool doInitialization(Module &M);
+ bool runOnFunction(Function &F, DomTreeUpdater *DTU);
private:
bool IsNullValue(Value *V);
@@ -86,8 +85,51 @@ private:
const char *Name);
};
+class ShadowStackGCLowering : public FunctionPass {
+ ShadowStackGCLoweringImpl Impl;
+
+public:
+ static char ID;
+
+ ShadowStackGCLowering();
+
+ bool doInitialization(Module &M) override { return Impl.doInitialization(M); }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addPreserved<DominatorTreeWrapperPass>();
+ }
+ bool runOnFunction(Function &F) override {
+ std::optional<DomTreeUpdater> DTU;
+ if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
+ DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
+ return Impl.runOnFunction(F, DTU ? &*DTU : nullptr);
+ }
+};
+
} // end anonymous namespace
+PreservedAnalyses ShadowStackGCLoweringPass::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ auto &Map = MAM.getResult<CollectorMetadataAnalysis>(M);
+ if (Map.StrategyMap.contains("shadow-stack"))
+ return PreservedAnalyses::all();
+
+ ShadowStackGCLoweringImpl Impl;
+ bool Changed = Impl.doInitialization(M);
+ for (auto &F : M) {
+ auto &FAM =
+ MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+ Changed |= Impl.runOnFunction(F, DT ? &DTU : nullptr);
+ }
+
+ if (!Changed)
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ return PA;
+}
+
char ShadowStackGCLowering::ID = 0;
char &llvm::ShadowStackGCLoweringID = ShadowStackGCLowering::ID;
@@ -104,7 +146,7 @@ ShadowStackGCLowering::ShadowStackGCLowering() : FunctionPass(ID) {
initializeShadowStackGCLoweringPass(*PassRegistry::getPassRegistry());
}
-Constant *ShadowStackGCLowering::GetFrameMap(Function &F) {
+Constant *ShadowStackGCLoweringImpl::GetFrameMap(Function &F) {
// doInitialization creates the abstract type of this value.
Type *VoidPtr = PointerType::getUnqual(F.getContext());
@@ -158,7 +200,7 @@ Constant *ShadowStackGCLowering::GetFrameMap(Function &F) {
return ConstantExpr::getGetElementPtr(FrameMap->getType(), GV, GEPIndices);
}
-Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) {
+Type *ShadowStackGCLoweringImpl::GetConcreteStackEntryType(Function &F) {
// doInitialization creates the generic version of this type.
std::vector<Type *> EltTys;
EltTys.push_back(StackEntryTy);
@@ -170,7 +212,7 @@ Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) {
/// doInitialization - If this module uses the GC intrinsics, find them now. If
/// not, exit fast.
-bool ShadowStackGCLowering::doInitialization(Module &M) {
+bool ShadowStackGCLoweringImpl::doInitialization(Module &M) {
bool Active = false;
for (Function &F : M) {
if (F.hasGC() && F.getGC() == "shadow-stack") {
@@ -224,13 +266,13 @@ bool ShadowStackGCLowering::doInitialization(Module &M) {
return true;
}
-bool ShadowStackGCLowering::IsNullValue(Value *V) {
+bool ShadowStackGCLoweringImpl::IsNullValue(Value *V) {
if (Constant *C = dyn_cast<Constant>(V))
return C->isNullValue();
return false;
}
-void ShadowStackGCLowering::CollectRoots(Function &F) {
+void ShadowStackGCLoweringImpl::CollectRoots(Function &F) {
// FIXME: Account for original alignment. Could fragment the root array.
// Approach 1: Null initialize empty slots at runtime. Yuck.
// Approach 2: Emit a map of the array instead of just a count.
@@ -258,11 +300,10 @@ void ShadowStackGCLowering::CollectRoots(Function &F) {
Roots.insert(Roots.begin(), MetaRoots.begin(), MetaRoots.end());
}
-GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
- IRBuilder<> &B, Type *Ty,
- Value *BasePtr, int Idx,
- int Idx2,
- const char *Name) {
+GetElementPtrInst *
+ShadowStackGCLoweringImpl::CreateGEP(LLVMContext &Context, IRBuilder<> &B,
+ Type *Ty, Value *BasePtr, int Idx,
+ int Idx2, const char *Name) {
Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0),
ConstantInt::get(Type::getInt32Ty(Context), Idx),
ConstantInt::get(Type::getInt32Ty(Context), Idx2)};
@@ -273,9 +314,11 @@ GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
return dyn_cast<GetElementPtrInst>(Val);
}
-GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
- IRBuilder<> &B, Type *Ty, Value *BasePtr,
- int Idx, const char *Name) {
+GetElementPtrInst *ShadowStackGCLoweringImpl::CreateGEP(LLVMContext &Context,
+ IRBuilder<> &B,
+ Type *Ty,
+ Value *BasePtr, int Idx,
+ const char *Name) {
Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0),
ConstantInt::get(Type::getInt32Ty(Context), Idx)};
Value *Val = B.CreateGEP(Ty, BasePtr, Indices, Name);
@@ -285,12 +328,9 @@ GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
return dyn_cast<GetElementPtrInst>(Val);
}
-void ShadowStackGCLowering::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addPreserved<DominatorTreeWrapperPass>();
-}
-
/// runOnFunction - Insert code to maintain the shadow stack.
-bool ShadowStackGCLowering::runOnFunction(Function &F) {
+bool ShadowStackGCLoweringImpl::runOnFunction(Function &F,
+ DomTreeUpdater *DTU) {
// Quick exit for functions that do not use the shadow stack GC.
if (!F.hasGC() || F.getGC() != "shadow-stack")
return false;
@@ -305,10 +345,6 @@ bool ShadowStackGCLowering::runOnFunction(Function &F) {
if (Roots.empty())
return false;
- std::optional<DomTreeUpdater> DTU;
- if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
- DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
-
// Build the constant map and figure the type of the shadow stack entry.
Value *FrameMap = GetFrameMap(F);
Type *ConcreteStackEntryTy = GetConcreteStackEntryType(F);
@@ -359,8 +395,7 @@ bool ShadowStackGCLowering::runOnFunction(Function &F) {
AtEntry.CreateStore(NewHeadVal, Head);
// For each instruction that escapes...
- EscapeEnumerator EE(F, "gc_cleanup", /*HandleExceptions=*/true,
- DTU ? &*DTU : nullptr);
+ EscapeEnumerator EE(F, "gc_cleanup", /*HandleExceptions=*/true, DTU);
while (IRBuilder<> *AtExit = EE.Next()) {
// Pop the entry from the shadow stack. Don't reuse CurrentHead from
// AtEntry, since that would make the value live for the entire function.