From 3d43b63a6e9668b90c6fb01f2255e4b42d45e75e Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Wed, 12 Dec 2012 14:31:53 +0000 Subject: Improve debug info generated with enabled AddressSanitizer. When ASan replaces with , it should also patch llvm.dbg.declare calls and replace debug info descriptors to mark that we've replaced alloca with a value that stores an address of the user variable, not the user variable itself. See PR11818 for more context. llvm-svn: 169984 --- .../Instrumentation/AddressSanitizer.cpp | 4 +++ llvm/lib/Transforms/Utils/Local.cpp | 35 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'llvm/lib/Transforms') diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index f095cff33c9..e0c610ffa48 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/DataLayout.h" +#include "llvm/DIBuilder.h" #include "llvm/Function.h" #include "llvm/IRBuilder.h" #include "llvm/InlineAsm.h" @@ -38,6 +39,7 @@ #include "llvm/Support/system_error.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Type.h" #include @@ -1158,6 +1160,7 @@ bool AddressSanitizer::poisonStackInFunction(Function &F) { SmallVector RetVec; uint64_t TotalSize = 0; bool HavePoisonedAllocas = false; + DIBuilder DIB(*F.getParent()); // Filter out Alloca instructions we want (and can) handle. // Collect Ret instructions. @@ -1228,6 +1231,7 @@ bool AddressSanitizer::poisonStackInFunction(Function &F) { Value *NewAllocaPtr = IRB.CreateIntToPtr( IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Pos)), AI->getType()); + replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB); AI->replaceAllUsesWith(NewAllocaPtr); // Analyze lifetime intrinsics only for static allocas we handle. if (CheckLifetime) diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 0e56817a1b7..58d973a61a1 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -928,3 +928,38 @@ DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) { return 0; } + +bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, + DIBuilder &Builder) { + DbgDeclareInst *DDI = FindAllocaDbgDeclare(AI); + if (!DDI) + return false; + DIVariable DIVar(DDI->getVariable()); + if (!DIVar.Verify()) + return false; + + // Create a copy of the original DIDescriptor for user variable, appending + // "deref" operation to a list of address elements, as new llvm.dbg.declare + // will take a value storing address of the memory for variable, not + // alloca itself. + Type *Int64Ty = Type::getInt64Ty(AI->getContext()); + SmallVector NewDIVarAddress; + if (DIVar.hasComplexAddress()) { + for (unsigned i = 0, n = DIVar.getNumAddrElements(); i < n; ++i) { + NewDIVarAddress.push_back( + ConstantInt::get(Int64Ty, DIVar.getAddrElement(i))); + } + } + NewDIVarAddress.push_back(ConstantInt::get(Int64Ty, DIBuilder::OpDeref)); + DIVariable NewDIVar = Builder.createComplexVariable( + DIVar.getTag(), DIVar.getContext(), DIVar.getName(), + DIVar.getFile(), DIVar.getLineNumber(), DIVar.getType(), + NewDIVarAddress, DIVar.getArgNumber()); + + // Insert llvm.dbg.declare in the same basic block as the original alloca, + // and remove old llvm.dbg.declare. + BasicBlock *BB = AI->getParent(); + Builder.insertDeclare(NewAllocaAddress, NewDIVar, BB); + DDI->eraseFromParent(); + return true; +} -- cgit v1.2.3