[llvm] r364542 - [DWARF] Handle the DW_OP_entry_value operand

Djordje Todorovic via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 27 06:52:34 PDT 2019


Author: djtodoro
Date: Thu Jun 27 06:52:34 2019
New Revision: 364542

URL: http://llvm.org/viewvc/llvm-project?rev=364542&view=rev
Log:
[DWARF] Handle the DW_OP_entry_value operand

Add the IR and the AsmPrinter parts for handling of the DW_OP_entry_values
DWARF operation.

([11/13] Introduce the debug entry values.)

Co-authored-by: Ananth Sowda <asowda at cisco.com>
Co-authored-by: Nikola Prica <nikola.prica at rt-rk.com>
Co-authored-by: Ivan Baev <ibaev at cisco.com>

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

Added:
    llvm/trunk/test/Verifier/diexpression-entry-value.ll
    llvm/trunk/test/Verifier/diexpression-valid-entry-value.ll
    llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_GNU_entry_value.s
    llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_entry_value.s
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/BinaryFormat/Dwarf.def
    llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp
    llvm/trunk/lib/IR/DebugInfoMetadata.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Thu Jun 27 06:52:34 2019
@@ -4729,6 +4729,17 @@ The current supported opcode vocabulary
   of the stack is treated as an address. The second stack entry is treated as an
   address space identifier.
 - ``DW_OP_stack_value`` marks a constant value.
+- If an expression is marked with ``DW_OP_entry_value`` all register and
+  memory read operations refer to the respective value at the function entry.
+  The first operand of ``DW_OP_entry_value`` is the size of following
+  DWARF expression.
+  ``DW_OP_entry_value`` may appear after the ``LiveDebugValues`` pass.
+  LLVM only supports entry values for function parameters
+  that are unmodified throughout a function and that are described as
+  simple register location descriptions.
+  ``DW_OP_entry_value`` may also appear after the ``AsmPrinter`` pass when
+  a call site parameter value (``DW_AT_call_site_parameter_value``)
+  is represented as entry value of the parameter.
 
 DWARF specifies three kinds of simple location descriptions: Register, memory,
 and implicit location descriptions.  Note that a location description is

Modified: llvm/trunk/include/llvm/BinaryFormat/Dwarf.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Dwarf.def?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Dwarf.def (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Dwarf.def Thu Jun 27 06:52:34 2019
@@ -633,6 +633,8 @@ HANDLE_DW_OP(0xa9, reinterpret, 5, DWARF
 // Vendor extensions:
 // Extensions for GNU-style thread-local storage.
 HANDLE_DW_OP(0xe0, GNU_push_tls_address, 0, GNU)
+// The GNU entry value extension.
+HANDLE_DW_OP(0xf3, GNU_entry_value, 0, GNU)
 // Extensions for Fission proposal.
 HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU)
 HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU)

Modified: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfoMetadata.h?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h (original)
+++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h Thu Jun 27 06:52:34 2019
@@ -2482,11 +2482,12 @@ public:
     ApplyOffset = 0,
     DerefBefore = 1 << 0,
     DerefAfter = 1 << 1,
-    StackValue = 1 << 2
+    StackValue = 1 << 2,
+    EntryValue = 1 << 3
   };
 
   /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
-  /// into a stack value.
+  /// into a stack value or/and an entry value.
   static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
                                int64_t Offset = 0);
 
@@ -2494,7 +2495,8 @@ public:
   /// stack value.
   static DIExpression *prependOpcodes(const DIExpression *Expr,
                                       SmallVectorImpl<uint64_t> &Ops,
-                                      bool StackValue = false);
+                                      bool StackValue = false,
+                                      bool EntryValue = false);
 
   /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
   /// returned expression is a stack value only if \p DIExpr is a stack value.
@@ -2558,6 +2560,13 @@ public:
       return true;
     return fragmentCmp(Other) == 0;
   }
