Skip to content

Commit 5828b04

Browse files
authored
[BOLT][DWARF] Refactor legacy ranges writers (llvm#96006)
Refactors legacy ranges writers to create a writer for each instance of a DWO file. We now write out everything into .debug_ranges after the all the DWO files are processed. This also changes the order that ranges is written out in, as before we wrote out while in the main CU processing loop and we now iterate through the CU buckets created by partitionCUs, after the main processing loop.
1 parent 4a1fdeb commit 5828b04

File tree

8 files changed

+190
-127
lines changed

8 files changed

+190
-127
lines changed

bolt/include/bolt/Core/DebugData.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,15 @@ class DebugRangesSectionWriter {
210210
static bool classof(const DebugRangesSectionWriter *Writer) {
211211
return Writer->getKind() == RangesWriterKind::DebugRangesWriter;
212212
}
213+
214+
/// Append a range to the main buffer.
215+
void appendToRangeBuffer(const DebugBufferVector &CUBuffer);
216+
217+
/// Sets Unit DIE to be updated for CU.
218+
void setDie(DIE *Die) { this->Die = Die; }
219+
220+
/// Returns Unit DIE to be updated for CU.
221+
DIE *getDie() const { return Die; }
213222

214223
/// Writes out range lists for a current CU being processed.
215224
void virtual finalizeSection(){};
@@ -232,6 +241,9 @@ class DebugRangesSectionWriter {
232241
static constexpr uint64_t EmptyRangesOffset{0};
233242

234243
private:
244+
/// Stores Unit DIE to be updated for CU.
245+
DIE *Die{0};
246+
235247
RangesWriterKind Kind;
236248
};
237249

bolt/include/bolt/Rewrite/DWARFRewriter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ class DWARFRewriter {
8989
/// Store Rangelists writer for each DWO CU.
9090
RangeListsDWOWriers RangeListsWritersByCU;
9191

92+
/// Stores ranges writer for each DWO CU.
93+
std::unordered_map<uint64_t, std::unique_ptr<DebugRangesSectionWriter>>
94+
LegacyRangesWritersByCU;
95+
9296
std::mutex LocListDebugInfoPatchesMutex;
9397

9498
/// Dwo id specific its RangesBase.

bolt/lib/Core/DebugData.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ uint64_t DebugRangesSectionWriter::getSectionOffset() {
177177
return SectionOffset;
178178
}
179179

180+
void DebugRangesSectionWriter::appendToRangeBuffer(
181+
const DebugBufferVector &CUBuffer) {
182+
*RangesStream << CUBuffer;
183+
SectionOffset = RangesBuffer->size();
184+
}
185+
180186
DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
181187

182188
uint64_t DebugRangeListsSectionWriter::addRanges(

bolt/lib/Rewrite/DWARFRewriter.cpp

Lines changed: 83 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,15 @@ void DWARFRewriter::updateDebugInfo() {
646646

647647
} else {
648648
LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
649+
if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
650+
assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
651+
"LegacyRangeLists writer for DWO unit already exists.");
652+
auto LegacyRangesSectionWriterByCU =
653+
std::make_unique<DebugRangesSectionWriter>();
654+
LegacyRangesSectionWriterByCU->initSection(CU);
655+
LegacyRangesWritersByCU[*DWOId] =
656+
std::move(LegacyRangesSectionWriterByCU);
657+
}
649658
}
650659
return LocListWritersByCU[CUIndex++].get();
651660
};
@@ -693,6 +702,7 @@ void DWARFRewriter::updateDebugInfo() {
693702
if (Unit->getVersion() >= 5) {
694703
TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
695704
} else {
705+
TempRangesSectionWriter = LegacyRangesWritersByCU[*DWOId].get();
696706
RangesBase = RangesSectionWriter->getSectionOffset();
697707
setDwoRangesBase(*DWOId, *RangesBase);
698708
}
@@ -1274,9 +1284,17 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
12741284
}
12751285

12761286
if (RangesBaseInfo) {
1277-
DIEBldr.replaceValue(&Die, RangesBaseInfo.getAttribute(),
1278-
RangesBaseInfo.getForm(),
1279-
DIEInteger(static_cast<uint32_t>(*RangesBase)));
1287+
if (RangesBaseInfo.getAttribute() == dwarf::DW_AT_GNU_ranges_base) {
1288+
auto RangesWriterIterator =
1289+
LegacyRangesWritersByCU.find(*Unit.getDWOId());
1290+
assert(RangesWriterIterator != LegacyRangesWritersByCU.end() &&
1291+
"RangesWriter does not exist for DWOId");
1292+
RangesWriterIterator->second->setDie(&Die);
1293+
} else {
1294+
DIEBldr.replaceValue(&Die, RangesBaseInfo.getAttribute(),
1295+
RangesBaseInfo.getForm(),
1296+
DIEInteger(static_cast<uint32_t>(*RangesBase)));
1297+
}
12801298
RangesBase = std::nullopt;
12811299
}
12821300
}
@@ -1294,20 +1312,12 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
12941312
RangesAttrInfo.getForm() == dwarf::DW_FORM_sec_offset)
12951313
NeedConverted = true;
12961314

