diff options
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.  | 