+
+  /// Check if the expression consists of exactly one entry value operand.
+  /// (This is the only configuration of entry values that is supported.)
+  bool isEntryValue() const {
+    return getNumElements() > 0 &&
+           getElement(0) == dwarf::DW_OP_entry_value;
+  }
 };
 
 inline bool operator==(const DIExpression::FragmentInfo &A,

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp Thu Jun 27 06:52:34 2019
@@ -41,6 +41,10 @@ using EntryIndex = DbgValueHistoryMap::E
 static Register isDescribedByReg(const MachineInstr &MI) {
   assert(MI.isDebugValue());
   assert(MI.getNumOperands() == 4);
+  // If the location of variable is an entry value (DW_OP_entry_value)
+  // do not consider it as a register location.
+  if (MI.getDebugExpression()->isEntryValue())
+    return 0;
   // If location of variable is described using a register (directly or
   // indirectly), this register is always a first operand.
   return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : Register();

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h Thu Jun 27 06:52:34 2019
@@ -66,6 +66,7 @@ public:
   const ConstantInt *getConstantInt() const { return Constant.CIP; }
   MachineLocation getLoc() const { return Loc; }
   bool isFragment() const { return getExpression()->isFragment(); }
+  bool isEntryVal() const { return getExpression()->isEntryValue(); }
   const DIExpression *getExpression() const { return Expression; }
   friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
   friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Jun 27 06:52:34 2019
@@ -1999,9 +1999,9 @@ void DwarfDebug::emitDebugLocEntry(ByteS
   }
 }
 
-static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
-                              const DbgValueLoc &Value,
-                              DwarfExpression &DwarfExpr) {
+void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
+                                   const DbgValueLoc &Value,
+                                   DwarfExpression &DwarfExpr) {
   auto *DIExpr = Value.getExpression();
   DIExpressionCursor ExprCursor(DIExpr);
   DwarfExpr.addFragmentOffset(DIExpr);
@@ -2017,6 +2017,12 @@ static void emitDebugLocValue(const AsmP
     if (Location.isIndirect())
       DwarfExpr.setMemoryLocationKind();
     DIExpressionCursor Cursor(DIExpr);
+
+    if (DIExpr->isEntryValue()) {
+      DwarfExpr.setEntryValueFlag();
+      DwarfExpr.addEntryValueExpression(Cursor);
+    }
+
     const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
     if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
       return;
@@ -2048,11 +2054,11 @@ void DebugLocEntry::finalize(const AsmPr
            "fragments are expected to be sorted");
 
     for (auto Fragment : Values)
-      emitDebugLocValue(AP, BT, Fragment, DwarfExpr);
+      DwarfDebug::emitDebugLocValue(AP, BT, Fragment, DwarfExpr);
 
   } else {
     assert(Values.size() == 1 && "only fragments may have >1 value");
-    emitDebugLocValue(AP, BT, Value, DwarfExpr);
+    DwarfDebug::emitDebugLocValue(AP, BT, Value, DwarfExpr);
   }
   DwarfExpr.finalize();
 }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu Jun 27 06:52:34 2019
@@ -52,6 +52,7 @@ class ByteStreamer;
 class DebugLocEntry;
 class DIE;
 class DwarfCompileUnit;
+class DwarfExpression;
 class DwarfTypeUnit;
 class DwarfUnit;
 class LexicalScope;
@@ -735,6 +736,10 @@ public:
 
   void addSectionLabel(const MCSymbol *Sym);
   const MCSymbol *getSectionLabel(const MCSection *S);
+
+  static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
+                                const DbgValueLoc &Value,
+                                DwarfExpression &DwarfExpr);
 };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp Thu Jun 27 06:52:34 2019
@@ -248,6 +248,10 @@ bool DwarfExpression::addMachineRegExpre
         addReg(Reg.DwarfRegNo, Reg.Comment);
       addOpPiece(Reg.Size);
     }
