[Lldb-commits] [lldb] r345958 - [LLDB] - Add support for DW_FORM_rnglistx and relative DW_RLE_* entries.

George Rimar via lldb-commits lldb-commits at lists.llvm.org
Fri Nov 2 02:03:25 PDT 2018


Author: grimar
Date: Fri Nov  2 02:03:25 2018
New Revision: 345958

URL: http://llvm.org/viewvc/llvm-project?rev=345958&view=rev
Log:
[LLDB] - Add support for DW_FORM_rnglistx and relative DW_RLE_* entries.

This adds support for DW_RLE_base_addressx, DW_RLE_startx_endx,
DW_RLE_startx_length, DW_FORM_rnglistx.

Differential revision: https://reviews.llvm.org/D53929

Added:
    lldb/trunk/lit/Breakpoint/Inputs/debug_rnglistx_rlex.yaml
    lldb/trunk/lit/Breakpoint/debug_rnglistx_rlex.test
Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp

Added: lldb/trunk/lit/Breakpoint/Inputs/debug_rnglistx_rlex.yaml
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Breakpoint/Inputs/debug_rnglistx_rlex.yaml?rev=345958&view=auto
==============================================================================
--- lldb/trunk/lit/Breakpoint/Inputs/debug_rnglistx_rlex.yaml (added)
+++ lldb/trunk/lit/Breakpoint/Inputs/debug_rnglistx_rlex.yaml Fri Nov  2 02:03:25 2018
@@ -0,0 +1,57 @@
+--- !ELF
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x0000000000201000
+Sections:        
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x0000000000201000
+    AddressAlign:    0x0000000000000010
+    Content:         31ED4989D15E4889E24883E4F0505449C7C08011200048C7C11011200048C7C700112000E897010000F4CCCCCCCCCCCC55B810202000483D102020004889E57417B8000000004885C0740D5DBF10202000FFE00F1F4400005DC3660F1F440000BE10202000554881EE102020004889E548C1FE034889F048C1E83F4801C648D1FE7415B8000000004885C0740B5DBF10202000FFE00F1F005DC3660F1F440000803D592F0000007517554889E5E87EFFFFFFC605472F0000015DC30F1F440000F3C30F1F4000662E0F1F840000000000554889E55DEB89CCCCCCCCCCCCCCCCCCC3CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC31C0C3CCCCCCCCCCCCCCCCCCCCCCCCCC415741564189FF415541544C8D25E61E000055488D2DE61E0000534989F64989D54C29E54883EC0848C1FD03E8430000004885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3
+  - Name:            .debug_str_offsets
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         28000000050000003000000067000000000000002800000076000000240000006F0000007400000022000000
+  - Name:            .debug_str
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x0000000000000001
+    Content:         2F686F6D652F756D622F74657374735F323031382F3131345F726E676C69737473007900696E74005F5A336261726900636C616E672076657273696F6E20382E302E3020287472756E6B203334353639392920286C6C766D2F7472756E6B203334353530362900746573742E6363006D61696E00780062617200
+  - Name:            .debug_loclists
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         '15000000050008000000000003000301005503020101005000'
+  - Name:            .debug_abbrev
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         011101252513050325721710171B2573171101552374178C01170000022E01111B120640187A196E2503253A0B3B0B49133F190000030500021703253A0B3B0B49130000042E01111B120640187A1903253A0B3B0B49133F1900000534001C0D03253A0B3B0B4913000006240003253E0B0B0B000000
+  - Name:            .debug_info
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         6600000005000108000000000100040001080000000000000002080000000000000000000000000C0000000C00000002000400000001570304010365000000030C0000000701036500000000040106000000015706010765000000050108010865000000000605050400
+  - Name:            .debug_rnglists
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         '1300000005000800010000000400000003000403010600'
+  - Name:            .debug_macinfo
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         '00'
+  - Name:            .debug_addr
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         1C00000005000800E010200000000000F010200000000000E310200000000000
+  - Name:            .debug_line
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         82000000050008004C000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E022200000000FC42F1EAF1396417A8FBE442FBADC7032200000000FC42F1EAF1396417A8FBE442FBADC703000902E01020000000000014050B0A130504063C0201000101000902F0102000000000001805030A140206000101
+  - Name:            .debug_line_str
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x0000000000000001
+    Content:         2F686F6D652F756D622F74657374735F323031382F3131345F726E676C6973747300746573742E636300
+Symbols:

