LLVM 18.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
67char StackProtector::ID = 0;
68
71}
72
74 "Insert stack protectors", false, true)
78 "Insert stack protectors", false, true)
79
81
85}
86
88 F = &Fn;
89 M = F->getParent();
90 if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
91 DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
92 TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
93 Trip = TM->getTargetTriple();
94 TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();
95 HasPrologue = false;
96 HasIRCheck = false;
97
98 SSPBufferSize = Fn.getFnAttributeAsParsedInteger(
99 "stack-protector-buffer-size", DefaultSSPBufferSize);
100 if (!requiresStackProtector(F, &Layout))
101 return false;
102
103 // TODO(etienneb): Functions with funclets are not correctly supported now.
104 // Do nothing if this is funclet-based personality.
105 if (Fn.hasPersonalityFn()) {
107 if (isFuncletEHPersonality(Personality))
108 return false;
109 }
110
111 ++NumFunProtected;
112 bool Changed = InsertStackProtectors();
113#ifdef EXPENSIVE_CHECKS
114 assert((!DTU ||
115 DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full)) &&
116 "Failed to maintain validity of domtree!");
117#endif
118 DTU.reset();
119 return Changed;
120}
121
122/// \param [out] IsLarge is set to true if a protectable array is found and
123/// it is "large" ( >= ssp-buffer-size). In the case of a structure with
124/// multiple arrays, this gets set if any of them is large.
125static bool ContainsProtectableArray(Type *Ty, Module *M, unsigned SSPBufferSize,
126 bool &IsLarge, bool Strong,
127 bool InStruct) {
128 if (!Ty)
129 return false;
130 if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
131 if (!AT->getElementType()->isIntegerTy(8)) {
132 // If we're on a non-Darwin platform or we're inside of a structure, don't
133 // add stack protectors unless the array is a character array.
134 // However, in strong mode any array, regardless of type and size,
135 // triggers a protector.
136 if (!Strong && (InStruct || !Triple(M->getTargetTriple()).isOSDarwin()))
137 return false;
138 }
139
140 // If an array has more than SSPBufferSize bytes of allocated space, then we
141 // emit stack protectors.
142 if (SSPBufferSize <= M->getDataLayout().getTypeAllocSize(AT)) {
143 IsLarge = true;
144 return true;
145 }
146
147 if (Strong)
148 // Require a protector for all arrays in strong mode
149 return true;
150 }
151
152 const StructType *ST = dyn_cast<StructType>(Ty);
153 if (!ST)
154 return false;
155
156 bool NeedsProtector = false;
157 for (Type *ET : ST->elements())
158 if (ContainsProtectableArray(ET, M, SSPBufferSize, IsLarge, Strong, true)) {
159 // If the element is a protectable array and is large (>= SSPBufferSize)
160 // then we are done. If the protectable array is not large, then
161 // keep looking in case a subsequent element is a large array.
162 if (IsLarge)
163 return true;
164 NeedsProtector = true;
165 }
166
167 return NeedsProtector;
168}
169
170/// Check whether a stack allocation has its address taken.
171static bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize,
172 Module *M,
174 const DataLayout &DL = M->getDataLayout();
175 for (const User *U : AI->users()) {
176 const auto *I = cast<Instruction>(U);
177 // If this instruction accesses memory make sure it doesn't access beyond
178 // the bounds of the allocated object.
179 std::optional<MemoryLocation> MemLoc = MemoryLocation::getOrNone(I);
180 if (MemLoc && MemLoc->Size.hasValue() &&
181 !TypeSize::isKnownGE(AllocSize, MemLoc->Size.getValue()))
182 return true;
183 switch (I->getOpcode()) {
184 case Instruction::Store:
185 if (AI == cast<StoreInst>(I)->getValueOperand())
186 return true;
187 break;
188 case Instruction::AtomicCmpXchg:
189 // cmpxchg conceptually includes both a load and store from the same
190 // location. So, like store, the value being stored is what matters.
191 if (AI == cast<AtomicCmpXchgInst>(I)->getNewValOperand())
192 return true;
193 break;
194 case Instruction::PtrToInt:
195 if (AI == cast<PtrToIntInst>(I)->getOperand(0))
196 return true;
197 break;
198 case Instruction::Call: {
199 // Ignore intrinsics that do not become real instructions.
200 // TODO: Narrow this to intrinsics that have store-like effects.
201 const auto *CI = cast<CallInst>(I);
202 if (!CI->isDebugOrPseudoInst() && !CI->isLifetimeStartOrEnd())
203 return true;
204 break;
205 }
206 case Instruction::Invoke:
207 return true;
208 case Instruction::GetElementPtr: {
209 // If the GEP offset is out-of-bounds, or is non-constant and so has to be
210 // assumed to be potentially out-of-bounds, then any memory access that
211 // would use it could also be out-of-bounds meaning stack protection is
212 // required.
213 const GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
214 unsigned IndexSize = DL.getIndexTypeSizeInBits(I->getType());
215 APInt Offset(IndexSize, 0);
216 if (!GEP->accumulateConstantOffset(DL, Offset))
217 return true;
218 TypeSize OffsetSize = TypeSize::getFixed(Offset.getLimitedValue());
219 if (!TypeSize::isKnownGT(AllocSize, OffsetSize))
220 return true;
221 // Adjust AllocSize to be the space remaining after this offset.
222 // We can't subtract a fixed size from a scalable one, so in that case
223 // assume the scalable value is of minimum size.
224 TypeSize NewAllocSize =
225 TypeSize::getFixed(AllocSize.getKnownMinValue()) - OffsetSize;
226 if (HasAddressTaken(I, NewAllocSize, M, VisitedPHIs))
227 return true;
228 break;
229 }
230 case Instruction::BitCast:
231 case Instruction::Select:
232 case Instruction::AddrSpaceCast:
233 if (HasAddressTaken(I, AllocSize, M, VisitedPHIs))
234 return true;
235 break;
236 case Instruction::PHI: {
237 // Keep track of what PHI nodes we have already visited to ensure
238 // they are only visited once.
239 const auto *PN = cast<PHINode>(I);
240 if (VisitedPHIs.insert(PN).second)
241 if (HasAddressTaken(PN, AllocSize, M, VisitedPHIs))
242 return true;
243 break;
244 }
245 case Instruction::Load:
246 case Instruction::AtomicRMW:
247 case Instruction::Ret:
248 // These instructions take an address operand, but have load-like or
249 // other innocuous behavior that should not trigger a stack protector.
250 // atomicrmw conceptually has both load and store semantics, but the
251 // value being stored must be integer; so if a pointer is being stored,
252 // we'll catch it in the PtrToInt case above.
253 break;
254 default:
255 // Conservatively return true for any instruction that takes an address
256 // operand, but is not handled above.
257 return true;
258 }
259 }
260 return false;
261}
262
263/// Search for the first call to the llvm.stackprotector intrinsic and return it
264/// if present.
266 for (const BasicBlock &BB : F)
267 for (const Instruction &I : BB)
268 if (const auto *II = dyn_cast<IntrinsicInst>(&I))
269 if (II->getIntrinsicID() == Intrinsic::stackprotector)
270 return II;
271 return nullptr;
272}
273
274/// Check whether or not this function needs a stack protector based
275/// upon the stack protector level.
276///
277/// We use two heuristics: a standard (ssp) and strong (sspstrong).
278/// The standard heuristic which will add a guard variable to functions that
279/// call alloca with a either a variable size or a size >= SSPBufferSize,
280/// functions with character buffers larger than SSPBufferSize, and functions
281/// with aggregates containing character buffers larger than SSPBufferSize. The
282/// strong heuristic will add a guard variables to functions that call alloca
283/// regardless of size, functions with any buffer regardless of type and size,
284/// functions with aggregates that contain any buffer regardless of type and
285/// size, and functions that contain stack-based variables that have had their
286/// address taken.
288 Module *M = F->getParent();
289 bool Strong = false;
290 bool NeedsProtector = false;
291
292 // The set of PHI nodes visited when determining if a variable's reference has
293 // been taken. This set is maintained to ensure we don't visit the same PHI
294 // node multiple times.
296
297 unsigned SSPBufferSize = F->getFnAttributeAsParsedInteger(
298 "stack-protector-buffer-size", DefaultSSPBufferSize);
299
300 if (F->hasFnAttribute(Attribute::SafeStack))
301 return false;
302
303 // We are constructing the OptimizationRemarkEmitter on the fly rather than
304 // using the analysis pass to avoid building DominatorTree and LoopInfo which
305 // are not available this late in the IR pipeline.
307
308 if (F->hasFnAttribute(Attribute::StackProtectReq)) {
309 if (!Layout)
310 return true;
311 ORE.emit([&]() {
312 return OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F)
313 << "Stack protection applied to function "
314 << ore::NV("Function", F)
315 << " due to a function attribute or command-line switch";
316 });
317 NeedsProtector = true;
318 Strong = true; // Use the same heuristic as strong to determine SSPLayout
319 } else if (F->hasFnAttribute(Attribute::StackProtectStrong))
320 Strong = true;
321 else if (!F->hasFnAttribute(Attribute::StackProtect))
322 return false;
323
324 for (const BasicBlock &BB : *F) {
325 for (const Instruction &I : BB) {
326 if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
327 if (AI->isArrayAllocation()) {
328 auto RemarkBuilder = [&]() {
329 return OptimizationRemark(DEBUG_TYPE, "StackProtectorAllocaOrArray",
330 &I)
331 << "Stack protection applied to function "
332 << ore::NV("Function", F)
333 << " due to a call to alloca or use of a variable length "
334 "array";
335 };
336 if (const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
337 if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
338 // A call to alloca with size >= SSPBufferSize requires
339 // stack protectors.
340 if (!Layout)
341 return true;
342 Layout->insert(
343 std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
344 ORE.emit(RemarkBuilder);
345 NeedsProtector = true;
346 } else if (Strong) {
347 // Require protectors for all alloca calls in strong mode.
348 if (!Layout)
349 return true;
350 Layout->insert(
351 std::make_pair(AI, MachineFrameInfo::SSPLK_SmallArray));
352 ORE.emit(RemarkBuilder);
353 NeedsProtector = true;
354 }
355 } else {
356 // A call to alloca with a variable size requires protectors.
357 if (!Layout)
358 return true;
359 Layout->insert(
360 std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
361 ORE.emit(RemarkBuilder);
362 NeedsProtector = true;
363 }
364 continue;
365 }
366
367 bool IsLarge = false;
368 if (ContainsProtectableArray(AI->getAllocatedType(), M, SSPBufferSize,
369 IsLarge, Strong, false)) {
370 if (!Layout)
371 return true;
372 Layout->insert(std::make_pair(
375 ORE.emit([&]() {
376 return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
377 << "Stack protection applied to function "
378 << ore::NV("Function", F)
379 << " due to a stack allocated buffer or struct containing a "
380 "buffer";
381 });
382 NeedsProtector = true;
383 continue;
384 }
385
386 if (Strong &&
388 AI, M->getDataLayout().getTypeAllocSize(AI->getAllocatedType()),
389 M, VisitedPHIs)) {
390 ++NumAddrTaken;
391 if (!Layout)
392 return true;
393 Layout->insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
394 ORE.emit([&]() {
395 return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
396 &I)
397 << "Stack protection applied to function "
398 << ore::NV("Function", F)
399 << " due to the address of a local variable being taken";
400 });
401 NeedsProtector = true;
402 }
403 // Clear any PHIs that we visited, to make sure we examine all uses of
404 // any subsequent allocas that we look at.
405 VisitedPHIs.clear();
406 }
407 }
408 }
409
410 return NeedsProtector;
411}
412
413/// Create a stack guard loading and populate whether SelectionDAG SSP is
414/// supported.
416 IRBuilder<> &B,
417 bool *SupportsSelectionDAGSP = nullptr) {
418 Value *Guard = TLI->getIRStackGuard(B);
419 StringRef GuardMode = M->getStackProtectorGuard();
420 if ((GuardMode == "tls" || GuardMode.empty()) && Guard)
421 return B.CreateLoad(B.getPtrTy(), Guard, true, "StackGuard");
422
423 // Use SelectionDAG SSP handling, since there isn't an IR guard.
424 //
425 // This is more or less weird, since we optionally output whether we
426 // should perform a SelectionDAG SP here. The reason is that it's strictly
427 // defined as !TLI->getIRStackGuard(B), where getIRStackGuard is also
428 // mutating. There is no way to get this bit without mutating the IR, so
429 // getting this bit has to happen in this right time.
430 //
431 // We could have define a new function TLI::supportsSelectionDAGSP(), but that
432 // will put more burden on the backends' overriding work, especially when it
433 // actually conveys the same information getIRStackGuard() already gives.
434 if (SupportsSelectionDAGSP)
435 *SupportsSelectionDAGSP = true;
436 TLI->insertSSPDeclarations(*M);
437 return B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackguard));
438}
439
440/// Insert code into the entry block that stores the stack guard
441/// variable onto the stack:
442///
443/// entry:
444/// StackGuardSlot = alloca i8*
445/// StackGuard = <stack guard>
446/// call void @llvm.stackprotector(StackGuard, StackGuardSlot)
447///
448/// Returns true if the platform/triple supports the stackprotectorcreate pseudo
449/// node.
450static bool CreatePrologue(Function *F, Module *M, Instruction *CheckLoc,
451 const TargetLoweringBase *TLI, AllocaInst *&AI) {
452 bool SupportsSelectionDAGSP = false;
453 IRBuilder<> B(&F->getEntryBlock().front());
454 PointerType *PtrTy = PointerType::getUnqual(CheckLoc->getContext());
455 AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
456
457 Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);
458 B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
459 {GuardSlot, AI});
460 return SupportsSelectionDAGSP;
461}
462
463/// InsertStackProtectors - Insert code into the prologue and epilogue of the
464/// function.
465///
466/// - The prologue code loads and stores the stack guard onto the stack.
467/// - The epilogue checks the value stored in the prologue against the original
468/// value. It calls __stack_chk_fail if they differ.
469bool StackProtector::InsertStackProtectors() {
470 // If the target wants to XOR the frame pointer into the guard value, it's
471 // impossible to emit the check in IR, so the target *must* support stack
472 // protection in SDAG.
473 bool SupportsSelectionDAGSP =
474 TLI->useStackGuardXorFP() ||
476 AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.
477 BasicBlock *FailBB = nullptr;
478
479 for (BasicBlock &BB : llvm::make_early_inc_range(*F)) {
480 // This is stack protector auto generated check BB, skip it.
481 if (&BB == FailBB)
482 continue;
483 Instruction *CheckLoc = dyn_cast<ReturnInst>(BB.getTerminator());
484 if (!CheckLoc && !DisableCheckNoReturn)
485 for (auto &Inst : BB)
486 if (auto *CB = dyn_cast<CallBase>(&Inst))
487 // Do stack check before noreturn calls that aren't nounwind (e.g:
488 // __cxa_throw).
489 if (CB->doesNotReturn() && !CB->doesNotThrow()) {
490 CheckLoc = CB;
491 break;
492 }
493
494 if (!CheckLoc)
495 continue;
496
497 // Generate prologue instrumentation if not already generated.
498 if (!HasPrologue) {
499 HasPrologue = true;
500 SupportsSelectionDAGSP &= CreatePrologue(F, M, CheckLoc, TLI, AI);
501 }
502
503 // SelectionDAG based code generation. Nothing else needs to be done here.
504 // The epilogue instrumentation is postponed to SelectionDAG.
505 if (SupportsSelectionDAGSP)
506 break;
507
508 // Find the stack guard slot if the prologue was not created by this pass
509 // itself via a previous call to CreatePrologue().
510 if (!AI) {
511 const CallInst *SPCall = findStackProtectorIntrinsic(*F);
512 assert(SPCall && "Call to llvm.stackprotector is missing");
513 AI = cast<AllocaInst>(SPCall->getArgOperand(1));
514 }
515
516 // Set HasIRCheck to true, so that SelectionDAG will not generate its own
517 // version. SelectionDAG called 'shouldEmitSDCheck' to check whether
518 // instrumentation has already been generated.
519 HasIRCheck = true;
520
521 // If we're instrumenting a block with a tail call, the check has to be
522 // inserted before the call rather than between it and the return. The
523 // verifier guarantees that a tail call is either directly before the
524 // return or with a single correct bitcast of the return value in between so
525 // we don't need to worry about many situations here.
526 Instruction *Prev = CheckLoc->getPrevNonDebugInstruction();
527 if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
528 CheckLoc = Prev;
529 else if (Prev) {
530 Prev = Prev->getPrevNonDebugInstruction();
531 if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
532 CheckLoc = Prev;
533 }
534
535 // Generate epilogue instrumentation. The epilogue intrumentation can be
536 // function-based or inlined depending on which mechanism the target is
537 // providing.
538 if (Function *GuardCheck = TLI->getSSPStackGuardCheck(*M)) {
539 // Generate the function-based epilogue instrumentation.
540 // The target provides a guard check function, generate a call to it.
541 IRBuilder<> B(CheckLoc);
542 LoadInst *Guard = B.CreateLoad(B.getPtrTy(), AI, true, "Guard");
543 CallInst *Call = B.CreateCall(GuardCheck, {Guard});
544 Call->setAttributes(GuardCheck->getAttributes());
545 Call->setCallingConv(GuardCheck->getCallingConv());
546 } else {
547 // Generate the epilogue with inline instrumentation.
548 // If we do not support SelectionDAG based calls, generate IR level
549 // calls.
550 //
551 // For each block with a return instruction, convert this:
552 //
553 // return:
554 // ...
555 // ret ...
556 //
557 // into this:
558 //
559 // return:
560 // ...
561 // %1 = <stack guard>
562 // %2 = load StackGuardSlot
563 // %3 = icmp ne i1 %1, %2
564 // br i1 %3, label %CallStackCheckFailBlk, label %SP_return
565 //
566 // SP_return:
567 // ret ...
568 //
569 // CallStackCheckFailBlk:
570 // call void @__stack_chk_fail()
571 // unreachable
572
573 // Create the FailBB. We duplicate the BB every time since the MI tail
574 // merge pass will merge together all of the various BB into one including
575 // fail BB generated by the stack protector pseudo instruction.
576 if (!FailBB)
577 FailBB = CreateFailBB();
578
579 IRBuilder<> B(CheckLoc);
580 Value *Guard = getStackGuard(TLI, M, B);
581 LoadInst *LI2 = B.CreateLoad(B.getPtrTy(), AI, true);
582 auto *Cmp = cast<ICmpInst>(B.CreateICmpNE(Guard, LI2));
583 auto SuccessProb =
585 auto FailureProb =
587 MDNode *Weights = MDBuilder(F->getContext())
588 .createBranchWeights(FailureProb.getNumerator(),
589 SuccessProb.getNumerator());
590
591 SplitBlockAndInsertIfThen(Cmp, CheckLoc,
592 /*Unreachable=*/false, Weights,
593 DTU ? &*DTU : nullptr,
594 /*LI=*/nullptr, /*ThenBlock=*/FailBB);
595
596 auto *BI = cast<BranchInst>(Cmp->getParent()->getTerminator());
597 BasicBlock *NewBB = BI->getSuccessor(1);
598 NewBB->setName("SP_return");
599 NewBB->moveAfter(&BB);
600
601 Cmp->setPredicate(Cmp->getInversePredicate());
602 BI->swapSuccessors();
603 }
604 }
605
606 // Return if we didn't modify any basic blocks. i.e., there are no return
607 // statements in the function.
608 return HasPrologue;
609}
610
611/// CreateFailBB - Create a basic block to jump to when the stack protector
612/// check fails.
613BasicBlock *StackProtector::CreateFailBB() {
615 BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
616 IRBuilder<> B(FailBB);
617 if (F->getSubprogram())
618 B.SetCurrentDebugLocation(
619 DILocation::get(Context, 0, 0, F->getSubprogram()));
620 FunctionCallee StackChkFail;
622 if (Trip.isOSOpenBSD()) {
623 StackChkFail = M->getOrInsertFunction("__stack_smash_handler",
624 Type::getVoidTy(Context),
625 PointerType::getUnqual(Context));
626 Args.push_back(B.CreateGlobalStringPtr(F->getName(), "SSH"));
627 } else {
628 StackChkFail =
629 M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
630 }
631 cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
632 B.CreateCall(StackChkFail, Args);
633 B.CreateUnreachable();
634 return FailBB;
635}
636
638 return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator());
639}
640
642 if (Layout.empty())
643 return;
644
645 for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) {
646 if (MFI.isDeadObjectIndex(I))
647 continue;
648
649 const AllocaInst *AI = MFI.getObjectAllocation(I);
650 if (!AI)
651 continue;
652
653 SSPLayoutMap::const_iterator LI = Layout.find(AI);
654 if (LI == Layout.end())
655 continue;
656
657 MFI.setObjectSSPLayout(I, LI->second);
658 }
659}
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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define DEBUG_TYPE
Hexagon Common GEP
#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.
Module.h This file contains the declarations for the Module class.
LLVMContext & Context
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:59
#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 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:167
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:76
an instruction to allocate memory on the stack
Definition: Instructions.h:58
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:60
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
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:323
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:228
static BranchProbability getBranchProbStackProtector(bool IsLikely)
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1394
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:110
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
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:220
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:312
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:168
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
Definition: Function.cpp:700
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1781
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition: Function.h:846
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Definition: Function.cpp:1867
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:341
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:948
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2639
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:177
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
Definition: MDBuilder.cpp:37
Metadata node.
Definition: Metadata.h:1037
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1504
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
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:145
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:662
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:366
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:451
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool shouldEmitSDCheck(const BasicBlock &BB) const
void copyToMachineFrameInfo(MachineFrameInfo &MFI) const
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:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
Class to represent struct types.
Definition: DerivedTypes.h:216
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
virtual bool useStackGuardXorFP() const
If this function returns true, stack protection checks should XOR the frame pointer (or whichever poi...
virtual Function * getSSPStackGuardCheck(const Module &M) const
If the target has a standard stack protection check function that performs validation and error handl...
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:78
const Triple & getTargetTriple() const
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
TargetOptions Options
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
Target-Independent Code Generator Pass Configuration Options.
virtual const TargetLowering * getTargetLowering() const
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool isOSOpenBSD() const
Definition: Triple.h:539
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or DriverKit).
Definition: Triple.h:517
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:333
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:1074
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:169
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition: TypeSize.h:211
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition: TypeSize.h:225
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1444
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
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:665
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 ...