brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.4 KiB · 5fd5d6c Raw
748 lines · cpp
1//===- StackProtector.cpp - Stack Protector Insertion ---------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This pass inserts stack protectors into functions which need them. A variable10// with a random value in it is stored onto the stack before the local variables11// are allocated. Upon exiting the block, the stored value is checked. If it's12// changed, then there was some sort of violation and the program aborts.13//14//===----------------------------------------------------------------------===//15 16#include "llvm/CodeGen/StackProtector.h"17#include "llvm/ADT/SmallVector.h"18#include "llvm/ADT/Statistic.h"19#include "llvm/Analysis/BranchProbabilityInfo.h"20#include "llvm/Analysis/MemoryLocation.h"21#include "llvm/Analysis/OptimizationRemarkEmitter.h"22#include "llvm/CodeGen/Analysis.h"23#include "llvm/CodeGen/Passes.h"24#include "llvm/CodeGen/TargetLowering.h"25#include "llvm/CodeGen/TargetPassConfig.h"26#include "llvm/CodeGen/TargetSubtargetInfo.h"27#include "llvm/IR/Attributes.h"28#include "llvm/IR/BasicBlock.h"29#include "llvm/IR/Constants.h"30#include "llvm/IR/DataLayout.h"31#include "llvm/IR/DerivedTypes.h"32#include "llvm/IR/Dominators.h"33#include "llvm/IR/EHPersonalities.h"34#include "llvm/IR/Function.h"35#include "llvm/IR/IRBuilder.h"36#include "llvm/IR/Instruction.h"37#include "llvm/IR/Instructions.h"38#include "llvm/IR/IntrinsicInst.h"39#include "llvm/IR/Intrinsics.h"40#include "llvm/IR/MDBuilder.h"41#include "llvm/IR/Module.h"42#include "llvm/IR/Type.h"43#include "llvm/IR/User.h"44#include "llvm/InitializePasses.h"45#include "llvm/Pass.h"46#include "llvm/Support/Casting.h"47#include "llvm/Support/CommandLine.h"48#include "llvm/Target/TargetMachine.h"49#include "llvm/Target/TargetOptions.h"50#include "llvm/Transforms/Utils/BasicBlockUtils.h"51#include <optional>52 53using namespace llvm;54 55#define DEBUG_TYPE "stack-protector"56 57STATISTIC(NumFunProtected, "Number of functions protected");58STATISTIC(NumAddrTaken, "Number of local variables that have their address"59                        " taken.");60 61static cl::opt<bool> EnableSelectionDAGSP("enable-selectiondag-sp",62                                          cl::init(true), cl::Hidden);63static cl::opt<bool> DisableCheckNoReturn("disable-check-noreturn-call",64                                          cl::init(false), cl::Hidden);65 66/// InsertStackProtectors - Insert code into the prologue and epilogue of the67/// function.68///69///  - The prologue code loads and stores the stack guard onto the stack.70///  - The epilogue checks the value stored in the prologue against the original71///    value. It calls __stack_chk_fail if they differ.72static bool InsertStackProtectors(const TargetMachine *TM, Function *F,73                                  DomTreeUpdater *DTU, bool &HasPrologue,74                                  bool &HasIRCheck);75 76/// CreateFailBB - Create a basic block to jump to when the stack protector77/// check fails.78static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);79 80bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {81  return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator());82}83 84void SSPLayoutInfo::copyToMachineFrameInfo(MachineFrameInfo &MFI) const {85  if (Layout.empty())86    return;87 88  for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) {89    if (MFI.isDeadObjectIndex(I))90      continue;91 92    const AllocaInst *AI = MFI.getObjectAllocation(I);93    if (!AI)94      continue;95 96    SSPLayoutMap::const_iterator LI = Layout.find(AI);97    if (LI == Layout.end())98      continue;99 100    MFI.setObjectSSPLayout(I, LI->second);101  }102}103 104SSPLayoutInfo SSPLayoutAnalysis::run(Function &F,105                                     FunctionAnalysisManager &FAM) {106 107  SSPLayoutInfo Info;108  Info.RequireStackProtector =109      SSPLayoutAnalysis::requiresStackProtector(&F, &Info.Layout);110  Info.SSPBufferSize = F.getFnAttributeAsParsedInteger(111      "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);112  return Info;113}114 115AnalysisKey SSPLayoutAnalysis::Key;116 117PreservedAnalyses StackProtectorPass::run(Function &F,118                                          FunctionAnalysisManager &FAM) {119  auto &Info = FAM.getResult<SSPLayoutAnalysis>(F);120  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);121  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);122 123  if (!Info.RequireStackProtector)124    return PreservedAnalyses::all();125 126  // TODO(etienneb): Functions with funclets are not correctly supported now.127  // Do nothing if this is funclet-based personality.128  if (F.hasPersonalityFn()) {129    EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());130    if (isFuncletEHPersonality(Personality))131      return PreservedAnalyses::all();132  }133 134  ++NumFunProtected;135  bool Changed = InsertStackProtectors(TM, &F, DT ? &DTU : nullptr,136                                       Info.HasPrologue, Info.HasIRCheck);137#ifdef EXPENSIVE_CHECKS138  assert((!DT ||139          DTU.getDomTree().verify(DominatorTree::VerificationLevel::Full)) &&140         "Failed to maintain validity of domtree!");141#endif142 143  if (!Changed)144    return PreservedAnalyses::all();145  PreservedAnalyses PA;146  PA.preserve<SSPLayoutAnalysis>();147  PA.preserve<DominatorTreeAnalysis>();148  return PA;149}150 151char StackProtector::ID = 0;152 153StackProtector::StackProtector() : FunctionPass(ID) {154  initializeStackProtectorPass(*PassRegistry::getPassRegistry());155}156 157INITIALIZE_PASS_BEGIN(StackProtector, DEBUG_TYPE,158                      "Insert stack protectors", false, true)159INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)160INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)161INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,162                    "Insert stack protectors", false, true)163 164FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }165 166void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {167  AU.addRequired<TargetPassConfig>();168  AU.addPreserved<DominatorTreeWrapperPass>();169}170 171bool StackProtector::runOnFunction(Function &Fn) {172  F = &Fn;173  M = F->getParent();174  if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())175    DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);176  TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();177  LayoutInfo.HasPrologue = false;178  LayoutInfo.HasIRCheck = false;179 180  LayoutInfo.SSPBufferSize = Fn.getFnAttributeAsParsedInteger(181      "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);182  if (!requiresStackProtector(F, &LayoutInfo.Layout))183    return false;184 185  // TODO(etienneb): Functions with funclets are not correctly supported now.186  // Do nothing if this is funclet-based personality.187  if (Fn.hasPersonalityFn()) {188    EHPersonality Personality = classifyEHPersonality(Fn.getPersonalityFn());189    if (isFuncletEHPersonality(Personality))190      return false;191  }192 193  ++NumFunProtected;194  bool Changed =195      InsertStackProtectors(TM, F, DTU ? &*DTU : nullptr,196                            LayoutInfo.HasPrologue, LayoutInfo.HasIRCheck);197#ifdef EXPENSIVE_CHECKS198  assert((!DTU ||199          DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full)) &&200         "Failed to maintain validity of domtree!");201#endif202  DTU.reset();203  return Changed;204}205 206/// \param [out] IsLarge is set to true if a protectable array is found and207/// it is "large" ( >= ssp-buffer-size).  In the case of a structure with208/// multiple arrays, this gets set if any of them is large.209static bool ContainsProtectableArray(Type *Ty, Module *M, unsigned SSPBufferSize,210                                     bool &IsLarge, bool Strong,211                                     bool InStruct) {212  if (!Ty)213    return false;214  if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {215    if (!AT->getElementType()->isIntegerTy(8)) {216      // If we're on a non-Darwin platform or we're inside of a structure, don't217      // add stack protectors unless the array is a character array.218      // However, in strong mode any array, regardless of type and size,219      // triggers a protector.220      if (!Strong && (InStruct || !M->getTargetTriple().isOSDarwin()))221        return false;222    }223 224    // If an array has more than SSPBufferSize bytes of allocated space, then we225    // emit stack protectors.226    if (SSPBufferSize <= M->getDataLayout().getTypeAllocSize(AT)) {227      IsLarge = true;228      return true;229    }230 231    if (Strong)232      // Require a protector for all arrays in strong mode233      return true;234  }235 236  const StructType *ST = dyn_cast<StructType>(Ty);237  if (!ST)238    return false;239 240  bool NeedsProtector = false;241  for (Type *ET : ST->elements())242    if (ContainsProtectableArray(ET, M, SSPBufferSize, IsLarge, Strong, true)) {243      // If the element is a protectable array and is large (>= SSPBufferSize)244      // then we are done.  If the protectable array is not large, then245      // keep looking in case a subsequent element is a large array.246      if (IsLarge)247        return true;248      NeedsProtector = true;249    }250 251  return NeedsProtector;252}253 254/// Maximum remaining allocation size observed for a phi node, and how often255/// the allocation size has already been decreased. We only allow a limited256/// number of decreases.257struct PhiInfo {258  TypeSize AllocSize;259  unsigned NumDecreased = 0;260  static constexpr unsigned MaxNumDecreased = 3;261  PhiInfo(TypeSize AllocSize) : AllocSize(AllocSize) {}262};263using PhiMap = SmallDenseMap<const PHINode *, PhiInfo, 16>;264 265/// Check whether a stack allocation has its address taken.266static bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize,267                            Module *M,268                            PhiMap &VisitedPHIs) {269  const DataLayout &DL = M->getDataLayout();270  for (const User *U : AI->users()) {271    const auto *I = cast<Instruction>(U);272    // If this instruction accesses memory make sure it doesn't access beyond273    // the bounds of the allocated object.274    std::optional<MemoryLocation> MemLoc = MemoryLocation::getOrNone(I);275    if (MemLoc && MemLoc->Size.hasValue() &&276        !TypeSize::isKnownGE(AllocSize, MemLoc->Size.getValue()))277      return true;278    switch (I->getOpcode()) {279    case Instruction::Store:280      if (AI == cast<StoreInst>(I)->getValueOperand())281        return true;282      break;283    case Instruction::AtomicCmpXchg:284      // cmpxchg conceptually includes both a load and store from the same285      // location. So, like store, the value being stored is what matters.286      if (AI == cast<AtomicCmpXchgInst>(I)->getNewValOperand())287        return true;288      break;289    case Instruction::AtomicRMW:290      if (AI == cast<AtomicRMWInst>(I)->getValOperand())291        return true;292      break;293    case Instruction::PtrToInt:294      if (AI == cast<PtrToIntInst>(I)->getOperand(0))295        return true;296      break;297    case Instruction::Call: {298      // Ignore intrinsics that do not become real instructions.299      // TODO: Narrow this to intrinsics that have store-like effects.300      const auto *CI = cast<CallInst>(I);301      if (!CI->isDebugOrPseudoInst() && !CI->isLifetimeStartOrEnd())302        return true;303      break;304    }305    case Instruction::Invoke:306      return true;307    case Instruction::GetElementPtr: {308      // If the GEP offset is out-of-bounds, or is non-constant and so has to be309      // assumed to be potentially out-of-bounds, then any memory access that310      // would use it could also be out-of-bounds meaning stack protection is311      // required.312      const GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);313      unsigned IndexSize = DL.getIndexTypeSizeInBits(I->getType());314      APInt Offset(IndexSize, 0);315      if (!GEP->accumulateConstantOffset(DL, Offset))316        return true;317      TypeSize OffsetSize = TypeSize::getFixed(Offset.getLimitedValue());318      if (!TypeSize::isKnownGT(AllocSize, OffsetSize))319        return true;320      // Adjust AllocSize to be the space remaining after this offset.321      // We can't subtract a fixed size from a scalable one, so in that case322      // assume the scalable value is of minimum size.323      TypeSize NewAllocSize =324          TypeSize::getFixed(AllocSize.getKnownMinValue()) - OffsetSize;325      if (HasAddressTaken(I, NewAllocSize, M, VisitedPHIs))326        return true;327      break;328    }329    case Instruction::BitCast:330    case Instruction::Select:331    case Instruction::AddrSpaceCast:332      if (HasAddressTaken(I, AllocSize, M, VisitedPHIs))333        return true;334      break;335    case Instruction::PHI: {336      // Keep track of what PHI nodes we have already visited to ensure337      // they are only visited once.338      const auto *PN = cast<PHINode>(I);339      auto [It, Inserted] = VisitedPHIs.try_emplace(PN, AllocSize);340      if (!Inserted) {341        if (TypeSize::isKnownGE(AllocSize, It->second.AllocSize))342          break;343 344        // Check again with smaller size.345        if (It->second.NumDecreased == PhiInfo::MaxNumDecreased)346          return true;347 348        It->second.AllocSize = AllocSize;349        ++It->second.NumDecreased;350      }351      if (HasAddressTaken(PN, AllocSize, M, VisitedPHIs))352        return true;353      break;354    }355    case Instruction::Load:356    case Instruction::Ret:357      // These instructions take an address operand, but have load-like or358      // other innocuous behavior that should not trigger a stack protector.359      break;360    default:361      // Conservatively return true for any instruction that takes an address362      // operand, but is not handled above.363      return true;364    }365  }366  return false;367}368 369/// Search for the first call to the llvm.stackprotector intrinsic and return it370/// if present.371static const CallInst *findStackProtectorIntrinsic(Function &F) {372  for (const BasicBlock &BB : F)373    for (const Instruction &I : BB)374      if (const auto *II = dyn_cast<IntrinsicInst>(&I))375        if (II->getIntrinsicID() == Intrinsic::stackprotector)376          return II;377  return nullptr;378}379 380/// Check whether or not this function needs a stack protector based381/// upon the stack protector level.382///383/// We use two heuristics: a standard (ssp) and strong (sspstrong).384/// The standard heuristic which will add a guard variable to functions that385/// call alloca with a either a variable size or a size >= SSPBufferSize,386/// functions with character buffers larger than SSPBufferSize, and functions387/// with aggregates containing character buffers larger than SSPBufferSize. The388/// strong heuristic will add a guard variables to functions that call alloca389/// regardless of size, functions with any buffer regardless of type and size,390/// functions with aggregates that contain any buffer regardless of type and391/// size, and functions that contain stack-based variables that have had their392/// address taken.393bool SSPLayoutAnalysis::requiresStackProtector(Function *F,394                                               SSPLayoutMap *Layout) {395  Module *M = F->getParent();396  bool Strong = false;397  bool NeedsProtector = false;398 399  // The set of PHI nodes visited when determining if a variable's reference has400  // been taken.  This set is maintained to ensure we don't visit the same PHI401  // node multiple times.402  PhiMap VisitedPHIs;403 404  unsigned SSPBufferSize = F->getFnAttributeAsParsedInteger(405      "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);406 407  if (F->hasFnAttribute(Attribute::SafeStack))408    return false;409 410  // We are constructing the OptimizationRemarkEmitter on the fly rather than411  // using the analysis pass to avoid building DominatorTree and LoopInfo which412  // are not available this late in the IR pipeline.413  OptimizationRemarkEmitter ORE(F);414 415  if (F->hasFnAttribute(Attribute::StackProtectReq)) {416    if (!Layout)417      return true;418    ORE.emit([&]() {419      return OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F)420             << "Stack protection applied to function "421             << ore::NV("Function", F)422             << " due to a function attribute or command-line switch";423    });424    NeedsProtector = true;425    Strong = true; // Use the same heuristic as strong to determine SSPLayout426  } else if (F->hasFnAttribute(Attribute::StackProtectStrong))427    Strong = true;428  else if (!F->hasFnAttribute(Attribute::StackProtect))429    return false;430 431  for (const BasicBlock &BB : *F) {432    for (const Instruction &I : BB) {433      if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {434        if (AI->isArrayAllocation()) {435          auto RemarkBuilder = [&]() {436            return OptimizationRemark(DEBUG_TYPE, "StackProtectorAllocaOrArray",437                                      &I)438                   << "Stack protection applied to function "439                   << ore::NV("Function", F)440                   << " due to a call to alloca or use of a variable length "441                      "array";442          };443          if (const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {444            if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {445              // A call to alloca with size >= SSPBufferSize requires446              // stack protectors.447              if (!Layout)448                return true;449              Layout->insert(450                  std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));451              ORE.emit(RemarkBuilder);452              NeedsProtector = true;453            } else if (Strong) {454              // Require protectors for all alloca calls in strong mode.455              if (!Layout)456                return true;457              Layout->insert(458                  std::make_pair(AI, MachineFrameInfo::SSPLK_SmallArray));459              ORE.emit(RemarkBuilder);460              NeedsProtector = true;461            }462          } else {463            // A call to alloca with a variable size requires protectors.464            if (!Layout)465              return true;466            Layout->insert(467                std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));468            ORE.emit(RemarkBuilder);469            NeedsProtector = true;470          }471          continue;472        }473 474        bool IsLarge = false;475        if (ContainsProtectableArray(AI->getAllocatedType(), M, SSPBufferSize,476                                     IsLarge, Strong, false)) {477          if (!Layout)478            return true;479          Layout->insert(std::make_pair(480              AI, IsLarge ? MachineFrameInfo::SSPLK_LargeArray481                          : MachineFrameInfo::SSPLK_SmallArray));482          ORE.emit([&]() {483            return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)484                   << "Stack protection applied to function "485                   << ore::NV("Function", F)486                   << " due to a stack allocated buffer or struct containing a "487                      "buffer";488          });489          NeedsProtector = true;490          continue;491        }492 493        if (Strong &&494            HasAddressTaken(495                AI, M->getDataLayout().getTypeAllocSize(AI->getAllocatedType()),496                M, VisitedPHIs)) {497          ++NumAddrTaken;498          if (!Layout)499            return true;500          Layout->insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));501          ORE.emit([&]() {502            return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",503                                      &I)504                   << "Stack protection applied to function "505                   << ore::NV("Function", F)506                   << " due to the address of a local variable being taken";507          });508          NeedsProtector = true;509        }510        // Clear any PHIs that we visited, to make sure we examine all uses of511        // any subsequent allocas that we look at.512        VisitedPHIs.clear();513      }514    }515  }516 517  return NeedsProtector;518}519 520/// Create a stack guard loading and populate whether SelectionDAG SSP is521/// supported.522static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,523                            IRBuilder<> &B,524                            bool *SupportsSelectionDAGSP = nullptr) {525  Value *Guard = TLI->getIRStackGuard(B);526  StringRef GuardMode = M->getStackProtectorGuard();527  if ((GuardMode == "tls" || GuardMode.empty()) && Guard)528    return B.CreateLoad(B.getPtrTy(), Guard, true, "StackGuard");529 530  // Use SelectionDAG SSP handling, since there isn't an IR guard.531  //532  // This is more or less weird, since we optionally output whether we533  // should perform a SelectionDAG SP here. The reason is that it's strictly534  // defined as !TLI->getIRStackGuard(B), where getIRStackGuard is also535  // mutating. There is no way to get this bit without mutating the IR, so536  // getting this bit has to happen in this right time.537  //538  // We could have define a new function TLI::supportsSelectionDAGSP(), but that539  // will put more burden on the backends' overriding work, especially when it540  // actually conveys the same information getIRStackGuard() already gives.541  if (SupportsSelectionDAGSP)542    *SupportsSelectionDAGSP = true;543  TLI->insertSSPDeclarations(*M);544  return B.CreateIntrinsic(Intrinsic::stackguard, {});545}546 547/// Insert code into the entry block that stores the stack guard548/// variable onto the stack:549///550///   entry:551///     StackGuardSlot = alloca i8*552///     StackGuard = <stack guard>553///     call void @llvm.stackprotector(StackGuard, StackGuardSlot)554///555/// Returns true if the platform/triple supports the stackprotectorcreate pseudo556/// node.557static bool CreatePrologue(Function *F, Module *M, Instruction *CheckLoc,558                           const TargetLoweringBase *TLI, AllocaInst *&AI) {559  bool SupportsSelectionDAGSP = false;560  IRBuilder<> B(&F->getEntryBlock().front());561  PointerType *PtrTy = PointerType::getUnqual(CheckLoc->getContext());562  AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");563 564  Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);565  B.CreateIntrinsic(Intrinsic::stackprotector, {GuardSlot, AI});566  return SupportsSelectionDAGSP;567}568 569bool InsertStackProtectors(const TargetMachine *TM, Function *F,570                           DomTreeUpdater *DTU, bool &HasPrologue,571                           bool &HasIRCheck) {572  auto *M = F->getParent();573  auto *TLI = TM->getSubtargetImpl(*F)->getTargetLowering();574 575  // If the target wants to XOR the frame pointer into the guard value, it's576  // impossible to emit the check in IR, so the target *must* support stack577  // protection in SDAG.578  bool SupportsSelectionDAGSP =579      TLI->useStackGuardXorFP() ||580      (EnableSelectionDAGSP && !TM->Options.EnableFastISel);581  AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.582  BasicBlock *FailBB = nullptr;583 584  for (BasicBlock &BB : llvm::make_early_inc_range(*F)) {585    // This is stack protector auto generated check BB, skip it.586    if (&BB == FailBB)587      continue;588    Instruction *CheckLoc = dyn_cast<ReturnInst>(BB.getTerminator());589    if (!CheckLoc && !DisableCheckNoReturn)590      for (auto &Inst : BB) {591        if (IntrinsicInst *IB = dyn_cast<IntrinsicInst>(&Inst);592            IB && (IB->getIntrinsicID() == Intrinsic::eh_sjlj_callsite)) {593          // eh_sjlj_callsite has to be in same BB as the594          // bb terminator. Don't insert within this range.595          CheckLoc = IB;596          break;597        }598        if (auto *CB = dyn_cast<CallBase>(&Inst))599          // Do stack check before noreturn calls that aren't nounwind (e.g:600          // __cxa_throw).601          if (CB->doesNotReturn() && !CB->doesNotThrow()) {602            CheckLoc = CB;603            break;604          }605      }606 607    if (!CheckLoc)608      continue;609 610    // Generate prologue instrumentation if not already generated.611    if (!HasPrologue) {612      HasPrologue = true;613      SupportsSelectionDAGSP &= CreatePrologue(F, M, CheckLoc, TLI, AI);614    }615 616    // SelectionDAG based code generation. Nothing else needs to be done here.617    // The epilogue instrumentation is postponed to SelectionDAG.618    if (SupportsSelectionDAGSP)619      break;620 621    // Find the stack guard slot if the prologue was not created by this pass622    // itself via a previous call to CreatePrologue().623    if (!AI) {624      const CallInst *SPCall = findStackProtectorIntrinsic(*F);625      assert(SPCall && "Call to llvm.stackprotector is missing");626      AI = cast<AllocaInst>(SPCall->getArgOperand(1));627    }628 629    // Set HasIRCheck to true, so that SelectionDAG will not generate its own630    // version. SelectionDAG called 'shouldEmitSDCheck' to check whether631    // instrumentation has already been generated.632    HasIRCheck = true;633 634    // If we're instrumenting a block with a tail call, the check has to be635    // inserted before the call rather than between it and the return.636    Instruction *Prev = CheckLoc->getPrevNode();637    if (auto *CI = dyn_cast_if_present<CallInst>(Prev))638      if (CI->isTailCall() && isInTailCallPosition(*CI, *TM))639        CheckLoc = Prev;640 641    // Generate epilogue instrumentation. The epilogue intrumentation can be642    // function-based or inlined depending on which mechanism the target is643    // providing.644    if (Function *GuardCheck = TLI->getSSPStackGuardCheck(*M)) {645      // Generate the function-based epilogue instrumentation.646      // The target provides a guard check function, generate a call to it.647      IRBuilder<> B(CheckLoc);648      LoadInst *Guard = B.CreateLoad(B.getPtrTy(), AI, true, "Guard");649      CallInst *Call = B.CreateCall(GuardCheck, {Guard});650      Call->setAttributes(GuardCheck->getAttributes());651      Call->setCallingConv(GuardCheck->getCallingConv());652    } else {653      // Generate the epilogue with inline instrumentation.654      // If we do not support SelectionDAG based calls, generate IR level655      // calls.656      //657      // For each block with a return instruction, convert this:658      //659      //   return:660      //     ...661      //     ret ...662      //663      // into this:664      //665      //   return:666      //     ...667      //     %1 = <stack guard>668      //     %2 = load StackGuardSlot669      //     %3 = icmp ne i1 %1, %2670      //     br i1 %3, label %CallStackCheckFailBlk, label %SP_return671      //672      //   SP_return:673      //     ret ...674      //675      //   CallStackCheckFailBlk:676      //     call void @__stack_chk_fail()677      //     unreachable678 679      // Create the FailBB. We duplicate the BB every time since the MI tail680      // merge pass will merge together all of the various BB into one including681      // fail BB generated by the stack protector pseudo instruction.682      if (!FailBB)683        FailBB = CreateFailBB(F, *TLI);684 685      IRBuilder<> B(CheckLoc);686      Value *Guard = getStackGuard(TLI, M, B);687      LoadInst *LI2 = B.CreateLoad(B.getPtrTy(), AI, true);688      auto *Cmp = cast<ICmpInst>(B.CreateICmpNE(Guard, LI2));689      auto SuccessProb =690          BranchProbabilityInfo::getBranchProbStackProtector(true);691      auto FailureProb =692          BranchProbabilityInfo::getBranchProbStackProtector(false);693      MDNode *Weights = MDBuilder(F->getContext())694                            .createBranchWeights(FailureProb.getNumerator(),695                                                 SuccessProb.getNumerator());696 697      SplitBlockAndInsertIfThen(Cmp, CheckLoc,698                                /*Unreachable=*/false, Weights, DTU,699                                /*LI=*/nullptr, /*ThenBlock=*/FailBB);700 701      auto *BI = cast<BranchInst>(Cmp->getParent()->getTerminator());702      BasicBlock *NewBB = BI->getSuccessor(1);703      NewBB->setName("SP_return");704      NewBB->moveAfter(&BB);705 706      Cmp->setPredicate(Cmp->getInversePredicate());707      BI->swapSuccessors();708    }709  }710 711  // Return if we didn't modify any basic blocks. i.e., there are no return712  // statements in the function.713  return HasPrologue;714}715 716BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI) {717  auto *M = F->getParent();718  LLVMContext &Context = F->getContext();719  BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);720  IRBuilder<> B(FailBB);721  if (F->getSubprogram())722    B.SetCurrentDebugLocation(723        DILocation::get(Context, 0, 0, F->getSubprogram()));724  FunctionCallee StackChkFail;725  SmallVector<Value *, 1> Args;726 727  if (const char *ChkFailName =728          TLI.getLibcallName(RTLIB::STACKPROTECTOR_CHECK_FAIL)) {729    StackChkFail =730        M->getOrInsertFunction(ChkFailName, Type::getVoidTy(Context));731  } else if (const char *SSHName =732                 TLI.getLibcallName(RTLIB::STACK_SMASH_HANDLER)) {733    StackChkFail = M->getOrInsertFunction(SSHName, Type::getVoidTy(Context),734                                          PointerType::getUnqual(Context));735    Args.push_back(B.CreateGlobalString(F->getName(), "SSH"));736  } else {737    Context.emitError("no libcall available for stack protector");738  }739 740  if (StackChkFail) {741    CallInst *Call = B.CreateCall(StackChkFail, Args);742    Call->addFnAttr(Attribute::NoReturn);743  }744 745  B.CreateUnreachable();746  return FailBB;747}748