Added: lldb/trunk/lit/Breakpoint/debug_rnglistx_rlex.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Breakpoint/debug_rnglistx_rlex.test?rev=345958&view=auto
==============================================================================
--- lldb/trunk/lit/Breakpoint/debug_rnglistx_rlex.test (added)
+++ lldb/trunk/lit/Breakpoint/debug_rnglistx_rlex.test Fri Nov  2 02:03:25 2018
@@ -0,0 +1,28 @@
+# RUN: yaml2obj %p/Inputs/debug_rnglistx_rlex.yaml > %ttest
+# RUN: lldb-test breakpoints %ttest %s | FileCheck %s
+
+# The following code and invocation were used.
+# clang -gdwarf-5 test.cc -o test_v5 -fuse-ld=lld -fno-rtti -O2 -ffunction-sections
+# Then output was converted to yaml and reduced.
+#
+# int bar(int x) {
+#    return ++x;
+# }
+# 
+# int main() {
+#   int y = 1;
+#   return bar(y);
+# }
+#
+# clang and LLD versions were 8.0.0 (trunk 345699)
+#
+# Output file contains DW_FORM_rnglistx and DW_RLE_startx_length.
+
+b bar
+b main
+
+# CHECK-LABEL: b bar
+# CHECK: Address: {{.*}}`bar(int) at test.cc:4:11
+
+# CHECK-LABEL: b main
+# CHECK: Address: {{.*}}`main at test.cc:9:3

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp?rev=345958&r1=345957&r2=345958&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp Fri Nov  2 02:03:25 2018
@@ -157,6 +157,7 @@ bool DWARFDebugInfoEntry::FastExtract(
 
           // signed or unsigned LEB 128 values
           case DW_FORM_addrx:
+          case DW_FORM_rnglistx:
           case DW_FORM_sdata:
           case DW_FORM_udata:
           case DW_FORM_ref_udata:
@@ -387,6 +388,13 @@ void DWARFDebugInfoEntry::DumpAncestry(S
   Dump(dwarf2Data, cu, s, recurse_depth);
 }
 
+static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges,
+                                   DWARFFormValue &form_value) {
+  if (form_value.Form() == DW_FORM_rnglistx)
+    return debug_ranges->GetOffset(form_value.Unsigned());
+  return form_value.Unsigned();
+}
+
 //----------------------------------------------------------------------
 // GetDIENamesAndRanges
 //
@@ -464,7 +472,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAnd
         case DW_AT_ranges: {
           const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
           if (debug_ranges)
-            debug_ranges->FindRanges(cu, form_value.Unsigned(), ranges);
+            debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges);
           else
             cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
                 "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
@@ -748,11 +756,13 @@ void DWARFDebugInfoEntry::DumpAttribute(
   } break;
 
   case DW_AT_ranges: {
-    lldb::offset_t ranges_offset = form_value.Unsigned();
+    if (!dwarf2Data)
+      break;
+    lldb::offset_t ranges_offset =
+        GetRangesOffset(dwarf2Data->DebugRanges(), form_value);
     dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
-    if (dwarf2Data)
-      DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
-                             &ranges_offset, base_addr);
+    DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
+                           &ranges_offset, base_addr);
   } break;
 
   default:
@@ -1062,12 +1072,11 @@ size_t DWARFDebugInfoEntry::GetAttribute
     bool check_specification_or_abstract_origin) const {
   ranges.Clear();
 
-  dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
-      dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET,
-      check_specification_or_abstract_origin);
-  if (debug_ranges_offset != DW_INVALID_OFFSET) {
+  DWARFFormValue form_value;
+  if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
     if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges())
