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