Skip to content

Commit fb8df8c

Browse files
authored
[lldb/DWARF] s/DWARFRangeList/llvm::DWARFAddressRangeVector (llvm#116620)
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.
1 parent 12a42a6 commit fb8df8c

File tree

11 files changed

+185
-168
lines changed

11 files changed

+185
-168
lines changed

lldb/include/lldb/Core/dwarf.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#ifndef LLDB_CORE_DWARF_H
1010
#define LLDB_CORE_DWARF_H
1111

12-
#include "lldb/Utility/RangeMap.h"
1312
#include <cstdint>
1413

1514
// Get the DWARF constant definitions from llvm
@@ -40,6 +39,4 @@ typedef uint64_t dw_offset_t; // Dwarf Debug Information Entry offset for any
4039

4140
#define DW_EH_PE_MASK_ENCODING 0x0F
4241

43-
typedef lldb_private::RangeVector<dw_addr_t, dw_addr_t, 2> DWARFRangeList;
44-
4542
#endif // LLDB_CORE_DWARF_H

lldb/source/Plugins/SymbolFile/DWARF/DIERef.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
1111

1212
#include "lldb/Core/dwarf.h"
13-
#include "lldb/Utility/LLDBAssert.h"
13+
#include "lldb/lldb-defines.h"
14+
#include "lldb/lldb-types.h"
1415
#include <cassert>
1516
#include <optional>
1617

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "clang/AST/Type.h"
4646
#include "clang/Basic/Specifiers.h"
4747
#include "llvm/ADT/StringExtras.h"
48+
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
4849
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
4950
#include "llvm/Demangle/Demangle.h"
5051

@@ -2360,7 +2361,7 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
23602361

23612362
Function *DWARFASTParserClang::ParseFunctionFromDWARF(
23622363
CompileUnit &comp_unit, const DWARFDIE &die, AddressRanges func_ranges) {
2363-
DWARFRangeList unused_func_ranges;
2364+
llvm::DWARFAddressRangesVector unused_func_ranges;
23642365
const char *name = nullptr;
23652366
const char *mangled = nullptr;
23662367
std::optional<int> decl_file;

lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88

99
#include "DWARFCompileUnit.h"
1010
#include "DWARFDebugAranges.h"
11+
#include "LogChannelDWARF.h"
1112
#include "SymbolFileDWARFDebugMap.h"
1213

1314
#include "lldb/Symbol/CompileUnit.h"
1415
#include "lldb/Symbol/LineTable.h"
1516
#include "lldb/Utility/Stream.h"
17+
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
1618

1719
using namespace lldb;
1820
using namespace lldb_private;
@@ -41,14 +43,17 @@ void DWARFCompileUnit::BuildAddressRangeTable(
4143

4244
const dw_offset_t cu_offset = GetOffset();
4345
if (die) {
44-
DWARFRangeList ranges =
46+
llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
4547
die->GetAttributeAddressRanges(this, /*check_hi_lo_pc=*/true);
46-
for (const DWARFRangeList::Entry &range : ranges)
47-
debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
48-
range.GetRangeEnd());
49-
50-
if (!ranges.IsEmpty())
51-
return;
48+
if (ranges) {
49+
for (const llvm::DWARFAddressRange &range : *ranges)
50+
debug_aranges->AppendRange(cu_offset, range.LowPC, range.HighPC);
51+
if (!ranges->empty())
52+
return;
53+
} else {
54+
LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
55+
"{1:x}: {0}", cu_offset);
56+
}
5257
}
5358

5459
if (debug_aranges->GetNumRanges() == num_debug_aranges) {

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
#include "DWARFDebugInfoEntry.h"
1414
#include "DWARFDeclContext.h"
1515
#include "DWARFUnit.h"
16+
#include "LogChannelDWARF.h"
1617
#include "lldb/Symbol/Type.h"
1718

1819
#include "llvm/ADT/iterator.h"
1920
#include "llvm/BinaryFormat/Dwarf.h"
21+
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
2022

2123
using namespace lldb_private;
2224
using namespace lldb_private::dwarf;
@@ -172,21 +174,27 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
172174
}
173175

174176
if (match_addr_range) {
175-
DWARFRangeList ranges =
176-
m_die->GetAttributeAddressRanges(m_cu, /*check_hi_lo_pc=*/true);
177-
if (ranges.FindEntryThatContains(address)) {
178-
check_children = true;
179-
switch (Tag()) {
180-
default:
181-
break;
182-
183-
case DW_TAG_inlined_subroutine: // Inlined Function
184-
case DW_TAG_lexical_block: // Block { } in code
185-
result = *this;
186-
break;
177+
if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
178+
m_die->GetAttributeAddressRanges(m_cu, /*check_hi_lo_pc=*/true)) {
179+
bool addr_in_range =
180+
llvm::any_of(*ranges, [&](const llvm::DWARFAddressRange &r) {
181+
return r.LowPC <= address && address < r.HighPC;
182+
});
183+
if (addr_in_range) {
184+
switch (Tag()) {
185+
default:
186+
break;
187+
188+
case DW_TAG_inlined_subroutine: // Inlined Function
189+
case DW_TAG_lexical_block: // Block { } in code
190+
result = *this;
191+
break;
192+
}
187193
}
194+
check_children = addr_in_range;
188195
} else {
189-
check_children = false;
196+
LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
197+
"DIE({1:x}): {0}", GetID());
190198
}
191199
}
192200

@@ -559,10 +567,11 @@ bool DWARFDIE::IsMethod() const {
559567
}
560568

561569
bool DWARFDIE::GetDIENamesAndRanges(
562-
const char *&name, const char *&mangled, DWARFRangeList &ranges,
563-
std::optional<int> &decl_file, std::optional<int> &decl_line,
564-
std::optional<int> &decl_column, std::optional<int> &call_file,
565-
std::optional<int> &call_line, std::optional<int> &call_column,
570+
const char *&name, const char *&mangled,
571+
llvm::DWARFAddressRangesVector &ranges, std::optional<int> &decl_file,
572+
std::optional<int> &decl_line, std::optional<int> &decl_column,
573+
std::optional<int> &call_file, std::optional<int> &call_line,
574+
std::optional<int> &call_column,
566575
lldb_private::DWARFExpressionList *frame_base) const {
567576
if (IsValid()) {
568577
return m_die->GetDIENamesAndRanges(

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "DWARFBaseDIE.h"
1313
#include "llvm/ADT/SmallSet.h"
1414
#include "llvm/ADT/iterator_range.h"
15+
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
1516

1617
namespace lldb_private::plugin {
1718
namespace dwarf {
@@ -97,11 +98,11 @@ class DWARFDIE : public DWARFBaseDIE {
9798
GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
9899

99100
bool GetDIENamesAndRanges(
100-
const char *&name, const char *&mangled, DWARFRangeList &ranges,
101-
std::optional<int> &decl_file, std::optional<int> &decl_line,
102-
std::optional<int> &decl_column, std::optional<int> &call_file,
103-
std::optional<int> &call_line, std::optional<int> &call_column,
104-
DWARFExpressionList *frame_base) const;
101+
const char *&name, const char *&mangled,
102+
llvm::DWARFAddressRangesVector &ranges, std::optional<int> &decl_file,
103+
std::optional<int> &decl_line, std::optional<int> &decl_column,
104+
std::optional<int> &call_file, std::optional<int> &call_line,
105+
std::optional<int> &call_column, DWARFExpressionList *frame_base) const;
105106

106107
// The following methods use LLVM naming convension in order to be are used by
107108
// LLVM libraries.

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
#include <limits>
1515
#include <optional>
1616

17-
#include "llvm/Support/LEB128.h"
18-
17+
#include "LogChannelDWARF.h"
1918
#include "lldb/Core/Module.h"
2019
#include "lldb/Expression/DWARFExpression.h"
2120
#include "lldb/Symbol/ObjectFile.h"
22-
#include "lldb/Utility/Stream.h"
23-
#include "lldb/Utility/StreamString.h"
21+
#include "llvm/ADT/STLExtras.h"
22+
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
23+
#include "llvm/Support/Error.h"
24+
#include "llvm/Support/FormatAdapters.h"
25+
#include "llvm/Support/LEB128.h"
2426

2527
#include "DWARFCompileUnit.h"
2628
#include "DWARFDebugAranges.h"
@@ -31,8 +33,6 @@
3133
#include "SymbolFileDWARF.h"
3234
#include "SymbolFileDWARFDwo.h"
3335

34-
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
35-
3636
using namespace lldb_private;
3737
using namespace lldb_private::dwarf;
3838
using namespace lldb_private::plugin::dwarf;
@@ -82,24 +82,11 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
8282
return true;
8383
}
8484

85-
static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit,
86-
const DWARFDebugInfoEntry &die,
87-
const DWARFFormValue &value) {
88-
llvm::Expected<DWARFRangeList> expected_ranges =
89-
(value.Form() == DW_FORM_rnglistx)
90-
? unit.FindRnglistFromIndex(value.Unsigned())
91-
: unit.FindRnglistFromOffset(value.Unsigned());
92-
if (expected_ranges)
93-
return std::move(*expected_ranges);
94-
95-
unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
96-
"[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
97-
"range extraction failed ({3}), please file a bug "
98-
"and attach the file at the start of this error message",
99-
die.GetOffset(),
100-
llvm::dwarf::FormEncodingString(value.Form()).str().c_str(),
101-
value.Unsigned(), toString(expected_ranges.takeError()).c_str());
102-
return DWARFRangeList();
85+
static llvm::Expected<llvm::DWARFAddressRangesVector>
86+
GetRanges(DWARFUnit &unit, const DWARFFormValue &value) {
87+
return (value.Form() == DW_FORM_rnglistx)
88+
? unit.FindRnglistFromIndex(value.Unsigned())
89+
: unit.FindRnglistFromOffset(value.Unsigned());
10390
}
10491

10592
static void ExtractAttrAndFormValue(
@@ -117,7 +104,7 @@ static void ExtractAttrAndFormValue(
117104
// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
118105
bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
119106
DWARFUnit *cu, const char *&name, const char *&mangled,
120-
DWARFRangeList &ranges, std::optional<int> &decl_file,
107+
llvm::DWARFAddressRangesVector &ranges, std::optional<int> &decl_file,
121108
std::optional<int> &decl_line, std::optional<int> &decl_column,
122109
std::optional<int> &call_file, std::optional<int> &call_line,
123110
std::optional<int> &call_column, DWARFExpressionList *frame_base) const {
@@ -173,7 +160,17 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
173160
break;
174161

175162
case DW_AT_ranges:
176-
ranges = GetRangesOrReportError(*cu, *this, form_value);
163+
if (llvm::Expected<llvm::DWARFAddressRangesVector> r =
164+
GetRanges(*cu, form_value)) {
165+
ranges = std::move(*r);
166+
} else {
167+
module->ReportError(
168+
"[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
169+
"range extraction failed ({3}), please file a bug "
170+
"and attach the file at the start of this error message",
171+
GetOffset(), llvm::dwarf::FormEncodingString(form_value.Form()),
172+
form_value.Unsigned(), fmt_consume(r.takeError()));
173+
}
177174
break;
178175

179176
case DW_AT_name:
@@ -259,22 +256,20 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
259256
}
260257
}
261258

262-
if (ranges.IsEmpty()) {
263-
if (lo_pc != LLDB_INVALID_ADDRESS) {
264-
if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
265-
ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
266-
else
267-
ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
268-
}
259+
if (ranges.empty() && lo_pc != LLDB_INVALID_ADDRESS) {
260+
lldb::addr_t range_hi_pc =
261+
(hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) ? hi_pc : lo_pc;
262+
ranges.emplace_back(lo_pc, range_hi_pc);
269263
}
270264

271-
if (set_frame_base_loclist_addr) {
272-
dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
265+
if (set_frame_base_loclist_addr && !ranges.empty()) {
266+
// TODO: Use the first range instead.
267+
dw_addr_t lowest_range_pc = llvm::min_element(ranges)->LowPC;
273268
assert(lowest_range_pc >= cu->GetBaseAddress());
274269
frame_base->SetFuncFileAddress(lowest_range_pc);
275270
}
276271

277-
if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
272+
if (ranges.empty() || name == nullptr || mangled == nullptr) {
278273
for (const DWARFDIE &die : dies) {
279274
if (die) {
280275
die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
@@ -283,7 +278,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
283278
}
284279
}
285280
}
286-
return !ranges.IsEmpty();
281+
return !ranges.empty();
287282
}
288283

289284
// Get all attribute values for a given DIE, including following any
@@ -499,24 +494,23 @@ bool DWARFDebugInfoEntry::GetAttributeAddressRange(
499494
return false;
500495
}
501496

502-
DWARFRangeList DWARFDebugInfoEntry::GetAttributeAddressRanges(
497+
llvm::Expected<llvm::DWARFAddressRangesVector>
498+
DWARFDebugInfoEntry::GetAttributeAddressRanges(
503499
DWARFUnit *cu, bool check_hi_lo_pc, bool check_elaborating_dies) const {
504500

505501
DWARFFormValue form_value;
506502
if (GetAttributeValue(cu, DW_AT_ranges, form_value))
507-
return GetRangesOrReportError(*cu, *this, form_value);
503+
return GetRanges(*cu, form_value);
508504

509-
DWARFRangeList ranges;
510505
if (check_hi_lo_pc) {
511506
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
512507
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
513508
if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
514-
check_elaborating_dies)) {
515-
if (lo_pc < hi_pc)
516-
ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
517-
}
509+
check_elaborating_dies) &&
510+
lo_pc < hi_pc)
511+
return llvm::DWARFAddressRangesVector{{lo_pc, hi_pc}};
518512
}
519-
return ranges;
513+
return llvm::createStringError("DIE has no address range information");
520514
}
521515

522516
// GetName
@@ -577,13 +571,15 @@ const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
577571
/// table instead of the compile unit offset.
578572
void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
579573
DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
574+
Log *log = GetLog(DWARFLog::DebugInfo);
580575
if (m_tag) {
581576
if (m_tag == DW_TAG_subprogram) {
582-
DWARFRangeList ranges =
583-
GetAttributeAddressRanges(cu, /*check_hi_lo_pc=*/true);
584-
for (const auto &r : ranges) {
585-
debug_aranges->AppendRange(GetOffset(), r.GetRangeBase(),
586-
r.GetRangeEnd());
577+
if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
578+
GetAttributeAddressRanges(cu, /*check_hi_lo_pc=*/true)) {
579+
for (const auto &r : *ranges)
580+
debug_aranges->AppendRange(GetOffset(), r.LowPC, r.HighPC);
581+
} else {
582+
LLDB_LOG_ERROR(log, ranges.takeError(), "DIE({1:x}): {0}", GetOffset());
587583
}
588584
}
589585

0 commit comments

Comments
 (0)