1 | //===- SafeStack.cpp - Safe Stack 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 splits the stack into the safe stack (kept as-is for LLVM backend) |
10 | // and the unsafe stack (explicitly allocated and managed through the runtime |
11 | // support library). |
12 | // |
13 | // http://clang.llvm.org/docs/SafeStack.html |
14 | // |
15 | //===----------------------------------------------------------------------===// |
16 | |
17 | #include "llvm/CodeGen/SafeStack.h" |
18 | #include "SafeStackLayout.h" |
19 | #include "llvm/ADT/APInt.h" |
20 | #include "llvm/ADT/ArrayRef.h" |
21 | #include "llvm/ADT/SmallPtrSet.h" |
22 | #include "llvm/ADT/SmallVector.h" |
23 | #include "llvm/ADT/Statistic.h" |
24 | #include "llvm/Analysis/AssumptionCache.h" |
25 | #include "llvm/Analysis/BranchProbabilityInfo.h" |
26 | #include "llvm/Analysis/DomTreeUpdater.h" |
27 | #include "llvm/Analysis/InlineCost.h" |
28 | #include "llvm/Analysis/LoopInfo.h" |
29 | #include "llvm/Analysis/ScalarEvolution.h" |
30 | #include "llvm/Analysis/ScalarEvolutionExpressions.h" |
31 | #include "llvm/Analysis/StackLifetime.h" |
32 | #include "llvm/Analysis/TargetLibraryInfo.h" |
33 | #include "llvm/CodeGen/TargetLowering.h" |
34 | #include "llvm/CodeGen/TargetPassConfig.h" |
35 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
36 | #include "llvm/IR/Argument.h" |
37 | #include "llvm/IR/Attributes.h" |
38 | #include "llvm/IR/ConstantRange.h" |
39 | #include "llvm/IR/Constants.h" |
40 | #include "llvm/IR/DIBuilder.h" |
41 | #include "llvm/IR/DataLayout.h" |
42 | #include "llvm/IR/DerivedTypes.h" |
43 | #include "llvm/IR/Dominators.h" |
44 | #include "llvm/IR/Function.h" |
45 | #include "llvm/IR/IRBuilder.h" |
46 | #include "llvm/IR/InstIterator.h" |
47 | #include "llvm/IR/Instruction.h" |
48 | #include "llvm/IR/Instructions.h" |
49 | #include "llvm/IR/IntrinsicInst.h" |
50 | #include "llvm/IR/Intrinsics.h" |
51 | #include "llvm/IR/MDBuilder.h" |
52 | #include "llvm/IR/Metadata.h" |
53 | #include "llvm/IR/Module.h" |
54 | #include "llvm/IR/Type.h" |
55 | #include "llvm/IR/Use.h" |
56 | #include "llvm/IR/Value.h" |
57 | #include "llvm/InitializePasses.h" |
58 | #include "llvm/Pass.h" |
59 | #include "llvm/Support/Casting.h" |
60 | #include "llvm/Support/Debug.h" |
61 | #include "llvm/Support/ErrorHandling.h" |
62 | #include "llvm/Support/MathExtras.h" |
63 | #include "llvm/Support/raw_ostream.h" |
64 | #include "llvm/Target/TargetMachine.h" |
65 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" |
66 | #include "llvm/Transforms/Utils/Cloning.h" |
67 | #include "llvm/Transforms/Utils/Local.h" |
68 | #include <algorithm> |
69 | #include <cassert> |
70 | #include <cstdint> |
71 | #include <optional> |
72 | #include <string> |
73 | #include <utility> |
74 | |
75 | using namespace llvm; |
76 | using namespace llvm::safestack; |
77 | |
78 | #define DEBUG_TYPE "safe-stack" |
79 | |
80 | namespace llvm { |
81 | |
82 | STATISTIC(NumFunctions, "Total number of functions" ); |
83 | STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack" ); |
84 | STATISTIC(NumUnsafeStackRestorePointsFunctions, |
85 | "Number of functions that use setjmp or exceptions" ); |
86 | |
87 | STATISTIC(NumAllocas, "Total number of allocas" ); |
88 | STATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas" ); |
89 | STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas" ); |
90 | STATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments" ); |
91 | STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads" ); |
92 | |
93 | } // namespace llvm |
94 | |
95 | /// Use __safestack_pointer_address even if the platform has a faster way of |
96 | /// access safe stack pointer. |
97 | static cl::opt<bool> |
98 | SafeStackUsePointerAddress("safestack-use-pointer-address" , |
99 | cl::init(Val: false), cl::Hidden); |
100 | |
101 | static cl::opt<bool> ClColoring("safe-stack-coloring" , |
102 | cl::desc("enable safe stack coloring" ), |
103 | cl::Hidden, cl::init(Val: true)); |
104 | |
105 | namespace { |
106 | |
107 | /// The SafeStack pass splits the stack of each function into the safe |
108 | /// stack, which is only accessed through memory safe dereferences (as |
109 | /// determined statically), and the unsafe stack, which contains all |
110 | /// local variables that are accessed in ways that we can't prove to |
111 | /// be safe. |
112 | class SafeStack { |
113 | Function &F; |
114 | const TargetLoweringBase &TL; |
115 | const DataLayout &DL; |
116 | DomTreeUpdater *DTU; |
117 | ScalarEvolution &SE; |
118 | |
119 | Type *StackPtrTy; |
120 | Type *IntPtrTy; |
121 | Type *Int32Ty; |
122 | |
123 | Value *UnsafeStackPtr = nullptr; |
124 | |
125 | /// Unsafe stack alignment. Each stack frame must ensure that the stack is |
126 | /// aligned to this value. We need to re-align the unsafe stack if the |
127 | /// alignment of any object on the stack exceeds this value. |
128 | /// |
129 | /// 16 seems like a reasonable upper bound on the alignment of objects that we |
130 | /// might expect to appear on the stack on most common targets. |
131 | static constexpr Align StackAlignment = Align::Constant<16>(); |
132 | |
133 | /// Return the value of the stack canary. |
134 | Value *getStackGuard(IRBuilder<> &IRB, Function &F); |
135 | |
136 | /// Load stack guard from the frame and check if it has changed. |
137 | void checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI, |
138 | AllocaInst *StackGuardSlot, Value *StackGuard); |
139 | |
140 | /// Find all static allocas, dynamic allocas, return instructions and |
141 | /// stack restore points (exception unwind blocks and setjmp calls) in the |
142 | /// given function and append them to the respective vectors. |
143 | void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas, |
144 | SmallVectorImpl<AllocaInst *> &DynamicAllocas, |
145 | SmallVectorImpl<Argument *> &ByValArguments, |
146 | SmallVectorImpl<Instruction *> &Returns, |
147 | SmallVectorImpl<Instruction *> &StackRestorePoints); |
148 | |
149 | /// Calculate the allocation size of a given alloca. Returns 0 if the |
150 | /// size can not be statically determined. |
151 | uint64_t getStaticAllocaAllocationSize(const AllocaInst* AI); |
152 | |
153 | /// Allocate space for all static allocas in \p StaticAllocas, |
154 | /// replace allocas with pointers into the unsafe stack. |
155 | /// |
156 | /// \returns A pointer to the top of the unsafe stack after all unsafe static |
157 | /// allocas are allocated. |
158 | Value *moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F, |
159 | ArrayRef<AllocaInst *> StaticAllocas, |
160 | ArrayRef<Argument *> ByValArguments, |
161 | Instruction *BasePointer, |
162 | AllocaInst *StackGuardSlot); |
163 | |
164 | /// Generate code to restore the stack after all stack restore points |
165 | /// in \p StackRestorePoints. |
166 | /// |
167 | /// \returns A local variable in which to maintain the dynamic top of the |
168 | /// unsafe stack if needed. |
169 | AllocaInst * |
170 | createStackRestorePoints(IRBuilder<> &IRB, Function &F, |
171 | ArrayRef<Instruction *> StackRestorePoints, |
172 | Value *StaticTop, bool NeedDynamicTop); |
173 | |
174 | /// Replace all allocas in \p DynamicAllocas with code to allocate |
175 | /// space dynamically on the unsafe stack and store the dynamic unsafe stack |
176 | /// top to \p DynamicTop if non-null. |
177 | void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr, |
178 | AllocaInst *DynamicTop, |
179 | ArrayRef<AllocaInst *> DynamicAllocas); |
180 | |
181 | bool IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize); |
182 | |
183 | bool IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U, |
184 | const Value *AllocaPtr, uint64_t AllocaSize); |
185 | bool IsAccessSafe(Value *Addr, uint64_t Size, const Value *AllocaPtr, |
186 | uint64_t AllocaSize); |
187 | |
188 | bool ShouldInlinePointerAddress(CallInst &CI); |
189 | void TryInlinePointerAddress(); |
190 | |
191 | public: |
192 | SafeStack(Function &F, const TargetLoweringBase &TL, const DataLayout &DL, |
193 | DomTreeUpdater *DTU, ScalarEvolution &SE) |
194 | : F(F), TL(TL), DL(DL), DTU(DTU), SE(SE), |
195 | StackPtrTy(PointerType::getUnqual(C&: F.getContext())), |
196 | IntPtrTy(DL.getIntPtrType(C&: F.getContext())), |
197 | Int32Ty(Type::getInt32Ty(C&: F.getContext())) {} |
198 | |
199 | // Run the transformation on the associated function. |
200 | // Returns whether the function was changed. |
201 | bool run(); |
202 | }; |
203 | |
204 | constexpr Align SafeStack::StackAlignment; |
205 | |
206 | uint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) { |
207 | uint64_t Size = DL.getTypeAllocSize(Ty: AI->getAllocatedType()); |
208 | if (AI->isArrayAllocation()) { |
209 | auto C = dyn_cast<ConstantInt>(Val: AI->getArraySize()); |
210 | if (!C) |
211 | return 0; |
212 | Size *= C->getZExtValue(); |
213 | } |
214 | return Size; |
215 | } |
216 | |
217 | bool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize, |
218 | const Value *AllocaPtr, uint64_t AllocaSize) { |
219 | const SCEV *AddrExpr = SE.getSCEV(V: Addr); |
220 | const auto *Base = dyn_cast<SCEVUnknown>(Val: SE.getPointerBase(V: AddrExpr)); |
221 | if (!Base || Base->getValue() != AllocaPtr) { |
222 | LLVM_DEBUG( |
223 | dbgs() << "[SafeStack] " |
224 | << (isa<AllocaInst>(AllocaPtr) ? "Alloca " : "ByValArgument " ) |
225 | << *AllocaPtr << "\n" |
226 | << "SCEV " << *AddrExpr << " not directly based on alloca\n" ); |
227 | return false; |
228 | } |
229 | |
230 | const SCEV *Expr = SE.removePointerBase(S: AddrExpr); |
231 | uint64_t BitWidth = SE.getTypeSizeInBits(Ty: Expr->getType()); |
232 | ConstantRange AccessStartRange = SE.getUnsignedRange(S: Expr); |
233 | ConstantRange SizeRange = |
234 | ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AccessSize)); |
235 | ConstantRange AccessRange = AccessStartRange.add(Other: SizeRange); |
236 | ConstantRange AllocaRange = |
237 | ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AllocaSize)); |
238 | bool Safe = AllocaRange.contains(CR: AccessRange); |
239 | |
240 | LLVM_DEBUG( |
241 | dbgs() << "[SafeStack] " |
242 | << (isa<AllocaInst>(AllocaPtr) ? "Alloca " : "ByValArgument " ) |
243 | << *AllocaPtr << "\n" |
244 | << " Access " << *Addr << "\n" |
245 | << " SCEV " << *Expr |
246 | << " U: " << SE.getUnsignedRange(Expr) |
247 | << ", S: " << SE.getSignedRange(Expr) << "\n" |
248 | << " Range " << AccessRange << "\n" |
249 | << " AllocaRange " << AllocaRange << "\n" |
250 | << " " << (Safe ? "safe" : "unsafe" ) << "\n" ); |
251 | |
252 | return Safe; |
253 | } |
254 | |
255 | bool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U, |
256 | const Value *AllocaPtr, |
257 | uint64_t AllocaSize) { |
258 | if (auto MTI = dyn_cast<MemTransferInst>(Val: MI)) { |
259 | if (MTI->getRawSource() != U && MTI->getRawDest() != U) |
260 | return true; |
261 | } else { |
262 | if (MI->getRawDest() != U) |
263 | return true; |
264 | } |
265 | |
266 | const auto *Len = dyn_cast<ConstantInt>(Val: MI->getLength()); |
267 | // Non-constant size => unsafe. FIXME: try SCEV getRange. |
268 | if (!Len) return false; |
269 | return IsAccessSafe(Addr: U, AccessSize: Len->getZExtValue(), AllocaPtr, AllocaSize); |
270 | } |
271 | |
272 | /// Check whether a given allocation must be put on the safe |
273 | /// stack or not. The function analyzes all uses of AI and checks whether it is |
274 | /// only accessed in a memory safe way (as decided statically). |
275 | bool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) { |
276 | // Go through all uses of this alloca and check whether all accesses to the |
277 | // allocated object are statically known to be memory safe and, hence, the |
278 | // object can be placed on the safe stack. |
279 | SmallPtrSet<const Value *, 16> Visited; |
280 | SmallVector<const Value *, 8> WorkList; |
281 | WorkList.push_back(Elt: AllocaPtr); |
282 | |
283 | // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc. |
284 | while (!WorkList.empty()) { |
285 | const Value *V = WorkList.pop_back_val(); |
286 | for (const Use &UI : V->uses()) { |
287 | auto I = cast<const Instruction>(Val: UI.getUser()); |
288 | assert(V == UI.get()); |
289 | |
290 | switch (I->getOpcode()) { |
291 | case Instruction::Load: |
292 | if (!IsAccessSafe(Addr: UI, AccessSize: DL.getTypeStoreSize(Ty: I->getType()), AllocaPtr, |
293 | AllocaSize)) |
294 | return false; |
295 | break; |
296 | |
297 | case Instruction::VAArg: |
298 | // "va-arg" from a pointer is safe. |
299 | break; |
300 | case Instruction::Store: |
301 | if (V == I->getOperand(i: 0)) { |
302 | // Stored the pointer - conservatively assume it may be unsafe. |
303 | LLVM_DEBUG(dbgs() |
304 | << "[SafeStack] Unsafe alloca: " << *AllocaPtr |
305 | << "\n store of address: " << *I << "\n" ); |
306 | return false; |
307 | } |
308 | |
309 | if (!IsAccessSafe(Addr: UI, AccessSize: DL.getTypeStoreSize(Ty: I->getOperand(i: 0)->getType()), |
310 | AllocaPtr, AllocaSize)) |
311 | return false; |
312 | break; |
313 | |
314 | case Instruction::Ret: |
315 | // Information leak. |
316 | return false; |
317 | |
318 | case Instruction::Call: |
319 | case Instruction::Invoke: { |
320 | const CallBase &CS = *cast<CallBase>(Val: I); |
321 | |
322 | if (I->isLifetimeStartOrEnd()) |
323 | continue; |
324 | |
325 | if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(Val: I)) { |
326 | if (!IsMemIntrinsicSafe(MI, U: UI, AllocaPtr, AllocaSize)) { |
327 | LLVM_DEBUG(dbgs() |
328 | << "[SafeStack] Unsafe alloca: " << *AllocaPtr |
329 | << "\n unsafe memintrinsic: " << *I << "\n" ); |
330 | return false; |
331 | } |
332 | continue; |
333 | } |
334 | |
335 | // LLVM 'nocapture' attribute is only set for arguments whose address |
336 | // is not stored, passed around, or used in any other non-trivial way. |
337 | // We assume that passing a pointer to an object as a 'nocapture |
338 | // readnone' argument is safe. |
339 | // FIXME: a more precise solution would require an interprocedural |
340 | // analysis here, which would look at all uses of an argument inside |
341 | // the function being called. |
342 | auto B = CS.arg_begin(), E = CS.arg_end(); |
343 | for (const auto *A = B; A != E; ++A) |
344 | if (A->get() == V) |
345 | if (!(CS.doesNotCapture(OpNo: A - B) && (CS.doesNotAccessMemory(OpNo: A - B) || |
346 | CS.doesNotAccessMemory()))) { |
347 | LLVM_DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr |
348 | << "\n unsafe call: " << *I << "\n" ); |
349 | return false; |
350 | } |
351 | continue; |
352 | } |
353 | |
354 | default: |
355 | if (Visited.insert(Ptr: I).second) |
356 | WorkList.push_back(Elt: cast<const Instruction>(Val: I)); |
357 | } |
358 | } |
359 | } |
360 | |
361 | // All uses of the alloca are safe, we can place it on the safe stack. |
362 | return true; |
363 | } |
364 | |
365 | Value *SafeStack::getStackGuard(IRBuilder<> &IRB, Function &F) { |
366 | Value *StackGuardVar = TL.getIRStackGuard(IRB); |
367 | Module *M = F.getParent(); |
368 | |
369 | if (!StackGuardVar) { |
370 | TL.insertSSPDeclarations(M&: *M); |
371 | return IRB.CreateCall(Callee: Intrinsic::getDeclaration(M, id: Intrinsic::stackguard)); |
372 | } |
373 | |
374 | return IRB.CreateLoad(Ty: StackPtrTy, Ptr: StackGuardVar, Name: "StackGuard" ); |
375 | } |
376 | |
377 | void SafeStack::findInsts(Function &F, |
378 | SmallVectorImpl<AllocaInst *> &StaticAllocas, |
379 | SmallVectorImpl<AllocaInst *> &DynamicAllocas, |
380 | SmallVectorImpl<Argument *> &ByValArguments, |
381 | SmallVectorImpl<Instruction *> &Returns, |
382 | SmallVectorImpl<Instruction *> &StackRestorePoints) { |
383 | for (Instruction &I : instructions(F: &F)) { |
384 | if (auto AI = dyn_cast<AllocaInst>(Val: &I)) { |
385 | ++NumAllocas; |
386 | |
387 | uint64_t Size = getStaticAllocaAllocationSize(AI); |
388 | if (IsSafeStackAlloca(AllocaPtr: AI, AllocaSize: Size)) |
389 | continue; |
390 | |
391 | if (AI->isStaticAlloca()) { |
392 | ++NumUnsafeStaticAllocas; |
393 | StaticAllocas.push_back(Elt: AI); |
394 | } else { |
395 | ++NumUnsafeDynamicAllocas; |
396 | DynamicAllocas.push_back(Elt: AI); |
397 | } |
398 | } else if (auto RI = dyn_cast<ReturnInst>(Val: &I)) { |
399 | if (CallInst *CI = I.getParent()->getTerminatingMustTailCall()) |
400 | Returns.push_back(Elt: CI); |
401 | else |
402 | Returns.push_back(Elt: RI); |
403 | } else if (auto CI = dyn_cast<CallInst>(Val: &I)) { |
404 | // setjmps require stack restore. |
405 | if (CI->getCalledFunction() && CI->canReturnTwice()) |
406 | StackRestorePoints.push_back(Elt: CI); |
407 | } else if (auto LP = dyn_cast<LandingPadInst>(Val: &I)) { |
408 | // Exception landing pads require stack restore. |
409 | StackRestorePoints.push_back(Elt: LP); |
410 | } else if (auto II = dyn_cast<IntrinsicInst>(Val: &I)) { |
411 | if (II->getIntrinsicID() == Intrinsic::gcroot) |
412 | report_fatal_error( |
413 | reason: "gcroot intrinsic not compatible with safestack attribute" ); |
414 | } |
415 | } |
416 | for (Argument &Arg : F.args()) { |
417 | if (!Arg.hasByValAttr()) |
418 | continue; |
419 | uint64_t Size = DL.getTypeStoreSize(Ty: Arg.getParamByValType()); |
420 | if (IsSafeStackAlloca(AllocaPtr: &Arg, AllocaSize: Size)) |
421 | continue; |
422 | |
423 | ++NumUnsafeByValArguments; |
424 | ByValArguments.push_back(Elt: &Arg); |
425 | } |
426 | } |
427 | |
428 | AllocaInst * |
429 | SafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F, |
430 | ArrayRef<Instruction *> StackRestorePoints, |
431 | Value *StaticTop, bool NeedDynamicTop) { |
432 | assert(StaticTop && "The stack top isn't set." ); |
433 | |
434 | if (StackRestorePoints.empty()) |
435 | return nullptr; |
436 | |
437 | // We need the current value of the shadow stack pointer to restore |
438 | // after longjmp or exception catching. |
439 | |
440 | // FIXME: On some platforms this could be handled by the longjmp/exception |
441 | // runtime itself. |
442 | |
443 | AllocaInst *DynamicTop = nullptr; |
444 | if (NeedDynamicTop) { |
445 | // If we also have dynamic alloca's, the stack pointer value changes |
446 | // throughout the function. For now we store it in an alloca. |
447 | DynamicTop = IRB.CreateAlloca(Ty: StackPtrTy, /*ArraySize=*/nullptr, |
448 | Name: "unsafe_stack_dynamic_ptr" ); |
449 | IRB.CreateStore(Val: StaticTop, Ptr: DynamicTop); |
450 | } |
451 | |
452 | // Restore current stack pointer after longjmp/exception catch. |
453 | for (Instruction *I : StackRestorePoints) { |
454 | ++NumUnsafeStackRestorePoints; |
455 | |
456 | IRB.SetInsertPoint(I->getNextNode()); |
457 | Value *CurrentTop = |
458 | DynamicTop ? IRB.CreateLoad(Ty: StackPtrTy, Ptr: DynamicTop) : StaticTop; |
459 | IRB.CreateStore(Val: CurrentTop, Ptr: UnsafeStackPtr); |
460 | } |
461 | |
462 | return DynamicTop; |
463 | } |
464 | |
465 | void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI, |
466 | AllocaInst *StackGuardSlot, Value *StackGuard) { |
467 | Value *V = IRB.CreateLoad(Ty: StackPtrTy, Ptr: StackGuardSlot); |
468 | Value *Cmp = IRB.CreateICmpNE(LHS: StackGuard, RHS: V); |
469 | |
470 | auto SuccessProb = BranchProbabilityInfo::getBranchProbStackProtector(IsLikely: true); |
471 | auto FailureProb = BranchProbabilityInfo::getBranchProbStackProtector(IsLikely: false); |
472 | MDNode *Weights = MDBuilder(F.getContext()) |
473 | .createBranchWeights(TrueWeight: SuccessProb.getNumerator(), |
474 | FalseWeight: FailureProb.getNumerator()); |
475 | Instruction *CheckTerm = |
476 | SplitBlockAndInsertIfThen(Cond: Cmp, SplitBefore: &RI, /* Unreachable */ true, BranchWeights: Weights, DTU); |
477 | IRBuilder<> IRBFail(CheckTerm); |
478 | // FIXME: respect -fsanitize-trap / -ftrap-function here? |
479 | FunctionCallee StackChkFail = |
480 | F.getParent()->getOrInsertFunction(Name: "__stack_chk_fail" , RetTy: IRB.getVoidTy()); |
481 | IRBFail.CreateCall(Callee: StackChkFail, Args: {}); |
482 | } |
483 | |
484 | /// We explicitly compute and set the unsafe stack layout for all unsafe |
485 | /// static alloca instructions. We save the unsafe "base pointer" in the |
486 | /// prologue into a local variable and restore it in the epilogue. |
487 | Value *SafeStack::moveStaticAllocasToUnsafeStack( |
488 | IRBuilder<> &IRB, Function &F, ArrayRef<AllocaInst *> StaticAllocas, |
489 | ArrayRef<Argument *> ByValArguments, Instruction *BasePointer, |
490 | AllocaInst *StackGuardSlot) { |
491 | if (StaticAllocas.empty() && ByValArguments.empty()) |
492 | return BasePointer; |
493 | |
494 | DIBuilder DIB(*F.getParent()); |
495 | |
496 | StackLifetime SSC(F, StaticAllocas, StackLifetime::LivenessType::May); |
497 | static const StackLifetime::LiveRange NoColoringRange(1, true); |
498 | if (ClColoring) |
499 | SSC.run(); |
500 | |
501 | for (const auto *I : SSC.getMarkers()) { |
502 | auto *Op = dyn_cast<Instruction>(Val: I->getOperand(i_nocapture: 1)); |
503 | const_cast<IntrinsicInst *>(I)->eraseFromParent(); |
504 | // Remove the operand bitcast, too, if it has no more uses left. |
505 | if (Op && Op->use_empty()) |
506 | Op->eraseFromParent(); |
507 | } |
508 | |
509 | // Unsafe stack always grows down. |
510 | StackLayout SSL(StackAlignment); |
511 | if (StackGuardSlot) { |
512 | Type *Ty = StackGuardSlot->getAllocatedType(); |
513 | Align Align = std::max(a: DL.getPrefTypeAlign(Ty), b: StackGuardSlot->getAlign()); |
514 | SSL.addObject(V: StackGuardSlot, Size: getStaticAllocaAllocationSize(AI: StackGuardSlot), |
515 | Alignment: Align, Range: SSC.getFullLiveRange()); |
516 | } |
517 | |
518 | for (Argument *Arg : ByValArguments) { |
519 | Type *Ty = Arg->getParamByValType(); |
520 | uint64_t Size = DL.getTypeStoreSize(Ty); |
521 | if (Size == 0) |
522 | Size = 1; // Don't create zero-sized stack objects. |
523 | |
524 | // Ensure the object is properly aligned. |
525 | Align Align = DL.getPrefTypeAlign(Ty); |
526 | if (auto A = Arg->getParamAlign()) |
527 | Align = std::max(a: Align, b: *A); |
528 | SSL.addObject(V: Arg, Size, Alignment: Align, Range: SSC.getFullLiveRange()); |
529 | } |
530 | |
531 | for (AllocaInst *AI : StaticAllocas) { |
532 | Type *Ty = AI->getAllocatedType(); |
533 | uint64_t Size = getStaticAllocaAllocationSize(AI); |
534 | if (Size == 0) |
535 | Size = 1; // Don't create zero-sized stack objects. |
536 | |
537 | // Ensure the object is properly aligned. |
538 | Align Align = std::max(a: DL.getPrefTypeAlign(Ty), b: AI->getAlign()); |
539 | |
540 | SSL.addObject(V: AI, Size, Alignment: Align, |
541 | Range: ClColoring ? SSC.getLiveRange(AI) : NoColoringRange); |
542 | } |
543 | |
544 | SSL.computeLayout(); |
545 | Align FrameAlignment = SSL.getFrameAlignment(); |
546 | |
547 | // FIXME: tell SSL that we start at a less-then-MaxAlignment aligned location |
548 | // (AlignmentSkew). |
549 | if (FrameAlignment > StackAlignment) { |
550 | // Re-align the base pointer according to the max requested alignment. |
551 | IRB.SetInsertPoint(BasePointer->getNextNode()); |
552 | BasePointer = cast<Instruction>(Val: IRB.CreateIntToPtr( |
553 | V: IRB.CreateAnd( |
554 | LHS: IRB.CreatePtrToInt(V: BasePointer, DestTy: IntPtrTy), |
555 | RHS: ConstantInt::get(Ty: IntPtrTy, V: ~(FrameAlignment.value() - 1))), |
556 | DestTy: StackPtrTy)); |
557 | } |
558 | |
559 | IRB.SetInsertPoint(BasePointer->getNextNode()); |
560 | |
561 | if (StackGuardSlot) { |
562 | unsigned Offset = SSL.getObjectOffset(V: StackGuardSlot); |
563 | Value *Off = |
564 | IRB.CreatePtrAdd(Ptr: BasePointer, Offset: ConstantInt::get(Ty: Int32Ty, V: -Offset)); |
565 | Value *NewAI = |
566 | IRB.CreateBitCast(V: Off, DestTy: StackGuardSlot->getType(), Name: "StackGuardSlot" ); |
567 | |
568 | // Replace alloc with the new location. |
569 | StackGuardSlot->replaceAllUsesWith(V: NewAI); |
570 | StackGuardSlot->eraseFromParent(); |
571 | } |
572 | |
573 | for (Argument *Arg : ByValArguments) { |
574 | unsigned Offset = SSL.getObjectOffset(V: Arg); |
575 | MaybeAlign Align(SSL.getObjectAlignment(V: Arg)); |
576 | Type *Ty = Arg->getParamByValType(); |
577 | |
578 | uint64_t Size = DL.getTypeStoreSize(Ty); |
579 | if (Size == 0) |
580 | Size = 1; // Don't create zero-sized stack objects. |
581 | |
582 | Value *Off = |
583 | IRB.CreatePtrAdd(Ptr: BasePointer, Offset: ConstantInt::get(Ty: Int32Ty, V: -Offset)); |
584 | Value *NewArg = IRB.CreateBitCast(V: Off, DestTy: Arg->getType(), |
585 | Name: Arg->getName() + ".unsafe-byval" ); |
586 | |
587 | // Replace alloc with the new location. |
588 | replaceDbgDeclare(Address: Arg, NewAddress: BasePointer, Builder&: DIB, DIExprFlags: DIExpression::ApplyOffset, |
589 | Offset: -Offset); |
590 | Arg->replaceAllUsesWith(V: NewArg); |
591 | IRB.SetInsertPoint(cast<Instruction>(Val: NewArg)->getNextNode()); |
592 | IRB.CreateMemCpy(Dst: Off, DstAlign: Align, Src: Arg, SrcAlign: Arg->getParamAlign(), Size); |
593 | } |
594 | |
595 | // Allocate space for every unsafe static AllocaInst on the unsafe stack. |
596 | for (AllocaInst *AI : StaticAllocas) { |
597 | IRB.SetInsertPoint(AI); |
598 | unsigned Offset = SSL.getObjectOffset(V: AI); |
599 | |
600 | replaceDbgDeclare(Address: AI, NewAddress: BasePointer, Builder&: DIB, DIExprFlags: DIExpression::ApplyOffset, Offset: -Offset); |
601 | replaceDbgValueForAlloca(AI, NewAllocaAddress: BasePointer, Builder&: DIB, Offset: -Offset); |
602 | |
603 | // Replace uses of the alloca with the new location. |
604 | // Insert address calculation close to each use to work around PR27844. |
605 | std::string Name = std::string(AI->getName()) + ".unsafe" ; |
606 | while (!AI->use_empty()) { |
607 | Use &U = *AI->use_begin(); |
608 | Instruction *User = cast<Instruction>(Val: U.getUser()); |
609 | |
610 | Instruction *InsertBefore; |
611 | if (auto *PHI = dyn_cast<PHINode>(Val: User)) |
612 | InsertBefore = PHI->getIncomingBlock(U)->getTerminator(); |
613 | else |
614 | InsertBefore = User; |
615 | |
616 | IRBuilder<> IRBUser(InsertBefore); |
617 | Value *Off = |
618 | IRBUser.CreatePtrAdd(Ptr: BasePointer, Offset: ConstantInt::get(Ty: Int32Ty, V: -Offset)); |
619 | Value *Replacement = IRBUser.CreateBitCast(V: Off, DestTy: AI->getType(), Name); |
620 | |
621 | if (auto *PHI = dyn_cast<PHINode>(Val: User)) |
622 | // PHI nodes may have multiple incoming edges from the same BB (why??), |
623 | // all must be updated at once with the same incoming value. |
624 | PHI->setIncomingValueForBlock(BB: PHI->getIncomingBlock(U), V: Replacement); |
625 | else |
626 | U.set(Replacement); |
627 | } |
628 | |
629 | AI->eraseFromParent(); |
630 | } |
631 | |
632 | // Re-align BasePointer so that our callees would see it aligned as |
633 | // expected. |
634 | // FIXME: no need to update BasePointer in leaf functions. |
635 | unsigned FrameSize = alignTo(Size: SSL.getFrameSize(), A: StackAlignment); |
636 | |
637 | MDBuilder MDB(F.getContext()); |
638 | SmallVector<Metadata *, 2> Data; |
639 | Data.push_back(Elt: MDB.createString(Str: "unsafe-stack-size" )); |
640 | Data.push_back(Elt: MDB.createConstant(C: ConstantInt::get(Ty: Int32Ty, V: FrameSize))); |
641 | MDNode *MD = MDTuple::get(Context&: F.getContext(), MDs: Data); |
642 | F.setMetadata(KindID: LLVMContext::MD_annotation, Node: MD); |
643 | |
644 | // Update shadow stack pointer in the function epilogue. |
645 | IRB.SetInsertPoint(BasePointer->getNextNode()); |
646 | |
647 | Value *StaticTop = |
648 | IRB.CreatePtrAdd(Ptr: BasePointer, Offset: ConstantInt::get(Ty: Int32Ty, V: -FrameSize), |
649 | Name: "unsafe_stack_static_top" ); |
650 | IRB.CreateStore(Val: StaticTop, Ptr: UnsafeStackPtr); |
651 | return StaticTop; |
652 | } |
653 | |
654 | void SafeStack::moveDynamicAllocasToUnsafeStack( |
655 | Function &F, Value *UnsafeStackPtr, AllocaInst *DynamicTop, |
656 | ArrayRef<AllocaInst *> DynamicAllocas) { |
657 | DIBuilder DIB(*F.getParent()); |
658 | |
659 | for (AllocaInst *AI : DynamicAllocas) { |
660 | IRBuilder<> IRB(AI); |
661 | |
662 | // Compute the new SP value (after AI). |
663 | Value *ArraySize = AI->getArraySize(); |
664 | if (ArraySize->getType() != IntPtrTy) |
665 | ArraySize = IRB.CreateIntCast(V: ArraySize, DestTy: IntPtrTy, isSigned: false); |
666 | |
667 | Type *Ty = AI->getAllocatedType(); |
668 | uint64_t TySize = DL.getTypeAllocSize(Ty); |
669 | Value *Size = IRB.CreateMul(LHS: ArraySize, RHS: ConstantInt::get(Ty: IntPtrTy, V: TySize)); |
670 | |
671 | Value *SP = IRB.CreatePtrToInt(V: IRB.CreateLoad(Ty: StackPtrTy, Ptr: UnsafeStackPtr), |
672 | DestTy: IntPtrTy); |
673 | SP = IRB.CreateSub(LHS: SP, RHS: Size); |
674 | |
675 | // Align the SP value to satisfy the AllocaInst, type and stack alignments. |
676 | auto Align = std::max(a: std::max(a: DL.getPrefTypeAlign(Ty), b: AI->getAlign()), |
677 | b: StackAlignment); |
678 | |
679 | Value *NewTop = IRB.CreateIntToPtr( |
680 | V: IRB.CreateAnd(LHS: SP, |
681 | RHS: ConstantInt::get(Ty: IntPtrTy, V: ~uint64_t(Align.value() - 1))), |
682 | DestTy: StackPtrTy); |
683 | |
684 | // Save the stack pointer. |
685 | IRB.CreateStore(Val: NewTop, Ptr: UnsafeStackPtr); |
686 | if (DynamicTop) |
687 | IRB.CreateStore(Val: NewTop, Ptr: DynamicTop); |
688 | |
689 | Value *NewAI = IRB.CreatePointerCast(V: NewTop, DestTy: AI->getType()); |
690 | if (AI->hasName() && isa<Instruction>(Val: NewAI)) |
691 | NewAI->takeName(V: AI); |
692 | |
693 | replaceDbgDeclare(Address: AI, NewAddress: NewAI, Builder&: DIB, DIExprFlags: DIExpression::ApplyOffset, Offset: 0); |
694 | AI->replaceAllUsesWith(V: NewAI); |
695 | AI->eraseFromParent(); |
696 | } |
697 | |
698 | if (!DynamicAllocas.empty()) { |
699 | // Now go through the instructions again, replacing stacksave/stackrestore. |
700 | for (Instruction &I : llvm::make_early_inc_range(Range: instructions(F: &F))) { |
701 | auto *II = dyn_cast<IntrinsicInst>(Val: &I); |
702 | if (!II) |
703 | continue; |
704 | |
705 | if (II->getIntrinsicID() == Intrinsic::stacksave) { |
706 | IRBuilder<> IRB(II); |
707 | Instruction *LI = IRB.CreateLoad(Ty: StackPtrTy, Ptr: UnsafeStackPtr); |
708 | LI->takeName(V: II); |
709 | II->replaceAllUsesWith(V: LI); |
710 | II->eraseFromParent(); |
711 | } else if (II->getIntrinsicID() == Intrinsic::stackrestore) { |
712 | IRBuilder<> IRB(II); |
713 | Instruction *SI = IRB.CreateStore(Val: II->getArgOperand(i: 0), Ptr: UnsafeStackPtr); |
714 | SI->takeName(V: II); |
715 | assert(II->use_empty()); |
716 | II->eraseFromParent(); |
717 | } |
718 | } |
719 | } |
720 | } |
721 | |
722 | bool SafeStack::ShouldInlinePointerAddress(CallInst &CI) { |
723 | Function *Callee = CI.getCalledFunction(); |
724 | if (CI.hasFnAttr(Kind: Attribute::AlwaysInline) && |
725 | isInlineViable(Callee&: *Callee).isSuccess()) |
726 | return true; |
727 | if (Callee->isInterposable() || Callee->hasFnAttribute(Kind: Attribute::NoInline) || |
728 | CI.isNoInline()) |
729 | return false; |
730 | return true; |
731 | } |
732 | |
733 | void SafeStack::TryInlinePointerAddress() { |
734 | auto *CI = dyn_cast<CallInst>(Val: UnsafeStackPtr); |
735 | if (!CI) |
736 | return; |
737 | |
738 | if(F.hasOptNone()) |
739 | return; |
740 | |
741 | Function *Callee = CI->getCalledFunction(); |
742 | if (!Callee || Callee->isDeclaration()) |
743 | return; |
744 | |
745 | if (!ShouldInlinePointerAddress(CI&: *CI)) |
746 | return; |
747 | |
748 | InlineFunctionInfo IFI; |
749 | InlineFunction(CB&: *CI, IFI); |
750 | } |
751 | |
752 | bool SafeStack::run() { |
753 | assert(F.hasFnAttribute(Attribute::SafeStack) && |
754 | "Can't run SafeStack on a function without the attribute" ); |
755 | assert(!F.isDeclaration() && "Can't run SafeStack on a function declaration" ); |
756 | |
757 | ++NumFunctions; |
758 | |
759 | SmallVector<AllocaInst *, 16> StaticAllocas; |
760 | SmallVector<AllocaInst *, 4> DynamicAllocas; |
761 | SmallVector<Argument *, 4> ByValArguments; |
762 | SmallVector<Instruction *, 4> Returns; |
763 | |
764 | // Collect all points where stack gets unwound and needs to be restored |
765 | // This is only necessary because the runtime (setjmp and unwind code) is |
766 | // not aware of the unsafe stack and won't unwind/restore it properly. |
767 | // To work around this problem without changing the runtime, we insert |
768 | // instrumentation to restore the unsafe stack pointer when necessary. |
769 | SmallVector<Instruction *, 4> StackRestorePoints; |
770 | |
771 | // Find all static and dynamic alloca instructions that must be moved to the |
772 | // unsafe stack, all return instructions and stack restore points. |
773 | findInsts(F, StaticAllocas, DynamicAllocas, ByValArguments, Returns, |
774 | StackRestorePoints); |
775 | |
776 | if (StaticAllocas.empty() && DynamicAllocas.empty() && |
777 | ByValArguments.empty() && StackRestorePoints.empty()) |
778 | return false; // Nothing to do in this function. |
779 | |
780 | if (!StaticAllocas.empty() || !DynamicAllocas.empty() || |
781 | !ByValArguments.empty()) |
782 | ++NumUnsafeStackFunctions; // This function has the unsafe stack. |
783 | |
784 | if (!StackRestorePoints.empty()) |
785 | ++NumUnsafeStackRestorePointsFunctions; |
786 | |
787 | IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt()); |
788 | // Calls must always have a debug location, or else inlining breaks. So |
789 | // we explicitly set a artificial debug location here. |
790 | if (DISubprogram *SP = F.getSubprogram()) |
791 | IRB.SetCurrentDebugLocation( |
792 | DILocation::get(Context&: SP->getContext(), Line: SP->getScopeLine(), Column: 0, Scope: SP)); |
793 | if (SafeStackUsePointerAddress) { |
794 | FunctionCallee Fn = F.getParent()->getOrInsertFunction( |
795 | Name: "__safestack_pointer_address" , RetTy: IRB.getPtrTy(AddrSpace: 0)); |
796 | UnsafeStackPtr = IRB.CreateCall(Callee: Fn); |
797 | } else { |
798 | UnsafeStackPtr = TL.getSafeStackPointerLocation(IRB); |
799 | } |
800 | |
801 | // Load the current stack pointer (we'll also use it as a base pointer). |
802 | // FIXME: use a dedicated register for it ? |
803 | Instruction *BasePointer = |
804 | IRB.CreateLoad(Ty: StackPtrTy, Ptr: UnsafeStackPtr, isVolatile: false, Name: "unsafe_stack_ptr" ); |
805 | assert(BasePointer->getType() == StackPtrTy); |
806 | |
807 | AllocaInst *StackGuardSlot = nullptr; |
808 | // FIXME: implement weaker forms of stack protector. |
809 | if (F.hasFnAttribute(Kind: Attribute::StackProtect) || |
810 | F.hasFnAttribute(Kind: Attribute::StackProtectStrong) || |
811 | F.hasFnAttribute(Kind: Attribute::StackProtectReq)) { |
812 | Value *StackGuard = getStackGuard(IRB, F); |
813 | StackGuardSlot = IRB.CreateAlloca(Ty: StackPtrTy, ArraySize: nullptr); |
814 | IRB.CreateStore(Val: StackGuard, Ptr: StackGuardSlot); |
815 | |
816 | for (Instruction *RI : Returns) { |
817 | IRBuilder<> IRBRet(RI); |
818 | checkStackGuard(IRB&: IRBRet, F, RI&: *RI, StackGuardSlot, StackGuard); |
819 | } |
820 | } |
821 | |
822 | // The top of the unsafe stack after all unsafe static allocas are |
823 | // allocated. |
824 | Value *StaticTop = moveStaticAllocasToUnsafeStack( |
825 | IRB, F, StaticAllocas, ByValArguments, BasePointer, StackGuardSlot); |
826 | |
827 | // Safe stack object that stores the current unsafe stack top. It is updated |
828 | // as unsafe dynamic (non-constant-sized) allocas are allocated and freed. |
829 | // This is only needed if we need to restore stack pointer after longjmp |
830 | // or exceptions, and we have dynamic allocations. |
831 | // FIXME: a better alternative might be to store the unsafe stack pointer |
832 | // before setjmp / invoke instructions. |
833 | AllocaInst *DynamicTop = createStackRestorePoints( |
834 | IRB, F, StackRestorePoints, StaticTop, NeedDynamicTop: !DynamicAllocas.empty()); |
835 | |
836 | // Handle dynamic allocas. |
837 | moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop, |
838 | DynamicAllocas); |
839 | |
840 | // Restore the unsafe stack pointer before each return. |
841 | for (Instruction *RI : Returns) { |
842 | IRB.SetInsertPoint(RI); |
843 | IRB.CreateStore(Val: BasePointer, Ptr: UnsafeStackPtr); |
844 | } |
845 | |
846 | TryInlinePointerAddress(); |
847 | |
848 | LLVM_DEBUG(dbgs() << "[SafeStack] safestack applied\n" ); |
849 | return true; |
850 | } |
851 | |
852 | class SafeStackLegacyPass : public FunctionPass { |
853 | const TargetMachine *TM = nullptr; |
854 | |
855 | public: |
856 | static char ID; // Pass identification, replacement for typeid.. |
857 | |
858 | SafeStackLegacyPass() : FunctionPass(ID) { |
859 | initializeSafeStackLegacyPassPass(*PassRegistry::getPassRegistry()); |
860 | } |
861 | |
862 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
863 | AU.addRequired<TargetPassConfig>(); |
864 | AU.addRequired<TargetLibraryInfoWrapperPass>(); |
865 | AU.addRequired<AssumptionCacheTracker>(); |
866 | AU.addPreserved<DominatorTreeWrapperPass>(); |
867 | } |
868 | |
869 | bool runOnFunction(Function &F) override { |
870 | LLVM_DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n" ); |
871 | |
872 | if (!F.hasFnAttribute(Kind: Attribute::SafeStack)) { |
873 | LLVM_DEBUG(dbgs() << "[SafeStack] safestack is not requested" |
874 | " for this function\n" ); |
875 | return false; |
876 | } |
877 | |
878 | if (F.isDeclaration()) { |
879 | LLVM_DEBUG(dbgs() << "[SafeStack] function definition" |
880 | " is not available\n" ); |
881 | return false; |
882 | } |
883 | |
884 | TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>(); |
885 | auto *TL = TM->getSubtargetImpl(F)->getTargetLowering(); |
886 | if (!TL) |
887 | report_fatal_error(reason: "TargetLowering instance is required" ); |
888 | |
889 | auto *DL = &F.getDataLayout(); |
890 | auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); |
891 | auto &ACT = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); |
892 | |
893 | // Compute DT and LI only for functions that have the attribute. |
894 | // This is only useful because the legacy pass manager doesn't let us |
895 | // compute analyzes lazily. |
896 | |
897 | DominatorTree *DT; |
898 | bool ShouldPreserveDominatorTree; |
899 | std::optional<DominatorTree> LazilyComputedDomTree; |
900 | |
901 | // Do we already have a DominatorTree avaliable from the previous pass? |
902 | // Note that we should *NOT* require it, to avoid the case where we end up |
903 | // not needing it, but the legacy PM would have computed it for us anyways. |
904 | if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>()) { |
905 | DT = &DTWP->getDomTree(); |
906 | ShouldPreserveDominatorTree = true; |
907 | } else { |
908 | // Otherwise, we need to compute it. |
909 | LazilyComputedDomTree.emplace(args&: F); |
910 | DT = &*LazilyComputedDomTree; |
911 | ShouldPreserveDominatorTree = false; |
912 | } |
913 | |
914 | // Likewise, lazily compute loop info. |
915 | LoopInfo LI(*DT); |
916 | |
917 | DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); |
918 | |
919 | ScalarEvolution SE(F, TLI, ACT, *DT, LI); |
920 | |
921 | return SafeStack(F, *TL, *DL, ShouldPreserveDominatorTree ? &DTU : nullptr, |
922 | SE) |
923 | .run(); |
924 | } |
925 | }; |
926 | |
927 | } // end anonymous namespace |
928 | |
929 | PreservedAnalyses SafeStackPass::run(Function &F, |
930 | FunctionAnalysisManager &FAM) { |
931 | LLVM_DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n" ); |
932 | |
933 | if (!F.hasFnAttribute(Kind: Attribute::SafeStack)) { |
934 | LLVM_DEBUG(dbgs() << "[SafeStack] safestack is not requested" |
935 | " for this function\n" ); |
936 | return PreservedAnalyses::all(); |
937 | } |
938 | |
939 | if (F.isDeclaration()) { |
940 | LLVM_DEBUG(dbgs() << "[SafeStack] function definition" |
941 | " is not available\n" ); |
942 | return PreservedAnalyses::all(); |
943 | } |
944 | |
945 | auto *TL = TM->getSubtargetImpl(F)->getTargetLowering(); |
946 | if (!TL) |
947 | report_fatal_error(reason: "TargetLowering instance is required" ); |
948 | |
949 | auto &DL = F.getDataLayout(); |
950 | |
951 | // preserve DominatorTree |
952 | auto &DT = FAM.getResult<DominatorTreeAnalysis>(IR&: F); |
953 | auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(IR&: F); |
954 | DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); |
955 | |
956 | bool Changed = SafeStack(F, *TL, DL, &DTU, SE).run(); |
957 | |
958 | if (!Changed) |
959 | return PreservedAnalyses::all(); |
960 | PreservedAnalyses PA; |
961 | PA.preserve<DominatorTreeAnalysis>(); |
962 | return PA; |
963 | } |
964 | |
965 | char SafeStackLegacyPass::ID = 0; |
966 | |
967 | INITIALIZE_PASS_BEGIN(SafeStackLegacyPass, DEBUG_TYPE, |
968 | "Safe Stack instrumentation pass" , false, false) |
969 | INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) |
970 | INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) |
971 | INITIALIZE_PASS_END(SafeStackLegacyPass, DEBUG_TYPE, |
972 | "Safe Stack instrumentation pass" , false, false) |
973 | |
974 | FunctionPass *llvm::createSafeStackPass() { return new SafeStackLegacyPass(); } |
975 | |