+
+    if (isEntryValue() && DwarfVersion >= 4)
+      emitOp(dwarf::DW_OP_stack_value);
+
     DwarfRegs.clear();
     return true;
   }
@@ -296,6 +300,19 @@ bool DwarfExpression::addMachineRegExpre
   return true;
 }
 
+void DwarfExpression::addEntryValueExpression(DIExpressionCursor &ExprCursor) {
+  auto Op = ExprCursor.take();
+  assert(Op && Op->getOp() == dwarf::DW_OP_entry_value);
+  assert(!isMemoryLocation() &&
+         "We don't support entry values of memory locations yet");
+
+  if (DwarfVersion >= 5)
+    emitOp(dwarf::DW_OP_entry_value);
+  else
+    emitOp(dwarf::DW_OP_GNU_entry_value);
+  emitUnsigned(Op->getArg(0));
+}
+
 /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
 static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
   while (ExprCursor) {

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h Thu Jun 27 06:52:34 2019
@@ -119,6 +119,9 @@ protected:
   /// The kind of location description being produced.
   enum { Unknown = 0, Register, Memory, Implicit };
 
+  /// The flags of location description being produced.
+  enum { EntryValue = 1 };
+
   unsigned LocationKind : 3;
   unsigned LocationFlags : 2;
   unsigned DwarfVersion : 4;
@@ -140,6 +143,10 @@ public:
     return LocationKind == Implicit;
   }
 
+  bool isEntryValue() const {
+    return LocationFlags & EntryValue;
+  }
+
   Optional<uint8_t> TagOffset;
 
 protected:
@@ -252,6 +259,11 @@ public:
     LocationKind = Memory;
   }
 
+  /// Lock this down to become an entry value location.
+  void setEntryValueFlag() {
+    LocationFlags |= EntryValue;
+  }
+
   /// Emit a machine register location. As an optimization this may also consume
   /// the prefix of a DwarfExpression if a more efficient representation for
   /// combining the register location and the first operation exists.
@@ -266,6 +278,9 @@ public:
                                DIExpressionCursor &Expr, unsigned MachineReg,
                                unsigned FragmentOffsetInBits = 0);
 
+  /// Emit entry value dwarf operation.
+  void addEntryValueExpression(DIExpressionCursor &ExprCursor);
+
   /// Emit all remaining operations in the DIExpressionCursor.
   ///
   /// \param FragmentOffsetInBits     If this is one fragment out of multiple

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp Thu Jun 27 06:52:34 2019
@@ -97,8 +97,10 @@ static DescVector getDescriptions() {
   Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB);
   Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
   Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
+  Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB);
 
   Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef);
+  Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB);
 
   return Descriptions;
 }
@@ -275,7 +277,8 @@ bool DWARFExpression::Operation::print(r
     } else {
       if (Signed)
         OS << format(" %+" PRId64, (int64_t)Operands[Operand]);
-      else
+      else if (Opcode != DW_OP_entry_value &&
+               Opcode != DW_OP_GNU_entry_value)
         OS << format(" 0x%" PRIx64, Operands[Operand]);
     }
   }