-      debug_ranges->FindRanges(cu, debug_ranges_offset, ranges);
+      debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value),
+                               ranges);
   } else if (check_hi_lo_pc) {
     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
@@ -1718,12 +1727,12 @@ bool DWARFDebugInfoEntry::LookupAddress(
                            ((function_die != NULL) || (block_die != NULL));
         }
       } else {
-        dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
-            dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
-        if (debug_ranges_offset != DW_INVALID_OFFSET) {
+        DWARFFormValue form_value;
+        if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
           DWARFRangeList ranges;
           DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
-          debug_ranges->FindRanges(cu, debug_ranges_offset, ranges);
+          debug_ranges->FindRanges(
+              cu, GetRangesOffset(debug_ranges, form_value), ranges);
 
           if (ranges.FindEntryThatContains(address)) {
             found_address = true;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp?rev=345958&r1=345957&r2=345958&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp Fri Nov  2 02:03:25 2018
@@ -128,6 +128,11 @@ bool DWARFDebugRanges::FindRanges(const
   return false;
 }
 
+uint64_t DWARFDebugRanges::GetOffset(size_t Index) const {
+  lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5");
+  return 0;
+}
+
 bool DWARFDebugRngLists::ExtractRangeList(
     const DWARFDataExtractor &data, uint8_t addrSize,
     lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
@@ -166,9 +171,27 @@ bool DWARFDebugRngLists::ExtractRangeLis
       break;
     }
 
+    case DW_RLE_base_addressx: {
+      dw_addr_t base = data.GetULEB128(offset_ptr);
+      rangeList.push_back({DW_RLE_base_addressx, base, 0});
+      break;
+    }
+
+    case DW_RLE_startx_endx: {
+      dw_addr_t start = data.GetULEB128(offset_ptr);
+      dw_addr_t end = data.GetULEB128(offset_ptr);
+      rangeList.push_back({DW_RLE_startx_endx, start, end});
+      break;
+    }
+
+    case DW_RLE_startx_length: {
+      dw_addr_t start = data.GetULEB128(offset_ptr);
+      dw_addr_t length = data.GetULEB128(offset_ptr);
+      rangeList.push_back({DW_RLE_startx_length, start, length});
+      break;
+    }
+
     default:
-      // Next encodings are not yet supported:
-      // DW_RLE_base_addressx, DW_RLE_startx_endx, DW_RLE_startx_length.
       lldbassert(0 && "unknown range list entry encoding");
       error = true;
     }
@@ -177,6 +200,15 @@ bool DWARFDebugRngLists::ExtractRangeLis
   return false;
 }
 
+static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu,
+                                                uint32_t index) {
+  uint32_t index_size = cu->GetAddressByteSize();
+  dw_offset_t addr_base = cu->GetAddrBase();
+  lldb::offset_t offset = addr_base + index * index_size;
+  return cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset,
+                                                                   index_size);
+}
+
 bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
                                     dw_offset_t debug_ranges_offset,
                                     DWARFRangeList &range_list) const {
@@ -200,6 +232,21 @@ bool DWARFDebugRngLists::FindRanges(cons
         range_list.Append(
             DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0));
         break;
+      case DW_RLE_base_addressx: {
+        BaseAddr = ReadAddressFromDebugAddrSection(cu, E.value0);
+        break;
+      }
+      case DW_RLE_startx_endx: {
+        dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
+        dw_addr_t end = ReadAddressFromDebugAddrSection(cu, E.value1);
+        range_list.Append(DWARFRangeList::Entry(start, end - start));
+        break;
+      }
+      case DW_RLE_startx_length: {
+        dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
+        range_list.Append(DWARFRangeList::Entry(start, E.value1));
+        break;
+      }
       default:
         llvm_unreachable("unexpected encoding");
       }