1297-
uint64_t CurRangeBase = 0;
1298-
if (Unit.isDWOUnit()) {
1299-
if (std::optional<uint64_t> DWOId = Unit.getDWOId())
1300-
CurRangeBase = getDwoRangesBase(*DWOId);
1301-
else
1302-
errs() << "BOLT-WARNING: [internal-dwarf-error]: DWOId is not found "
1303-
"for DWO Unit.";
1304-
}
13051315
if (NeedConverted || RangesAttrInfo.getForm() == dwarf::DW_FORM_rnglistx)
13061316
DIEBldr.replaceValue(&Die, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx,
13071317
DIEInteger(DebugRangesOffset));
13081318
else
13091319
DIEBldr.replaceValue(&Die, dwarf::DW_AT_ranges, RangesAttrInfo.getForm(),
1310-
DIEInteger(DebugRangesOffset - CurRangeBase));
1320+
DIEInteger(DebugRangesOffset));
13111321

13121322
if (!RangesBase) {
13131323
if (LowPCAttrInfo &&
@@ -1324,15 +1334,21 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
13241334

13251335
// If we are at this point we are in the CU/Skeleton CU, and
13261336
// DW_AT_GNU_ranges_base or DW_AT_rnglists_base doesn't exist.
1327-
if (Unit.getVersion() <= 4)
1337+
if (Unit.getVersion() <= 4) {
13281338
DIEBldr.addValue(&Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4,
1329-
DIEInteger(*RangesBase));
1330-
else if (Unit.getVersion() == 5)
1339+
DIEInteger(INT_MAX));
1340+
auto RangesWriterIterator =
1341+
LegacyRangesWritersByCU.find(*Unit.getDWOId());
1342+
assert(RangesWriterIterator != LegacyRangesWritersByCU.end() &&
1343+
"RangesWriter does not exist for DWOId");
1344+
RangesWriterIterator->second->setDie(&Die);
1345+
} else if (Unit.getVersion() == 5) {
13311346
DIEBldr.addValue(&Die, dwarf::DW_AT_rnglists_base,
13321347
dwarf::DW_FORM_sec_offset, DIEInteger(*RangesBase));
1333-
else
1348+
} else {
13341349
DIEBldr.addValue(&Die, dwarf::DW_AT_rnglists_base,
13351350
dwarf::DW_FORM_sec_offset, DIEInteger(*RangesBase));
1351+
}
13361352
return;
13371353
}
13381354

@@ -1611,6 +1627,30 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
16111627
DIEStreamer &Streamer,
16121628
CUOffsetMap &CUMap,
16131629
const std::list<DWARFUnit *> &CUs) {
1630+
for (DWARFUnit *CU : CUs) {
1631+
if (CU->getVersion() != 4)
1632+
continue;
1633+
std::optional<uint64_t> DWOId = CU->getDWOId();
1634+
if (!DWOId)
1635+
continue;
1636+
auto RangesWriterIterator = LegacyRangesWritersByCU.find(*DWOId);
1637+
assert(RangesWriterIterator != LegacyRangesWritersByCU.end() &&
1638+
"RangesWriter does not exist for DWOId");
1639+
std::unique_ptr<DebugRangesSectionWriter> &LegacyRangesWriter =
1640+
RangesWriterIterator->second;
1641+
std::optional<DIE *> Die = LegacyRangesWriter->getDie();
1642+
if (!Die || !Die.value())
1643+
continue;
1644+
DIEValue DvalGNUBase =
1645+
Die.value()->findAttribute(dwarf::DW_AT_GNU_ranges_base);
1646+
assert(DvalGNUBase && "GNU_ranges_base attribute does not exist for DWOId");
1647+
DIEBlder.replaceValue(
1648+
Die.value(), dwarf::DW_AT_GNU_ranges_base, DvalGNUBase.getForm(),
1649+
DIEInteger(LegacyRangesSectionWriter->getSectionOffset()));
1650+
std::unique_ptr<DebugBufferVector> RangesWritersContents =
1651+
LegacyRangesWriter->releaseBuffer();
1652+
LegacyRangesSectionWriter->appendToRangeBuffer(*RangesWritersContents);
1653+
}
16141654
DIEBlder.generateAbbrevs();
16151655
DIEBlder.finish();
16161656
// generate debug_info and CUMap
@@ -2098,7 +2138,6 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
20982138
DWARFUnit &Unit, DIEBuilder &DIEBldr, DIE &Die,
20992139
uint64_t RangesSectionOffset, DIEValue &LowPCAttrInfo,
21002140
DIEValue &HighPCAttrInfo, std::optional<uint64_t> RangesBase) {
2101-
uint32_t BaseOffset = 0;
21022141
dwarf::Form LowForm = LowPCAttrInfo.getForm();
21032142
dwarf::Attribute RangeBaseAttribute = dwarf::DW_AT_GNU_ranges_base;
21042143
dwarf::Form RangesForm = dwarf::DW_FORM_sec_offset;
@@ -2113,45 +2152,40 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
21132152
Die.getTag() == dwarf::DW_TAG_skeleton_unit;
21142153
if (!IsUnitDie)
21152154
DIEBldr.deleteValue(&Die, LowPCAttrInfo.getAttribute());
2116-
// In DWARF4 for DW_AT_low_pc in binary DW_FORM_addr is used. In the DWO
2117-
// section DW_FORM_GNU_addr_index is used. So for if we are converting
2118-
// DW_AT_low_pc/DW_AT_high_pc and see DW_FORM_GNU_addr_index. We are
2119-
// converting in DWO section, and DW_AT_ranges [DW_FORM_sec_offset] is
2120-
// relative to DW_AT_GNU_ranges_base.
2121-
if (LowForm == dwarf::DW_FORM_GNU_addr_index) {
2122-
// Ranges are relative to DW_AT_GNU_ranges_base.
2123-
uint64_t CurRangeBase = 0;
2124-
if (std::optional<uint64_t> DWOId = Unit.getDWOId()) {
2125-
CurRangeBase = getDwoRangesBase(*DWOId);
2126-
}
2127-
BaseOffset = CurRangeBase;
2128-
} else {
2129-
// In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or
2130-
// DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is
2131-
// when it's absent.
2132-
if (IsUnitDie) {
2133-
if (LowForm == dwarf::DW_FORM_addrx) {
2134-
const uint32_t Index = AddrWriter->getIndexFromAddress(0, Unit);
2135-
DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
2136-
LowPCAttrInfo.getForm(), DIEInteger(Index));
2137-
} else {
2138-
DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
2139-
LowPCAttrInfo.getForm(), DIEInteger(0));
2140-
}
2155+
2156+
// In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or
2157+
// DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is
2158+
// when it's absent.
2159+
if (IsUnitDie) {
2160+
if (LowForm == dwarf::DW_FORM_addrx) {
2161+
const uint32_t Index = AddrWriter->getIndexFromAddress(0, Unit);
2162+
DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
2163+
LowPCAttrInfo.getForm(), DIEInteger(Index));
2164+
} else {
2165+
DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
2166+
LowPCAttrInfo.getForm(), DIEInteger(0));
21412167
}
2142-
// Original CU didn't have DW_AT_*_base. We converted it's children (or
2143-
// dwo), so need to insert it into CU.
2144-
if (RangesBase)
2168+
}
2169+
// Original CU didn't have DW_AT_*_base. We converted it's children (or
2170+
// dwo), so need to insert it into CU.
2171+
if (RangesBase) {
2172+
if (Unit.getVersion() >= 5) {
21452173
DIEBldr.addValue(&Die, RangeBaseAttribute, dwarf::DW_FORM_sec_offset,
21462174
DIEInteger(*RangesBase));
2175+
} else {
2176+
DIEBldr.addValue(&Die, RangeBaseAttribute, dwarf::DW_FORM_sec_offset,
2177+
DIEInteger(INT_MAX));
2178+
auto RangesWriterIterator =
2179+
LegacyRangesWritersByCU.find(*Unit.getDWOId());
2180+
assert(RangesWriterIterator != LegacyRangesWritersByCU.end() &&
2181+
"RangesWriter does not exist for DWOId");
2182+
RangesWriterIterator->second->setDie(&Die);
2183+
}
21472184
}
21482185

2149-
uint64_t RangeAttrVal = RangesSectionOffset - BaseOffset;
2150-
if (Unit.getVersion() >= 5)
2151-
RangeAttrVal = RangesSectionOffset;
21522186
// HighPC was conveted into DW_AT_ranges.
21532187
// For DWARF5 we only access ranges through index.
21542188

21552189
DIEBldr.replaceValue(&Die, HighPCAttrInfo.getAttribute(), dwarf::DW_AT_ranges,
2156-
RangesForm, DIEInteger(RangeAttrVal));
2190+
RangesForm, DIEInteger(RangesSectionOffset));
21572191
}

bolt/test/X86/debug-fission-single-convert.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
# CHECK-DWO-DWO: 00000010
3232
# CHECK-DWO-DWO: 00000050
3333
# CHECK-DWO-DWO: DW_TAG_subprogram
34-
# CHECK-DWO-DWO-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000
34+
# CHECK-DWO-DWO-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000010
3535
# CHECK-DWO-DWO: DW_TAG_subprogram
36-
# CHECK-DWO-DWO-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000020
36+
# CHECK-DWO-DWO-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000030
3737
# CHECK-DWO-DWO: DW_TAG_subprogram
38-
# CHECK-DWO-DWO-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000040
38+
# CHECK-DWO-DWO-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000050
3939

4040
# CHECK-ADDR-SEC: .debug_addr contents:
4141
# CHECK-ADDR-SEC: 0x00000000: Addrs: [

bolt/test/X86/dwarf4-df-dualcu.test

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,38 @@
3737

3838
; BOLT: .debug_ranges
3939
; BOLT-NEXT: 00000000 <End of list>
40-
; BOLT-NEXT: 00000010 [[#%.16x,ADDR:]] [[#%.16x,ADDRB:]]
40+
; BOLT-NEXT: 00000010 [[#%.16x,ADDR1:]] [[#%.16x,ADDRB1:]]
41+
; BOLT-NEXT: 00000010 [[#%.16x,ADDR2:]] [[#%.16x,ADDRB2:]]
4142
; BOLT-NEXT: 00000010 <End of list>
42-
; BOLT-NEXT: 00000030 [[#%.16x,ADDR1:]] [[#%.16x,ADDR1B:]]
43-
; BOLT-NEXT: 00000030 <End of list>
44-
; BOLT-NEXT: 00000050 [[#%.16x,ADDR2:]] [[#%.16x,ADDR2B:]]
45-
; BOLT-NEXT: 00000050 [[#%.16x,ADDR3:]] [[#%.16x,ADDR3B:]]
43+
; BOLT-NEXT: 00000040 <End of list>
44+
; BOLT-NEXT: 00000050 [[#%.16x,ADDR1:]] [[#%.16x,ADDRB1:]]
4645
; BOLT-NEXT: 00000050 <End of list>
47-
; BOLT-NEXT: 00000080 [[#%.16x,ADDR4:]] [[#%.16x,ADDR4B:]]
48-
; BOLT-NEXT: 00000080 <End of list>
49-
; BOLT-NEXT: 000000a0 [[#%.16x,ADDR5:]] [[#%.16x,ADDR5B:]]
50-
; BOLT-NEXT: 000000a0 <End of list>
46+
; BOLT-NEXT: 00000070 [[#%.16x,ADDR2:]] [[#%.16x,ADDRB2:]]
47+
; BOLT-NEXT: 00000070 <End of list>
48+
; BOLT-NEXT: 00000090 [[#%.16x,ADDR3:]] [[#%.16x,ADDRB3:]]
49+
; BOLT-NEXT: 00000090 <End of list>
50+
; BOLT-NEXT: 000000b0 <End of list>
51+
; BOLT-NEXT: 000000c0 [[#%.16x,ADDR3:]] [[#%.16x,ADDRB3:]]
52+
; BOLT-NEXT: 000000c0 <End of list>
5153

5254
; BOLT: DW_TAG_compile_unit
5355
; BOLT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000016] = "main.dwo.dwo")
5456
; BOLT-NEXT: DW_AT_GNU_dwo_id
5557
; BOLT-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
56-
; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000050
57-
; BOLT-NEXT: [0x[[#ADDR2]], 0x[[#ADDR2B]])
58-
; BOLT-NEXT: [0x[[#ADDR3]], 0x[[#ADDR3B]]))
58+
; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000010
59+
; BOLT-NEXT: [0x[[#ADDR1]], 0x[[#ADDRB1]])
60+
; BOLT-NEXT: [0x[[#ADDR2]], 0x[[#ADDRB2]]))
5961
; BOLT-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000)
60-
; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x00000010)
62+
; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x00000040)
6163
; BOLT-NEXT: Compile
6264
; BOLT: DW_TAG_compile_unit
6365
; BOLT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000023] = "helper.dwo.dwo")
6466
; BOLT-NEXT: DW_AT_GNU_dwo_id
6567
; BOLT-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
66-
; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x000000a0
67-
; BOLT-NEXT: [0x[[#ADDR5]], 0x[[#ADDR5B]])
68+
; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000090
69+
; BOLT-NEXT: [0x[[#ADDR3]], 0x[[#ADDRB3]])
6870
; BOLT-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000010)
69-
; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x00000080)
71+
; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x000000b0)
7072

7173
; PRE-BOLT-DWO-MAIN: version = 0x0004
7274
; PRE-BOLT-DWO-MAIN: DW_TAG_compile_unit
@@ -113,13 +115,13 @@
113115
; BOLT-DWO-MAIN-NEXT: DW_AT_decl_line
114116
; BOLT-DWO-MAIN-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x1)
115117
; BOLT-DWO-MAIN: DW_TAG_subprogram [4]
116-
; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000
118+
; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000010
117119
; BOLT-DWO-MAIN-NEXT: )
118120
; BOLT-DWO-MAIN-NEXT: DW_AT_frame_base
119121
; BOLT-DWO-MAIN-NEXT: DW_AT_linkage_name [DW_FORM_GNU_str_index] (indexed (00000003) string = "_Z3usePiS_")
120122
; BOLT-DWO-MAIN-NEXT: DW_AT_name [DW_FORM_GNU_str_index] (indexed (00000004) string = "use")
121123
; BOLT-DWO-MAIN: DW_TAG_subprogram [6]
122-
; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000020
124+
; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000030
123125
; BOLT-DWO-MAIN-NEXT: )
124126
; BOLT-DWO-MAIN-NEXT: DW_AT_frame_base [DW_FORM_exprloc] (DW_OP_reg6 RBP)
125127
; BOLT-DWO-MAIN-NEXT: DW_AT_name [DW_FORM_GNU_str_index] (indexed (00000005) string = "main")
@@ -160,4 +162,4 @@
160162
; BOLT-DWO-HELPER-NEXT: DW_AT_decl_line
161163
; BOLT-DWO-HELPER-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x1)
162164
; BOLT-DWO-HELPER: DW_TAG_subprogram [4]
163-
; BOLT-DWO-HELPER-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000
165+
; BOLT-DWO-HELPER-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000010

0 commit comments

Comments
 (0)