summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-12-12 14:31:53 +0000
committerAlexey Samsonov <samsonov@google.com>2012-12-12 14:31:53 +0000
commit3d43b63a6e9668b90c6fb01f2255e4b42d45e75e (patch)
tree61944e9be784e785370dccdaa3e87a283e97ac4d /llvm/lib/Transforms
parent9bd2e1bacc5455ebcf93aad3cf564ff88cabca96 (diff)
downloadbcm5719-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.cpp4
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp35
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;
+}
OpenPOWER on IntegriCloud