llvm.org GIT mirror llvm / 756714d
[CodeGen] Split SafeStack into a LegacyPass and a utility. NFC. This lets the pass focus on gathering the required analyzes, and the utility class focus on the transformation. Differential Revision: https://reviews.llvm.org/D31303 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302609 91177308-0d34-0410-b5e6-96231b3b80d8 Ahmed Bougacha 3 years ago
4 changed file(s) with 93 addition(s) and 76 deletion(s). Raw diff Collapse all Expand all
318318 void initializeSCEVAAWrapperPassPass(PassRegistry&);
319319 void initializeSLPVectorizerPass(PassRegistry&);
320320 void initializeSROALegacyPassPass(PassRegistry&);
321 void initializeSafeStackPass(PassRegistry&);
321 void initializeSafeStackLegacyPassPass(PassRegistry&);
322322 void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&);
323323 void initializeSanitizerCoverageModulePass(PassRegistry&);
324324 void initializeScalarEvolutionWrapperPassPass(PassRegistry&);
7878 initializeRAGreedyPass(Registry);
7979 initializeRegisterCoalescerPass(Registry);
8080 initializeRenameIndependentSubregsPass(Registry);
81 initializeSafeStackPass(Registry);
81 initializeSafeStackLegacyPassPass(Registry);
8282 initializeShrinkWrapPass(Registry);
8383 initializeSlotIndexesPass(Registry);
8484 initializeStackColoringPass(Registry);
1818 #include "SafeStackLayout.h"
1919 #include "llvm/ADT/Statistic.h"
2020 #include "llvm/ADT/Triple.h"
21 #include "llvm/Analysis/AssumptionCache.h"
2122 #include "llvm/Analysis/BranchProbabilityInfo.h"
2223 #include "llvm/Analysis/ScalarEvolution.h"
2324 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
9192 /// determined statically), and the unsafe stack, which contains all
9293 /// local variables that are accessed in ways that we can't prove to
9394 /// be safe.
94 class SafeStack : public FunctionPass {
95 const TargetMachine *TM;
96 const TargetLoweringBase *TL;
97 const DataLayout *DL;
98 ScalarEvolution *SE;
95 class SafeStack {
96 Function &F;
97 const TargetLoweringBase &TL;
98 const DataLayout &DL;
99 ScalarEvolution &SE;
99100
100101 Type *StackPtrTy;
101102 Type *IntPtrTy;
170171 uint64_t AllocaSize);
171172
172173 public:
173 static char ID; // Pass identification, replacement for typeid.
174 SafeStack(const TargetMachine *TM)
175 : FunctionPass(ID), TM(TM), TL(nullptr), DL(nullptr) {
176 initializeSafeStackPass(*PassRegistry::getPassRegistry());
177 }
178 SafeStack() : SafeStack(nullptr) {}
179
180 void getAnalysisUsage(AnalysisUsage &AU) const override {
181 AU.addRequired();
182 }
183
184 bool doInitialization(Module &M) override {
185 DL = &M.getDataLayout();
186
187 StackPtrTy = Type::getInt8PtrTy(M.getContext());
188 IntPtrTy = DL->getIntPtrType(M.getContext());
189 Int32Ty = Type::getInt32Ty(M.getContext());
190 Int8Ty = Type::getInt8Ty(M.getContext());
191
192 return false;
193 }
194
195 bool runOnFunction(Function &F) override;
196 }; // class SafeStack
174 SafeStack(Function &F, const TargetLoweringBase &TL, const DataLayout &DL,
175 ScalarEvolution &SE)
176 : F(F), TL(TL), DL(DL), SE(SE),
177 StackPtrTy(Type::getInt8PtrTy(F.getContext())),
178 IntPtrTy(DL.getIntPtrType(F.getContext())),
179 Int32Ty(Type::getInt32Ty(F.getContext())),
180 Int8Ty(Type::getInt8Ty(F.getContext())) {}
181
182 // Run the transformation on the associated function.
183 // Returns whether the function was changed.
184 bool run();
185 };
197186
198187 uint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) {
199 uint64_t Size = DL->getTypeAllocSize(AI->getAllocatedType());
188 uint64_t Size = DL.getTypeAllocSize(AI->getAllocatedType());
200189 if (AI->isArrayAllocation()) {
201190 auto C = dyn_cast(AI->getArraySize());
202191 if (!C)
208197
209198 bool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize,
210199 const Value *AllocaPtr, uint64_t AllocaSize) {
211 AllocaOffsetRewriter Rewriter(*SE, AllocaPtr);
212 const SCEV *Expr = Rewriter.visit(SE->getSCEV(Addr));
213
214 uint64_t BitWidth = SE->getTypeSizeInBits(Expr->getType());
215 ConstantRange AccessStartRange = SE->getUnsignedRange(Expr);
200 AllocaOffsetRewriter Rewriter(SE, AllocaPtr);
201 const SCEV *Expr = Rewriter.visit(SE.getSCEV(Addr));
202
203 uint64_t BitWidth = SE.getTypeSizeInBits(Expr->getType());
204 ConstantRange AccessStartRange = SE.getUnsignedRange(Expr);
216205 ConstantRange SizeRange =
217206 ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AccessSize));
218207 ConstantRange AccessRange = AccessStartRange.add(SizeRange);
225214 << *AllocaPtr << "\n"
226215 << " Access " << *Addr << "\n"
227216 << " SCEV " << *Expr
228 << " U: " << SE->getUnsignedRange(Expr)
229 << ", S: " << SE->getSignedRange(Expr) << "\n"
217 << " U: " << SE.getUnsignedRange(Expr)
218 << ", S: " << SE.getSignedRange(Expr) << "\n"
230219 << " Range " << AccessRange << "\n"
231220 << " AllocaRange " << AllocaRange << "\n"
232221 << " " << (Safe ? "safe" : "unsafe") << "\n");
265254
266255 switch (I->getOpcode()) {
267256 case Instruction::Load: {
268 if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getType()), AllocaPtr,
257 if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getType()), AllocaPtr,
269258 AllocaSize))
270259 return false;
271260 break;
281270 return false;
282271 }
283272
284 if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getOperand(0)->getType()),
273 if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getOperand(0)->getType()),
285274 AllocaPtr, AllocaSize))
286275 return false;
287276 break;
342331 }
343332
344333 Value *SafeStack::getStackGuard(IRBuilder<> &IRB, Function &F) {
345 Value *StackGuardVar = TL->getIRStackGuard(IRB);
334 Value *StackGuardVar = TL.getIRStackGuard(IRB);
346335 if (!StackGuardVar)
347336 StackGuardVar =
348337 F.getParent()->getOrInsertGlobal("__stack_chk_guard", StackPtrTy);
389378 if (!Arg.hasByValAttr())
390379 continue;
391380 uint64_t Size =
392 DL->getTypeStoreSize(Arg.getType()->getPointerElementType());
381 DL.getTypeStoreSize(Arg.getType()->getPointerElementType());
393382 if (IsSafeStackAlloca(&Arg, Size))
394383 continue;
395384
475464 if (StackGuardSlot) {
476465 Type *Ty = StackGuardSlot->getAllocatedType();
477466 unsigned Align =
478 std::max(DL->getPrefTypeAlignment(Ty), StackGuardSlot->getAlignment());
467 std::max(DL.getPrefTypeAlignment(Ty), StackGuardSlot->getAlignment());
479468 SSL.addObject(StackGuardSlot, getStaticAllocaAllocationSize(StackGuardSlot),
480469 Align, SSC.getFullLiveRange());
481470 }
482471
483472 for (Argument *Arg : ByValArguments) {
484473 Type *Ty = Arg->getType()->getPointerElementType();
485 uint64_t Size = DL->getTypeStoreSize(Ty);
474 uint64_t Size = DL.getTypeStoreSize(Ty);
486475 if (Size == 0)
487476 Size = 1; // Don't create zero-sized stack objects.
488477
489478 // Ensure the object is properly aligned.
490 unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty),
479 unsigned Align = std::max((unsigned)DL.getPrefTypeAlignment(Ty),
491480 Arg->getParamAlignment());
492481 SSL.addObject(Arg, Size, Align, SSC.getFullLiveRange());
493482 }
500489
501490 // Ensure the object is properly aligned.
502491 unsigned Align =
503 std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment());
492 std::max((unsigned)DL.getPrefTypeAlignment(Ty), AI->getAlignment());
504493
505494 SSL.addObject(AI, Size, Align, SSC.getLiveRange(AI));
506495 }
538527 unsigned Offset = SSL.getObjectOffset(Arg);
539528 Type *Ty = Arg->getType()->getPointerElementType();
540529
541 uint64_t Size = DL->getTypeStoreSize(Ty);
530 uint64_t Size = DL.getTypeStoreSize(Ty);
542531 if (Size == 0)
543532 Size = 1; // Don't create zero-sized stack objects.
544533
629618 ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false);
630619
631620 Type *Ty = AI->getAllocatedType();
632 uint64_t TySize = DL->getTypeAllocSize(Ty);
621 uint64_t TySize = DL.getTypeAllocSize(Ty);
633622 Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize));
634623
635624 Value *SP = IRB.CreatePtrToInt(IRB.CreateLoad(UnsafeStackPtr), IntPtrTy);
637626
638627 // Align the SP value to satisfy the AllocaInst, type and stack alignments.
639628 unsigned Align = std::max(
640 std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()),
629 std::max((unsigned)DL.getPrefTypeAlignment(Ty), AI->getAlignment()),
641630 (unsigned)StackAlignment);
642631
643632 assert(isPowerOf2_32(Align));
684673 }
685674 }
686675
687 bool SafeStack::runOnFunction(Function &F) {
688 DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");
689
690 if (!F.hasFnAttribute(Attribute::SafeStack)) {
691 DEBUG(dbgs() << "[SafeStack] safestack is not requested"
692 " for this function\n");
693 return false;
694 }
695
696 if (F.isDeclaration()) {
697 DEBUG(dbgs() << "[SafeStack] function definition"
698 " is not available\n");
699 return false;
700 }
701
702 if (!TM)
703 report_fatal_error("Target machine is required");
704 TL = TM->getSubtargetImpl(F)->getTargetLowering();
705 SE = &getAnalysis().getSE();
676 bool SafeStack::run() {
677 assert(F.hasFnAttribute(Attribute::SafeStack) &&
678 "Can't run SafeStack on a function without the attribute");
679 assert(!F.isDeclaration() && "Can't run SafeStack on a function declaration");
706680
707681 ++NumFunctions;
708682
735709 ++NumUnsafeStackRestorePointsFunctions;
736710
737711 IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt());
738 UnsafeStackPtr = TL->getSafeStackPointerLocation(IRB);
712 UnsafeStackPtr = TL.getSafeStackPointerLocation(IRB);
739713
740714 // Load the current stack pointer (we'll also use it as a base pointer).
741715 // FIXME: use a dedicated register for it ?
787761 return true;
788762 }
789763
764 class SafeStackLegacyPass : public FunctionPass {
765 const TargetMachine *TM;
766
767 public:
768 static char ID; // Pass identification, replacement for typeid..
769 SafeStackLegacyPass(const TargetMachine *TM) : FunctionPass(ID), TM(TM) {
770 initializeSafeStackLegacyPassPass(*PassRegistry::getPassRegistry());
771 }
772
773 SafeStackLegacyPass() : SafeStackLegacyPass(nullptr) {}
774
775 void getAnalysisUsage(AnalysisUsage &AU) const override {
776 AU.addRequired();
777 }
778
779 bool runOnFunction(Function &F) override {
780 DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");
781
782 if (!F.hasFnAttribute(Attribute::SafeStack)) {
783 DEBUG(dbgs() << "[SafeStack] safestack is not requested"
784 " for this function\n");
785 return false;
786 }
787
788 if (F.isDeclaration()) {
789 DEBUG(dbgs() << "[SafeStack] function definition"
790 " is not available\n");
791 return false;
792 }
793
794 if (!TM)
795 report_fatal_error("Target machine is required");
796 auto *TL = TM->getSubtargetImpl(F)->getTargetLowering();
797 if (!TL)
798 report_fatal_error("TargetLowering instance is required");
799
800 auto *DL = &F.getParent()->getDataLayout();
801 auto &SE = getAnalysis().getSE();
802
803 return SafeStack(F, *TL, *DL, SE).run();
804 }
805 };
806
790807 } // anonymous namespace
791808
792 char SafeStack::ID = 0;
793 INITIALIZE_TM_PASS_BEGIN(SafeStack, "safe-stack",
809 char SafeStackLegacyPass::ID = 0;
810 INITIALIZE_TM_PASS_BEGIN(SafeStackLegacyPass, "safe-stack",
794811 "Safe Stack instrumentation pass", false, false)
795 INITIALIZE_TM_PASS_END(SafeStack, "safe-stack",
812 INITIALIZE_TM_PASS_END(SafeStackLegacyPass, "safe-stack",
796813 "Safe Stack instrumentation pass", false, false)
797814
798815 FunctionPass *llvm::createSafeStackPass(const llvm::TargetMachine *TM) {
799 return new SafeStack(TM);
800 }
816 return new SafeStackLegacyPass(TM);
817 }
389389 initializeRewriteSymbolsLegacyPassPass(Registry);
390390 initializeWinEHPreparePass(Registry);
391391 initializeDwarfEHPreparePass(Registry);
392 initializeSafeStackPass(Registry);
392 initializeSafeStackLegacyPassPass(Registry);
393393 initializeSjLjEHPreparePass(Registry);
394394 initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
395395 initializeGlobalMergePass(Registry);