@@ -214,7 +261,8 @@ void DWARFDebugRngLists::Extract(SymbolF
   lldb::offset_t offset = 0;
 
   uint64_t length = data.GetU32(&offset);
-  if (length == 0xffffffff)
+  bool isDwarf64 = (length == 0xffffffff);
+  if (isDwarf64)
     length = data.GetU64(&offset);
   lldb::offset_t end = offset + length;
 
@@ -232,7 +280,7 @@ void DWARFDebugRngLists::Extract(SymbolF
 
   uint32_t offsetsAmount = data.GetU32(&offset);
   for (uint32_t i = 0; i < offsetsAmount; ++i)
-    Offsets.push_back(data.GetPointer(&offset));
+    Offsets.push_back(data.GetMaxU64(&offset, isDwarf64 ? 8 : 4));
 
   lldb::offset_t listOffset = offset;
   std::vector<RngListEntry> rangeList;
@@ -241,3 +289,7 @@ void DWARFDebugRngLists::Extract(SymbolF
     listOffset = offset;
   }
 }
+
+uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const {
+  return Offsets[Index];
+}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h?rev=345958&r1=345957&r2=345958&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h Fri Nov  2 02:03:25 2018
@@ -22,15 +22,17 @@ public:
   virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0;
   virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
                           DWARFRangeList &range_list) const = 0;
+  virtual uint64_t GetOffset(size_t Index) const = 0;
 };
 
 class DWARFDebugRanges final : public DWARFDebugRangesBase {
 public:
   DWARFDebugRanges();
 
-  virtual void Extract(SymbolFileDWARF *dwarf2Data) override;
-  virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
-                          DWARFRangeList &range_list) const override;
+  void Extract(SymbolFileDWARF *dwarf2Data) override;
+  bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
+                  DWARFRangeList &range_list) const override;
+  uint64_t GetOffset(size_t Index) const override;
 
   static void Dump(lldb_private::Stream &s,
                    const lldb_private::DWARFDataExtractor &debug_ranges_data,
@@ -58,6 +60,7 @@ public:
   void Extract(SymbolFileDWARF *dwarf2Data) override;
   bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
                   DWARFRangeList &range_list) const override;
+  uint64_t GetOffset(size_t Index) const override;
 
 protected:
   bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp?rev=345958&r1=345957&r2=345958&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp Fri Nov  2 02:03:25 2018
@@ -248,6 +248,7 @@ bool DWARFFormValue::ExtractValue(const
       m_value.value.uval = data.GetU64(offset_ptr);
       break;
     case DW_FORM_addrx:
+    case DW_FORM_rnglistx:
     case DW_FORM_strx:
     case DW_FORM_udata:
     case DW_FORM_ref_udata:
@@ -393,6 +394,7 @@ bool DWARFFormValue::SkipValue(dw_form_t
 
     // signed or unsigned LEB 128 values
     case DW_FORM_addrx:
+    case DW_FORM_rnglistx:
     case DW_FORM_sdata:
     case DW_FORM_udata:
     case DW_FORM_ref_udata:
@@ -777,6 +779,7 @@ bool DWARFFormValue::FormIsSupported(dw_
   switch (form) {
     case DW_FORM_addr:
     case DW_FORM_addrx:
+    case DW_FORM_rnglistx:
     case DW_FORM_block2:
     case DW_FORM_block4:
     case DW_FORM_data2:

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp?rev=345958&r1=345957&r2=345958&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp Fri Nov  2 02:03:25 2018
@@ -309,6 +309,8 @@ void DWARFUnit::ExtractDIEsEndCheck(lldb
 void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
   SetAddrBase(
       cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_addr_base, 0));
+  SetRangesBase(cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
+                                                   DW_AT_rnglists_base, 0));
 
   uint64_t base_addr = cu_die.GetAttributeValueAsAddress(
       m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);




More information about the lldb-commits mailing list