Lines Matching +full:ssc +full:- +full:range
1 //===- SafeStack.cpp - Safe Stack Insertion -------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass splits the stack into the safe stack (kept as-is for LLVM backend)
15 //===----------------------------------------------------------------------===//
78 #define DEBUG_TYPE "safe-stack"
98 SafeStackUsePointerAddress("safestack-use-pointer-address",
101 static cl::opt<bool> ClColoring("safe-stack-coloring",
126 /// aligned to this value. We need to re-align the unsafe stack if the
176 /// top to \p DynamicTop if non-null.
207 uint64_t Size = DL.getTypeAllocSize(AI->getAllocatedType()); in getStaticAllocaAllocationSize()
208 if (AI->isArrayAllocation()) { in getStaticAllocaAllocationSize()
209 auto C = dyn_cast<ConstantInt>(AI->getArraySize()); in getStaticAllocaAllocationSize()
212 Size *= C->getZExtValue(); in getStaticAllocaAllocationSize()
221 if (!Base || Base->getValue() != AllocaPtr) { in IsAccessSafe()
231 uint64_t BitWidth = SE.getTypeSizeInBits(Expr->getType()); in IsAccessSafe()
248 << " Range " << AccessRange << "\n" in IsAccessSafe()
259 if (MTI->getRawSource() != U && MTI->getRawDest() != U) in IsMemIntrinsicSafe()
262 if (MI->getRawDest() != U) in IsMemIntrinsicSafe()
266 const auto *Len = dyn_cast<ConstantInt>(MI->getLength()); in IsMemIntrinsicSafe()
267 // Non-constant size => unsafe. FIXME: try SCEV getRange. in IsMemIntrinsicSafe()
269 return IsAccessSafe(U, Len->getZExtValue(), AllocaPtr, AllocaSize); in IsMemIntrinsicSafe()
286 for (const Use &UI : V->uses()) { in IsSafeStackAlloca()
290 switch (I->getOpcode()) { in IsSafeStackAlloca()
292 if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getType()), AllocaPtr, in IsSafeStackAlloca()
298 // "va-arg" from a pointer is safe. in IsSafeStackAlloca()
301 if (V == I->getOperand(0)) { in IsSafeStackAlloca()
302 // Stored the pointer - conservatively assume it may be unsafe. in IsSafeStackAlloca()
309 if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getOperand(0)->getType()), in IsSafeStackAlloca()
322 if (I->isLifetimeStartOrEnd()) in IsSafeStackAlloca()
336 // is not stored, passed around, or used in any other non-trivial way. in IsSafeStackAlloca()
344 if (A->get() == V) in IsSafeStackAlloca()
345 if (!(CS.doesNotCapture(A - B) && (CS.doesNotAccessMemory(A - B) || in IsSafeStackAlloca()
391 if (AI->isStaticAlloca()) { in findInsts()
399 if (CallInst *CI = I.getParent()->getTerminatingMustTailCall()) in findInsts()
405 if (CI->getCalledFunction() && CI->canReturnTwice()) in findInsts()
411 if (II->getIntrinsicID() == Intrinsic::gcroot) in findInsts()
456 IRB.SetInsertPoint(I->getNextNode()); in createStackRestorePoints()
478 // FIXME: respect -fsanitize-trap / -ftrap-function here? in checkStackGuard()
480 F.getParent()->getOrInsertFunction("__stack_chk_fail", IRB.getVoidTy()); in checkStackGuard()
496 StackLifetime SSC(F, StaticAllocas, StackLifetime::LivenessType::May); in moveStaticAllocasToUnsafeStack() local
499 SSC.run(); in moveStaticAllocasToUnsafeStack()
501 for (const auto *I : SSC.getMarkers()) { in moveStaticAllocasToUnsafeStack()
502 auto *Op = dyn_cast<Instruction>(I->getOperand(1)); in moveStaticAllocasToUnsafeStack()
503 const_cast<IntrinsicInst *>(I)->eraseFromParent(); in moveStaticAllocasToUnsafeStack()
505 if (Op && Op->use_empty()) in moveStaticAllocasToUnsafeStack()
506 Op->eraseFromParent(); in moveStaticAllocasToUnsafeStack()
512 Type *Ty = StackGuardSlot->getAllocatedType(); in moveStaticAllocasToUnsafeStack()
513 Align Align = std::max(DL.getPrefTypeAlign(Ty), StackGuardSlot->getAlign()); in moveStaticAllocasToUnsafeStack()
515 Align, SSC.getFullLiveRange()); in moveStaticAllocasToUnsafeStack()
519 Type *Ty = Arg->getParamByValType(); in moveStaticAllocasToUnsafeStack()
522 Size = 1; // Don't create zero-sized stack objects. in moveStaticAllocasToUnsafeStack()
526 if (auto A = Arg->getParamAlign()) in moveStaticAllocasToUnsafeStack()
528 SSL.addObject(Arg, Size, Align, SSC.getFullLiveRange()); in moveStaticAllocasToUnsafeStack()
532 Type *Ty = AI->getAllocatedType(); in moveStaticAllocasToUnsafeStack()
535 Size = 1; // Don't create zero-sized stack objects. in moveStaticAllocasToUnsafeStack()
538 Align Align = std::max(DL.getPrefTypeAlign(Ty), AI->getAlign()); in moveStaticAllocasToUnsafeStack()
541 ClColoring ? SSC.getLiveRange(AI) : NoColoringRange); in moveStaticAllocasToUnsafeStack()
547 // FIXME: tell SSL that we start at a less-then-MaxAlignment aligned location in moveStaticAllocasToUnsafeStack()
550 // Re-align the base pointer according to the max requested alignment. in moveStaticAllocasToUnsafeStack()
551 IRB.SetInsertPoint(BasePointer->getNextNode()); in moveStaticAllocasToUnsafeStack()
555 ConstantInt::get(IntPtrTy, ~(FrameAlignment.value() - 1))), in moveStaticAllocasToUnsafeStack()
559 IRB.SetInsertPoint(BasePointer->getNextNode()); in moveStaticAllocasToUnsafeStack()
564 IRB.CreatePtrAdd(BasePointer, ConstantInt::get(Int32Ty, -Offset)); in moveStaticAllocasToUnsafeStack()
566 IRB.CreateBitCast(Off, StackGuardSlot->getType(), "StackGuardSlot"); in moveStaticAllocasToUnsafeStack()
569 StackGuardSlot->replaceAllUsesWith(NewAI); in moveStaticAllocasToUnsafeStack()
570 StackGuardSlot->eraseFromParent(); in moveStaticAllocasToUnsafeStack()
576 Type *Ty = Arg->getParamByValType(); in moveStaticAllocasToUnsafeStack()
580 Size = 1; // Don't create zero-sized stack objects. in moveStaticAllocasToUnsafeStack()
583 IRB.CreatePtrAdd(BasePointer, ConstantInt::get(Int32Ty, -Offset)); in moveStaticAllocasToUnsafeStack()
584 Value *NewArg = IRB.CreateBitCast(Off, Arg->getType(), in moveStaticAllocasToUnsafeStack()
585 Arg->getName() + ".unsafe-byval"); in moveStaticAllocasToUnsafeStack()
589 -Offset); in moveStaticAllocasToUnsafeStack()
590 Arg->replaceAllUsesWith(NewArg); in moveStaticAllocasToUnsafeStack()
591 IRB.SetInsertPoint(cast<Instruction>(NewArg)->getNextNode()); in moveStaticAllocasToUnsafeStack()
592 IRB.CreateMemCpy(Off, Align, Arg, Arg->getParamAlign(), Size); in moveStaticAllocasToUnsafeStack()
600 replaceDbgDeclare(AI, BasePointer, DIB, DIExpression::ApplyOffset, -Offset); in moveStaticAllocasToUnsafeStack()
601 replaceDbgValueForAlloca(AI, BasePointer, DIB, -Offset); in moveStaticAllocasToUnsafeStack()
605 std::string Name = std::string(AI->getName()) + ".unsafe"; in moveStaticAllocasToUnsafeStack()
606 while (!AI->use_empty()) { in moveStaticAllocasToUnsafeStack()
607 Use &U = *AI->use_begin(); in moveStaticAllocasToUnsafeStack()
612 InsertBefore = PHI->getIncomingBlock(U)->getTerminator(); in moveStaticAllocasToUnsafeStack()
618 IRBUser.CreatePtrAdd(BasePointer, ConstantInt::get(Int32Ty, -Offset)); in moveStaticAllocasToUnsafeStack()
619 Value *Replacement = IRBUser.CreateBitCast(Off, AI->getType(), Name); in moveStaticAllocasToUnsafeStack()
624 PHI->setIncomingValueForBlock(PHI->getIncomingBlock(U), Replacement); in moveStaticAllocasToUnsafeStack()
629 AI->eraseFromParent(); in moveStaticAllocasToUnsafeStack()
632 // Re-align BasePointer so that our callees would see it aligned as in moveStaticAllocasToUnsafeStack()
639 Data.push_back(MDB.createString("unsafe-stack-size")); in moveStaticAllocasToUnsafeStack()
645 IRB.SetInsertPoint(BasePointer->getNextNode()); in moveStaticAllocasToUnsafeStack()
648 IRB.CreatePtrAdd(BasePointer, ConstantInt::get(Int32Ty, -FrameSize), in moveStaticAllocasToUnsafeStack()
663 Value *ArraySize = AI->getArraySize(); in moveDynamicAllocasToUnsafeStack()
664 if (ArraySize->getType() != IntPtrTy) in moveDynamicAllocasToUnsafeStack()
667 Type *Ty = AI->getAllocatedType(); in moveDynamicAllocasToUnsafeStack()
676 auto Align = std::max(std::max(DL.getPrefTypeAlign(Ty), AI->getAlign()), in moveDynamicAllocasToUnsafeStack()
681 ConstantInt::get(IntPtrTy, ~uint64_t(Align.value() - 1))), in moveDynamicAllocasToUnsafeStack()
689 Value *NewAI = IRB.CreatePointerCast(NewTop, AI->getType()); in moveDynamicAllocasToUnsafeStack()
690 if (AI->hasName() && isa<Instruction>(NewAI)) in moveDynamicAllocasToUnsafeStack()
691 NewAI->takeName(AI); in moveDynamicAllocasToUnsafeStack()
694 AI->replaceAllUsesWith(NewAI); in moveDynamicAllocasToUnsafeStack()
695 AI->eraseFromParent(); in moveDynamicAllocasToUnsafeStack()
705 if (II->getIntrinsicID() == Intrinsic::stacksave) { in moveDynamicAllocasToUnsafeStack()
708 LI->takeName(II); in moveDynamicAllocasToUnsafeStack()
709 II->replaceAllUsesWith(LI); in moveDynamicAllocasToUnsafeStack()
710 II->eraseFromParent(); in moveDynamicAllocasToUnsafeStack()
711 } else if (II->getIntrinsicID() == Intrinsic::stackrestore) { in moveDynamicAllocasToUnsafeStack()
713 Instruction *SI = IRB.CreateStore(II->getArgOperand(0), UnsafeStackPtr); in moveDynamicAllocasToUnsafeStack()
714 SI->takeName(II); in moveDynamicAllocasToUnsafeStack()
715 assert(II->use_empty()); in moveDynamicAllocasToUnsafeStack()
716 II->eraseFromParent(); in moveDynamicAllocasToUnsafeStack()
727 if (Callee->isInterposable() || Callee->hasFnAttribute(Attribute::NoInline) || in ShouldInlinePointerAddress()
741 Function *Callee = CI->getCalledFunction(); in TryInlinePointerAddress()
742 if (!Callee || Callee->isDeclaration()) in TryInlinePointerAddress()
787 IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt()); in run()
792 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP)); in run()
794 FunctionCallee Fn = F.getParent()->getOrInsertFunction( in run()
805 assert(BasePointer->getType() == StackPtrTy); in run()
828 // as unsafe dynamic (non-constant-sized) allocas are allocated and freed. in run()
885 auto *TL = TM->getSubtargetImpl(F)->getTargetLowering(); in runOnFunction()
905 DT = &DTWP->getDomTree(); in runOnFunction()
945 auto *TL = TM->getSubtargetImpl(F)->getTargetLowering(); in run()