[Lldb-commits] [lldb] [lldb/DWARF] s/DWARFRangeList/llvm::DWARFAddressRangeVector (PR #116620)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 4 04:26:18 PST 2024


https://github.com/labath updated https://github.com/llvm/llvm-project/pull/116620

>From 5cca8f301abde9333715e97d671afc23d75b9acd Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 18 Nov 2024 14:33:40 +0100
Subject: [PATCH] [lldb/DWARF] s/DWARFRangeList/llvm::DWARFAddressRangeVector

The main difference is that the llvm class (just a std::vector in
disguise) is not sorted. It turns out this isn't an issue because the
callers either:
- ignore the range list;
- convert it to a different format (which is then sorted);
- or query the minimum value (which is faster than sorting)

The last case is something I want to get rid of in a followup as a part
of removing the assumption that function's entry point is also its
lowest address.
---
 lldb/include/lldb/Core/dwarf.h                |  3 -
 lldb/source/Plugins/SymbolFile/DWARF/DIERef.h |  3 +-
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  3 +-
 .../SymbolFile/DWARF/DWARFCompileUnit.cpp     | 19 ++--
 .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp     | 43 +++++----
 .../Plugins/SymbolFile/DWARF/DWARFDIE.h       | 11 ++-
 .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp  | 96 +++++++++----------
 .../SymbolFile/DWARF/DWARFDebugInfoEntry.h    | 20 ++--
 .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp    | 67 ++++++-------
 .../Plugins/SymbolFile/DWARF/DWARFUnit.h      |  7 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      | 81 +++++++++-------
 11 files changed, 185 insertions(+), 168 deletions(-)

diff --git a/lldb/include/lldb/Core/dwarf.h b/lldb/include/lldb/Core/dwarf.h
index e162a090ba7c97..4de5c8f24db02c 100644
--- a/lldb/include/lldb/Core/dwarf.h
+++ b/lldb/include/lldb/Core/dwarf.h
@@ -9,7 +9,6 @@
 #ifndef LLDB_CORE_DWARF_H
 #define LLDB_CORE_DWARF_H
 
-#include "lldb/Utility/RangeMap.h"
 #include <cstdint>
 
 // Get the DWARF constant definitions from llvm
@@ -40,6 +39,4 @@ typedef uint64_t dw_offset_t; // Dwarf Debug Information Entry offset for any
 
 #define DW_EH_PE_MASK_ENCODING 0x0F
 
-typedef lldb_private::RangeVector<dw_addr_t, dw_addr_t, 2> DWARFRangeList;
-
 #endif // LLDB_CORE_DWARF_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
index ad443aacb46ecc..69be0aa1280c16 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -10,7 +10,8 @@
 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
 
 #include "lldb/Core/dwarf.h"
-#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
 #include <cassert>
 #include <optional>
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index d9bdeb560e1220..05d994ae82d8d4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -45,6 +45,7 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 #include "llvm/Demangle/Demangle.h"
 
 #include <map>
@@ -2353,7 +2354,7 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
 
 Function *DWARFASTParserClang::ParseFunctionFromDWARF(
     CompileUnit &comp_unit, const DWARFDIE &die, AddressRanges func_ranges) {
-  DWARFRangeList unused_func_ranges;
+  llvm::DWARFAddressRangesVector unused_func_ranges;
   const char *name = nullptr;
   const char *mangled = nullptr;
   std::optional<int> decl_file;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index ec4c297cf7e164..7f2edbfa95feef 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -8,11 +8,13 @@
 
 #include "DWARFCompileUnit.h"
 #include "DWARFDebugAranges.h"
+#include "LogChannelDWARF.h"
 #include "SymbolFileDWARFDebugMap.h"
 
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Utility/Stream.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -41,14 +43,17 @@ void DWARFCompileUnit::BuildAddressRangeTable(
 
   const dw_offset_t cu_offset = GetOffset();
   if (die) {
-    DWARFRangeList ranges =
+    llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
         die->GetAttributeAddressRanges(this, /*check_hi_lo_pc=*/true);
-    for (const DWARFRangeList::Entry &range : ranges)
-      debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
-                                 range.GetRangeEnd());
-
-    if (!ranges.IsEmpty())
-      return;
+    if (ranges) {
+      for (const llvm::DWARFAddressRange &range : *ranges)
+        debug_aranges->AppendRange(cu_offset, range.LowPC, range.HighPC);
+      if (!ranges->empty())
+        return;
+    } else {
+      LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
+                     "{1:x}: {0}", cu_offset);
+    }
   }
 
   if (debug_aranges->GetNumRanges() == num_debug_aranges) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 4c9f1d8505f6e6..ac63b50c3ba2d4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -13,10 +13,12 @@
 #include "DWARFDebugInfoEntry.h"
 #include "DWARFDeclContext.h"
 #include "DWARFUnit.h"
+#include "LogChannelDWARF.h"
 #include "lldb/Symbol/Type.h"
 
 #include "llvm/ADT/iterator.h"
 #include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 
 using namespace lldb_private;
 using namespace lldb_private::dwarf;
@@ -172,21 +174,27 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
   }
 
   if (match_addr_range) {
-    DWARFRangeList ranges =
-        m_die->GetAttributeAddressRanges(m_cu, /*check_hi_lo_pc=*/true);
-    if (ranges.FindEntryThatContains(address)) {
-      check_children = true;
-      switch (Tag()) {
-      default:
-        break;
-
-      case DW_TAG_inlined_subroutine: // Inlined Function
-      case DW_TAG_lexical_block:      // Block { } in code
-        result = *this;
-        break;
+    if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
+            m_die->GetAttributeAddressRanges(m_cu, /*check_hi_lo_pc=*/true)) {
+      bool addr_in_range =
+          llvm::any_of(*ranges, [&](const llvm::DWARFAddressRange &r) {
+            return r.LowPC <= address && address < r.HighPC;
+          });
+      if (addr_in_range) {
+        switch (Tag()) {
+        default:
+          break;
+
+        case DW_TAG_inlined_subroutine: // Inlined Function
+        case DW_TAG_lexical_block:      // Block { } in code
+          result = *this;
+          break;
+        }
       }
+      check_children = addr_in_range;
     } else {
-      check_children = false;
+      LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
+                     "DIE({1:x}): {0}", GetID());
     }
   }
 
