[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