diff options
Diffstat (limited to 'llvm/lib/CodeGen/SafeStack.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SafeStack.cpp | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index b4a2ec436db..19cd59b9dba 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -15,6 +15,8 @@ // //===----------------------------------------------------------------------===// +#include "SafeStackColoring.h" +#include "SafeStackLayout.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/BranchProbabilityInfo.h" @@ -46,6 +48,7 @@ #include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; +using namespace llvm::safestack; #define DEBUG_TYPE "safestack" @@ -516,40 +519,66 @@ Value *SafeStack::moveStaticAllocasToUnsafeStack( DIBuilder DIB(*F.getParent()); - // Compute maximum alignment among static objects on the unsafe stack. - unsigned MaxAlignment = 0; + StackColoring SSC(F, StaticAllocas); + SSC.run(); + SSC.removeAllMarkers(); + + // Unsafe stack always grows down. + StackLayout SSL(StackAlignment); + if (StackGuardSlot) { + Type *Ty = StackGuardSlot->getAllocatedType(); + unsigned Align = + std::max(DL->getPrefTypeAlignment(Ty), StackGuardSlot->getAlignment()); + SSL.addObject(StackGuardSlot, getStaticAllocaAllocationSize(StackGuardSlot), + Align, SSC.getLiveRange(StackGuardSlot)); + } + for (Argument *Arg : ByValArguments) { Type *Ty = Arg->getType()->getPointerElementType(); + uint64_t Size = DL->getTypeStoreSize(Ty); + if (Size == 0) + Size = 1; // Don't create zero-sized stack objects. + + // Ensure the object is properly aligned. unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty), Arg->getParamAlignment()); - if (Align > MaxAlignment) - MaxAlignment = Align; + SSL.addObject(Arg, Size, Align, SSC.getFullLiveRange()); } + for (AllocaInst *AI : StaticAllocas) { Type *Ty = AI->getAllocatedType(); + uint64_t Size = getStaticAllocaAllocationSize(AI); + if (Size == 0) + Size = 1; // Don't create zero-sized stack objects. + + // Ensure the object is properly aligned. unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); - if (Align > MaxAlignment) - MaxAlignment = Align; + + SSL.addObject(AI, Size, Align, SSC.getLiveRange(AI)); } - if (MaxAlignment > StackAlignment) { + SSL.computeLayout(); + unsigned FrameAlignment = SSL.getFrameAlignment(); + + // FIXME: tell SSL that we start at a less-then-MaxAlignment aligned location + // (AlignmentSkew). + if (FrameAlignment > StackAlignment) { // Re-align the base pointer according to the max requested alignment. - assert(isPowerOf2_32(MaxAlignment)); + assert(isPowerOf2_32(FrameAlignment)); IRB.SetInsertPoint(BasePointer->getNextNode()); BasePointer = cast<Instruction>(IRB.CreateIntToPtr( IRB.CreateAnd(IRB.CreatePtrToInt(BasePointer, IntPtrTy), - ConstantInt::get(IntPtrTy, ~uint64_t(MaxAlignment - 1))), + ConstantInt::get(IntPtrTy, ~uint64_t(FrameAlignment - 1))), StackPtrTy)); } - int64_t StaticOffset = 0; // Current stack top. IRB.SetInsertPoint(BasePointer->getNextNode()); if (StackGuardSlot) { - StaticOffset += getStaticAllocaAllocationSize(StackGuardSlot); + unsigned Offset = SSL.getObjectOffset(StackGuardSlot); Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8* - ConstantInt::get(Int32Ty, -StaticOffset)); + ConstantInt::get(Int32Ty, -Offset)); Value *NewAI = IRB.CreateBitCast(Off, StackGuardSlot->getType(), "StackGuardSlot"); @@ -559,29 +588,21 @@ Value *SafeStack::moveStaticAllocasToUnsafeStack( } for (Argument *Arg : ByValArguments) { + unsigned Offset = SSL.getObjectOffset(Arg); Type *Ty = Arg->getType()->getPointerElementType(); uint64_t Size = DL->getTypeStoreSize(Ty); if (Size == 0) Size = 1; // Don't create zero-sized stack objects. - // Ensure the object is properly aligned. - unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty), - Arg->getParamAlignment()); - - // Add alignment. - // NOTE: we ensure that BasePointer itself is aligned to >= Align. - StaticOffset += Size; - StaticOffset = alignTo(StaticOffset, Align); - Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8* - ConstantInt::get(Int32Ty, -StaticOffset)); + ConstantInt::get(Int32Ty, -Offset)); Value *NewArg = IRB.CreateBitCast(Off, Arg->getType(), Arg->getName() + ".unsafe-byval"); // Replace alloc with the new location. replaceDbgDeclare(Arg, BasePointer, BasePointer->getNextNode(), DIB, - /*Deref=*/true, -StaticOffset); + /*Deref=*/true, -Offset); Arg->replaceAllUsesWith(NewArg); IRB.SetInsertPoint(cast<Instruction>(NewArg)->getNextNode()); IRB.CreateMemCpy(Off, Arg, Size, Arg->getParamAlignment()); @@ -590,23 +611,14 @@ Value *SafeStack::moveStaticAllocasToUnsafeStack( // Allocate space for every unsafe static AllocaInst on the unsafe stack. for (AllocaInst *AI : StaticAllocas) { IRB.SetInsertPoint(AI); + unsigned Offset = SSL.getObjectOffset(AI); - Type *Ty = AI->getAllocatedType(); uint64_t Size = getStaticAllocaAllocationSize(AI); if (Size == 0) Size = 1; // Don't create zero-sized stack objects. - // Ensure the object is properly aligned. - unsigned Align = - std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); - - // Add alignment. - // NOTE: we ensure that BasePointer itself is aligned to >= Align. - StaticOffset += Size; - StaticOffset = alignTo(StaticOffset, Align); - - replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/true, -StaticOffset); - replaceDbgValueForAlloca(AI, BasePointer, DIB, -StaticOffset); + replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/true, -Offset); + replaceDbgValueForAlloca(AI, BasePointer, DIB, -Offset); // Replace uses of the alloca with the new location. // Insert address calculation close to each use to work around PR27844. @@ -623,7 +635,7 @@ Value *SafeStack::moveStaticAllocasToUnsafeStack( IRBuilder<> IRBUser(InsertBefore); Value *Off = IRBUser.CreateGEP(BasePointer, // BasePointer is i8* - ConstantInt::get(Int32Ty, -StaticOffset)); + ConstantInt::get(Int32Ty, -Offset)); Value *Replacement = IRBUser.CreateBitCast(Off, AI->getType(), Name); if (auto *PHI = dyn_cast<PHINode>(User)) { @@ -644,13 +656,13 @@ Value *SafeStack::moveStaticAllocasToUnsafeStack( // Re-align BasePointer so that our callees would see it aligned as // expected. // FIXME: no need to update BasePointer in leaf functions. - StaticOffset = alignTo(StaticOffset, StackAlignment); + unsigned FrameSize = alignTo(SSL.getFrameSize(), StackAlignment); // Update shadow stack pointer in the function epilogue. IRB.SetInsertPoint(BasePointer->getNextNode()); Value *StaticTop = - IRB.CreateGEP(BasePointer, ConstantInt::get(Int32Ty, -StaticOffset), + IRB.CreateGEP(BasePointer, ConstantInt::get(Int32Ty, -FrameSize), "unsafe_stack_static_top"); IRB.CreateStore(StaticTop, UnsafeStackPtr); return StaticTop; |