@@ -559,10 +567,11 @@ bool DWARFDIE::IsMethod() const {
 }
 
 bool DWARFDIE::GetDIENamesAndRanges(
-    const char *&name, const char *&mangled, DWARFRangeList &ranges,
-    std::optional<int> &decl_file, std::optional<int> &decl_line,
-    std::optional<int> &decl_column, std::optional<int> &call_file,
-    std::optional<int> &call_line, std::optional<int> &call_column,
+    const char *&name, const char *&mangled,
+    llvm::DWARFAddressRangesVector &ranges, std::optional<int> &decl_file,
+    std::optional<int> &decl_line, std::optional<int> &decl_column,
+    std::optional<int> &call_file, std::optional<int> &call_line,
+    std::optional<int> &call_column,
     lldb_private::DWARFExpressionList *frame_base) const {
   if (IsValid()) {
     return m_die->GetDIENamesAndRanges(
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 077b78eb26d0c3..64421a5f16559b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -12,6 +12,7 @@
 #include "DWARFBaseDIE.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 
 namespace lldb_private::plugin {
 namespace dwarf {
@@ -97,11 +98,11 @@ class DWARFDIE : public DWARFBaseDIE {
   GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
 
   bool GetDIENamesAndRanges(
-      const char *&name, const char *&mangled, DWARFRangeList &ranges,
-      std::optional<int> &decl_file, std::optional<int> &decl_line,
-      std::optional<int> &decl_column, std::optional<int> &call_file,
-      std::optional<int> &call_line, std::optional<int> &call_column,
-      DWARFExpressionList *frame_base) const;
+      const char *&name, const char *&mangled,
+      llvm::DWARFAddressRangesVector &ranges, std::optional<int> &decl_file,
+      std::optional<int> &decl_line, std::optional<int> &decl_column,
+      std::optional<int> &call_file, std::optional<int> &call_line,
+      std::optional<int> &call_column, DWARFExpressionList *frame_base) const;
 
   /// The range of all the children of this DIE.
   llvm::iterator_range<child_iterator> children() const;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 4ecb2ed616a128..6d073411de876c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -14,13 +14,15 @@
 #include <limits>
 #include <optional>
 
-#include "llvm/Support/LEB128.h"
-
+#include "LogChannelDWARF.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/LEB128.h"
 
 #include "DWARFCompileUnit.h"
 #include "DWARFDebugAranges.h"
@@ -31,8 +33,6 @@
 #include "SymbolFileDWARF.h"
 #include "SymbolFileDWARFDwo.h"
 
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-
 using namespace lldb_private;
 using namespace lldb_private::dwarf;
 using namespace lldb_private::plugin::dwarf;
@@ -82,24 +82,11 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
   return true;
 }
 
-static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit,
-                                             const DWARFDebugInfoEntry &die,
-                                             const DWARFFormValue &value) {
-  llvm::Expected<DWARFRangeList> expected_ranges =
-      (value.Form() == DW_FORM_rnglistx)
-          ? unit.FindRnglistFromIndex(value.Unsigned())
-          : unit.FindRnglistFromOffset(value.Unsigned());
-  if (expected_ranges)
-    return std::move(*expected_ranges);
-
-  unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
-      "[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
-      "range extraction failed ({3}), please file a bug "
-      "and attach the file at the start of this error message",
-      die.GetOffset(),
-      llvm::dwarf::FormEncodingString(value.Form()).str().c_str(),
-      value.Unsigned(), toString(expected_ranges.takeError()).c_str());
-  return DWARFRangeList();
+static llvm::Expected<llvm::DWARFAddressRangesVector>
+GetRanges(DWARFUnit &unit, const DWARFFormValue &value) {
+  return (value.Form() == DW_FORM_rnglistx)
+             ? unit.FindRnglistFromIndex(value.Unsigned())
+             : unit.FindRnglistFromOffset(value.Unsigned());
 }
 
 static void ExtractAttrAndFormValue(
@@ -117,7 +104,7 @@ static void ExtractAttrAndFormValue(
 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
 bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
     DWARFUnit *cu, const char *&name, const char *&mangled,
-    DWARFRangeList &ranges, std::optional<int> &decl_file,
+    llvm::DWARFAddressRangesVector &ranges, std::optional<int> &decl_file,
     std::optional<int> &decl_line, std::optional<int> &decl_column,
     std::optional<int> &call_file, std::optional<int> &call_line,
     std::optional<int> &call_column, DWARFExpressionList *frame_base) const {
@@ -173,7 +160,17 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
           break;
 
         case DW_AT_ranges:
-          ranges = GetRangesOrReportError(*cu, *this, form_value);
+          if (llvm::Expected<llvm::DWARFAddressRangesVector> r =
+                  GetRanges(*cu, form_value)) {
+            ranges = std::move(*r);
+          } else {
+            module->ReportError(
+                "[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
+                "range extraction failed ({3}), please file a bug "
+                "and attach the file at the start of this error message",
+                GetOffset(), llvm::dwarf::FormEncodingString(form_value.Form()),
+                form_value.Unsigned(), fmt_consume(r.takeError()));
+          }
           break;
 
         case DW_AT_name:
@@ -259,22 +256,20 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
     }
   }
 
-  if (ranges.IsEmpty()) {
-    if (lo_pc != LLDB_INVALID_ADDRESS) {
-      if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
-        ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
-      else
-        ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
-    }
+  if (ranges.empty() && lo_pc != LLDB_INVALID_ADDRESS) {
+    lldb::addr_t range_hi_pc =
+        (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) ? hi_pc : lo_pc;
+    ranges.emplace_back(lo_pc, range_hi_pc);
   }
 
-  if (set_frame_base_loclist_addr) {
-    dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
+  if (set_frame_base_loclist_addr && !ranges.empty()) {
+    // TODO: Use the first range instead.
+    dw_addr_t lowest_range_pc = llvm::min_element(ranges)->LowPC;
     assert(lowest_range_pc >= cu->GetBaseAddress());
     frame_base->SetFuncFileAddress(lowest_range_pc);
   }
 
-  if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
+  if (ranges.empty() || name == nullptr || mangled == nullptr) {
     for (const DWARFDIE &die : dies) {
       if (die) {
         die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
@@ -283,7 +278,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
       }
     }
   }
-  return !ranges.IsEmpty();
+  return !ranges.empty();
 }
 
 // Get all attribute values for a given DIE, including following any
@@ -499,24 +494,23 @@ bool DWARFDebugInfoEntry::GetAttributeAddressRange(
   return false;
 }
 
-DWARFRangeList DWARFDebugInfoEntry::GetAttributeAddressRanges(
+llvm::Expected<llvm::DWARFAddressRangesVector>
+DWARFDebugInfoEntry::GetAttributeAddressRanges(
     DWARFUnit *cu, bool check_hi_lo_pc, bool check_elaborating_dies) const {
 
   DWARFFormValue form_value;
   if (GetAttributeValue(cu, DW_AT_ranges, form_value))
-    return GetRangesOrReportError(*cu, *this, form_value);
+    return GetRanges(*cu, form_value);
 
-  DWARFRangeList ranges;
   if (check_hi_lo_pc) {
     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
     if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
-                                 check_elaborating_dies)) {
-      if (lo_pc < hi_pc)
-        ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
-    }
+                                 check_elaborating_dies) &&
+        lo_pc < hi_pc)
+      return llvm::DWARFAddressRangesVector{{lo_pc, hi_pc}};
   }
-  return ranges;
+  return llvm::createStringError("DIE has no address range information");
 }
 
 // GetName
@@ -577,13 +571,15 @@ const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
 /// table instead of the compile unit offset.
 void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
     DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
+  Log *log = GetLog(DWARFLog::DebugInfo);
   if (m_tag) {
     if (m_tag == DW_TAG_subprogram) {
-      DWARFRangeList ranges =
-          GetAttributeAddressRanges(cu, /*check_hi_lo_pc=*/true);
-      for (const auto &r : ranges) {
-        debug_aranges->AppendRange(GetOffset(), r.GetRangeBase(),
-                                   r.GetRangeEnd());
+      if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
+              GetAttributeAddressRanges(cu, /*check_hi_lo_pc=*/true)) {
+        for (const auto &r : *ranges)
+          debug_aranges->AppendRange(GetOffset(), r.LowPC, r.HighPC);
+      } else {
+        LLDB_LOG_ERROR(log, ranges.takeError(), "DIE({1:x}): {0}", GetOffset());
       }
     }
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 0e50aab3292ae6..de6bbf1d527899 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -10,7 +10,6 @@
 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
 
 #include "SymbolFileDWARF.h"
-#include "llvm/ADT/SmallVector.h"
 
 #include "DWARFAttribute.h"
 #include "DWARFBaseDIE.h"
@@ -20,6 +19,7 @@
 #include <vector>
 
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 
 namespace lldb_private::plugin {
 namespace dwarf {
@@ -95,7 +95,7 @@ class DWARFDebugInfoEntry {
                                 dw_addr_t &hi_pc, uint64_t fail_value,
                                 bool check_elaborating_dies = false) const;
 
-  DWARFRangeList
+  llvm::Expected<llvm::DWARFAddressRangesVector>
   GetAttributeAddressRanges(DWARFUnit *cu, bool check_hi_lo_pc,
                             bool check_elaborating_dies = false) const;
 
@@ -106,15 +106,13 @@ class DWARFDebugInfoEntry {
 
   const char *GetPubname(const DWARFUnit *cu) const;
 
-  bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name,
-                            const char *&mangled, DWARFRangeList &rangeList,
-                            std::optional<int> &decl_file,
-                            std::optional<int> &decl_line,
-                            std::optional<int> &decl_column,
-                            std::optional<int> &call_file,
-                            std::optional<int> &call_line,
-                            std::optional<int> &call_column,
-                            DWARFExpressionList *frame_base = nullptr) const;
+  bool GetDIENamesAndRanges(
+      DWARFUnit *cu, const char *&name, const char *&mangled,
+      llvm::DWARFAddressRangesVector &rangeList, std::optional<int> &decl_file,
+      std::optional<int> &decl_line, std::optional<int> &decl_column,
+      std::optional<int> &call_file, std::optional<int> &call_line,
+      std::optional<int> &call_column,
+      DWARFExpressionList *frame_base = nullptr) const;
 
   const llvm::DWARFAbbreviationDeclaration *
   GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 0c9fd31cbfaefe..07de23f9de2fd6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -1029,9 +1029,8 @@ DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const {
   return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset);
 }
 
-llvm::Expected<DWARFRangeList>
+llvm::Expected<llvm::DWARFAddressRangesVector>
 DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
-  llvm::DWARFAddressRangesVector llvm_ranges;
   if (GetVersion() <= 4) {
     llvm::DWARFDataExtractor data =
         m_dwarf.GetDWARFContext().getOrLoadRangesData().GetAsLLVMDWARF();
@@ -1040,48 +1039,38 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
     llvm::DWARFDebugRangeList list;
     if (llvm::Error e = list.extract(data, &offset))
       return e;
-    llvm_ranges = list.getAbsoluteRanges(
+    return list.getAbsoluteRanges(
         llvm::object::SectionedAddress{GetBaseAddress()});
-  } else {
-    if (!GetRnglistTable())
-      return llvm::createStringError(std::errc::invalid_argument,
-                                     "missing or invalid range list table");
-
-    llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVMDWARF();
-
-    // As DW_AT_rnglists_base may be missing we need to call setAddressSize.
-    data.setAddressSize(m_header.getAddressByteSize());
-    auto range_list_or_error = GetRnglistTable()->findList(data, offset);
-    if (!range_list_or_error)
-      return range_list_or_error.takeError();
-
-    llvm::Expected<llvm::DWARFAddressRangesVector> expected_llvm_ranges =
-        range_list_or_error->getAbsoluteRanges(
-            llvm::object::SectionedAddress{GetBaseAddress()},
-            GetAddressByteSize(), [&](uint32_t index) {
-              uint32_t index_size = GetAddressByteSize();
-              dw_offset_t addr_base = GetAddrBase();
-              lldb::offset_t offset =
-                  addr_base + static_cast<lldb::offset_t>(index) * index_size;
-              return llvm::object::SectionedAddress{
-                  m_dwarf.GetDWARFContext().getOrLoadAddrData().GetMaxU64(
-                      &offset, index_size)};
-            });
-    if (!expected_llvm_ranges)
-      return expected_llvm_ranges.takeError();
-    llvm_ranges = std::move(*expected_llvm_ranges);
   }
 
-  DWARFRangeList ranges;
-  for (const llvm::DWARFAddressRange &llvm_range : llvm_ranges) {
-    ranges.Append(DWARFRangeList::Entry(llvm_range.LowPC,
-                                        llvm_range.HighPC - llvm_range.LowPC));
-  }
-  ranges.Sort();
-  return ranges;
+  // DWARF >= v5
+  if (!GetRnglistTable())
+    return llvm::createStringError(std::errc::invalid_argument,
+                                   "missing or invalid range list table");
+
+  llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVMDWARF();
+
+  // As DW_AT_rnglists_base may be missing we need to call setAddressSize.
+  data.setAddressSize(m_header.getAddressByteSize());
+  auto range_list_or_error = GetRnglistTable()->findList(data, offset);
+  if (!range_list_or_error)
+    return range_list_or_error.takeError();
+
+  return range_list_or_error->getAbsoluteRanges(
+      llvm::object::SectionedAddress{GetBaseAddress()}, GetAddressByteSize(),
+      [&](uint32_t index) {
+        uint32_t index_size = GetAddressByteSize();
+        dw_offset_t addr_base = GetAddrBase();
+        lldb::offset_t offset =
+            addr_base + static_cast<lldb::offset_t>(index) * index_size;
+        return llvm::object::SectionedAddress{
+            m_dwarf.GetDWARFContext().getOrLoadAddrData().GetMaxU64(
+                &offset, index_size)};
+      });
 }
 
-llvm::Expected<DWARFRangeList> DWARFUnit::FindRnglistFromIndex(uint32_t index) {
+llvm::Expected<llvm::DWARFAddressRangesVector>
+DWARFUnit::FindRnglistFromIndex(uint32_t index) {
   llvm::Expected<uint64_t> maybe_offset = GetRnglistOffset(index);
   if (!maybe_offset)
     return maybe_offset.takeError();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 1267e20f087121..0a0019c25836b4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -13,6 +13,7 @@
 #include "DWARFDebugInfoEntry.h"
 #include "lldb/Utility/XcodeSDK.h"
 #include "lldb/lldb-enumerations.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
 #include "llvm/Support/RWMutex.h"
@@ -213,12 +214,14 @@ class DWARFUnit : public UserID {
 
   /// Return a list of address ranges resulting from a (possibly encoded)
   /// range list starting at a given offset in the appropriate ranges section.
-  llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset);
+  llvm::Expected<llvm::DWARFAddressRangesVector>
+  FindRnglistFromOffset(dw_offset_t offset);
 
   /// Return a list of address ranges retrieved from an encoded range
   /// list whose offset is found via a table lookup given an index (DWARF v5
   /// and later).
-  llvm::Expected<DWARFRangeList> FindRnglistFromIndex(uint32_t index);
+  llvm::Expected<llvm::DWARFAddressRangesVector>
+  FindRnglistFromIndex(uint32_t index);
 
   /// Return a rangelist's offset based on an index. The index designates
   /// an entry in the rangelist table's offset array and is supplied by
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 6f19b264eb3dda..1efac9cb747202 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -7,7 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "SymbolFileDWARF.h"
-
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/FileUtilities.h"
@@ -888,13 +889,13 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
 Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
                                          const DWARFDIE &die) {
   ASSERT_MODULE_LOCK(this);
+  Log *log = GetLog(LLDBLog::Symbols);
   if (!die.IsValid())
     return nullptr;
 
   auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
   if (auto err = type_system_or_err.takeError()) {
-    LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
-                   "Unable to parse function: {0}");
+    LLDB_LOG_ERROR(log, std::move(err), "Unable to parse function: {0}");
     return nullptr;
   }
   auto ts = *type_system_or_err;
@@ -906,13 +907,18 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
 
   AddressRanges ranges;
   ModuleSP module_sp(die.GetModule());
-  for (const auto &range : die.GetDIE()->GetAttributeAddressRanges(
-           die.GetCU(), /*check_hi_lo_pc=*/true)) {
-    if (range.base < m_first_code_address)
-      continue;
-    if (Address base_addr(range.base, module_sp->GetSectionList());
-        base_addr.IsValid() && FixupAddress(base_addr))
-      ranges.emplace_back(std::move(base_addr), range.size);
+  if (llvm::Expected<llvm::DWARFAddressRangesVector> die_ranges =
+          die.GetDIE()->GetAttributeAddressRanges(die.GetCU(),
+                                                  /*check_hi_lo_pc=*/true)) {
+    for (const auto &range : *die_ranges) {
+      if (range.valid() && range.LowPC < m_first_code_address)
+        continue;
+      if (Address base_addr(range.LowPC, module_sp->GetSectionList());
+          base_addr.IsValid() && FixupAddress(base_addr))
+        ranges.emplace_back(std::move(base_addr), range.HighPC - range.LowPC);
+    }
+  } else {
+    LLDB_LOG_ERROR(log, die_ranges.takeError(), "DIE({1:x}): {0}", die.GetID());
   }
   if (ranges.empty())
     return nullptr;
@@ -1316,7 +1322,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(CompileUnit &comp_unit,
       continue;
 
     Block *block = parent_block->CreateChild(die.GetID()).get();
-    DWARFRangeList ranges;
+    llvm::DWARFAddressRangesVector ranges;
     const char *name = nullptr;
     const char *mangled_name = nullptr;
 
@@ -1329,21 +1335,19 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(CompileUnit &comp_unit,
     if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
                                  decl_line, decl_column, call_file, call_line,
                                  call_column, nullptr)) {
-      const size_t num_ranges = ranges.GetSize();
-      for (size_t i = 0; i < num_ranges; ++i) {
-        const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
-        const addr_t range_base = range.GetRangeBase();
-        if (range_base >= subprogram_low_pc)
-          block->AddRange(Block::Range(range_base - subprogram_low_pc,
-                                       range.GetByteSize()));
+      for (const llvm::DWARFAddressRange &range : ranges) {
+        if (!range.valid())
+          continue;
+        if (range.LowPC >= subprogram_low_pc)
+          block->AddRange(Block::Range(range.LowPC - subprogram_low_pc,
+                                       range.HighPC - range.LowPC));
         else {
           GetObjectFile()->GetModule()->ReportError(
               "{0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
               "that is less than the function's low PC {3:x16}. Please file "
               "a bug and attach the file at the "
               "start of this error message",
-              block->GetID(), range_base, range.GetRangeEnd(),
-              subprogram_low_pc);
+              block->GetID(), range.LowPC, range.HighPC, subprogram_low_pc);
         }
       }
       block->FinalizeRanges();
@@ -3197,14 +3201,21 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
   if (function_die) {
     // We can't use the file address from the Function object as (in the OSO
     // case) it will already be remapped to the main module.
-    DWARFRangeList ranges = function_die.GetDIE()->GetAttributeAddressRanges(
-        function_die.GetCU(),
-        /*check_hi_lo_pc=*/true);
-    lldb::addr_t function_file_addr =
-        ranges.GetMinRangeBase(LLDB_INVALID_ADDRESS);
-    if (function_file_addr != LLDB_INVALID_ADDRESS)
-      ParseBlocksRecursive(*comp_unit, &func.GetBlock(false),
-                           function_die.GetFirstChild(), function_file_addr);
+    if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
+        function_die.GetDIE()->GetAttributeAddressRanges(
+            function_die.GetCU(),
+            /*check_hi_lo_pc=*/true)) {
+      if (ranges->empty())
+        return 0;
+      // TODO: Use the first range instead.
+      dw_addr_t function_file_addr = llvm::min_element(*ranges)->LowPC;
+      if (function_file_addr != LLDB_INVALID_ADDRESS)
+        ParseBlocksRecursive(*comp_unit, &func.GetBlock(false),
+                             function_die.GetFirstChild(), function_file_addr);
+    } else {
+      LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
+                     "{1:x}: {0}", dwarf_cu->GetOffset());
+    }
   }
 
   return functions_added;
@@ -3233,10 +3244,16 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
       DWARFDIE function_die = GetDIE(sc.function->GetID());
 
       dw_addr_t func_lo_pc = LLDB_INVALID_ADDRESS;
-      DWARFRangeList ranges = function_die.GetDIE()->GetAttributeAddressRanges(
-          function_die.GetCU(), /*check_hi_lo_pc=*/true);
-      if (!ranges.IsEmpty())
-        func_lo_pc = ranges.GetMinRangeBase(0);
+      if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
+              function_die.GetDIE()->GetAttributeAddressRanges(
+                  function_die.GetCU(), /*check_hi_lo_pc=*/true)) {
+        // TODO: Use the first range element instead.
+        if (!ranges->empty())
+          func_lo_pc = llvm::min_element(*ranges)->LowPC;
+      } else {
+        LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
+                       "DIE({1:x}): {0}", function_die.GetID());
+      }
       if (func_lo_pc != LLDB_INVALID_ADDRESS) {
         const size_t num_variables =
             ParseVariablesInFunctionContext(sc, function_die, func_lo_pc);



More information about the lldb-commits mailing list