[lldb] Fix DW_OP_addrx uses.
authorAli Tamur <tamur@google.com>
Thu, 7 Mar 2019 19:41:08 +0000 (19:41 +0000)
committerAli Tamur <tamur@google.com>
Thu, 7 Mar 2019 19:41:08 +0000 (19:41 +0000)
Summary: DW_OP_GNU_addr_index has been renamed as DW_OP_addrx in the standard. clang produces DW_OP_addrx tags and with this change lldb starts to process them.

Reviewers: aprantl, jingham, davide, clayborg, serge-sans-paille

Reviewed By: aprantl

Subscribers: jdoerfert, dblaikie, labath, shafik, lldb-commits

Tags: #lldb

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

llvm-svn: 355629

lldb/lit/SymbolFile/DWARF/dwarf5_locations.s [new file with mode: 0644]
lldb/source/Expression/DWARFExpression.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp

diff --git a/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s b/lldb/lit/SymbolFile/DWARF/dwarf5_locations.s
new file mode 100644 (file)
index 0000000..7ca9e72
--- /dev/null
@@ -0,0 +1,66 @@
+# This tests that lldb is able to process DW_OP_addrx tags introduced in dwarf5.
+# REQUIRES: lld
+# RUN: llvm-mc -g -dwarf-version=5 -triple x86_64-unknown-linux-gnu %s -filetype=obj > %t.o
+# RUN: ld.lld -m elf_x86_64 %t.o -o %t 
+# RUN: lldb-test symbols %t | FileCheck %s
+
+# CHECK: Variable{0xffffffff00000011}, name = "color"
+# CHECK-SAME: location = DW_OP_addrx(0x0)
+
+        .text
+        .section        .debug_str,"MS",@progbits,1
+.Lstr_offsets_base0:
+        .asciz  "color"
+
+        .section        .debug_str_offsets,"",@progbits
+        .long   .Lstr_offsets_base0
+
+        .section        .debug_abbrev,"",@progbits
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   114                     # DW_AT_str_offsets_base
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   52                      # DW_TAG_variable
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   37                      # DW_FORM_strx1
+        .byte   63                      # DW_AT_external
+        .byte   25                      # DW_FORM_flag_present
+        .byte   2                       # DW_AT_location
+        .byte   24                      # DW_FORM_exprloc
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+        .byte   0                       # EOM(4)
+
+        .section        .debug_info,"",@progbits
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  5                       # DWARF version number
+        .byte   1                       # DWARF Unit Type
+        .byte   8                       # Address Size (in bytes)
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   1                       # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit
+        .long   .Lstr_offsets_base0     # DW_AT_str_offsets_base
+        .byte   2                       # Abbrev [2] 0x1e:0xb DW_TAG_variable
+        .byte   0                       # DW_AT_name
+                                        # DW_AT_external
+        .byte   2                       # DW_AT_location
+        .byte   161
+        .byte   0
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:
+
+        .section        .debug_addr,"",@progbits
+        .long   .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+        .short  5                       # DWARF version number
+        .byte   8                       # Address size
+        .byte   0                       # Segment selector size
+        .quad   color
+.Ldebug_addr_end0:
+
index 679b779..2596a7b 100644 (file)
@@ -514,6 +514,10 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset,
       s->Printf("DW_OP_GNU_addr_index(0x%" PRIx64 ")",
                 m_data.GetULEB128(&offset));
       break;
+    case DW_OP_addrx:
+      s->Printf("DW_OP_addrx(0x%" PRIx64 ")",
+                m_data.GetULEB128(&offset));
+      break;
     case DW_OP_GNU_const_index: // 0xfc
       s->Printf("DW_OP_GNU_const_index(0x%" PRIx64 ")",
                 m_data.GetULEB128(&offset));
@@ -877,6 +881,7 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data,
     return 8;
 
   // All opcodes that have a single ULEB (signed or unsigned) argument
+  case DW_OP_addrx:           // 0xa1 1 ULEB128 index
   case DW_OP_constu:          // 0x10 1 ULEB128 constant
   case DW_OP_consts:          // 0x11 1 SLEB128 constant
   case DW_OP_plus_uconst:     // 0x23 1 ULEB128 addend
@@ -957,7 +962,7 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx,
         return op_file_addr;
       else
         ++curr_op_addr_idx;
-    } else if (op == DW_OP_GNU_addr_index) {
+    } else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {
       uint64_t index = m_data.GetULEB128(&offset);
       if (curr_op_addr_idx == op_addr_idx) {
         if (!m_dwarf_cu) {
@@ -2902,13 +2907,14 @@ bool DWARFExpression::Evaluate(
     } break;
 
     //----------------------------------------------------------------------
-    // OPCODE: DW_OP_GNU_addr_index
+    // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.)
     // OPERANDS: 1
     //      ULEB128: index to the .debug_addr section
     // DESCRIPTION: Pushes an address to the stack from the .debug_addr
     // section with the base address specified by the DW_AT_addr_base attribute
     // and the 0 based index is the ULEB128 encoded index.
     //----------------------------------------------------------------------
+    case DW_OP_addrx:
     case DW_OP_GNU_addr_index: {
       if (!dwarf_cu) {
         if (error_ptr)
@@ -3194,6 +3200,7 @@ static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data,
   case DW_OP_call_ref:
     size = dwarf_ref_size;
     break;
+  case DW_OP_addrx:
   case DW_OP_piece:
   case DW_OP_plus_uconst:
   case DW_OP_regx:
index 22e62c4..554f091 100644 (file)
@@ -326,6 +326,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
                 break;
 
               // signed or unsigned LEB 128 values
+              case DW_FORM_addrx:
               case DW_FORM_sdata:
               case DW_FORM_udata:
               case DW_FORM_ref_udata:
@@ -456,6 +457,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
 
         case DW_AT_high_pc:
           if (form_value.Form() == DW_FORM_addr ||
+              form_value.Form() == DW_FORM_addrx ||
               form_value.Form() == DW_FORM_GNU_addr_index) {
             hi_pc = form_value.Address();
           } else {
@@ -1031,7 +1033,8 @@ dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
   if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
                         check_specification_or_abstract_origin)) {
     dw_form_t form = form_value.Form();
-    if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
+    if (form == DW_FORM_addr || form == DW_FORM_addrx ||
+        form == DW_FORM_GNU_addr_index)
       return form_value.Address();
 
     // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
index bc0acfb..3fba8cc 100644 (file)
@@ -681,6 +681,7 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
     return 1;
   switch (a_form) {
   case DW_FORM_addr:
+  case DW_FORM_addrx:
   case DW_FORM_flag:
   case DW_FORM_data1:
   case DW_FORM_data2:
index 36e3d7d..ab43056 100644 (file)
@@ -166,6 +166,7 @@ void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) {
   case DW_FORM_ref_sig8:
     llvm_unreachable("Unhandled atom form");
 
+  case DW_FORM_addrx:
   case DW_FORM_string:
   case DW_FORM_block:
   case DW_FORM_block1: