diff options
author | Vitaly Buka <vitalybuka@google.com> | 2016-10-18 23:29:52 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2016-10-18 23:29:52 +0000 |
commit | 5910a92560244efd7ce386c3220cc0a07c04121c (patch) | |
tree | 85cebfdfc29b6002acb30a6b128b2f53600140aa /llvm/lib/Transforms | |
parent | d88e52012bd8e73f06621658b33cecb7ffa150a6 (diff) | |
download | bcm5719-llvm-5910a92560244efd7ce386c3220cc0a07c04121c.tar.gz bcm5719-llvm-5910a92560244efd7ce386c3220cc0a07c04121c.zip |
[asan] Simplify calculation of stack frame layout extraction calculation of stack description into separate function.
Reviewers: eugenis
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D25754
llvm-svn: 284547
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 66 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp | 34 |
2 files changed, 48 insertions, 52 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 507776a4cb8..586c399dbca 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -2246,26 +2246,6 @@ void FunctionStackPoisoner::processStaticAllocas() { // If we have a call to llvm.localescape, keep it in the entry block. if (LocalEscapeCall) LocalEscapeCall->moveBefore(InsBefore); - // Find static allocas with lifetime analysis. - DenseMap<const AllocaInst *, - std::pair<const ASanStackVariableDescription *, unsigned>> - AllocaToSVDMap; - for (const auto &APC : StaticAllocaPoisonCallVec) { - assert(APC.InsBefore); - assert(APC.AI); - assert(ASan.isInterestingAlloca(*APC.AI)); - assert(APC.AI->isStaticAlloca()); - - auto &Pair = AllocaToSVDMap[APC.AI]; - if (const DILocation *FnLoc = EntryDebugLocation.get()) { - if (const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) { - if (LifetimeLoc->getFile() == FnLoc->getFile()) - if (unsigned Line = LifetimeLoc->getLine()) - Pair.second = std::min(Pair.second ? Pair.second : Line, Line); - } - } - } - SmallVector<ASanStackVariableDescription, 16> SVD; SVD.reserve(AllocaVec.size()); for (AllocaInst *AI : AllocaVec) { @@ -2276,20 +2256,40 @@ void FunctionStackPoisoner::processStaticAllocas() { AI, 0, 0}; - auto It = AllocaToSVDMap.find(AI); - if (It != AllocaToSVDMap.end()) { - D.LifetimeSize = D.Size; - D.Line = It->second.second; - } SVD.push_back(D); } + // Minimal header size (left redzone) is 4 pointers, // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms. size_t MinHeaderSize = ASan.LongSize / 2; const ASanStackFrameLayout &L = ComputeASanStackFrameLayout(SVD, 1ULL << Mapping.Scale, MinHeaderSize); - DEBUG(dbgs() << L.DescriptionString << " --- " << L.FrameSize << "\n"); + // Build AllocaToSVDMap for ASanStackVariableDescription lookup. + DenseMap<const AllocaInst *, ASanStackVariableDescription *> AllocaToSVDMap; + for (auto &Desc : SVD) + AllocaToSVDMap[Desc.AI] = &Desc; + + // Update SVD with information from lifetime intrinsics. + for (const auto &APC : StaticAllocaPoisonCallVec) { + assert(APC.InsBefore); + assert(APC.AI); + assert(ASan.isInterestingAlloca(*APC.AI)); + assert(APC.AI->isStaticAlloca()); + + ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI]; + Desc.LifetimeSize = Desc.Size; + if (const DILocation *FnLoc = EntryDebugLocation.get()) { + if (const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) { + if (LifetimeLoc->getFile() == FnLoc->getFile()) + if (unsigned Line = LifetimeLoc->getLine()) + Desc.Line = std::min(Desc.Line ? Desc.Line : Line, Line); + } + } + } + + auto DescriptionString = ComputeASanStackFrameDescription(SVD); + DEBUG(dbgs() << DescriptionString << " --- " << L.FrameSize << "\n"); uint64_t LocalStackSize = L.FrameSize; bool DoStackMalloc = ClUseAfterReturn && !ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize; @@ -2372,7 +2372,7 @@ void FunctionStackPoisoner::processStaticAllocas() { ConstantInt::get(IntptrTy, ASan.LongSize / 8)), IntptrPtrTy); GlobalVariable *StackDescriptionGlobal = - createPrivateGlobalForString(*F.getParent(), L.DescriptionString, + createPrivateGlobalForString(*F.getParent(), DescriptionString, /*AllowMerging*/ true); Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, IntptrTy); IRB.CreateStore(Description, BasePlus1); @@ -2392,21 +2392,11 @@ void FunctionStackPoisoner::processStaticAllocas() { copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase); if (!StaticAllocaPoisonCallVec.empty()) { - // Complete AllocaToSVDMap - for (const auto &Desc : SVD) { - auto It = AllocaToSVDMap.find(Desc.AI); - if (It != AllocaToSVDMap.end()) { - It->second.first = &Desc; - } - } - const auto &ShadowInScope = GetShadowBytes(SVD, L); // Poison static allocas near lifetime intrinsics. for (const auto &APC : StaticAllocaPoisonCallVec) { - // Must be already set. - assert(AllocaToSVDMap[APC.AI].first); - const auto &Desc = *AllocaToSVDMap[APC.AI].first; + const ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI]; assert(Desc.Offset % L.Granularity == 0); size_t Begin = Desc.Offset / L.Granularity; size_t End = Begin + (APC.Size + L.Granularity - 1) / L.Granularity; diff --git a/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp b/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp index dc226b2e2cc..86d7ce87745 100644 --- a/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp +++ b/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp @@ -61,9 +61,6 @@ ComputeASanStackFrameLayout(SmallVectorImpl<ASanStackVariableDescription> &Vars, Vars[i].Alignment = std::max(Vars[i].Alignment, kMinAlignment); std::stable_sort(Vars.begin(), Vars.end(), CompareVars); - SmallString<2048> StackDescriptionStorage; - raw_svector_ostream StackDescription(StackDescriptionStorage); - StackDescription << NumVars; ASanStackFrameLayout Layout; Layout.Granularity = Granularity; @@ -76,34 +73,42 @@ ComputeASanStackFrameLayout(SmallVectorImpl<ASanStackVariableDescription> &Vars, size_t Alignment = std::max(Granularity, Vars[i].Alignment); (void)Alignment; // Used only in asserts. size_t Size = Vars[i].Size; - std::string Name = Vars[i].Name; assert((Alignment & (Alignment - 1)) == 0); assert(Layout.FrameAlignment >= Alignment); assert((Offset % Alignment) == 0); assert(Size > 0); - assert(Vars[i].LifetimeSize <= Size); - if (Vars[i].Line) { - Name += ":"; - Name += std::to_string(Vars[i].Line); - } - StackDescription << " " << Offset << " " << Size << " " << Name.size() - << " " << Name; size_t NextAlignment = IsLast ? Granularity : std::max(Granularity, Vars[i + 1].Alignment); - size_t SizeWithRedzone = VarAndRedzoneSize(Vars[i].Size, NextAlignment); + size_t SizeWithRedzone = VarAndRedzoneSize(Size, NextAlignment); Vars[i].Offset = Offset; Offset += SizeWithRedzone; } if (Offset % MinHeaderSize) { Offset += MinHeaderSize - (Offset % MinHeaderSize); } - Layout.DescriptionString = StackDescription.str(); Layout.FrameSize = Offset; assert((Layout.FrameSize % MinHeaderSize) == 0); - return Layout; } +SmallString<64> ComputeASanStackFrameDescription( + const SmallVectorImpl<ASanStackVariableDescription> &Vars) { + SmallString<2048> StackDescriptionStorage; + raw_svector_ostream StackDescription(StackDescriptionStorage); + StackDescription << Vars.size(); + + for (const auto &Var : Vars) { + std::string Name = Var.Name; + if (Var.Line) { + Name += ":"; + Name += std::to_string(Var.Line); + } + StackDescription << " " << Var.Offset << " " << Var.Size << " " + << Name.size() << " " << Name; + } + return StackDescription.str(); +} + SmallVector<uint8_t, 64> GetShadowBytes(const SmallVectorImpl<ASanStackVariableDescription> &Vars, const ASanStackFrameLayout &Layout) { @@ -130,6 +135,7 @@ SmallVector<uint8_t, 64> GetShadowBytesAfterScope( const size_t Granularity = Layout.Granularity; for (const auto &Var : Vars) { + assert(Var.LifetimeSize <= Var.Size); const size_t LifetimeShadowSize = (Var.LifetimeSize + Granularity - 1) / Granularity; const size_t Offset = Var.Offset / Granularity; |