diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2024-01-09 20:00:28 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-19 21:14:10 +0000 |
| commit | cdc20ff6a7f12464aed70d9b6e67ea07da9f0399 (patch) | |
| tree | 0c2f259d41b6d1f146c344cb9cf2b15ea99d35bb /contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp | |
| parent | 7adf29b6244fe016ef869f287a66048195f9af29 (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/ShadowStackGCLowering.cpp | 97 |
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. |
