Skip to content

[lldb/DWARF] s/DWARFRangeList/llvm::DWARFAddressRangeVector #116620

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 13, 2024

Conversation

labath
Copy link
Collaborator

@labath labath commented Nov 18, 2024

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.

@labath labath requested a review from jasonmolenda November 18, 2024 13:53
@labath labath requested a review from JDevlieghere as a code owner November 18, 2024 13:53
@llvmbot llvmbot added the lldb label Nov 18, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 18, 2024

@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)

Changes

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.


Patch is 30.08 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116620.diff

11 Files Affected:

  • (modified) lldb/include/lldb/Core/dwarf.h (-3)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DIERef.h (+2-1)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+2-1)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (+12-7)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp (+26-17)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h (+6-5)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp (+45-50)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (+9-11)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (+28-39)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h (+5-2)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (+49-38)
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..0575d30d4fc315 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,19 @@ 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) {
+    ranges.emplace_back(
+        lo_pc, (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) ? hi_pc : 0);
   }
 
-  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 +277,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
       }
     }
   }
-  return !ranges.IsEmpty();
+  return !ranges.empty();
 }
 
 // Get all attribute values for a given DIE, including following any
@@ -499,24 +493,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 +570,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 (!Get...
[truncated]

if (llvm::Expected<llvm::DWARFAddressRangesVector> die_ranges =
die.GetDIE()->GetAttributeAddressRanges(die.GetCU(),
/*check_hi_lo_pc=*/true)) {
for (auto &range : *die_ranges) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can range be const-qualified? :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

}
if (ranges.empty() && lo_pc != LLDB_INVALID_ADDRESS) {
ranges.emplace_back(
lo_pc, (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) ? hi_pc : 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The possibilities for the 2nd argument went from hi_pc - lo_pc or 0 to hi_pc or 0. Is this intentional? I'm not sure if the format is now (base address, length) or (low address, high address).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. The new format is now (low pc, high pc), so the second case should be low_pc instead of zero. I don't remember ever seeing a lone low_pc attribute, so this might not matter in practice.

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.
@labath
Copy link
Collaborator Author

labath commented Dec 4, 2024

Rebased on top of other changes. Ping :)

Copy link

github-actions bot commented Dec 4, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me. Thanks!

@labath labath merged commit fb8df8c into llvm:main Dec 13, 2024
7 checks passed
@labath labath deleted the ranges branch December 13, 2024 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants