]> granicus.if.org Git - llvm/commitdiff
[SafeStack] Insert the deref after the offset
authorPetr Hosek <phosek@chromium.org>
Mon, 22 Jul 2019 18:52:42 +0000 (18:52 +0000)
committerPetr Hosek <phosek@chromium.org>
Mon, 22 Jul 2019 18:52:42 +0000 (18:52 +0000)
While debugging code that uses SafeStack, we've noticed that LLVM
produces an invalid DWARF. Concretely, in the following example:

  int main(int argc, char* argv[]) {
    std::string value = "";
    printf("%s\n", value.c_str());
    return 0;
  }

DWARF would describe the value variable as being located at:

  DW_OP_breg14 R14+0, DW_OP_deref, DW_OP_constu 0x20, DW_OP_minus

The assembly to get this variable is:

  leaq    -32(%r14), %rbx

The order of operations in the DWARF symbols is incorrect in this case.
Specifically, the deref is incorrect; this appears to be incorrectly
re-inserted in repalceOneDbgValueForAlloca.

With this change which inserts the deref after the offset instead of
before it, LLVM produces correct DWARF:

  DW_OP_breg14 R14-32

Differential Revision: https://reviews.llvm.org/D64971

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366726 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/Local.cpp
test/Transforms/SafeStack/X86/debug-loc2.ll

index c2d4303ecb090ce5f4c6c456445c2c06b7ba7a80..be1605411176dbf716f03d8fdc199a3cb5a256e9 100644 (file)
@@ -1597,13 +1597,13 @@ static void replaceOneDbgValueForAlloca(DbgValueInst *DVI, Value *NewAddress,
       DIExpr->getElement(0) != dwarf::DW_OP_deref)
     return;
 
-  // Insert the offset immediately after the first deref.
+  // Insert the offset before the first deref.
   // We could just change the offset argument of dbg.value, but it's unsigned...
   if (Offset) {
     SmallVector<uint64_t, 4> Ops;
-    Ops.push_back(dwarf::DW_OP_deref);
     DIExpression::appendOffset(Ops, Offset);
     Ops.append(DIExpr->elements_begin() + 1, DIExpr->elements_end());
+    Ops.push_back(dwarf::DW_OP_deref);
     DIExpr = Builder.createExpression(Ops);
   }
 
index afa143f9c08d24defe2920205153ba33086e6420..30623962691f9200ef4dea0d7f191e0a903da934 100644 (file)
@@ -25,7 +25,7 @@ entry:
   tail call void @llvm.dbg.value(metadata i32* %x1, metadata !10, metadata !24), !dbg !16
 
 ; Supported dbg.value: rewritted based on the [[USP]] value.
-; CHECK: call void @llvm.dbg.value(metadata i8* %[[USP]], metadata ![[X1:.*]], metadata !DIExpression(DW_OP_deref, DW_OP_constu, 4, DW_OP_minus))
+; CHECK: call void @llvm.dbg.value(metadata i8* %[[USP]], metadata ![[X1:.*]], metadata !DIExpression(DW_OP_constu, 4, DW_OP_minus, DW_OP_deref))
   tail call void @llvm.dbg.value(metadata i32* %x1, metadata !10, metadata !15), !dbg !16
   call void @capture(i32* nonnull %x1), !dbg !17
 
@@ -33,7 +33,7 @@ entry:
 ; CHECK: call void @llvm.random.metadata.use(metadata ![[EMPTY]])
   call void @llvm.random.metadata.use(metadata i32* %x2)
 
-; CHECK: call void @llvm.dbg.value(metadata i8* %[[USP]], metadata ![[X2:.*]], metadata !DIExpression(DW_OP_deref, DW_OP_constu, 8, DW_OP_minus))
+; CHECK: call void @llvm.dbg.value(metadata i8* %[[USP]], metadata ![[X2:.*]], metadata !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref))
   call void @llvm.dbg.value(metadata i32* %x2, metadata !12, metadata !15), !dbg !18
   call void @capture(i32* nonnull %x2), !dbg !19
   ret void, !dbg !20