@@ -284,6 +287,7 @@ bool DWARFExpression::Operation::print(r
 
 void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
                             DWARFUnit *U, bool IsEH) const {
+  uint32_t EntryValExprSize = 0;
   for (auto &Op : *this) {
     if (!Op.print(OS, this, RegInfo, U, IsEH)) {
       uint32_t FailOffset = Op.getEndOffset();
@@ -291,6 +295,20 @@ void DWARFExpression::print(raw_ostream
         OS << format(" %02x", Data.getU8(&FailOffset));
       return;
     }
+
+    if (Op.getCode() == DW_OP_entry_value ||
+        Op.getCode() == DW_OP_GNU_entry_value) {
+      OS << "(";
+      EntryValExprSize = Op.getRawOperand(0);
+      continue;
+    }
+
+    if (EntryValExprSize) {
+      EntryValExprSize--;
+      if (EntryValExprSize == 0)
+        OS << ")";
+    }
+
     if (Op.getEndOffset() < Data.getData().size())
       OS << ", ";
   }

Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=364542&r1=364541&r2=364542&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Thu Jun 27 06:52:34 2019
@@ -836,6 +836,7 @@ unsigned DIExpression::ExprOperand::getS
   case dwarf::DW_OP_deref_size:
   case dwarf::DW_OP_plus_uconst:
   case dwarf::DW_OP_LLVM_tag_offset:
+  case dwarf::DW_OP_entry_value:
     return 2;
   default:
     return 1;
@@ -876,6 +877,13 @@ bool DIExpression::isValid() const {
         return false;
       break;
     }
+    case dwarf::DW_OP_entry_value: {
+      // An entry value operator must appear at the begin and the size
+      // of following expression should be 1, because we support only
+      // entry values of a simple register location.
+      return I->get() == expr_op_begin()->get() && I->getArg(0) == 1 &&
+             getNumElements() == 2;
+    }
     case dwarf::DW_OP_LLVM_convert:
     case dwarf::DW_OP_LLVM_tag_offset:
     case dwarf::DW_OP_constu:
@@ -994,15 +1002,24 @@ DIExpression *DIExpression::prepend(cons
     Ops.push_back(dwarf::DW_OP_deref);
 
   bool StackValue = Flags & DIExpression::StackValue;
+  bool EntryValue = Flags & DIExpression::EntryValue;
 
-  return prependOpcodes(Expr, Ops, StackValue);
+  return prependOpcodes(Expr, Ops, StackValue, EntryValue);
 }
 
 DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
                                            SmallVectorImpl<uint64_t> &Ops,
-                                           bool StackValue) {
+                                           bool StackValue,
+                                           bool EntryValue) {
   assert(Expr && "Can't prepend ops to this expression");
 
+  if (EntryValue) {
+    Ops.push_back(dwarf::DW_OP_entry_value);
+    // Add size info needed for entry value expression.
+    // Add plus one for target register operand.
+    Ops.push_back(Expr->getNumElements() + 1);
+  }
+
   // If there are no ops to prepend, do not even add the DW_OP_stack_value.
   if (Ops.empty())
     StackValue = false;

Added: llvm/trunk/test/Verifier/diexpression-entry-value.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/diexpression-entry-value.ll?rev=364542&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/diexpression-entry-value.ll (added)
+++ llvm/trunk/test/Verifier/diexpression-entry-value.ll Thu Jun 27 06:52:34 2019
@@ -0,0 +1,7 @@
+; RUN: not opt -S < %s 2>&1 | FileCheck %s
+
+!named = !{!0, !1, !2}
+; CHECK: invalid expression
+!0 = !DIExpression(DW_OP_entry_value, 4, DW_OP_constu, 0, DW_OP_stack_value)
+!1 = !DIExpression(DW_OP_constu, 0, DW_OP_entry_value, 1, DW_OP_constu, 0)
+!2 = !DIExpression(DW_OP_entry_value, 100, DW_OP_constu, 0)

Added: llvm/trunk/test/Verifier/diexpression-valid-entry-value.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/diexpression-valid-entry-value.ll?rev=364542&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/diexpression-valid-entry-value.ll (added)
+++ llvm/trunk/test/Verifier/diexpression-valid-entry-value.ll Thu Jun 27 06:52:34 2019
@@ -0,0 +1,5 @@
+; RUN: opt -S < %s 2>&1 | FileCheck %s
+
+!named = !{!0}
+; CHECK-NOT: invalid expression
+!0 = !DIExpression(DW_OP_entry_value, 1)

Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_GNU_entry_value.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_GNU_entry_value.s?rev=364542&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_GNU_entry_value.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_GNU_entry_value.s Thu Jun 27 06:52:34 2019
@@ -0,0 +1,59 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | llvm-dwarfdump - | FileCheck %s
+#
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name ("a")
+# CHECK-NEXT: DW_AT_location
+# CHECK-NEXT: DW_OP_GNU_entry_value(DW_OP_reg5 RDI), DW_OP_stack_value)
+
+	.section	.debug_str,"MS", at progbits,1
+.Linfo_producer:
+	.asciz	"hand-written DWARF"
+.Lname_a:
+	.asciz	"a"
+
+	.section	.debug_loc,"", at progbits
+.Ldebug_loc0:
+	.quad	0
+	.quad	1
+	.short	.Lloc0_end-.Lloc0_start # Loc expr size
+.Lloc0_start:
+	.byte	243                     # DW_OP_GNU_entry_value
+	.byte	1                       # 1
+	.byte	85                      # super-register DW_OP_reg5
+	.byte	159                     # DW_OP_stack_value
+.Lloc0_end:
+	.quad	0
+	.quad	0
+	.section	.debug_abbrev,"", at progbits
+	.byte	1                       # Abbreviation Code
+	.byte	17                      # DW_TAG_compile_unit
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	37                      # DW_AT_producer
+	.byte	14                      # DW_FORM_strp
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	5                       # Abbreviation Code
+	.byte	52                      # DW_TAG_variable
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	2                       # DW_AT_location
+	.byte	23                      # DW_FORM_sec_offset
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	0                       # EOM(3)
+
+	.section	.debug_info,"", at progbits
+.Lcu_begin0:
+	.long	.Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+	.short	4                       # DWARF version number
+	.long	.debug_abbrev           # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] DW_TAG_compile_unit
+	.long	.Linfo_producer         # DW_AT_producer
+	.byte	5                       # Abbrev [5] DW_TAG_variable
+	.long	.Lname_a                # DW_AT_name
+	.long	.Ldebug_loc0            # DW_AT_location
+	.byte	0                       # End Of Children Mark
+.Lcu_end0:

Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_entry_value.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_entry_value.s?rev=364542&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_entry_value.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_loc_OP_entry_value.s Thu Jun 27 06:52:34 2019
@@ -0,0 +1,59 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | llvm-dwarfdump - | FileCheck %s
+#
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name ("a")
+# CHECK-NEXT: DW_AT_location
+# CHECK-NEXT: DW_OP_entry_value(DW_OP_reg5 RDI), DW_OP_stack_value)
+
+	.section	.debug_str,"MS", at progbits,1
+.Linfo_producer:
+	.asciz	"hand-written DWARF"
+.Lname_a:
+	.asciz	"a"
+
+	.section	.debug_loc,"", at progbits
+.Ldebug_loc0:
+	.quad	0
+	.quad	1
+	.short	.Lloc0_end-.Lloc0_start # Loc expr size
+.Lloc0_start:
+	.byte   163                     # DW_OP_entry_value
+	.byte	1                       # 1
+	.byte	85                      # super-register DW_OP_reg5
+	.byte	159                     # DW_OP_stack_value
+.Lloc0_end:
+	.quad	0
+	.quad	0
+	.section	.debug_abbrev,"", at progbits
+	.byte	1                       # Abbreviation Code
+	.byte	17                      # DW_TAG_compile_unit
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	37                      # DW_AT_producer
+	.byte	14                      # DW_FORM_strp
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	5                       # Abbreviation Code
+	.byte	52                      # DW_TAG_variable
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	2                       # DW_AT_location
+	.byte	23                      # DW_FORM_sec_offset
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	0                       # EOM(3)
+
+	.section	.debug_info,"", at progbits
+.Lcu_begin0:
+	.long	.Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+	.short	4                       # DWARF version number
+	.long	.debug_abbrev           # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] DW_TAG_compile_unit
+	.long	.Linfo_producer         # DW_AT_producer
+	.byte	5                       # Abbrev [5] DW_TAG_variable
+	.long	.Lname_a                # DW_AT_name
+	.long	.Ldebug_loc0            # DW_AT_location
+	.byte	0                       # End Of Children Mark
+.Lcu_end0:




More information about the llvm-commits mailing list