LLVM 20.0.0git
StackProtector.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass inserts stack protectors into functions which need them. A variable
10// with a random value in it is stored onto the stack before the local variables
11// are allocated. Upon exiting the block, the stored value is checked. If it's
12// changed, then there was some sort of violation and the program aborts.
13//
14//===----------------------------------------------------------------------===//
15
19#include "llvm/ADT/Statistic.h"
23#include "llvm/CodeGen/Passes.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"
32#include "llvm/IR/Dominators.h"
34#include "llvm/IR/Function.h"
35#include "llvm/IR/IRBuilder.h"
36#include "llvm/IR/Instruction.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"
45#include "llvm/Pass.h"
51#include <optional>
52#include <utility>
53
54using namespace llvm;
55
56#define DEBUG_TYPE "stack-protector"
57
58STATISTIC(NumFunProtected, "Number of functions protected");
59STATISTIC(NumAddrTaken, "Number of local variables that have their address"
60 " taken.");
61
62static cl::opt<bool> EnableSelectionDAGSP("enable-selectiondag-sp",
63 cl::init(true), cl::Hidden);
64static cl::opt<bool> DisableCheckNoReturn("disable-check-noreturn-call",
65 cl::init(false), cl::Hidden);
66
67/// InsertStackProtectors - Insert code into the prologue and epilogue of the
68/// function.
69///
70/// - The prologue code loads and stores the stack guard onto the stack.
71/// - The epilogue checks the value stored in the prologue against the original
72/// value. It calls __stack_chk_fail if they differ.
73static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
74 DomTreeUpdater *DTU, bool &HasPrologue,
75 bool &HasIRCheck);
76
77/// CreateFailBB - Create a basic block to jump to when the stack protector
78/// check fails.
79static BasicBlock *CreateFailBB(Function *F, const Triple &Trip);
80
82 return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator());
83}
84
86 if (Layout.empty())
87 return;
88
89 for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) {
90 if (MFI.isDeadObjectIndex(I))
91 continue;
92
93 const AllocaInst *AI = MFI.getObjectAllocation(I);
94 if (!AI)
95 continue;
96
97 SSPLayoutMap::const_iterator LI = Layout.find(AI);
98 if (LI == Layout.end())
99 continue;
100
101 MFI.setObjectSSPLayout(I, LI->second);
102 }
103}
104
107
109 Info.RequireStackProtector =
111 Info.SSPBufferSize = F.getFnAttributeAsParsedInteger(
112 "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);
113 return Info;
114}
115
116AnalysisKey SSPLayoutAnalysis::Key;
117
122 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
123
124 if (!Info.RequireStackProtector)
125 return PreservedAnalyses::all();
126
127 // TODO(etienneb): Functions with funclets are not correctly supported now.
128 // Do nothing if this is funclet-based personality.
129 if (F.hasPersonalityFn()) {
130 EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());
131 if (isFuncletEHPersonality(Personality))
132 return PreservedAnalyses::all();
133 }
134
135 ++NumFunProtected;
136 bool Changed = InsertStackProtectors(TM, &F, DT ? &DTU : nullptr,
137 Info.HasPrologue, Info.HasIRCheck);
138#ifdef EXPENSIVE_CHECKS
139 assert((!DT || DT->verify(DominatorTree::VerificationLevel::Full)) &&
140 "Failed to maintain validity of domtree!");
141#endif
142
143 if (!Changed)
144 return PreservedAnalyses::all();
148 return PA;
149}
150
151char StackProtector::ID = 0;
152
155}
156
158 "Insert stack protectors", false, true)
162 "Insert stack protectors", false, true)
163
165
169}
170
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()) {
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_CHECKS
198 assert((!DTU ||
199 DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full)) &&
200 "Failed to maintain validity of domtree!");
201#endif
202 DTU.reset();
203 return Changed;
204}
205
206/// \param [out] IsLarge is set to true if a protectable array is found and
207/// it is "large" ( >= ssp-buffer-size). In the case of a structure with
208/// 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't
217 // 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 || !Triple(M->getTargetTriple()).isOSDarwin()))
221 return false;
222 }
223
224 // If an array has more than SSPBufferSize bytes of allocated space, then we
225 // 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 mode
233 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, then
245 // 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/// Check whether a stack allocation has its address taken.
255static bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize,
256 Module *M,
258 const DataLayout &DL = M->getDataLayout();
259 for (const User *U : AI->users()) {
260 const auto *I = cast<Instruction>(U);
261 // If this instruction accesses memory make sure it doesn't access beyond
262 // the bounds of the allocated object.
263 std::optional<MemoryLocation> MemLoc = MemoryLocation::getOrNone(I);
264 if (MemLoc && MemLoc->Size.hasValue() &&
265 !TypeSize::isKnownGE(AllocSize, MemLoc->Size.getValue()))
266 return true;
267 switch (I->getOpcode()) {
268 case Instruction::Store:
269 if (AI == cast<StoreInst>(I)->getValueOperand())
270 return true;
271 break;
272 case Instruction::AtomicCmpXchg:
273 // cmpxchg conceptually includes both a load and store from the same
274 // location. So, like store, the value being stored is what matters.
275 if (AI == cast<AtomicCmpXchgInst>(I)->getNewValOperand())
276 return true;
277 break;
278 case Instruction::PtrToInt:
279 if (AI == cast<PtrToIntInst>(I)->getOperand(0))
280 return true;
281 break;
282 case Instruction::Call: {
283 // Ignore intrinsics that do not become real instructions.
284 // TODO: Narrow this to intrinsics that have store-like effects.
285 const auto *CI = cast<CallInst>(I);
286 if (!CI->isDebugOrPseudoInst() && !CI->isLifetimeStartOrEnd())
287 return true;
288 break;
289 }
290 case Instruction::Invoke:
291 return true;
292 case Instruction::GetElementPtr: {
293 // If the GEP offset is out-of-bounds, or is non-constant and so has to be
294 // assumed to be potentially out-of-bounds, then any memory access that
295 // would use it could also be out-of-bounds meaning stack protection is
296 // required.
297 const GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
298 unsigned IndexSize = DL.getIndexTypeSizeInBits(I->getType());
299 APInt Offset(IndexSize, 0);
300 if (!GEP->accumulateConstantOffset(DL, Offset))
301 return true;
302 TypeSize OffsetSize = TypeSize::getFixed(Offset.getLimitedValue());
303 if (!TypeSize::isKnownGT(AllocSize, OffsetSize))
304 return true;
305 // Adjust AllocSize to be the space remaining after this offset.
306 // We can't subtract a fixed size from a scalable one, so in that case
307 // assume the scalable value is of minimum size.
308 TypeSize NewAllocSize =
309 TypeSize::getFixed(AllocSize.getKnownMinValue()) - OffsetSize;
310 if (HasAddressTaken(I, NewAllocSize, M, VisitedPHIs))
311 return true;
312 break;
313 }
314 case Instruction::BitCast:
315 case Instruction::Select:
316 case Instruction::AddrSpaceCast:
317 if (HasAddressTaken(I, AllocSize, M, VisitedPHIs))
318 return true;
319 break;
320 case Instruction::PHI: {
321 // Keep track of what PHI nodes we have already visited to ensure
322 // they are only visited once.
323 const auto *PN = cast<PHINode>(I);
324 if (VisitedPHIs.insert(PN).second)
325 if (HasAddressTaken(PN, AllocSize, M, VisitedPHIs))
326 return true;
327 break;
328 }
329 case Instruction::Load:
330 case Instruction::AtomicRMW:
331 case Instruction::Ret:
332 // These instructions take an address operand, but have load-like or
333 // other innocuous behavior that should not trigger a stack protector.
334 // atomicrmw conceptually has both load and store semantics, but the
335 // value being stored must be integer; so if a pointer is being stored,
336 // we'll catch it in the PtrToInt case above.
337 break;
338 default:
339 // Conservatively return true for any instruction that takes an address
340 // operand, but is not handled above.
341 return true;
342 }
343 }
344 return false;
345}
346
347/// Search for the first call to the llvm.stackprotector intrinsic and return it
348/// if present.
350 for (const BasicBlock &BB : F)
351 for (const Instruction &I : BB)
352 if (const auto *II = dyn_cast<IntrinsicInst>(&I))
353 if (II->getIntrinsicID() == Intrinsic::stackprotector)
354 return II;
355 return nullptr;
356}
357
358/// Check whether or not this function needs a stack protector based
359/// upon the stack protector level.
360///
361/// We use two heuristics: a standard (ssp) and strong (sspstrong).
362/// The standard heuristic which will add a guard variable to functions that
363/// call alloca with a either a variable size or a size >= SSPBufferSize,
364/// functions with character buffers larger than SSPBufferSize, and functions
365/// with aggregates containing character buffers larger than SSPBufferSize. The
366/// strong heuristic will add a guard variables to functions that call alloca
367/// regardless of size, functions with any buffer regardless of type and size,
368/// functions with aggregates that contain any buffer regardless of type and
369/// size, and functions that contain stack-based variables that have had their
370/// address taken.
372 SSPLayoutMap *Layout) {
373 Module *M = F->getParent();
374 bool Strong = false;
375 bool NeedsProtector = false;
376
377 // The set of PHI nodes visited when determining if a variable's reference has
378 // been taken. This set is maintained to ensure we don't visit the same PHI
379 // node multiple times.
381
382 unsigned SSPBufferSize = F->getFnAttributeAsParsedInteger(
383 "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);
384
385 if (F->hasFnAttribute(Attribute::SafeStack))
386 return false;
387
388 // We are constructing the OptimizationRemarkEmitter on the fly rather than
389 // using the analysis pass to avoid building DominatorTree and LoopInfo which
390 // are not available this late in the IR pipeline.
392
393 if (F->hasFnAttribute(Attribute::StackProtectReq)) {
394 if (!Layout)
395 return true;
396 ORE.emit([&]() {
397 return OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F)
398 << "Stack protection applied to function "
399 << ore::NV("Function", F)
400 << " due to a function attribute or command-line switch";
401 });
402 NeedsProtector = true;
403 Strong = true; // Use the same heuristic as strong to determine SSPLayout
404 } else if (F->hasFnAttribute(Attribute::StackProtectStrong))
405 Strong = true;
406 else if (!F->hasFnAttribute(Attribute::StackProtect))
407 return false;
408
409 for (const BasicBlock &BB : *F) {
410 for (const Instruction &I : BB) {
411 if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
412 if (AI->isArrayAllocation()) {
413 auto RemarkBuilder = [&]() {
414 return OptimizationRemark(DEBUG_TYPE, "StackProtectorAllocaOrArray",
415 &I)
416 << "Stack protection applied to function "
417 << ore::NV("Function", F)
418 << " due to a call to alloca or use of a variable length "
419 "array";
420 };
421 if (const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
422 if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
423 // A call to alloca with size >= SSPBufferSize requires
424 // stack protectors.
425 if (!Layout)
426 return true;
427 Layout->insert(
428 std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
429 ORE.emit(RemarkBuilder);
430 NeedsProtector = true;
431 } else if (Strong) {
432 // Require protectors for all alloca calls in strong mode.
433 if (!Layout)
434 return true;
435 Layout->insert(
436 std::make_pair(AI, MachineFrameInfo::SSPLK_SmallArray));
437 ORE.emit(RemarkBuilder);
438 NeedsProtector = true;
439 }
440 } else {
441 // A call to alloca with a variable size requires protectors.
442 if (!Layout)
443 return true;
444 Layout->insert(
445 std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
446 ORE.emit(RemarkBuilder);
447 NeedsProtector = true;
448 }
449 continue;
450 }
451
452 bool IsLarge = false;
453 if (ContainsProtectableArray(AI->getAllocatedType(), M, SSPBufferSize,
454 IsLarge, Strong, false)) {
455 if (!Layout)
456 return true;
457 Layout->insert(std::make_pair(
460 ORE.emit([&]() {
461 return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
462 << "Stack protection applied to function "
463 << ore::NV("Function", F)
464 << " due to a stack allocated buffer or struct containing a "
465 "buffer";
466 });
467 NeedsProtector = true;
468 continue;
469 }
470
471 if (Strong &&
473 AI, M->getDataLayout().getTypeAllocSize(AI->getAllocatedType()),
474 M, VisitedPHIs)) {
475 ++NumAddrTaken;
476 if (!Layout)
477 return true;
478 Layout->insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
479 ORE.emit([&]() {
480 return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
481 &I)
482 << "Stack protection applied to function "
483 << ore::NV("Function", F)
484 << " due to the address of a local variable being taken";
485 });
486 NeedsProtector = true;
487 }
488 // Clear any PHIs that we visited, to make sure we examine all uses of
489 // any subsequent allocas that we look at.
490 VisitedPHIs.clear();
491 }
492 }
493 }
494
495 return NeedsProtector;
496}
497
498/// Create a stack guard loading and populate whether SelectionDAG SSP is
499/// supported.
501 IRBuilder<> &B,
502 bool *SupportsSelectionDAGSP = nullptr) {
503 Value *Guard = TLI->getIRStackGuard(B);
504 StringRef GuardMode = M->getStackProtectorGuard();
505 if ((GuardMode == "tls" || GuardMode.empty()) && Guard)
506 return B.CreateLoad(B.getPtrTy(), Guard, true, "StackGuard");
507
508 // Use SelectionDAG SSP handling, since there isn't an IR guard.
509 //
510 // This is more or less weird, since we optionally output whether we
511 // should perform a SelectionDAG SP here. The reason is that it's strictly
512 // defined as !TLI->getIRStackGuard(B), where getIRStackGuard is also
513 // mutating. There is no way to get this bit without mutating the IR, so
514 // getting this bit has to happen in this right time.
515 //
516 // We could have define a new function TLI::supportsSelectionDAGSP(), but that
517 // will put more burden on the backends' overriding work, especially when it
518 // actually conveys the same information getIRStackGuard() already gives.
519 if (SupportsSelectionDAGSP)
520 *SupportsSelectionDAGSP = true;
521 TLI->insertSSPDeclarations(*M);
522 return B.CreateIntrinsic(Intrinsic::stackguard, {}, {});
523}
524
525/// Insert code into the entry block that stores the stack guard
526/// variable onto the stack:
527///
528/// entry:
529/// StackGuardSlot = alloca i8*
530/// StackGuard = <stack guard>
531/// call void @llvm.stackprotector(StackGuard, StackGuardSlot)
532///
533/// Returns true if the platform/triple supports the stackprotectorcreate pseudo
534/// node.
535static bool CreatePrologue(Function *F, Module *M, Instruction *CheckLoc,
536 const TargetLoweringBase *TLI, AllocaInst *&AI) {
537 bool SupportsSelectionDAGSP = false;
538 IRBuilder<> B(&F->getEntryBlock().front());
539 PointerType *PtrTy = PointerType::getUnqual(CheckLoc->getContext());
540 AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
541
542 Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);
543 B.CreateIntrinsic(Intrinsic::stackprotector, {}, {GuardSlot, AI});
544 return SupportsSelectionDAGSP;
545}
546
548 DomTreeUpdater *DTU, bool &HasPrologue,
549 bool &HasIRCheck) {
550 auto *M = F->getParent();
551 auto *TLI = TM->getSubtargetImpl(*F)->getTargetLowering();
552
553 // If the target wants to XOR the frame pointer into the guard value, it's
554 // impossible to emit the check in IR, so the target *must* support stack
555 // protection in SDAG.
556 bool SupportsSelectionDAGSP =
557 TLI->useStackGuardXorFP() ||
558 (EnableSelectionDAGSP && !TM->Options.EnableFastISel);
559 AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.
560 BasicBlock *FailBB = nullptr;
561
563 // This is stack protector auto generated check BB, skip it.
564 if (&BB == FailBB)
565 continue;
566 Instruction *CheckLoc = dyn_cast<ReturnInst>(BB.getTerminator());
567 if (!CheckLoc && !DisableCheckNoReturn)
568 for (auto &Inst : BB)
569 if (auto *CB = dyn_cast<CallBase>(&Inst))
570 // Do stack check before noreturn calls that aren't nounwind (e.g:
571 // __cxa_throw).
572 if (CB->doesNotReturn() && !CB->doesNotThrow()) {
573 CheckLoc = CB;
574 break;
575 }
576
577 if (!CheckLoc)
578 continue;
579
580 // Generate prologue instrumentation if not already generated.
581 if (!HasPrologue) {
582 HasPrologue = true;
583 SupportsSelectionDAGSP &= CreatePrologue(F, M, CheckLoc, TLI, AI);
584 }
585
586 // SelectionDAG based code generation. Nothing else needs to be done here.
587 // The epilogue instrumentation is postponed to SelectionDAG.
588 if (SupportsSelectionDAGSP)
589 break;
590
591 // Find the stack guard slot if the prologue was not created by this pass
592 // itself via a previous call to CreatePrologue().
593 if (!AI) {
594 const CallInst *SPCall = findStackProtectorIntrinsic(*F);
595 assert(SPCall && "Call to llvm.stackprotector is missing");
596 AI = cast<AllocaInst>(SPCall->getArgOperand(1));
597 }
598
599 // Set HasIRCheck to true, so that SelectionDAG will not generate its own
600 // version. SelectionDAG called 'shouldEmitSDCheck' to check whether
601 // instrumentation has already been generated.
602 HasIRCheck = true;
603
604 // If we're instrumenting a block with a tail call, the check has to be
605 // inserted before the call rather than between it and the return. The
606 // verifier guarantees that a tail call is either directly before the
607 // return or with a single correct bitcast of the return value in between so
608 // we don't need to worry about many situations here.
609 Instruction *Prev = CheckLoc->getPrevNonDebugInstruction();
610 if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
611 CheckLoc = Prev;
612 else if (Prev) {
613 Prev = Prev->getPrevNonDebugInstruction();
614 if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
615 CheckLoc = Prev;
616 }
617
618 // Generate epilogue instrumentation. The epilogue intrumentation can be
619 // function-based or inlined depending on which mechanism the target is
620 // providing.
621 if (Function *GuardCheck = TLI->getSSPStackGuardCheck(*M)) {
622 // Generate the function-based epilogue instrumentation.
623 // The target provides a guard check function, generate a call to it.
624 IRBuilder<> B(CheckLoc);
625 LoadInst *Guard = B.CreateLoad(B.getPtrTy(), AI, true, "Guard");
626 CallInst *Call = B.CreateCall(GuardCheck, {Guard});
627 Call->setAttributes(GuardCheck->getAttributes());
628 Call->setCallingConv(GuardCheck->getCallingConv());
629 } else {
630 // Generate the epilogue with inline instrumentation.
631 // If we do not support SelectionDAG based calls, generate IR level
632 // calls.
633 //
634 // For each block with a return instruction, convert this:
635 //
636 // return:
637 // ...
638 // ret ...
639 //
640 // into this:
641 //
642 // return:
643 // ...
644 // %1 = <stack guard>
645 // %2 = load StackGuardSlot
646 // %3 = icmp ne i1 %1, %2
647 // br i1 %3, label %CallStackCheckFailBlk, label %SP_return
648 //
649 // SP_return:
650 // ret ...
651 //
652 // CallStackCheckFailBlk:
653 // call void @__stack_chk_fail()
654 // unreachable
655
656 // Create the FailBB. We duplicate the BB every time since the MI tail
657 // merge pass will merge together all of the various BB into one including
658 // fail BB generated by the stack protector pseudo instruction.
659 if (!FailBB)
660 FailBB = CreateFailBB(F, TM->getTargetTriple());
661
662 IRBuilder<> B(CheckLoc);
663 Value *Guard = getStackGuard(TLI, M, B);
664 LoadInst *LI2 = B.CreateLoad(B.getPtrTy(), AI, true);
665 auto *Cmp = cast<ICmpInst>(B.CreateICmpNE(Guard, LI2));
666 auto SuccessProb =
668 auto FailureProb =
670 MDNode *Weights = MDBuilder(F->getContext())
671 .createBranchWeights(FailureProb.getNumerator(),
672 SuccessProb.getNumerator());
673
674 SplitBlockAndInsertIfThen(Cmp, CheckLoc,
675 /*Unreachable=*/false, Weights, DTU,
676 /*LI=*/nullptr, /*ThenBlock=*/FailBB);
677
678 auto *BI = cast<BranchInst>(Cmp->getParent()->getTerminator());
679 BasicBlock *NewBB = BI->getSuccessor(1);
680 NewBB->setName("SP_return");
681 NewBB->moveAfter(&BB);
682
683 Cmp->setPredicate(Cmp->getInversePredicate());
684 BI->swapSuccessors();
685 }
686 }
687
688 // Return if we didn't modify any basic blocks. i.e., there are no return
689 // statements in the function.
690 return HasPrologue;
691}
692
694 auto *M = F->getParent();
695 LLVMContext &Context = F->getContext();
696 BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
697 IRBuilder<> B(FailBB);
698 if (F->getSubprogram())
699 B.SetCurrentDebugLocation(
700 DILocation::get(Context, 0, 0, F->getSubprogram()));
701 FunctionCallee StackChkFail;
703 if (Trip.isOSOpenBSD()) {
704 StackChkFail = M->getOrInsertFunction("__stack_smash_handler",
705 Type::getVoidTy(Context),
706 PointerType::getUnqual(Context));
707 Args.push_back(B.CreateGlobalString(F->getName(), "SSH"));
708 } else {
709 StackChkFail =
710 M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
711 }
712 cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
713 B.CreateCall(StackChkFail, Args);
714 B.CreateUnreachable();
715 return FailBB;
716}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
basic Basic Alias true
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define DEBUG_TYPE
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize, Module *M, SmallPtrSet< const PHINode *, 16 > &VisitedPHIs)
Check whether a stack allocation has its address taken.
static Value * getStackGuard(const TargetLoweringBase *TLI, Module *M, IRBuilder<> &B, bool *SupportsSelectionDAGSP=nullptr)
Create a stack guard loading and populate whether SelectionDAG SSP is supported.
static bool InsertStackProtectors(const TargetMachine *TM, Function *F, DomTreeUpdater *DTU, bool &HasPrologue, bool &HasIRCheck)
InsertStackProtectors - Insert code into the prologue and epilogue of the function.
static BasicBlock * CreateFailBB(Function *F, const Triple &Trip)
CreateFailBB - Create a basic block to jump to when the stack protector check fails.
static cl::opt< bool > DisableCheckNoReturn("disable-check-noreturn-call", cl::init(false), cl::Hidden)
static bool CreatePrologue(Function *F, Module *M, Instruction *CheckLoc, const TargetLoweringBase *TLI, AllocaInst *&AI)
Insert code into the entry block that stores the stack guard variable onto the stack:
Insert stack protectors
static bool ContainsProtectableArray(Type *Ty, Module *M, unsigned SSPBufferSize, bool &IsLarge, bool Strong, bool InStruct)
static cl::opt< bool > EnableSelectionDAGSP("enable-selectiondag-sp", cl::init(true), cl::Hidden)
static const CallInst * findStackProtectorIntrinsic(Function &F)
Search for the first call to the llvm.stackprotector intrinsic and return it if present.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
Class for arbitrary precision integers.
Definition: APInt.h:78
an instruction to allocate memory on the stack
Definition: Instructions.h:63
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:429
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:212
void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
Definition: BasicBlock.cpp:287
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:239
static BranchProbability getBranchProbStackProtector(bool IsLikely)
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1294
This class represents a function call, abstracting a target machine's calling convention.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:156
bool empty() const
Definition: DenseMap.h:98
iterator end()
Definition: DenseMap.h:84
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:211
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:279
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:317
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
Definition: Function.cpp:778
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition: Function.h:905
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Definition: Function.cpp:1048
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:933
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:656
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2697
const Instruction * getPrevNonDebugInstruction(bool SkipPseudoOp=false) const
Return a pointer to the previous non-debug instruction in the same basic block as 'this',...
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
An instruction for reading from memory.
Definition: Instructions.h:176
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
Definition: MDBuilder.cpp:37
Metadata node.
Definition: Metadata.h:1069
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1543
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
@ SSPLK_SmallArray
Array or nested array < SSP-buffer-size.
@ SSPLK_LargeArray
Array or nested array >= SSP-buffer-size.
@ SSPLK_AddrOf
The address of this allocation is exposed and triggered protection.
void setObjectSSPLayout(int ObjectIdx, SSPLayoutKind Kind)
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
static std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
The optimization diagnostic interface.
void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for applied optimization remarks.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:686
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
void preserve()
Mark an analysis as preserved.
Definition: Analysis.h:131
static bool requiresStackProtector(Function *F, SSPLayoutMap *Layout=nullptr)
Check whether or not F needs a stack protector based upon the stack protector level.
Result run(Function &F, FunctionAnalysisManager &FAM)
void copyToMachineFrameInfo(MachineFrameInfo &MFI) const
bool shouldEmitSDCheck(const BasicBlock &BB) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static bool requiresStackProtector(Function *F, SSPLayoutMap *Layout=nullptr)
Check whether or not F needs a stack protector based upon the stack protector level.
bool runOnFunction(Function &Fn) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
Class to represent struct types.
Definition: DerivedTypes.h:218
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
virtual Value * getIRStackGuard(IRBuilderBase &IRB) const
If the target has a standard location for the stack protector guard, returns the address of that loca...
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
Target-Independent Code Generator Pass Configuration Options.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool isOSOpenBSD() const
Definition: Triple.h:590
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
Definition: Triple.h:568
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:345
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static Type * getVoidTy(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:74
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:377
iterator_range< user_iterator > users()
Definition: Value.h:421
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1075
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:168
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition: TypeSize.h:225
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition: TypeSize.h:239
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:657
FunctionPass * createStackProtectorPass()
createStackProtectorPass - This pass adds stack protectors to functions.
void initializeStackProtectorPass(PassRegistry &)
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:28