diff options
| author | Alexey Samsonov <samsonov@google.com> | 2012-12-12 14:31:53 +0000 | 
|---|---|---|
| committer | Alexey Samsonov <samsonov@google.com> | 2012-12-12 14:31:53 +0000 | 
| commit | 3d43b63a6e9668b90c6fb01f2255e4b42d45e75e (patch) | |
| tree | 61944e9be784e785370dccdaa3e87a283e97ac4d /llvm/lib/Transforms | |
| parent | 9bd2e1bacc5455ebcf93aad3cf564ff88cabca96 (diff) | |
| download | bcm5719-llvm-3d43b63a6e9668b90c6fb01f2255e4b42d45e75e.tar.gz bcm5719-llvm-3d43b63a6e9668b90c6fb01f2255e4b42d45e75e.zip | |
Improve debug info generated with enabled AddressSanitizer.
When ASan replaces <alloca instruction> with
<offset into a common large alloca>, 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
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 35 | 
2 files changed, 39 insertions, 0 deletions
| 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 <algorithm> @@ -1158,6 +1160,7 @@ bool AddressSanitizer::poisonStackInFunction(Function &F) {    SmallVector<Instruction*, 8> 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<Value*, 4> 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; +} | 

