1 //===- bolt/Rewrite/DWARFRewriter.cpp -------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "bolt/Rewrite/DWARFRewriter.h"
10 #include "bolt/Core/BinaryContext.h"
11 #include "bolt/Core/BinaryFunction.h"
12 #include "bolt/Core/DIEBuilder.h"
13 #include "bolt/Core/DebugData.h"
14 #include "bolt/Core/DynoStats.h"
15 #include "bolt/Core/ParallelUtilities.h"
16 #include "bolt/Rewrite/RewriteInstance.h"
17 #include "bolt/Utils/Utils.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/BinaryFormat/Dwarf.h"
22 #include "llvm/CodeGen/AsmPrinter.h"
23 #include "llvm/CodeGen/DIE.h"
24 #include "llvm/DWARFLinker/Classic/DWARFStreamer.h"
25 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
26 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
27 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
28 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
29 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
30 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
31 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
32 #include "llvm/MC/MCAsmBackend.h"
33 #include "llvm/MC/MCAsmLayout.h"
34 #include "llvm/MC/MCObjectWriter.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/Object/ObjectFile.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/CommandLine.h"
39 #include "llvm/Support/Debug.h"
40 #include "llvm/Support/Endian.h"
41 #include "llvm/Support/Error.h"
42 #include "llvm/Support/FileSystem.h"
43 #include "llvm/Support/LEB128.h"
44 #include "llvm/Support/ThreadPool.h"
45 #include "llvm/Support/raw_ostream.h"
53 #include <unordered_map>
58 #define DEBUG_TYPE "bolt"
60 static void printDie(const DWARFDie
&DIE
) {
61 DIDumpOptions DumpOpts
;
62 DumpOpts
.ShowForm
= true;
63 DumpOpts
.Verbose
= true;
64 DumpOpts
.ChildRecurseDepth
= 0;
65 DumpOpts
.ShowChildren
= false;
66 DIE
.dump(dbgs(), 0, DumpOpts
);
69 /// Lazily parse DWARF DIE and print it out.
71 static void printDie(DWARFUnit
&DU
, uint64_t DIEOffset
) {
72 uint64_t OriginalOffsets
= DIEOffset
;
73 uint64_t NextCUOffset
= DU
.getNextUnitOffset();
74 DWARFDataExtractor DebugInfoData
= DU
.getDebugInfoExtractor();
75 DWARFDebugInfoEntry DIEEntry
;
76 if (DIEEntry
.extractFast(DU
, &DIEOffset
, DebugInfoData
, NextCUOffset
, 0)) {
77 if (const DWARFAbbreviationDeclaration
*AbbrDecl
=
78 DIEEntry
.getAbbreviationDeclarationPtr()) {
79 DWARFDie
DDie(&DU
, &DIEEntry
);
82 dbgs() << "Failed to extract abbreviation for"
83 << Twine::utohexstr(OriginalOffsets
) << "\n";
86 dbgs() << "Failed to extract DIE for " << Twine::utohexstr(OriginalOffsets
)
93 /// Take a set of DWARF address ranges corresponding to the input binary and
94 /// translate them to a set of address ranges in the output binary.
95 static DebugAddressRangesVector
96 translateInputToOutputRanges(const BinaryFunction
&BF
,
97 const DWARFAddressRangesVector
&InputRanges
) {
98 DebugAddressRangesVector OutputRanges
;
100 // If the function hasn't changed return the same ranges.
101 if (!BF
.isEmitted()) {
102 OutputRanges
.resize(InputRanges
.size());
103 llvm::transform(InputRanges
, OutputRanges
.begin(),
104 [](const DWARFAddressRange
&Range
) {
105 return DebugAddressRange(Range
.LowPC
, Range
.HighPC
);
110 for (const DWARFAddressRange
&Range
: InputRanges
)
111 llvm::append_range(OutputRanges
, BF
.translateInputToOutputRange(
112 {Range
.LowPC
, Range
.HighPC
}));
114 // Post-processing pass to sort and merge ranges.
115 llvm::sort(OutputRanges
);
116 DebugAddressRangesVector MergedRanges
;
117 uint64_t PrevHighPC
= 0;
118 for (const DebugAddressRange
&Range
: OutputRanges
) {
119 if (Range
.LowPC
<= PrevHighPC
) {
120 MergedRanges
.back().HighPC
=
121 std::max(MergedRanges
.back().HighPC
, Range
.HighPC
);
123 MergedRanges
.emplace_back(Range
.LowPC
, Range
.HighPC
);
125 PrevHighPC
= MergedRanges
.back().HighPC
;
131 /// Similar to translateInputToOutputRanges() but operates on location lists.
132 static DebugLocationsVector
133 translateInputToOutputLocationList(const BinaryFunction
&BF
,
134 const DebugLocationsVector
&InputLL
) {
135 DebugLocationsVector OutputLL
;
137 // If the function hasn't changed - there's nothing to update.
141 for (const DebugLocationEntry
&Entry
: InputLL
) {
142 DebugAddressRangesVector OutRanges
=
143 BF
.translateInputToOutputRange({Entry
.LowPC
, Entry
.HighPC
});
144 if (!OutRanges
.empty() && !OutputLL
.empty()) {
145 if (OutRanges
.front().LowPC
== OutputLL
.back().HighPC
&&
146 Entry
.Expr
== OutputLL
.back().Expr
) {
147 OutputLL
.back().HighPC
=
148 std::max(OutputLL
.back().HighPC
, OutRanges
.front().HighPC
);
149 OutRanges
.erase(OutRanges
.begin());
152 llvm::transform(OutRanges
, std::back_inserter(OutputLL
),
153 [&Entry
](const DebugAddressRange
&R
) {
154 return DebugLocationEntry
{R
.LowPC
, R
.HighPC
, Entry
.Expr
};
158 // Sort and merge adjacent entries with identical locations.
160 OutputLL
, [](const DebugLocationEntry
&A
, const DebugLocationEntry
&B
) {
161 return A
.LowPC
< B
.LowPC
;
163 DebugLocationsVector MergedLL
;
164 uint64_t PrevHighPC
= 0;
165 const SmallVectorImpl
<uint8_t> *PrevExpr
= nullptr;
166 for (const DebugLocationEntry
&Entry
: OutputLL
) {
167 if (Entry
.LowPC
<= PrevHighPC
&& *PrevExpr
== Entry
.Expr
) {
168 MergedLL
.back().HighPC
= std::max(Entry
.HighPC
, MergedLL
.back().HighPC
);
170 const uint64_t Begin
= std::max(Entry
.LowPC
, PrevHighPC
);
171 const uint64_t End
= std::max(Begin
, Entry
.HighPC
);
172 MergedLL
.emplace_back(DebugLocationEntry
{Begin
, End
, Entry
.Expr
});
174 PrevHighPC
= MergedLL
.back().HighPC
;
175 PrevExpr
= &MergedLL
.back().Expr
;
181 using namespace dwarf_linker
;
182 using namespace dwarf_linker::classic
;
186 /// Emits debug information into .debug_info or .debug_types section.
187 class DIEStreamer
: public DwarfStreamer
{
189 DWARFRewriter
&Rewriter
;
192 /// Emit the compilation unit header for \p Unit in the debug_info
195 /// A Dwarf 4 section header is encoded as:
196 /// uint32_t Unit length (omitting this field)
198 /// uint32_t Abbreviation table offset
199 /// uint8_t Address size
200 /// Leading to a total of 11 bytes.
202 /// A Dwarf 5 section header is encoded as:
203 /// uint32_t Unit length (omitting this field)
205 /// uint8_t Unit type
206 /// uint8_t Address size
207 /// uint32_t Abbreviation table offset
208 /// Leading to a total of 12 bytes.
209 void emitCompileUnitHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
,
210 unsigned DwarfVersion
) {
212 AsmPrinter
&Asm
= getAsmPrinter();
213 switchToDebugInfoSection(DwarfVersion
);
215 emitCommonHeader(Unit
, UnitDIE
, DwarfVersion
);
217 if (DwarfVersion
>= 5 &&
218 Unit
.getUnitType() != dwarf::UnitType::DW_UT_compile
) {
219 std::optional
<uint64_t> DWOId
= Unit
.getDWOId();
221 "DWOId does not exist and this is not a DW_UT_compile Unit");
222 Asm
.emitInt64(*DWOId
);
226 void emitCommonHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
, uint16_t Version
) {
227 dwarf::UnitType UT
= dwarf::UnitType(Unit
.getUnitType());
228 llvm::AsmPrinter
&Asm
= getAsmPrinter();
230 // Emit size of content not including length itself
231 Asm
.emitInt32(Unit
.getHeaderSize() + UnitDIE
.getSize() - 4);
232 Asm
.emitInt16(Version
);
234 // DWARF v5 reorders the address size and adds a unit type.
237 Asm
.emitInt8(Asm
.MAI
->getCodePointerSize());
242 Asm
.emitInt8(Asm
.MAI
->getCodePointerSize());
246 void emitTypeUnitHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
,
247 unsigned DwarfVersion
) {
248 AsmPrinter
&Asm
= getAsmPrinter();
249 const uint64_t TypeSignature
= cast
<DWARFTypeUnit
>(Unit
).getTypeHash();
250 DIE
*TypeDIE
= DIEBldr
->getTypeDIE(Unit
);
251 const DIEBuilder::DWARFUnitInfo
&UI
= DIEBldr
->getUnitInfoByDwarfUnit(Unit
);
252 Rewriter
.addGDBTypeUnitEntry(
253 {UI
.UnitOffset
, TypeSignature
, TypeDIE
->getOffset()});
254 if (Unit
.getVersion() < 5) {
255 // Switch the section to .debug_types section.
256 std::unique_ptr
<MCStreamer
> &MS
= Asm
.OutStreamer
;
257 llvm::MCContext
&MC
= Asm
.OutContext
;
258 const llvm::MCObjectFileInfo
*MOFI
= MC
.getObjectFileInfo();
260 MS
->switchSection(MOFI
->getDwarfTypesSection(0));
261 MC
.setDwarfVersion(DwarfVersion
);
263 switchToDebugInfoSection(DwarfVersion
);
265 emitCommonHeader(Unit
, UnitDIE
, DwarfVersion
);
266 Asm
.OutStreamer
->emitIntValue(TypeSignature
, sizeof(TypeSignature
));
267 Asm
.emitDwarfLengthOrOffset(TypeDIE
? TypeDIE
->getOffset() : 0);
270 void emitUnitHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
) {
271 if (Unit
.isTypeUnit())
272 emitTypeUnitHeader(Unit
, UnitDIE
, Unit
.getVersion());
274 emitCompileUnitHeader(Unit
, UnitDIE
, Unit
.getVersion());
277 void emitDIE(DIE
&Die
) override
{
278 AsmPrinter
&Asm
= getAsmPrinter();
279 Asm
.emitDwarfDIE(Die
);
283 DIEStreamer(DIEBuilder
*DIEBldr
, DWARFRewriter
&Rewriter
,
284 DWARFLinkerBase::OutputFileType OutFileType
,
285 raw_pwrite_stream
&OutFile
,
286 std::function
<StringRef(StringRef Input
)> Translator
,
287 DWARFLinkerBase::MessageHandlerTy Warning
)
288 : DwarfStreamer(OutFileType
, OutFile
, Translator
, Warning
),
289 DIEBldr(DIEBldr
), Rewriter(Rewriter
){};
291 using DwarfStreamer::emitCompileUnitHeader
;
293 void emitUnit(DWARFUnit
&Unit
, DIE
&UnitDIE
) {
294 emitUnitHeader(Unit
, UnitDIE
);
299 /// Finds attributes FormValue and Offset.
301 /// \param DIE die to look up in.
302 /// \param Attrs finds the first attribute that matches and extracts it.
303 /// \return an optional AttrInfo with DWARFFormValue and Offset.
304 std::optional
<AttrInfo
> findAttributeInfo(const DWARFDie DIE
,
305 std::vector
<dwarf::Attribute
> Attrs
) {
306 for (dwarf::Attribute
&Attr
: Attrs
)
307 if (std::optional
<AttrInfo
> Info
= findAttributeInfo(DIE
, Attr
))
315 using namespace llvm
;
316 using namespace llvm::support::endian
;
317 using namespace object
;
318 using namespace bolt
;
322 extern cl::OptionCategory BoltCategory
;
323 extern cl::opt
<unsigned> Verbosity
;
324 extern cl::opt
<std::string
> OutputFilename
;
326 static cl::opt
<bool> KeepARanges(
329 "keep or generate .debug_aranges section if .gdb_index is written"),
330 cl::Hidden
, cl::cat(BoltCategory
));
333 DeterministicDebugInfo("deterministic-debuginfo",
334 cl::desc("disables parallel execution of tasks that may produce "
335 "nondeterministic debug info"),
337 cl::cat(BoltCategory
));
339 static cl::opt
<std::string
> DwarfOutputPath(
341 cl::desc("Path to where .dwo files or dwp file will be written out to."),
342 cl::init(""), cl::cat(BoltCategory
));
345 WriteDWP("write-dwp",
346 cl::desc("output a single dwarf package file (dwp) instead of "
347 "multiple non-relocatable dwarf object files (dwo)."),
348 cl::init(false), cl::cat(BoltCategory
));
351 DebugSkeletonCu("debug-skeleton-cu",
352 cl::desc("prints out offsetrs for abbrev and debu_info of "
353 "Skeleton CUs that get patched."),
354 cl::ZeroOrMore
, cl::Hidden
, cl::init(false),
355 cl::cat(BoltCategory
));
357 static cl::opt
<unsigned> BatchSize(
358 "cu-processing-batch-size",
360 "Specifies the size of batches for processing CUs. Higher number has "
361 "better performance, but more memory usage. Default value is 1."),
362 cl::Hidden
, cl::init(1), cl::cat(BoltCategory
));
364 static cl::opt
<bool> AlwaysConvertToRanges(
365 "always-convert-to-ranges",
366 cl::desc("This option is for testing purposes only. It forces BOLT to "
367 "convert low_pc/high_pc to ranges always."),
368 cl::ReallyHidden
, cl::init(false), cl::cat(BoltCategory
));
371 static bool getLowAndHighPC(const DIE
&Die
, const DWARFUnit
&DU
,
372 uint64_t &LowPC
, uint64_t &HighPC
,
373 uint64_t &SectionIndex
) {
374 DIEValue DvalLowPc
= Die
.findAttribute(dwarf::DW_AT_low_pc
);
375 DIEValue DvalHighPc
= Die
.findAttribute(dwarf::DW_AT_high_pc
);
376 if (!DvalLowPc
|| !DvalHighPc
)
379 dwarf::Form Form
= DvalLowPc
.getForm();
380 bool AddrOffset
= Form
== dwarf::DW_FORM_LLVM_addrx_offset
;
381 uint64_t LowPcValue
= DvalLowPc
.getDIEInteger().getValue();
382 if (Form
== dwarf::DW_FORM_GNU_addr_index
|| Form
== dwarf::DW_FORM_addrx
||
385 uint32_t Index
= AddrOffset
? (LowPcValue
>> 32) : LowPcValue
;
386 std::optional
<object::SectionedAddress
> SA
=
387 DU
.getAddrOffsetSectionItem(Index
);
391 SA
->Address
+= (LowPcValue
& 0xffffffff);
394 SectionIndex
= SA
->SectionIndex
;
399 if (DvalHighPc
.getForm() == dwarf::DW_FORM_addr
)
400 HighPC
= DvalHighPc
.getDIEInteger().getValue();
402 HighPC
= LowPC
+ DvalHighPc
.getDIEInteger().getValue();
407 static Expected
<llvm::DWARFAddressRangesVector
>
408 getDIEAddressRanges(const DIE
&Die
, DWARFUnit
&DU
) {
409 uint64_t LowPC
, HighPC
, Index
;
410 if (getLowAndHighPC(Die
, DU
, LowPC
, HighPC
, Index
))
411 return DWARFAddressRangesVector
{{LowPC
, HighPC
, Index
}};
412 if (DIEValue Dval
= Die
.findAttribute(dwarf::DW_AT_ranges
)) {
413 if (Dval
.getForm() == dwarf::DW_FORM_rnglistx
)
414 return DU
.findRnglistFromIndex(Dval
.getDIEInteger().getValue());
416 return DU
.findRnglistFromOffset(Dval
.getDIEInteger().getValue());
419 return DWARFAddressRangesVector();
422 static std::optional
<uint64_t> getAsAddress(const DWARFUnit
&DU
,
423 const DIEValue
&AttrVal
) {
424 DWARFFormValue::ValueType
Value(AttrVal
.getDIEInteger().getValue());
425 if (std::optional
<object::SectionedAddress
> SA
=
426 DWARFFormValue::getAsSectionedAddress(Value
, AttrVal
.getForm(), &DU
))
431 /// Returns DWO Name to be used. Handles case where user specifies output DWO
432 /// directory, and there are duplicate names. Assumes DWO ID is unique.
434 getDWOName(llvm::DWARFUnit
&CU
,
435 std::unordered_map
<std::string
, uint32_t> &NameToIndexMap
) {
436 std::optional
<uint64_t> DWOId
= CU
.getDWOId();
437 assert(DWOId
&& "DWO ID not found.");
440 std::string DWOName
= dwarf::toString(
441 CU
.getUnitDIE().find({dwarf::DW_AT_dwo_name
, dwarf::DW_AT_GNU_dwo_name
}),
443 assert(!DWOName
.empty() &&
444 "DW_AT_dwo_name/DW_AT_GNU_dwo_name does not exists.");
445 if (!opts::DwarfOutputPath
.empty()) {
446 DWOName
= std::string(sys::path::filename(DWOName
));
447 auto Iter
= NameToIndexMap
.find(DWOName
);
448 if (Iter
== NameToIndexMap
.end())
449 Iter
= NameToIndexMap
.insert({DWOName
, 0}).first
;
450 DWOName
.append(std::to_string(Iter
->second
));
453 DWOName
.append(".dwo");
457 static std::unique_ptr
<DIEStreamer
>
458 createDIEStreamer(const Triple
&TheTriple
, raw_pwrite_stream
&OutFile
,
459 StringRef Swift5ReflectionSegmentName
, DIEBuilder
&DIEBldr
,
460 DWARFRewriter
&Rewriter
) {
462 std::unique_ptr
<DIEStreamer
> Streamer
= std::make_unique
<DIEStreamer
>(
463 &DIEBldr
, Rewriter
, DWARFLinkerBase::OutputFileType::Object
, OutFile
,
464 [](StringRef Input
) -> StringRef
{ return Input
; },
465 [&](const Twine
&Warning
, StringRef Context
, const DWARFDie
*) {});
466 Error Err
= Streamer
->init(TheTriple
, Swift5ReflectionSegmentName
);
469 << "BOLT-WARNING: [internal-dwarf-error]: Could not init DIEStreamer!"
470 << toString(std::move(Err
)) << "\n";
474 static DWARFRewriter::UnitMeta
475 emitUnit(DIEBuilder
&DIEBldr
, DIEStreamer
&Streamer
, DWARFUnit
&Unit
) {
476 DIE
*UnitDIE
= DIEBldr
.getUnitDIEbyUnit(Unit
);
477 const DIEBuilder::DWARFUnitInfo
&U
= DIEBldr
.getUnitInfoByDwarfUnit(Unit
);
478 Streamer
.emitUnit(Unit
, *UnitDIE
);
479 uint64_t TypeHash
= 0;
480 if (DWARFTypeUnit
*DTU
= dyn_cast_or_null
<DWARFTypeUnit
>(&Unit
))
481 TypeHash
= DTU
->getTypeHash();
482 return {U
.UnitOffset
, U
.UnitLength
, TypeHash
};
485 static void emitDWOBuilder(const std::string
&DWOName
,
486 DIEBuilder
&DWODIEBuilder
, DWARFRewriter
&Rewriter
,
487 DWARFUnit
&SplitCU
, DWARFUnit
&CU
,
488 DWARFRewriter::DWPState
&State
,
489 DebugLocWriter
&LocWriter
) {
490 // Populate debug_info and debug_abbrev for current dwo into StringRef.
491 DWODIEBuilder
.generateAbbrevs();
492 DWODIEBuilder
.finish();
494 SmallVector
<char, 20> OutBuffer
;
495 std::shared_ptr
<raw_svector_ostream
> ObjOS
=
496 std::make_shared
<raw_svector_ostream
>(OutBuffer
);
497 const object::ObjectFile
*File
= SplitCU
.getContext().getDWARFObj().getFile();
498 auto TheTriple
= std::make_unique
<Triple
>(File
->makeTriple());
499 std::unique_ptr
<DIEStreamer
> Streamer
= createDIEStreamer(
500 *TheTriple
, *ObjOS
, "DwoStreamerInitAug2", DWODIEBuilder
, Rewriter
);
501 DWARFRewriter::UnitMetaVectorType TUMetaVector
;
502 DWARFRewriter::UnitMeta CUMI
= {0, 0, 0};
503 if (SplitCU
.getContext().getMaxDWOVersion() >= 5) {
504 for (std::unique_ptr
<llvm::DWARFUnit
> &CU
:
505 SplitCU
.getContext().dwo_info_section_units()) {
506 if (!CU
->isTypeUnit())
508 DWARFRewriter::UnitMeta MI
=
509 emitUnit(DWODIEBuilder
, *Streamer
, *CU
.get());
510 TUMetaVector
.emplace_back(MI
);
512 CUMI
= emitUnit(DWODIEBuilder
, *Streamer
, SplitCU
);
514 for (std::unique_ptr
<llvm::DWARFUnit
> &CU
:
515 SplitCU
.getContext().dwo_compile_units())
516 emitUnit(DWODIEBuilder
, *Streamer
, *CU
.get());
518 // emit debug_types sections for dwarf4
519 for (DWARFUnit
*CU
: DWODIEBuilder
.getDWARF4TUVector()) {
520 DWARFRewriter::UnitMeta MI
= emitUnit(DWODIEBuilder
, *Streamer
, *CU
);
521 TUMetaVector
.emplace_back(MI
);
525 Streamer
->emitAbbrevs(DWODIEBuilder
.getAbbrevs(),
526 SplitCU
.getContext().getMaxVersion());
529 std::unique_ptr
<MemoryBuffer
> ObjectMemBuffer
=
530 MemoryBuffer::getMemBuffer(ObjOS
->str(), "in-memory object file", false);
531 std::unique_ptr
<object::ObjectFile
> Obj
= cantFail(
532 object::ObjectFile::createObjectFile(ObjectMemBuffer
->getMemBufferRef()),
533 "error creating in-memory object");
535 DWARFRewriter::OverriddenSectionsMap OverriddenSections
;
536 for (const SectionRef
&Secs
: Obj
->sections()) {
537 StringRef Contents
= cantFail(Secs
.getContents());
538 StringRef Name
= cantFail(Secs
.getName());
539 DWARFSectionKind Kind
=
540 StringSwitch
<DWARFSectionKind
>(Name
)
541 .Case(".debug_abbrev", DWARFSectionKind::DW_SECT_ABBREV
)
542 .Case(".debug_info", DWARFSectionKind::DW_SECT_INFO
)
543 .Case(".debug_types", DWARFSectionKind::DW_SECT_EXT_TYPES
)
544 .Default(DWARFSectionKind::DW_SECT_EXT_unknown
);
545 if (Kind
== DWARFSectionKind::DW_SECT_EXT_unknown
)
547 OverriddenSections
[Kind
] = Contents
;
550 Rewriter
.updateDWP(CU
, OverriddenSections
, CUMI
, TUMetaVector
, State
,
553 Rewriter
.writeDWOFiles(CU
, OverriddenSections
, DWOName
, LocWriter
);
556 void DWARFRewriter::addStringHelper(DIEBuilder
&DIEBldr
, DIE
&Die
,
557 const DWARFUnit
&Unit
,
558 DIEValue
&DIEAttrInfo
, StringRef Str
) {
559 uint32_t NewOffset
= StrWriter
->addString(Str
);
560 if (Unit
.getVersion() >= 5) {
561 StrOffstsWriter
->updateAddressMap(DIEAttrInfo
.getDIEInteger().getValue(),
565 DIEBldr
.replaceValue(&Die
, DIEAttrInfo
.getAttribute(), DIEAttrInfo
.getForm(),
566 DIEInteger(NewOffset
));
569 using DWARFUnitVec
= std::vector
<DWARFUnit
*>;
570 using CUPartitionVector
= std::vector
<DWARFUnitVec
>;
571 /// Partitions CUs in to buckets. Bucket size is controlled by
572 /// cu-processing-batch-size. All the CUs that have cross CU reference reference
573 /// as a source are put in to the same initial bucket.
574 static CUPartitionVector
partitionCUs(DWARFContext
&DwCtx
) {
575 CUPartitionVector
Vec(2);
576 unsigned Counter
= 0;
577 const DWARFDebugAbbrev
*Abbr
= DwCtx
.getDebugAbbrev();
578 for (std::unique_ptr
<DWARFUnit
> &CU
: DwCtx
.compile_units()) {
579 Expected
<const DWARFAbbreviationDeclarationSet
*> AbbrDeclSet
=
580 Abbr
->getAbbreviationDeclarationSet(CU
->getAbbreviationsOffset());
582 consumeError(AbbrDeclSet
.takeError());
585 bool CrossCURefFound
= false;
586 for (const DWARFAbbreviationDeclaration
&Decl
: *AbbrDeclSet
.get()) {
587 for (const DWARFAbbreviationDeclaration::AttributeSpec
&Attr
:
589 if (Attr
.Form
== dwarf::DW_FORM_ref_addr
) {
590 CrossCURefFound
= true;
597 if (CrossCURefFound
) {
598 Vec
[0].push_back(CU
.get());
601 Vec
.back().push_back(CU
.get());
603 if (Counter
% opts::BatchSize
== 0 && !Vec
.back().empty())
609 void DWARFRewriter::updateDebugInfo() {
610 ErrorOr
<BinarySection
&> DebugInfo
= BC
.getUniqueSectionByName(".debug_info");
614 ARangesSectionWriter
= std::make_unique
<DebugARangesSectionWriter
>();
615 StrWriter
= std::make_unique
<DebugStrWriter
>(BC
);
617 StrOffstsWriter
= std::make_unique
<DebugStrOffsetsWriter
>();
619 if (!opts::DeterministicDebugInfo
) {
620 opts::DeterministicDebugInfo
= true;
621 errs() << "BOLT-WARNING: --deterministic-debuginfo is being deprecated\n";
624 if (BC
.isDWARF5Used()) {
625 AddrWriter
= std::make_unique
<DebugAddrWriterDwarf5
>(&BC
);
626 RangeListsSectionWriter
= std::make_unique
<DebugRangeListsSectionWriter
>();
627 DebugRangeListsSectionWriter::setAddressWriter(AddrWriter
.get());
629 AddrWriter
= std::make_unique
<DebugAddrWriter
>(&BC
);
632 if (BC
.isDWARFLegacyUsed())
633 LegacyRangesSectionWriter
= std::make_unique
<DebugRangesSectionWriter
>();
635 DebugLoclistWriter::setAddressWriter(AddrWriter
.get());
637 uint32_t CUIndex
= 0;
638 std::mutex AccessMutex
;
639 // Needs to be invoked in the same order as CUs are processed.
640 auto createRangeLocList
= [&](DWARFUnit
&CU
) -> DebugLocWriter
* {
641 std::lock_guard
<std::mutex
> Lock(AccessMutex
);
642 const uint16_t DwarfVersion
= CU
.getVersion();
643 if (DwarfVersion
>= 5) {
644 LocListWritersByCU
[CUIndex
] =
645 std::make_unique
<DebugLoclistWriter
>(CU
, DwarfVersion
, false);
647 if (std::optional
<uint64_t> DWOId
= CU
.getDWOId()) {
648 assert(RangeListsWritersByCU
.count(*DWOId
) == 0 &&
649 "RangeLists writer for DWO unit already exists.");
650 auto RangeListsSectionWriter
=
651 std::make_unique
<DebugRangeListsSectionWriter
>();
652 RangeListsSectionWriter
->initSection(CU
);
653 RangeListsWritersByCU
[*DWOId
] = std::move(RangeListsSectionWriter
);
657 LocListWritersByCU
[CUIndex
] = std::make_unique
<DebugLocWriter
>();
659 return LocListWritersByCU
[CUIndex
++].get();
662 // Unordered maps to handle name collision if output DWO directory is
664 std::unordered_map
<std::string
, uint32_t> NameToIndexMap
;
666 auto updateDWONameCompDir
= [&](DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
,
667 DIE
&UnitDIE
) -> std::string
{
668 DIEValue DWONameAttrInfo
= UnitDIE
.findAttribute(dwarf::DW_AT_dwo_name
);
669 if (!DWONameAttrInfo
)
670 DWONameAttrInfo
= UnitDIE
.findAttribute(dwarf::DW_AT_GNU_dwo_name
);
671 assert(DWONameAttrInfo
&& "DW_AT_dwo_name is not in Skeleton CU.");
672 std::string ObjectName
;
675 std::lock_guard
<std::mutex
> Lock(AccessMutex
);
676 ObjectName
= getDWOName(Unit
, NameToIndexMap
);
678 addStringHelper(DIEBldr
, UnitDIE
, Unit
, DWONameAttrInfo
,
681 DIEValue CompDirAttrInfo
= UnitDIE
.findAttribute(dwarf::DW_AT_comp_dir
);
682 assert(CompDirAttrInfo
&& "DW_AT_comp_dir is not in Skeleton CU.");
684 if (!opts::DwarfOutputPath
.empty()) {
685 if (!sys::fs::exists(opts::DwarfOutputPath
))
686 sys::fs::create_directory(opts::DwarfOutputPath
);
687 addStringHelper(DIEBldr
, UnitDIE
, Unit
, CompDirAttrInfo
,
688 opts::DwarfOutputPath
.c_str());
696 auto processUnitDIE
= [&](DWARFUnit
*Unit
, DIEBuilder
*DIEBlder
) {
697 // Check if the unit is a skeleton and we need special updates for it and
698 // its matching split/DWO CU.
699 std::optional
<DWARFUnit
*> SplitCU
;
700 std::optional
<uint64_t> RangesBase
;
701 std::optional
<uint64_t> DWOId
= Unit
->getDWOId();
703 SplitCU
= BC
.getDWOCU(*DWOId
);
704 DebugLocWriter
*DebugLocWriter
= createRangeLocList(*Unit
);
705 DebugRangesSectionWriter
*RangesSectionWriter
=
706 Unit
->getVersion() >= 5 ? RangeListsSectionWriter
.get()
707 : LegacyRangesSectionWriter
.get();
708 // Skipping CUs that failed to load.
710 DIEBuilder
DWODIEBuilder(&(*SplitCU
)->getContext(), true);
711 DWODIEBuilder
.buildDWOUnit(**SplitCU
);
712 std::string DWOName
= updateDWONameCompDir(
713 *Unit
, *DIEBlder
, *DIEBlder
->getUnitDIEbyUnit(*Unit
));
715 DebugLoclistWriter
DebugLocDWoWriter(*Unit
, Unit
->getVersion(), true);
716 DebugRangesSectionWriter
*TempRangesSectionWriter
= RangesSectionWriter
;
717 if (Unit
->getVersion() >= 5) {
718 TempRangesSectionWriter
= RangeListsWritersByCU
[*DWOId
].get();
720 RangesBase
= RangesSectionWriter
->getSectionOffset();
721 // For DWARF5 there is now .debug_rnglists.dwo, so don't need to
722 // update rnglists base.
724 DwoRangesBase
[*DWOId
] = *RangesBase
;
725 setDwoRangesBase(*DWOId
, *RangesBase
);
729 updateUnitDebugInfo(*(*SplitCU
), DWODIEBuilder
, DebugLocDWoWriter
,
730 *TempRangesSectionWriter
);
731 DebugLocDWoWriter
.finalize(DWODIEBuilder
,
732 *DWODIEBuilder
.getUnitDIEbyUnit(**SplitCU
));
733 if (Unit
->getVersion() >= 5)
734 TempRangesSectionWriter
->finalizeSection();
736 emitDWOBuilder(DWOName
, DWODIEBuilder
, *this, **SplitCU
, *Unit
, State
,
740 if (Unit
->getVersion() >= 5) {
741 RangesBase
= RangesSectionWriter
->getSectionOffset() +
742 getDWARF5RngListLocListHeaderSize();
743 RangesSectionWriter
->initSection(*Unit
);
744 StrOffstsWriter
->finalizeSection(*Unit
, *DIEBlder
);
747 updateUnitDebugInfo(*Unit
, *DIEBlder
, *DebugLocWriter
, *RangesSectionWriter
,
749 DebugLocWriter
->finalize(*DIEBlder
, *DIEBlder
->getUnitDIEbyUnit(*Unit
));
750 if (Unit
->getVersion() >= 5)
751 RangesSectionWriter
->finalizeSection();
752 AddrWriter
->update(*DIEBlder
, *Unit
);
755 DIEBuilder
DIEBlder(BC
.DwCtx
.get());
756 DIEBlder
.buildTypeUnits(StrOffstsWriter
.get());
757 SmallVector
<char, 20> OutBuffer
;
758 std::unique_ptr
<raw_svector_ostream
> ObjOS
=
759 std::make_unique
<raw_svector_ostream
>(OutBuffer
);
760 const object::ObjectFile
*File
= BC
.DwCtx
->getDWARFObj().getFile();
761 auto TheTriple
= std::make_unique
<Triple
>(File
->makeTriple());
762 std::unique_ptr
<DIEStreamer
> Streamer
=
763 createDIEStreamer(*TheTriple
, *ObjOS
, "TypeStreamer", DIEBlder
, *this);
764 CUOffsetMap OffsetMap
= finalizeTypeSections(DIEBlder
, *Streamer
);
766 const bool SingleThreadedMode
=
767 opts::NoThreads
|| opts::DeterministicDebugInfo
;
768 if (!SingleThreadedMode
)
769 DIEBlder
.buildCompileUnits();
770 if (SingleThreadedMode
) {
771 CUPartitionVector PartVec
= partitionCUs(*BC
.DwCtx
);
772 for (std::vector
<DWARFUnit
*> &Vec
: PartVec
) {
773 DIEBlder
.buildCompileUnits(Vec
);
774 for (DWARFUnit
*CU
: DIEBlder
.getProcessedCUs())
775 processUnitDIE(CU
, &DIEBlder
);
776 finalizeCompileUnits(DIEBlder
, *Streamer
, OffsetMap
,
777 DIEBlder
.getProcessedCUs());
780 // Update unit debug info in parallel
781 ThreadPool
&ThreadPool
= ParallelUtilities::getThreadPool();
782 for (std::unique_ptr
<DWARFUnit
> &CU
: BC
.DwCtx
->compile_units())
783 ThreadPool
.async(processUnitDIE
, CU
.get(), &DIEBlder
);
790 finalizeDebugSections(DIEBlder
, *Streamer
, *ObjOS
, OffsetMap
);
791 updateGdbIndexSection(OffsetMap
, CUIndex
);
794 void DWARFRewriter::updateUnitDebugInfo(
795 DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
, DebugLocWriter
&DebugLocWriter
,
796 DebugRangesSectionWriter
&RangesSectionWriter
,
797 std::optional
<uint64_t> RangesBase
) {
798 // Cache debug ranges so that the offset for identical ranges could be reused.
799 std::map
<DebugAddressRangesVector
, uint64_t> CachedRanges
;
801 uint64_t DIEOffset
= Unit
.getOffset() + Unit
.getHeaderSize();
802 uint64_t NextCUOffset
= Unit
.getNextUnitOffset();
803 const std::vector
<std::unique_ptr
<DIEBuilder::DIEInfo
>> &DIs
=
804 DIEBldr
.getDIEsByUnit(Unit
);
806 // Either updates or normalizes DW_AT_range to DW_AT_low_pc and DW_AT_high_pc.
807 auto updateLowPCHighPC
= [&](DIE
*Die
, const DIEValue
&LowPCVal
,
808 const DIEValue
&HighPCVal
, uint64_t LowPC
,
809 const uint64_t HighPC
) {
810 dwarf::Attribute AttrLowPC
= dwarf::DW_AT_low_pc
;
811 dwarf::Form FormLowPC
= dwarf::DW_FORM_addr
;
812 dwarf::Attribute AttrHighPC
= dwarf::DW_AT_high_pc
;
813 dwarf::Form FormHighPC
= dwarf::DW_FORM_data4
;
814 const uint32_t Size
= HighPC
- LowPC
;
815 // Whatever was generated is not low_pc/high_pc, so will reset to
816 // default for size 1.
817 if (!LowPCVal
|| !HighPCVal
) {
818 if (Unit
.getVersion() >= 5)
819 FormLowPC
= dwarf::DW_FORM_addrx
;
820 else if (Unit
.isDWOUnit())
821 FormLowPC
= dwarf::DW_FORM_GNU_addr_index
;
823 AttrLowPC
= LowPCVal
.getAttribute();
824 FormLowPC
= LowPCVal
.getForm();
825 AttrHighPC
= HighPCVal
.getAttribute();
826 FormHighPC
= HighPCVal
.getForm();
829 if (FormLowPC
== dwarf::DW_FORM_addrx
||
830 FormLowPC
== dwarf::DW_FORM_GNU_addr_index
)
831 LowPC
= AddrWriter
->getIndexFromAddress(LowPC
, Unit
);
834 DIEBldr
.replaceValue(Die
, AttrLowPC
, FormLowPC
, DIEInteger(LowPC
));
836 DIEBldr
.addValue(Die
, AttrLowPC
, FormLowPC
, DIEInteger(LowPC
));
838 DIEBldr
.replaceValue(Die
, AttrHighPC
, FormHighPC
, DIEInteger(Size
));
840 DIEBldr
.deleteValue(Die
, dwarf::DW_AT_ranges
);
841 DIEBldr
.addValue(Die
, AttrHighPC
, FormHighPC
, DIEInteger(Size
));
845 for (const std::unique_ptr
<DIEBuilder::DIEInfo
> &DI
: DIs
) {
847 switch (Die
->getTag()) {
848 case dwarf::DW_TAG_compile_unit
:
849 case dwarf::DW_TAG_skeleton_unit
: {
850 // For dwarf5 section 3.1.3
851 // The following attributes are not part of a split full compilation unit
852 // entry but instead are inherited (if present) from the corresponding
853 // skeleton compilation unit: DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges,
854 // DW_AT_stmt_list, DW_AT_comp_dir, DW_AT_str_offsets_base,
855 // DW_AT_addr_base and DW_AT_rnglists_base.
856 if (Unit
.getVersion() == 5 && Unit
.isDWOUnit())
858 auto ModuleRangesOrError
= getDIEAddressRanges(*Die
, Unit
);
859 if (!ModuleRangesOrError
) {
860 consumeError(ModuleRangesOrError
.takeError());
863 DWARFAddressRangesVector
&ModuleRanges
= *ModuleRangesOrError
;
864 DebugAddressRangesVector OutputRanges
=
865 BC
.translateModuleAddressRanges(ModuleRanges
);
866 DIEValue LowPCAttrInfo
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
867 // For a case where LLD GCs only function used in the CU.
868 // If CU doesn't have DW_AT_low_pc we are not going to convert,
869 // so don't need to do anything.
870 if (OutputRanges
.empty() && !Unit
.isDWOUnit() && LowPCAttrInfo
)
871 OutputRanges
.push_back({0, 0});
872 const uint64_t RangesSectionOffset
=
873 RangesSectionWriter
.addRanges(OutputRanges
);
874 if (!Unit
.isDWOUnit())
875 ARangesSectionWriter
->addCURanges(Unit
.getOffset(),
876 std::move(OutputRanges
));
877 updateDWARFObjectAddressRanges(Unit
, DIEBldr
, *Die
, RangesSectionOffset
,
879 DIEValue StmtListAttrVal
= Die
->findAttribute(dwarf::DW_AT_stmt_list
);
880 if (LineTablePatchMap
.count(&Unit
))
881 DIEBldr
.replaceValue(Die
, dwarf::DW_AT_stmt_list
,
882 StmtListAttrVal
.getForm(),
883 DIEInteger(LineTablePatchMap
[&Unit
]));
887 case dwarf::DW_TAG_subprogram
: {
888 // Get function address either from ranges or [LowPC, HighPC) pair.
889 uint64_t Address
= UINT64_MAX
;
890 uint64_t SectionIndex
, HighPC
;
891 DebugAddressRangesVector FunctionRanges
;
892 if (!getLowAndHighPC(*Die
, Unit
, Address
, HighPC
, SectionIndex
)) {
893 Expected
<DWARFAddressRangesVector
> RangesOrError
=
894 getDIEAddressRanges(*Die
, Unit
);
895 if (!RangesOrError
) {
896 consumeError(RangesOrError
.takeError());
899 DWARFAddressRangesVector Ranges
= *RangesOrError
;
900 // Not a function definition.
904 for (const DWARFAddressRange
&Range
: Ranges
) {
905 if (const BinaryFunction
*Function
=
906 BC
.getBinaryFunctionAtAddress(Range
.LowPC
))
907 FunctionRanges
.append(Function
->getOutputAddressRanges());
910 if (const BinaryFunction
*Function
=
911 BC
.getBinaryFunctionAtAddress(Address
))
912 FunctionRanges
= Function
->getOutputAddressRanges();
915 // Clear cached ranges as the new function will have its own set.
916 CachedRanges
.clear();
917 DIEValue LowPCVal
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
918 DIEValue HighPCVal
= Die
->findAttribute(dwarf::DW_AT_high_pc
);
919 if (FunctionRanges
.empty()) {
920 if (LowPCVal
&& HighPCVal
) {
921 FunctionRanges
.push_back({0, HighPCVal
.getDIEInteger().getValue()});
923 // I haven't seen this case, but who knows what other compilers
925 FunctionRanges
.push_back({0, 1});
926 errs() << "BOLT-WARNING: [internal-dwarf-error]: subprogram got GCed "
927 "by the linker, DW_AT_ranges is used\n";
931 if (FunctionRanges
.size() == 1 && !opts::AlwaysConvertToRanges
) {
932 updateLowPCHighPC(Die
, LowPCVal
, HighPCVal
, FunctionRanges
.back().LowPC
,
933 FunctionRanges
.back().HighPC
);
937 updateDWARFObjectAddressRanges(
938 Unit
, DIEBldr
, *Die
, RangesSectionWriter
.addRanges(FunctionRanges
));
942 case dwarf::DW_TAG_lexical_block
:
943 case dwarf::DW_TAG_inlined_subroutine
:
944 case dwarf::DW_TAG_try_block
:
945 case dwarf::DW_TAG_catch_block
: {
946 uint64_t RangesSectionOffset
= 0;
947 Expected
<DWARFAddressRangesVector
> RangesOrError
=
948 getDIEAddressRanges(*Die
, Unit
);
949 const BinaryFunction
*Function
=
950 RangesOrError
&& !RangesOrError
->empty()
951 ? BC
.getBinaryFunctionContainingAddress(
952 RangesOrError
->front().LowPC
)
954 DebugAddressRangesVector OutputRanges
;
956 OutputRanges
= translateInputToOutputRanges(*Function
, *RangesOrError
);
957 LLVM_DEBUG(if (OutputRanges
.empty() != RangesOrError
->empty()) {
958 dbgs() << "BOLT-DEBUG: problem with DIE at 0x"
959 << Twine::utohexstr(Die
->getOffset()) << " in CU at 0x"
960 << Twine::utohexstr(Unit
.getOffset()) << '\n';
962 if (opts::AlwaysConvertToRanges
|| OutputRanges
.size() > 1) {
963 RangesSectionOffset
= RangesSectionWriter
.addRanges(
964 std::move(OutputRanges
), CachedRanges
);
965 OutputRanges
.clear();
966 } else if (OutputRanges
.empty()) {
967 OutputRanges
.push_back({0, RangesOrError
.get().front().HighPC
});
969 } else if (!RangesOrError
) {
970 consumeError(RangesOrError
.takeError());
972 OutputRanges
.push_back({0, !RangesOrError
->empty()
973 ? RangesOrError
.get().front().HighPC
976 DIEValue LowPCVal
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
977 DIEValue HighPCVal
= Die
->findAttribute(dwarf::DW_AT_high_pc
);
978 if (OutputRanges
.size() == 1) {
979 updateLowPCHighPC(Die
, LowPCVal
, HighPCVal
, OutputRanges
.back().LowPC
,
980 OutputRanges
.back().HighPC
);
983 updateDWARFObjectAddressRanges(Unit
, DIEBldr
, *Die
, RangesSectionOffset
);
986 case dwarf::DW_TAG_call_site
: {
987 auto patchPC
= [&](DIE
*Die
, DIEValue
&AttrVal
, StringRef Entry
) -> void {
988 std::optional
<uint64_t> Address
= getAsAddress(Unit
, AttrVal
);
989 const BinaryFunction
*Function
=
990 BC
.getBinaryFunctionContainingAddress(*Address
);
991 uint64_t UpdatedAddress
= *Address
;
994 Function
->translateInputToOutputAddress(UpdatedAddress
);
996 if (AttrVal
.getForm() == dwarf::DW_FORM_addrx
) {
997 const uint32_t Index
=
998 AddrWriter
->getIndexFromAddress(UpdatedAddress
, Unit
);
999 DIEBldr
.replaceValue(Die
, AttrVal
.getAttribute(), AttrVal
.getForm(),
1001 } else if (AttrVal
.getForm() == dwarf::DW_FORM_addr
) {
1002 DIEBldr
.replaceValue(Die
, AttrVal
.getAttribute(), AttrVal
.getForm(),
1003 DIEInteger(UpdatedAddress
));
1005 errs() << "BOLT-ERROR: unsupported form for " << Entry
<< "\n";
1008 DIEValue CallPcAttrVal
= Die
->findAttribute(dwarf::DW_AT_call_pc
);
1010 patchPC(Die
, CallPcAttrVal
, "DW_AT_call_pc");
1012 DIEValue CallRetPcAttrVal
=
1013 Die
->findAttribute(dwarf::DW_AT_call_return_pc
);
1014 if (CallRetPcAttrVal
)
1015 patchPC(Die
, CallRetPcAttrVal
, "DW_AT_call_return_pc");
1020 // Handle any tag that can have DW_AT_location attribute.
1021 DIEValue LocAttrInfo
= Die
->findAttribute(dwarf::DW_AT_location
);
1022 DIEValue LowPCAttrInfo
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
1024 if (doesFormBelongToClass(LocAttrInfo
.getForm(),
1025 DWARFFormValue::FC_Constant
,
1026 Unit
.getVersion()) ||
1027 doesFormBelongToClass(LocAttrInfo
.getForm(),
1028 DWARFFormValue::FC_SectionOffset
,
1029 Unit
.getVersion())) {
1030 uint64_t Offset
= LocAttrInfo
.getForm() == dwarf::DW_FORM_loclistx
1031 ? LocAttrInfo
.getDIELocList().getValue()
1032 : LocAttrInfo
.getDIEInteger().getValue();
1033 DebugLocationsVector InputLL
;
1035 std::optional
<object::SectionedAddress
> SectionAddress
=
1036 Unit
.getBaseAddress();
1037 uint64_t BaseAddress
= 0;
1039 BaseAddress
= SectionAddress
->Address
;
1041 if (Unit
.getVersion() >= 5 &&
1042 LocAttrInfo
.getForm() == dwarf::DW_FORM_loclistx
) {
1043 std::optional
<uint64_t> LocOffset
= Unit
.getLoclistOffset(Offset
);
1044 assert(LocOffset
&& "Location Offset is invalid.");
1045 Offset
= *LocOffset
;
1048 Error E
= Unit
.getLocationTable().visitLocationList(
1049 &Offset
, [&](const DWARFLocationEntry
&Entry
) {
1050 switch (Entry
.Kind
) {
1052 llvm_unreachable("Unsupported DWARFLocationEntry Kind.");
1053 case dwarf::DW_LLE_end_of_list
:
1055 case dwarf::DW_LLE_base_address
: {
1056 assert(Entry
.SectionIndex
== SectionedAddress::UndefSection
&&
1057 "absolute address expected");
1058 BaseAddress
= Entry
.Value0
;
1061 case dwarf::DW_LLE_offset_pair
:
1063 (Entry
.SectionIndex
== SectionedAddress::UndefSection
&&
1064 (!Unit
.isDWOUnit() || Unit
.getVersion() == 5)) &&
1065 "absolute address expected");
1066 InputLL
.emplace_back(DebugLocationEntry
{
1067 BaseAddress
+ Entry
.Value0
, BaseAddress
+ Entry
.Value1
,
1070 case dwarf::DW_LLE_start_length
:
1071 InputLL
.emplace_back(DebugLocationEntry
{
1072 Entry
.Value0
, Entry
.Value0
+ Entry
.Value1
, Entry
.Loc
});
1074 case dwarf::DW_LLE_base_addressx
: {
1075 std::optional
<object::SectionedAddress
> EntryAddress
=
1076 Unit
.getAddrOffsetSectionItem(Entry
.Value0
);
1077 assert(EntryAddress
&& "base Address not found.");
1078 BaseAddress
= EntryAddress
->Address
;
1081 case dwarf::DW_LLE_startx_length
: {
1082 std::optional
<object::SectionedAddress
> EntryAddress
=
1083 Unit
.getAddrOffsetSectionItem(Entry
.Value0
);
1084 assert(EntryAddress
&& "Address does not exist.");
1085 InputLL
.emplace_back(DebugLocationEntry
{
1086 EntryAddress
->Address
,
1087 EntryAddress
->Address
+ Entry
.Value1
, Entry
.Loc
});
1090 case dwarf::DW_LLE_startx_endx
: {
1091 std::optional
<object::SectionedAddress
> StartAddress
=
1092 Unit
.getAddrOffsetSectionItem(Entry
.Value0
);
1093 assert(StartAddress
&& "Start Address does not exist.");
1094 std::optional
<object::SectionedAddress
> EndAddress
=
1095 Unit
.getAddrOffsetSectionItem(Entry
.Value1
);
1096 assert(EndAddress
&& "Start Address does not exist.");
1097 InputLL
.emplace_back(DebugLocationEntry
{
1098 StartAddress
->Address
, EndAddress
->Address
, Entry
.Loc
});
1105 if (E
|| InputLL
.empty()) {
1106 consumeError(std::move(E
));
1107 errs() << "BOLT-WARNING: empty location list detected at 0x"
1108 << Twine::utohexstr(Offset
) << " for DIE at 0x" << Die
1109 << " in CU at 0x" << Twine::utohexstr(Unit
.getOffset())
1112 const uint64_t Address
= InputLL
.front().LowPC
;
1113 DebugLocationsVector OutputLL
;
1114 if (const BinaryFunction
*Function
=
1115 BC
.getBinaryFunctionContainingAddress(Address
)) {
1116 OutputLL
= translateInputToOutputLocationList(*Function
, InputLL
);
1117 LLVM_DEBUG(if (OutputLL
.empty()) {
1118 dbgs() << "BOLT-DEBUG: location list translated to an empty "
1120 << Die
<< " in CU at 0x"
1121 << Twine::utohexstr(Unit
.getOffset()) << '\n';
1124 // It's possible for a subprogram to be removed and to have
1125 // address of 0. Adding this entry to output to preserve debug
1129 DebugLocWriter
.addList(DIEBldr
, *Die
, LocAttrInfo
, OutputLL
);
1132 assert((doesFormBelongToClass(LocAttrInfo
.getForm(),
1133 DWARFFormValue::FC_Exprloc
,
1134 Unit
.getVersion()) ||
1135 doesFormBelongToClass(LocAttrInfo
.getForm(),
1136 DWARFFormValue::FC_Block
,
1137 Unit
.getVersion())) &&
1138 "unexpected DW_AT_location form");
1139 if (Unit
.isDWOUnit() || Unit
.getVersion() >= 5) {
1140 std::vector
<uint8_t> Sblock
;
1141 DIEValueList
*AttrLocValList
;
1142 if (doesFormBelongToClass(LocAttrInfo
.getForm(),
1143 DWARFFormValue::FC_Exprloc
,
1144 Unit
.getVersion())) {
1145 for (const DIEValue
&Val
: LocAttrInfo
.getDIELoc().values()) {
1146 Sblock
.push_back(Val
.getDIEInteger().getValue());
1148 DIELoc
*LocAttr
= const_cast<DIELoc
*>(&LocAttrInfo
.getDIELoc());
1149 AttrLocValList
= static_cast<DIEValueList
*>(LocAttr
);
1151 for (const DIEValue
&Val
: LocAttrInfo
.getDIEBlock().values()) {
1152 Sblock
.push_back(Val
.getDIEInteger().getValue());
1154 DIEBlock
*BlockAttr
=
1155 const_cast<DIEBlock
*>(&LocAttrInfo
.getDIEBlock());
1156 AttrLocValList
= static_cast<DIEValueList
*>(BlockAttr
);
1158 ArrayRef
<uint8_t> Expr
= ArrayRef
<uint8_t>(Sblock
);
1160 StringRef((const char *)Expr
.data(), Expr
.size()),
1161 Unit
.getContext().isLittleEndian(), 0);
1162 DWARFExpression
LocExpr(Data
, Unit
.getAddressByteSize(),
1163 Unit
.getFormParams().Format
);
1164 uint32_t PrevOffset
= 0;
1165 DIEValueList
*NewAttr
;
1167 uint32_t NewExprSize
= 0;
1168 DIELoc
*Loc
= nullptr;
1169 DIEBlock
*Block
= nullptr;
1170 if (LocAttrInfo
.getForm() == dwarf::DW_FORM_exprloc
) {
1171 Loc
= DIEBldr
.allocateDIEValue
<DIELoc
>();
1173 Value
= DIEValue(LocAttrInfo
.getAttribute(),
1174 LocAttrInfo
.getForm(), Loc
);
1175 } else if (doesFormBelongToClass(LocAttrInfo
.getForm(),
1176 DWARFFormValue::FC_Block
,
1177 Unit
.getVersion())) {
1178 Block
= DIEBldr
.allocateDIEValue
<DIEBlock
>();
1180 Value
= DIEValue(LocAttrInfo
.getAttribute(),
1181 LocAttrInfo
.getForm(), Block
);
1183 errs() << "BOLT-WARNING: Unexpected Form value in Updating "
1188 for (const DWARFExpression::Operation
&Expr
: LocExpr
) {
1189 uint32_t CurEndOffset
= PrevOffset
+ 1;
1190 if (Expr
.getDescription().Op
.size() == 1)
1191 CurEndOffset
= Expr
.getOperandEndOffset(0);
1192 if (Expr
.getDescription().Op
.size() == 2)
1193 CurEndOffset
= Expr
.getOperandEndOffset(1);
1194 if (Expr
.getDescription().Op
.size() > 2)
1195 errs() << "BOLT-WARNING: [internal-dwarf-error]: Unsupported "
1196 "number of operands.\n";
1197 // not addr index, just copy.
1198 if (!(Expr
.getCode() == dwarf::DW_OP_GNU_addr_index
||
1199 Expr
.getCode() == dwarf::DW_OP_addrx
)) {
1200 auto Itr
= AttrLocValList
->values().begin();
1201 std::advance(Itr
, PrevOffset
);
1202 uint32_t CopyNum
= CurEndOffset
- PrevOffset
;
1203 NewExprSize
+= CopyNum
;
1205 DIEBldr
.addValue(NewAttr
, *Itr
);
1206 std::advance(Itr
, 1);
1209 const uint64_t Index
= Expr
.getRawOperand(0);
1210 std::optional
<object::SectionedAddress
> EntryAddress
=
1211 Unit
.getAddrOffsetSectionItem(Index
);
1212 assert(EntryAddress
&& "Address is not found.");
1213 assert(Index
<= std::numeric_limits
<uint32_t>::max() &&
1214 "Invalid Operand Index.");
1215 const uint32_t AddrIndex
= AddrWriter
->getIndexFromAddress(
1216 EntryAddress
->Address
, Unit
);
1217 // update Index into .debug_address section for DW_AT_location.
1218 // The Size field is not stored in IR, we need to minus 1 in
1219 // offset for each expr.
1221 raw_svector_ostream
OSE(Tmp
);
1222 encodeULEB128(AddrIndex
, OSE
);
1224 DIEBldr
.addValue(NewAttr
, static_cast<dwarf::Attribute
>(0),
1225 dwarf::DW_FORM_data1
,
1226 DIEInteger(Expr
.getCode()));
1228 for (uint8_t Byte
: Tmp
) {
1229 DIEBldr
.addValue(NewAttr
, static_cast<dwarf::Attribute
>(0),
1230 dwarf::DW_FORM_data1
, DIEInteger(Byte
));
1234 PrevOffset
= CurEndOffset
;
1237 // update the size since the index might be changed
1239 Loc
->setSize(NewExprSize
);
1241 Block
->setSize(NewExprSize
);
1242 DIEBldr
.replaceValue(Die
, LocAttrInfo
.getAttribute(),
1243 LocAttrInfo
.getForm(), Value
);
1246 } else if (LowPCAttrInfo
) {
1247 const std::optional
<uint64_t> Result
=
1248 LowPCAttrInfo
.getDIEInteger().getValue();
1249 if (Result
.has_value()) {
1250 const uint64_t Address
= Result
.value();
1251 uint64_t NewAddress
= 0;
1252 if (const BinaryFunction
*Function
=
1253 BC
.getBinaryFunctionContainingAddress(Address
)) {
1254 NewAddress
= Function
->translateInputToOutputAddress(Address
);
1256 << "BOLT-DEBUG: Fixing low_pc 0x"
1257 << Twine::utohexstr(Address
) << " for DIE with tag "
1258 << Die
->getTag() << " to 0x"
1259 << Twine::utohexstr(NewAddress
) << '\n');
1262 dwarf::Form Form
= LowPCAttrInfo
.getForm();
1263 assert(Form
!= dwarf::DW_FORM_LLVM_addrx_offset
&&
1264 "DW_FORM_LLVM_addrx_offset is not supported");
1265 std::lock_guard
<std::mutex
> Lock(DWARFRewriterMutex
);
1266 if (Form
== dwarf::DW_FORM_addrx
||
1267 Form
== dwarf::DW_FORM_GNU_addr_index
) {
1268 const uint32_t Index
= AddrWriter
->getIndexFromAddress(
1269 NewAddress
? NewAddress
: Address
, Unit
);
1270 DIEBldr
.replaceValue(Die
, LowPCAttrInfo
.getAttribute(),
1271 LowPCAttrInfo
.getForm(), DIEInteger(Index
));
1273 DIEBldr
.replaceValue(Die
, LowPCAttrInfo
.getAttribute(),
1274 LowPCAttrInfo
.getForm(),
1275 DIEInteger(NewAddress
));
1277 } else if (opts::Verbosity
>= 1) {
1278 errs() << "BOLT-WARNING: unexpected form value for attribute "
1285 if (DIEOffset
> NextCUOffset
)
1286 errs() << "BOLT-WARNING: corrupt DWARF detected at 0x"
1287 << Twine::utohexstr(Unit
.getOffset()) << '\n';
1290 void DWARFRewriter::updateDWARFObjectAddressRanges(
1291 DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
, DIE
&Die
, uint64_t DebugRangesOffset
,
1292 std::optional
<uint64_t> RangesBase
) {
1295 // If DW_AT_GNU_ranges_base is present, update it. No further modifications
1296 // are needed for ranges base.
1298 DIEValue RangesBaseInfo
= Die
.findAttribute(dwarf::DW_AT_GNU_ranges_base
);
1299 if (!RangesBaseInfo
) {
1300 RangesBaseInfo
= Die
.findAttribute(dwarf::DW_AT_rnglists_base
);
1303 if (RangesBaseInfo
) {
1304 DIEBldr
.replaceValue(&Die
, RangesBaseInfo
.getAttribute(),
1305 RangesBaseInfo
.getForm(),
1306 DIEInteger(static_cast<uint32_t>(*RangesBase
)));
1307 RangesBase
= std::nullopt
;
1311 DIEValue LowPCAttrInfo
= Die
.findAttribute(dwarf::DW_AT_low_pc
);
1312 DIEValue RangesAttrInfo
= Die
.findAttribute(dwarf::DW_AT_ranges
);
1313 if (RangesAttrInfo
) {
1314 // Case 1: The object was already non-contiguous and had DW_AT_ranges.
1315 // In this case we simply need to update the value of DW_AT_ranges
1316 // and introduce DW_AT_GNU_ranges_base if required.
1317 // For DWARF5 converting all of DW_AT_ranges into DW_FORM_rnglistx
1318 bool NeedConverted
= false;
1320 if (Unit
.getVersion() >= 5 &&
1321 RangesAttrInfo
.getForm() == dwarf::DW_FORM_sec_offset
)
1322 NeedConverted
= true;
1324 uint64_t CurRangeBase
= 0;
1325 if (Unit
.isDWOUnit()) {
1326 if (std::optional
<uint64_t> DWOId
= Unit
.getDWOId())
1327 CurRangeBase
= getDwoRangesBase(*DWOId
);
1329 errs() << "BOLT-WARNING: [internal-dwarf-error]: DWOId is not found "
1332 if (NeedConverted
|| RangesAttrInfo
.getForm() == dwarf::DW_FORM_rnglistx
)
1333 DIEBldr
.replaceValue(&Die
, dwarf::DW_AT_ranges
, dwarf::DW_FORM_rnglistx
,
1334 DIEInteger(DebugRangesOffset
));
1336 DIEBldr
.replaceValue(&Die
, dwarf::DW_AT_ranges
, RangesAttrInfo
.getForm(),
1337 DIEInteger(DebugRangesOffset
- CurRangeBase
));
1340 if (LowPCAttrInfo
&&
1341 LowPCAttrInfo
.getForm() != dwarf::DW_FORM_GNU_addr_index
&&
1342 LowPCAttrInfo
.getForm() != dwarf::DW_FORM_addrx
)
1343 DIEBldr
.replaceValue(&Die
, dwarf::DW_AT_low_pc
, LowPCAttrInfo
.getForm(),
1348 if (!(Die
.getTag() == dwarf::DW_TAG_compile_unit
||
1349 Die
.getTag() == dwarf::DW_TAG_skeleton_unit
))
1352 // If we are at this point we are in the CU/Skeleton CU, and
1353 // DW_AT_GNU_ranges_base or DW_AT_rnglists_base doesn't exist.
1354 if (Unit
.getVersion() <= 4)
1355 DIEBldr
.addValue(&Die
, dwarf::DW_AT_GNU_ranges_base
, dwarf::DW_FORM_data4
,
1356 DIEInteger(*RangesBase
));
1357 else if (Unit
.getVersion() == 5)
1358 DIEBldr
.addValue(&Die
, dwarf::DW_AT_rnglists_base
,
1359 dwarf::DW_FORM_sec_offset
, DIEInteger(*RangesBase
));
1361 DIEBldr
.addValue(&Die
, dwarf::DW_AT_rnglists_base
,
1362 dwarf::DW_FORM_sec_offset
, DIEInteger(*RangesBase
));
1366 // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back
1367 // to back. Replace with new attributes and patch the DIE.
1368 DIEValue HighPCAttrInfo
= Die
.findAttribute(dwarf::DW_AT_high_pc
);
1369 if (LowPCAttrInfo
&& HighPCAttrInfo
) {
1371 convertToRangesPatchDebugInfo(Unit
, DIEBldr
, Die
, DebugRangesOffset
,
1372 LowPCAttrInfo
, HighPCAttrInfo
, RangesBase
);
1373 } else if (!(Unit
.isDWOUnit() &&
1374 Die
.getTag() == dwarf::DW_TAG_compile_unit
)) {
1375 if (opts::Verbosity
>= 1)
1376 errs() << "BOLT-WARNING: cannot update ranges for DIE in Unit offset 0x"
1377 << Unit
.getOffset() << '\n';
1381 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout
&Layout
) {
1382 ErrorOr
<BinarySection
&> DbgInfoSection
=
1383 BC
.getUniqueSectionByName(".debug_info");
1384 ErrorOr
<BinarySection
&> TypeInfoSection
=
1385 BC
.getUniqueSectionByName(".debug_types");
1386 assert(((BC
.DwCtx
->getNumTypeUnits() > 0 && TypeInfoSection
) ||
1387 BC
.DwCtx
->getNumTypeUnits() == 0) &&
1388 "Was not able to retrieve Debug Types section.");
1390 // There is no direct connection between CU and TU, but same offsets,
1391 // encoded in DW_AT_stmt_list, into .debug_line get modified.
1392 // We take advantage of that to map original CU line table offsets to new
1394 std::unordered_map
<uint64_t, uint64_t> DebugLineOffsetMap
;
1396 auto GetStatementListValue
= [](DWARFUnit
*Unit
) {
1397 std::optional
<DWARFFormValue
> StmtList
=
1398 Unit
->getUnitDIE().find(dwarf::DW_AT_stmt_list
);
1399 std::optional
<uint64_t> Offset
= dwarf::toSectionOffset(StmtList
);
1400 assert(Offset
&& "Was not able to retrieve value of DW_AT_stmt_list.");
1404 for (const std::unique_ptr
<DWARFUnit
> &CU
: BC
.DwCtx
->compile_units()) {
1405 const unsigned CUID
= CU
->getOffset();
1406 MCSymbol
*Label
= BC
.getDwarfLineTable(CUID
).getLabel();
1410 std::optional
<AttrInfo
> AttrVal
=
1411 findAttributeInfo(CU
.get()->getUnitDIE(), dwarf::DW_AT_stmt_list
);
1415 const uint64_t LineTableOffset
= Layout
.getSymbolOffset(*Label
);
1416 DebugLineOffsetMap
[GetStatementListValue(CU
.get())] = LineTableOffset
;
1417 assert(DbgInfoSection
&& ".debug_info section must exist");
1418 LineTablePatchMap
[CU
.get()] = LineTableOffset
;
1421 for (const std::unique_ptr
<DWARFUnit
> &TU
: BC
.DwCtx
->types_section_units()) {
1422 DWARFUnit
*Unit
= TU
.get();
1423 std::optional
<AttrInfo
> AttrVal
=
1424 findAttributeInfo(TU
.get()->getUnitDIE(), dwarf::DW_AT_stmt_list
);
1427 auto Iter
= DebugLineOffsetMap
.find(GetStatementListValue(Unit
));
1428 assert(Iter
!= DebugLineOffsetMap
.end() &&
1429 "Type Unit Updated Line Number Entry does not exist.");
1430 TypeUnitRelocMap
[Unit
] = Iter
->second
;
1433 // Set .debug_info as finalized so it won't be skipped over when
1434 // we process sections while writing out the new binary. This ensures
1435 // that the pending relocations will be processed and not ignored.
1437 DbgInfoSection
->setIsFinalized();
1439 if (TypeInfoSection
)
1440 TypeInfoSection
->setIsFinalized();
1443 CUOffsetMap
DWARFRewriter::finalizeTypeSections(DIEBuilder
&DIEBlder
,
1444 DIEStreamer
&Streamer
) {
1445 // update TypeUnit DW_AT_stmt_list with new .debug_line information.
1446 for (const std::unique_ptr
<DWARFUnit
> &TU
: BC
.DwCtx
->types_section_units()) {
1447 DIE
*UnitDIE
= DIEBlder
.getUnitDIEbyUnit(*TU
.get());
1448 DIEValue StmtAttrInfo
= UnitDIE
->findAttribute(dwarf::DW_AT_stmt_list
);
1449 if (!StmtAttrInfo
|| !TypeUnitRelocMap
.count(TU
.get()))
1451 DIEBlder
.replaceValue(UnitDIE
, dwarf::DW_AT_stmt_list
,
1452 StmtAttrInfo
.getForm(),
1453 DIEInteger(TypeUnitRelocMap
[TU
.get()]));
1456 // generate and populate abbrevs here
1457 DIEBlder
.generateAbbrevs();
1459 SmallVector
<char, 20> OutBuffer
;
1460 std::shared_ptr
<raw_svector_ostream
> ObjOS
=
1461 std::make_shared
<raw_svector_ostream
>(OutBuffer
);
1462 const object::ObjectFile
*File
= BC
.DwCtx
->getDWARFObj().getFile();
1463 auto TheTriple
= std::make_unique
<Triple
>(File
->makeTriple());
1464 std::unique_ptr
<DIEStreamer
> TypeStreamer
=
1465 createDIEStreamer(*TheTriple
, *ObjOS
, "TypeStreamer", DIEBlder
, *this);
1467 // generate debug_info and CUMap
1469 for (std::unique_ptr
<llvm::DWARFUnit
> &CU
: BC
.DwCtx
->info_section_units()) {
1470 if (!CU
->isTypeUnit())
1472 emitUnit(DIEBlder
, Streamer
, *CU
.get());
1473 uint32_t StartOffset
= CUOffset
;
1474 DIE
*UnitDIE
= DIEBlder
.getUnitDIEbyUnit(*CU
.get());
1475 CUOffset
+= CU
.get()->getHeaderSize();
1476 CUOffset
+= UnitDIE
->getSize();
1477 CUMap
[CU
.get()->getOffset()] = {StartOffset
, CUOffset
- StartOffset
- 4};
1480 // Emit Type Unit of DWARF 4 to .debug_type section
1481 for (DWARFUnit
*TU
: DIEBlder
.getDWARF4TUVector())
1482 emitUnit(DIEBlder
, *TypeStreamer
, *TU
);
1484 TypeStreamer
->finish();
1486 std::unique_ptr
<MemoryBuffer
> ObjectMemBuffer
=
1487 MemoryBuffer::getMemBuffer(ObjOS
->str(), "in-memory object file", false);
1488 std::unique_ptr
<object::ObjectFile
> Obj
= cantFail(
1489 object::ObjectFile::createObjectFile(ObjectMemBuffer
->getMemBufferRef()),
1490 "error creating in-memory object");
1492 for (const SectionRef
&Section
: Obj
->sections()) {
1493 StringRef Contents
= cantFail(Section
.getContents());
1494 StringRef Name
= cantFail(Section
.getName());
1495 if (Name
.equals(".debug_types"))
1496 BC
.registerOrUpdateNoteSection(".debug_types", copyByteArray(Contents
),
1502 void DWARFRewriter::finalizeDebugSections(DIEBuilder
&DIEBlder
,
1503 DIEStreamer
&Streamer
,
1504 raw_svector_ostream
&ObjOS
,
1505 CUOffsetMap
&CUMap
) {
1506 if (StrWriter
->isInitialized()) {
1507 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
1508 std::unique_ptr
<DebugStrBufferVector
> DebugStrSectionContents
=
1509 StrWriter
->releaseBuffer();
1510 BC
.registerOrUpdateNoteSection(".debug_str",
1511 copyByteArray(*DebugStrSectionContents
),
1512 DebugStrSectionContents
->size());
1515 if (StrOffstsWriter
->isFinalized()) {
1516 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str_offsets");
1517 std::unique_ptr
<DebugStrOffsetsBufferVector
>
1518 DebugStrOffsetsSectionContents
= StrOffstsWriter
->releaseBuffer();
1519 BC
.registerOrUpdateNoteSection(
1520 ".debug_str_offsets", copyByteArray(*DebugStrOffsetsSectionContents
),
1521 DebugStrOffsetsSectionContents
->size());
1524 if (BC
.isDWARFLegacyUsed()) {
1525 std::unique_ptr
<DebugBufferVector
> RangesSectionContents
=
1526 LegacyRangesSectionWriter
->releaseBuffer();
1527 BC
.registerOrUpdateNoteSection(".debug_ranges",
1528 copyByteArray(*RangesSectionContents
),
1529 RangesSectionContents
->size());
1532 if (BC
.isDWARF5Used()) {
1533 std::unique_ptr
<DebugBufferVector
> RangesSectionContents
=
1534 RangeListsSectionWriter
->releaseBuffer();
1535 BC
.registerOrUpdateNoteSection(".debug_rnglists",
1536 copyByteArray(*RangesSectionContents
),
1537 RangesSectionContents
->size());
1540 if (BC
.isDWARF5Used()) {
1541 std::unique_ptr
<DebugBufferVector
> LocationListSectionContents
=
1542 makeFinalLocListsSection(DWARFVersion::DWARF5
);
1543 if (!LocationListSectionContents
->empty())
1544 BC
.registerOrUpdateNoteSection(
1545 ".debug_loclists", copyByteArray(*LocationListSectionContents
),
1546 LocationListSectionContents
->size());
1549 if (BC
.isDWARFLegacyUsed()) {
1550 std::unique_ptr
<DebugBufferVector
> LocationListSectionContents
=
1551 makeFinalLocListsSection(DWARFVersion::DWARFLegacy
);
1552 if (!LocationListSectionContents
->empty())
1553 BC
.registerOrUpdateNoteSection(
1554 ".debug_loc", copyByteArray(*LocationListSectionContents
),
1555 LocationListSectionContents
->size());
1558 // AddrWriter should be finalized after debug_loc since more addresses can be
1560 if (AddrWriter
->isInitialized()) {
1561 AddressSectionBuffer AddressSectionContents
= AddrWriter
->finalize();
1562 BC
.registerOrUpdateNoteSection(".debug_addr",
1563 copyByteArray(AddressSectionContents
),
1564 AddressSectionContents
.size());
1567 Streamer
.emitAbbrevs(DIEBlder
.getAbbrevs(), BC
.DwCtx
->getMaxVersion());
1570 std::unique_ptr
<MemoryBuffer
> ObjectMemBuffer
=
1571 MemoryBuffer::getMemBuffer(ObjOS
.str(), "in-memory object file", false);
1572 std::unique_ptr
<object::ObjectFile
> Obj
= cantFail(
1573 object::ObjectFile::createObjectFile(ObjectMemBuffer
->getMemBufferRef()),
1574 "error creating in-memory object");
1576 for (const SectionRef
&Secs
: Obj
->sections()) {
1577 StringRef Contents
= cantFail(Secs
.getContents());
1578 StringRef Name
= cantFail(Secs
.getName());
1579 if (Name
.equals(".debug_abbrev")) {
1580 BC
.registerOrUpdateNoteSection(".debug_abbrev", copyByteArray(Contents
),
1582 } else if (Name
.equals(".debug_info")) {
1583 BC
.registerOrUpdateNoteSection(".debug_info", copyByteArray(Contents
),
1588 // Skip .debug_aranges if we are re-generating .gdb_index.
1589 if (opts::KeepARanges
|| !BC
.getGdbIndexSection()) {
1590 SmallVector
<char, 16> ARangesBuffer
;
1591 raw_svector_ostream
OS(ARangesBuffer
);
1593 auto MAB
= std::unique_ptr
<MCAsmBackend
>(
1594 BC
.TheTarget
->createMCAsmBackend(*BC
.STI
, *BC
.MRI
, MCTargetOptions()));
1596 ARangesSectionWriter
->writeARangesSection(OS
, CUMap
);
1597 const StringRef
&ARangesContents
= OS
.str();
1599 BC
.registerOrUpdateNoteSection(".debug_aranges",
1600 copyByteArray(ARangesContents
),
1601 ARangesContents
.size());
1605 void DWARFRewriter::finalizeCompileUnits(DIEBuilder
&DIEBlder
,
1606 DIEStreamer
&Streamer
,
1608 const std::list
<DWARFUnit
*> &CUs
) {
1609 DIEBlder
.generateAbbrevs();
1611 // generate debug_info and CUMap
1612 for (DWARFUnit
*CU
: CUs
) {
1613 emitUnit(DIEBlder
, Streamer
, *CU
);
1614 const uint32_t StartOffset
= CUOffset
;
1615 DIE
*UnitDIE
= DIEBlder
.getUnitDIEbyUnit(*CU
);
1616 CUOffset
+= CU
->getHeaderSize();
1617 CUOffset
+= UnitDIE
->getSize();
1618 CUMap
[CU
->getOffset()] = {StartOffset
, CUOffset
- StartOffset
- 4};
1622 // Creates all the data structures necessary for creating MCStreamer.
1623 // They are passed by reference because they need to be kept around.
1624 // Also creates known debug sections. These are sections handled by
1625 // handleDebugDataPatching.
1628 std::unique_ptr
<BinaryContext
>
1629 createDwarfOnlyBC(const object::ObjectFile
&File
) {
1630 return cantFail(BinaryContext::createBinaryContext(
1632 DWARFContext::create(File
, DWARFContext::ProcessDebugRelocations::Ignore
,
1633 nullptr, "", WithColor::defaultErrorHandler
,
1634 WithColor::defaultWarningHandler
)));
1637 StringMap
<DWARFRewriter::KnownSectionsEntry
>
1638 createKnownSectionsMap(const MCObjectFileInfo
&MCOFI
) {
1639 StringMap
<DWARFRewriter::KnownSectionsEntry
> KnownSectionsTemp
= {
1640 {"debug_info.dwo", {MCOFI
.getDwarfInfoDWOSection(), DW_SECT_INFO
}},
1641 {"debug_types.dwo", {MCOFI
.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES
}},
1642 {"debug_str_offsets.dwo",
1643 {MCOFI
.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS
}},
1644 {"debug_str.dwo", {MCOFI
.getDwarfStrDWOSection(), DW_SECT_EXT_unknown
}},
1645 {"debug_loc.dwo", {MCOFI
.getDwarfLocDWOSection(), DW_SECT_EXT_LOC
}},
1646 {"debug_abbrev.dwo", {MCOFI
.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV
}},
1647 {"debug_line.dwo", {MCOFI
.getDwarfLineDWOSection(), DW_SECT_LINE
}},
1648 {"debug_loclists.dwo",
1649 {MCOFI
.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS
}},
1650 {"debug_rnglists.dwo",
1651 {MCOFI
.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS
}}};
1652 return KnownSectionsTemp
;
1655 StringRef
getSectionName(const SectionRef
&Section
) {
1656 Expected
<StringRef
> SectionName
= Section
.getName();
1657 assert(SectionName
&& "Invalid section name.");
1658 StringRef Name
= *SectionName
;
1659 Name
= Name
.substr(Name
.find_first_not_of("._"));
1663 // Exctracts an appropriate slice if input is DWP.
1664 // Applies patches or overwrites the section.
1665 std::optional
<StringRef
> updateDebugData(
1666 DWARFContext
&DWCtx
, StringRef SectionName
, StringRef SectionContents
,
1667 const StringMap
<DWARFRewriter::KnownSectionsEntry
> &KnownSections
,
1668 MCStreamer
&Streamer
, DWARFRewriter
&Writer
,
1669 const DWARFUnitIndex::Entry
*CUDWOEntry
, uint64_t DWOId
,
1670 std::unique_ptr
<DebugBufferVector
> &OutputBuffer
,
1671 DebugRangeListsSectionWriter
*RangeListsWriter
, DebugLocWriter
&LocWriter
,
1672 const llvm::bolt::DWARFRewriter::OverriddenSectionsMap
&OverridenSections
) {
1674 using DWOSectionContribution
=
1675 const DWARFUnitIndex::Entry::SectionContribution
;
1676 auto getSliceData
= [&](const DWARFUnitIndex::Entry
*DWOEntry
,
1677 StringRef OutData
, DWARFSectionKind Sec
,
1678 uint64_t &DWPOffset
) -> StringRef
{
1680 DWOSectionContribution
*DWOContrubution
= DWOEntry
->getContribution(Sec
);
1681 DWPOffset
= DWOContrubution
->getOffset();
1682 OutData
= OutData
.substr(DWPOffset
, DWOContrubution
->getLength());
1687 auto SectionIter
= KnownSections
.find(SectionName
);
1688 if (SectionIter
== KnownSections
.end())
1689 return std::nullopt
;
1690 Streamer
.switchSection(SectionIter
->second
.first
);
1691 uint64_t DWPOffset
= 0;
1693 auto getOverridenSection
=
1694 [&](DWARFSectionKind Kind
) -> std::optional
<StringRef
> {
1695 auto Iter
= OverridenSections
.find(Kind
);
1696 if (Iter
== OverridenSections
.end()) {
1698 << "BOLT-WARNING: [internal-dwarf-error]: Could not find overriden "
1700 << Twine::utohexstr(DWOId
) << ".\n";
1701 return std::nullopt
;
1703 return Iter
->second
;
1705 switch (SectionIter
->second
.second
) {
1707 if (!SectionName
.equals("debug_str.dwo"))
1708 errs() << "BOLT-WARNING: unsupported debug section: " << SectionName
1710 return SectionContents
;
1712 case DWARFSectionKind::DW_SECT_INFO
: {
1713 return getOverridenSection(DWARFSectionKind::DW_SECT_INFO
);
1715 case DWARFSectionKind::DW_SECT_EXT_TYPES
: {
1716 return getOverridenSection(DWARFSectionKind::DW_SECT_EXT_TYPES
);
1718 case DWARFSectionKind::DW_SECT_STR_OFFSETS
: {
1719 return getSliceData(CUDWOEntry
, SectionContents
,
1720 DWARFSectionKind::DW_SECT_STR_OFFSETS
, DWPOffset
);
1722 case DWARFSectionKind::DW_SECT_ABBREV
: {
1723 return getOverridenSection(DWARFSectionKind::DW_SECT_ABBREV
);
1725 case DWARFSectionKind::DW_SECT_EXT_LOC
:
1726 case DWARFSectionKind::DW_SECT_LOCLISTS
: {
1727 OutputBuffer
= LocWriter
.getBuffer();
1728 // Creating explicit StringRef here, otherwise
1729 // with implicit conversion it will take null byte as end of
1731 return StringRef(reinterpret_cast<const char *>(OutputBuffer
->data()),
1732 OutputBuffer
->size());
1734 case DWARFSectionKind::DW_SECT_LINE
: {
1735 return getSliceData(CUDWOEntry
, SectionContents
,
1736 DWARFSectionKind::DW_SECT_LINE
, DWPOffset
);
1738 case DWARFSectionKind::DW_SECT_RNGLISTS
: {
1739 assert(RangeListsWriter
&& "RangeListsWriter was not created.");
1740 OutputBuffer
= RangeListsWriter
->releaseBuffer();
1741 return StringRef(reinterpret_cast<const char *>(OutputBuffer
->data()),
1742 OutputBuffer
->size());
1749 void DWARFRewriter::initDWPState(DWPState
&State
) {
1750 SmallString
<0> OutputNameStr
;
1751 StringRef OutputName
;
1752 if (opts::DwarfOutputPath
.empty()) {
1754 Twine(opts::OutputFilename
).concat(".dwp").toStringRef(OutputNameStr
);
1756 StringRef ExeFileName
= llvm::sys::path::filename(opts::OutputFilename
);
1757 OutputName
= Twine(opts::DwarfOutputPath
)
1759 .concat(ExeFileName
)
1761 .toStringRef(OutputNameStr
);
1762 errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will "
1763 "possibly be written to another location that is not the same as "
1768 std::make_unique
<ToolOutputFile
>(OutputName
, EC
, sys::fs::OF_None
);
1769 const object::ObjectFile
*File
= BC
.DwCtx
->getDWARFObj().getFile();
1770 State
.TmpBC
= createDwarfOnlyBC(*File
);
1771 State
.Streamer
= State
.TmpBC
->createStreamer(State
.Out
->os());
1772 State
.MCOFI
= State
.Streamer
->getContext().getObjectFileInfo();
1773 State
.KnownSections
= createKnownSectionsMap(*State
.MCOFI
);
1774 MCSection
*const StrSection
= State
.MCOFI
->getDwarfStrDWOSection();
1776 // Data Structures for DWP book keeping
1777 // Size of array corresponds to the number of sections supported by DWO format
1780 State
.Strings
= std::make_unique
<DWPStringPool
>(*State
.Streamer
, StrSection
);
1782 // Setup DWP code once.
1783 DWARFContext
*DWOCtx
= BC
.getDWOContext();
1786 State
.CUIndex
= &DWOCtx
->getCUIndex();
1787 State
.IsDWP
= !State
.CUIndex
->getRows().empty();
1791 void DWARFRewriter::finalizeDWP(DWPState
&State
) {
1792 if (State
.Version
< 5) {
1793 // Lie about there being no info contributions so the TU index only includes
1794 // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
1795 // contribution to the info section, so we do not want to lie about it.
1796 State
.ContributionOffsets
[0] = 0;
1798 writeIndex(*State
.Streamer
.get(), State
.MCOFI
->getDwarfTUIndexSection(),
1799 State
.ContributionOffsets
, State
.TypeIndexEntries
,
1800 State
.IndexVersion
);
1802 if (State
.Version
< 5) {
1803 // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
1804 // section does not exist, so no need to do anything about this.
1805 State
.ContributionOffsets
[getContributionIndex(DW_SECT_EXT_TYPES
, 2)] = 0;
1806 // Unlie about the info contribution
1807 State
.ContributionOffsets
[0] = 1;
1809 writeIndex(*State
.Streamer
.get(), State
.MCOFI
->getDwarfCUIndexSection(),
1810 State
.ContributionOffsets
, State
.IndexEntries
, State
.IndexVersion
);
1812 State
.Streamer
->finish();
1816 void DWARFRewriter::updateDWP(DWARFUnit
&CU
,
1817 const OverriddenSectionsMap
&OverridenSections
,
1818 const DWARFRewriter::UnitMeta
&CUMI
,
1819 DWARFRewriter::UnitMetaVectorType
&TUMetaVector
,
1820 DWPState
&State
, DebugLocWriter
&LocWriter
) {
1821 const uint64_t DWOId
= *CU
.getDWOId();
1822 MCSection
*const StrOffsetSection
= State
.MCOFI
->getDwarfStrOffDWOSection();
1823 assert(StrOffsetSection
&& "StrOffsetSection does not exist.");
1824 // Skipping CUs that we failed to load.
1825 std::optional
<DWARFUnit
*> DWOCU
= BC
.getDWOCU(DWOId
);
1829 if (State
.Version
== 0) {
1830 State
.Version
= CU
.getVersion();
1831 State
.IndexVersion
= State
.Version
< 5 ? 2 : 5;
1832 } else if (State
.Version
!= CU
.getVersion()) {
1833 errs() << "BOLT-ERROR: incompatible DWARF compile unit versions\n";
1837 UnitIndexEntry CurEntry
= {};
1838 CurEntry
.DWOName
= dwarf::toString(
1839 CU
.getUnitDIE().find({dwarf::DW_AT_dwo_name
, dwarf::DW_AT_GNU_dwo_name
}),
1841 const char *Name
= CU
.getUnitDIE().getShortName();
1843 CurEntry
.Name
= Name
;
1844 StringRef CurStrSection
;
1845 StringRef CurStrOffsetSection
;
1847 // This maps each section contained in this file to its length.
1848 // This information is later on used to calculate the contributions,
1849 // i.e. offset and length, of each compile/type unit to a section.
1850 std::vector
<std::pair
<DWARFSectionKind
, uint32_t>> SectionLength
;
1852 const DWARFUnitIndex::Entry
*CUDWOEntry
= nullptr;
1854 CUDWOEntry
= State
.CUIndex
->getFromHash(DWOId
);
1856 bool StrSectionWrittenOut
= false;
1857 const object::ObjectFile
*DWOFile
=
1858 (*DWOCU
)->getContext().getDWARFObj().getFile();
1860 DebugRangeListsSectionWriter
*RangeListssWriter
= nullptr;
1861 if (CU
.getVersion() == 5) {
1862 assert(RangeListsWritersByCU
.count(DWOId
) != 0 &&
1863 "No RangeListsWriter for DWO ID.");
1864 RangeListssWriter
= RangeListsWritersByCU
[DWOId
].get();
1866 auto AddType
= [&](unsigned int Index
, uint32_t IndexVersion
, uint64_t Offset
,
1867 uint64_t Length
, uint64_t Hash
) -> void {
1868 UnitIndexEntry TUEntry
= CurEntry
;
1869 if (IndexVersion
< 5)
1870 TUEntry
.Contributions
[0] = {};
1871 TUEntry
.Contributions
[Index
].setOffset(Offset
);
1872 TUEntry
.Contributions
[Index
].setLength(Length
);
1873 State
.ContributionOffsets
[Index
] +=
1874 TUEntry
.Contributions
[Index
].getLength32();
1875 State
.TypeIndexEntries
.insert(std::make_pair(Hash
, TUEntry
));
1877 for (const SectionRef
&Section
: DWOFile
->sections()) {
1878 std::unique_ptr
<DebugBufferVector
> OutputData
;
1879 StringRef SectionName
= getSectionName(Section
);
1880 Expected
<StringRef
> ContentsExp
= Section
.getContents();
1881 assert(ContentsExp
&& "Invalid contents.");
1882 std::optional
<StringRef
> TOutData
= updateDebugData(
1883 (*DWOCU
)->getContext(), SectionName
, *ContentsExp
, State
.KnownSections
,
1884 *State
.Streamer
, *this, CUDWOEntry
, DWOId
, OutputData
,
1885 RangeListssWriter
, LocWriter
, OverridenSections
);
1889 StringRef OutData
= *TOutData
;
1890 if (SectionName
== "debug_types.dwo") {
1891 State
.Streamer
->emitBytes(OutData
);
1895 if (SectionName
.equals("debug_str.dwo")) {
1896 CurStrSection
= OutData
;
1898 // Since handleDebugDataPatching returned true, we already know this is
1900 auto SectionIter
= State
.KnownSections
.find(SectionName
);
1901 if (SectionIter
->second
.second
== DWARFSectionKind::DW_SECT_STR_OFFSETS
)
1902 CurStrOffsetSection
= OutData
;
1904 State
.Streamer
->emitBytes(OutData
);
1905 unsigned int Index
=
1906 getContributionIndex(SectionIter
->second
.second
, State
.IndexVersion
);
1907 uint64_t Offset
= State
.ContributionOffsets
[Index
];
1908 uint64_t Length
= OutData
.size();
1909 if (CU
.getVersion() >= 5 &&
1910 SectionIter
->second
.second
== DWARFSectionKind::DW_SECT_INFO
) {
1911 for (UnitMeta
&MI
: TUMetaVector
)
1912 MI
.Offset
+= State
.DebugInfoSize
;
1914 Offset
= State
.DebugInfoSize
+ CUMI
.Offset
;
1915 Length
= CUMI
.Length
;
1916 State
.DebugInfoSize
+= OutData
.size();
1918 CurEntry
.Contributions
[Index
].setOffset(Offset
);
1919 CurEntry
.Contributions
[Index
].setLength(Length
);
1920 State
.ContributionOffsets
[Index
] +=
1921 CurEntry
.Contributions
[Index
].getLength32();
1924 // Strings are combined in to a new string section, and de-duplicated
1926 if (!StrSectionWrittenOut
&& !CurStrOffsetSection
.empty() &&
1927 !CurStrSection
.empty()) {
1928 writeStringsAndOffsets(*State
.Streamer
.get(), *State
.Strings
.get(),
1929 StrOffsetSection
, CurStrSection
,
1930 CurStrOffsetSection
, CU
.getVersion());
1931 StrSectionWrittenOut
= true;
1934 CompileUnitIdentifiers CUI
{DWOId
, CurEntry
.Name
.c_str(),
1935 CurEntry
.DWOName
.c_str()};
1936 auto P
= State
.IndexEntries
.insert(std::make_pair(CUI
.Signature
, CurEntry
));
1938 Error Err
= buildDuplicateError(*P
.first
, CUI
, "");
1939 errs() << "BOLT-ERROR: " << toString(std::move(Err
)) << "\n";
1944 const unsigned Index
= getContributionIndex(
1945 State
.IndexVersion
< 5 ? DW_SECT_EXT_TYPES
: DW_SECT_INFO
,
1946 State
.IndexVersion
);
1947 for (UnitMeta
&MI
: TUMetaVector
)
1948 AddType(Index
, State
.IndexVersion
, MI
.Offset
, MI
.Length
, MI
.TUHash
);
1951 void DWARFRewriter::writeDWOFiles(
1952 DWARFUnit
&CU
, const OverriddenSectionsMap
&OverridenSections
,
1953 const std::string
&DWOName
, DebugLocWriter
&LocWriter
) {
1954 // Setup DWP code once.
1955 DWARFContext
*DWOCtx
= BC
.getDWOContext();
1956 const uint64_t DWOId
= *CU
.getDWOId();
1957 const DWARFUnitIndex
*CUIndex
= nullptr;
1960 CUIndex
= &DWOCtx
->getCUIndex();
1961 IsDWP
= !CUIndex
->getRows().empty();
1964 // Skipping CUs that we failed to load.
1965 std::optional
<DWARFUnit
*> DWOCU
= BC
.getDWOCU(DWOId
);
1967 errs() << "BOLT-WARNING: [internal-dwarf-error]: CU for DWO_ID "
1968 << Twine::utohexstr(DWOId
) << " is not found.\n";
1972 std::string CompDir
= opts::DwarfOutputPath
.empty()
1973 ? CU
.getCompilationDir()
1974 : opts::DwarfOutputPath
.c_str();
1975 auto FullPath
= CompDir
.append("/").append(DWOName
);
1978 std::unique_ptr
<ToolOutputFile
> TempOut
=
1979 std::make_unique
<ToolOutputFile
>(FullPath
, EC
, sys::fs::OF_None
);
1981 const DWARFUnitIndex::Entry
*CUDWOEntry
= nullptr;
1983 CUDWOEntry
= CUIndex
->getFromHash(DWOId
);
1985 const object::ObjectFile
*File
=
1986 (*DWOCU
)->getContext().getDWARFObj().getFile();
1987 std::unique_ptr
<BinaryContext
> TmpBC
= createDwarfOnlyBC(*File
);
1988 std::unique_ptr
<MCStreamer
> Streamer
= TmpBC
->createStreamer(TempOut
->os());
1989 const MCObjectFileInfo
&MCOFI
= *Streamer
->getContext().getObjectFileInfo();
1990 StringMap
<KnownSectionsEntry
> KnownSections
= createKnownSectionsMap(MCOFI
);
1992 DebugRangeListsSectionWriter
*RangeListssWriter
= nullptr;
1993 if (CU
.getVersion() == 5) {
1994 assert(RangeListsWritersByCU
.count(DWOId
) != 0 &&
1995 "No RangeListsWriter for DWO ID.");
1996 RangeListssWriter
= RangeListsWritersByCU
[DWOId
].get();
1998 // Handling .debug_rnglists.dwo separately. The original .o/.dwo might not
1999 // have .debug_rnglists so won't be part of the loop below.
2000 if (!RangeListssWriter
->empty()) {
2001 std::unique_ptr
<DebugBufferVector
> OutputData
;
2002 if (std::optional
<StringRef
> OutData
= updateDebugData(
2003 (*DWOCU
)->getContext(), "debug_rnglists.dwo", "", KnownSections
,
2004 *Streamer
, *this, CUDWOEntry
, DWOId
, OutputData
,
2005 RangeListssWriter
, LocWriter
, OverridenSections
))
2006 Streamer
->emitBytes(*OutData
);
2010 for (const SectionRef
&Section
: File
->sections()) {
2011 std::unique_ptr
<DebugBufferVector
> OutputData
;
2012 StringRef SectionName
= getSectionName(Section
);
2013 if (SectionName
== "debug_rnglists.dwo")
2015 Expected
<StringRef
> ContentsExp
= Section
.getContents();
2016 assert(ContentsExp
&& "Invalid contents.");
2017 if (std::optional
<StringRef
> OutData
= updateDebugData(
2018 (*DWOCU
)->getContext(), SectionName
, *ContentsExp
, KnownSections
,
2019 *Streamer
, *this, CUDWOEntry
, DWOId
, OutputData
, RangeListssWriter
,
2020 LocWriter
, OverridenSections
))
2021 Streamer
->emitBytes(*OutData
);
2027 void DWARFRewriter::addGDBTypeUnitEntry(const GDBIndexTUEntry
&&Entry
) {
2028 std::lock_guard
<std::mutex
> Lock(DWARFRewriterMutex
);
2029 if (!BC
.getGdbIndexSection())
2031 GDBIndexTUEntryVector
.emplace_back(Entry
);
2034 void DWARFRewriter::updateGdbIndexSection(CUOffsetMap
&CUMap
, uint32_t NumCUs
) {
2035 if (!BC
.getGdbIndexSection())
2038 // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
2039 // for .gdb_index section format.
2041 StringRef GdbIndexContents
= BC
.getGdbIndexSection()->getContents();
2043 const char *Data
= GdbIndexContents
.data();
2045 // Parse the header.
2046 const uint32_t Version
= read32le(Data
);
2047 if (Version
!= 7 && Version
!= 8) {
2048 errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n";
2052 // Some .gdb_index generators use file offsets while others use section
2053 // offsets. Hence we can only rely on offsets relative to each other,
2054 // and ignore their absolute values.
2055 const uint32_t CUListOffset
= read32le(Data
+ 4);
2056 const uint32_t CUTypesOffset
= read32le(Data
+ 8);
2057 const uint32_t AddressTableOffset
= read32le(Data
+ 12);
2058 const uint32_t SymbolTableOffset
= read32le(Data
+ 16);
2059 const uint32_t ConstantPoolOffset
= read32le(Data
+ 20);
2062 // Map CUs offsets to indices and verify existing index table.
2063 std::map
<uint32_t, uint32_t> OffsetToIndexMap
;
2064 const uint32_t CUListSize
= CUTypesOffset
- CUListOffset
;
2065 const uint32_t TUListSize
= AddressTableOffset
- CUTypesOffset
;
2066 const unsigned NUmCUsEncoded
= CUListSize
/ 16;
2067 unsigned MaxDWARFVersion
= BC
.DwCtx
->getMaxVersion();
2068 unsigned NumDWARF5TUs
=
2069 getGDBIndexTUEntryVector().size() - BC
.DwCtx
->getNumTypeUnits();
2070 bool SkipTypeUnits
= false;
2071 // For DWARF5 Types are in .debug_info.
2072 // LLD doesn't generate Types CU List, and in CU list offset
2073 // only includes CUs.
2074 // GDB 11+ includes only CUs in CU list and generates Types
2076 // GDB 9 includes CUs and TUs in CU list and generates TYpes
2077 // list. The NumCUs is CUs + TUs, so need to modify the check.
2079 // GDB-11, DWARF5: TU units from dwo are not included.
2080 // GDB-11, DWARF4: TU units from dwo are included.
2081 if (MaxDWARFVersion
>= 5)
2082 SkipTypeUnits
= !TUListSize
? true
2083 : ((NUmCUsEncoded
+ NumDWARF5TUs
) ==
2084 BC
.DwCtx
->getNumCompileUnits());
2086 if (!((CUListSize
== NumCUs
* 16) ||
2087 (CUListSize
== (NumCUs
+ NumDWARF5TUs
) * 16))) {
2088 errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n";
2091 DenseSet
<uint64_t> OriginalOffsets
;
2092 for (unsigned Index
= 0, Units
= BC
.DwCtx
->getNumCompileUnits();
2093 Index
< Units
; ++Index
) {
2094 const DWARFUnit
*CU
= BC
.DwCtx
->getUnitAtIndex(Index
);
2095 if (SkipTypeUnits
&& CU
->isTypeUnit())
2097 const uint64_t Offset
= read64le(Data
);
2099 if (CU
->getOffset() != Offset
) {
2100 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n";
2104 OriginalOffsets
.insert(Offset
);
2105 OffsetToIndexMap
[Offset
] = Index
;
2108 // Ignore old address table.
2109 const uint32_t OldAddressTableSize
= SymbolTableOffset
- AddressTableOffset
;
2110 // Move Data to the beginning of symbol table.
2111 Data
+= SymbolTableOffset
- CUTypesOffset
;
2113 // Calculate the size of the new address table.
2114 uint32_t NewAddressTableSize
= 0;
2115 for (const auto &CURangesPair
: ARangesSectionWriter
->getCUAddressRanges()) {
2116 const SmallVector
<DebugAddressRange
, 2> &Ranges
= CURangesPair
.second
;
2117 NewAddressTableSize
+= Ranges
.size() * 20;
2120 // Difference between old and new table (and section) sizes.
2121 // Could be negative.
2122 int32_t Delta
= NewAddressTableSize
- OldAddressTableSize
;
2124 size_t NewGdbIndexSize
= GdbIndexContents
.size() + Delta
;
2126 // Free'd by ExecutableFileMemoryManager.
2127 auto *NewGdbIndexContents
= new uint8_t[NewGdbIndexSize
];
2128 uint8_t *Buffer
= NewGdbIndexContents
;
2130 write32le(Buffer
, Version
);
2131 write32le(Buffer
+ 4, CUListOffset
);
2132 write32le(Buffer
+ 8, CUTypesOffset
);
2133 write32le(Buffer
+ 12, AddressTableOffset
);
2134 write32le(Buffer
+ 16, SymbolTableOffset
+ Delta
);
2135 write32le(Buffer
+ 20, ConstantPoolOffset
+ Delta
);
2138 using MapEntry
= std::pair
<uint32_t, CUInfo
>;
2139 std::vector
<MapEntry
> CUVector(CUMap
.begin(), CUMap
.end());
2140 // Need to sort since we write out all of TUs in .debug_info before CUs.
2141 std::sort(CUVector
.begin(), CUVector
.end(),
2142 [](const MapEntry
&E1
, const MapEntry
&E2
) -> bool {
2143 return E1
.second
.Offset
< E2
.second
.Offset
;
2145 // Writing out CU List <Offset, Size>
2146 for (auto &CUInfo
: CUVector
) {
2147 // Skipping TU for DWARF5 when they are not included in CU list.
2148 if (!OriginalOffsets
.count(CUInfo
.first
))
2150 write64le(Buffer
, CUInfo
.second
.Offset
);
2151 // Length encoded in CU doesn't contain first 4 bytes that encode length.
2152 write64le(Buffer
+ 8, CUInfo
.second
.Length
+ 4);
2156 // Rewrite TU CU List, since abbrevs can be different.
2158 // 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature =
2159 // 0x418503b8111e9a7b Spec says " triplet, the first value is the CU offset,
2160 // the second value is the type offset in the CU, and the third value is the
2161 // type signature" Looking at what is being generated by gdb-add-index. The
2162 // first entry is TU offset, second entry is offset from it, and third entry
2163 // is the type signature.
2165 for (const GDBIndexTUEntry
&Entry
: getGDBIndexTUEntryVector()) {
2166 write64le(Buffer
, Entry
.UnitOffset
);
2167 write64le(Buffer
+ 8, Entry
.TypeDIERelativeOffset
);
2168 write64le(Buffer
+ 16, Entry
.TypeHash
);
2169 Buffer
+= sizeof(GDBIndexTUEntry
);
2172 // Generate new address table.
2173 for (const std::pair
<const uint64_t, DebugAddressRangesVector
> &CURangesPair
:
2174 ARangesSectionWriter
->getCUAddressRanges()) {
2175 const uint32_t CUIndex
= OffsetToIndexMap
[CURangesPair
.first
];
2176 const DebugAddressRangesVector
&Ranges
= CURangesPair
.second
;
2177 for (const DebugAddressRange
&Range
: Ranges
) {
2178 write64le(Buffer
, Range
.LowPC
);
2179 write64le(Buffer
+ 8, Range
.HighPC
);
2180 write32le(Buffer
+ 16, CUIndex
);
2185 const size_t TrailingSize
=
2186 GdbIndexContents
.data() + GdbIndexContents
.size() - Data
;
2187 assert(Buffer
+ TrailingSize
== NewGdbIndexContents
+ NewGdbIndexSize
&&
2188 "size calculation error");
2190 // Copy over the rest of the original data.
2191 memcpy(Buffer
, Data
, TrailingSize
);
2193 // Register the new section.
2194 BC
.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents
,
2198 std::unique_ptr
<DebugBufferVector
>
2199 DWARFRewriter::makeFinalLocListsSection(DWARFVersion Version
) {
2200 auto LocBuffer
= std::make_unique
<DebugBufferVector
>();
2201 auto LocStream
= std::make_unique
<raw_svector_ostream
>(*LocBuffer
);
2203 std::unique_ptr
<MCObjectWriter
>(BC
.createObjectWriter(*LocStream
));
2205 for (std::pair
<const uint64_t, std::unique_ptr
<DebugLocWriter
>> &Loc
:
2206 LocListWritersByCU
) {
2207 DebugLocWriter
*LocWriter
= Loc
.second
.get();
2208 auto *LocListWriter
= llvm::dyn_cast
<DebugLoclistWriter
>(LocWriter
);
2210 // Filter out DWARF4, writing out DWARF5
2211 if (Version
== DWARFVersion::DWARF5
&&
2212 (!LocListWriter
|| LocListWriter
->getDwarfVersion() <= 4))
2215 // Filter out DWARF5, writing out DWARF4
2216 if (Version
== DWARFVersion::DWARFLegacy
&&
2217 (LocListWriter
&& LocListWriter
->getDwarfVersion() >= 5))
2220 // Skipping DWARF4/5 split dwarf.
2221 if (LocListWriter
&& LocListWriter
->getDwarfVersion() <= 4)
2223 std::unique_ptr
<DebugBufferVector
> CurrCULocationLists
=
2224 LocWriter
->getBuffer();
2225 *LocStream
<< *CurrCULocationLists
;
2231 void DWARFRewriter::convertToRangesPatchDebugInfo(
2232 DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
, DIE
&Die
,
2233 uint64_t RangesSectionOffset
, DIEValue
&LowPCAttrInfo
,
2234 DIEValue
&HighPCAttrInfo
, std::optional
<uint64_t> RangesBase
) {
2235 uint32_t BaseOffset
= 0;
2236 dwarf::Form LowForm
= LowPCAttrInfo
.getForm();
2237 dwarf::Attribute RangeBaseAttribute
= dwarf::DW_AT_GNU_ranges_base
;
2238 dwarf::Form RangesForm
= dwarf::DW_FORM_sec_offset
;
2240 if (Unit
.getVersion() >= 5) {
2241 RangeBaseAttribute
= dwarf::DW_AT_rnglists_base
;
2242 RangesForm
= dwarf::DW_FORM_rnglistx
;
2243 } else if (Unit
.getVersion() < 4) {
2244 RangesForm
= dwarf::DW_FORM_data4
;
2246 bool IsUnitDie
= Die
.getTag() == dwarf::DW_TAG_compile_unit
||
2247 Die
.getTag() == dwarf::DW_TAG_skeleton_unit
;
2249 DIEBldr
.deleteValue(&Die
, LowPCAttrInfo
.getAttribute());
2250 // In DWARF4 for DW_AT_low_pc in binary DW_FORM_addr is used. In the DWO
2251 // section DW_FORM_GNU_addr_index is used. So for if we are converting
2252 // DW_AT_low_pc/DW_AT_high_pc and see DW_FORM_GNU_addr_index. We are
2253 // converting in DWO section, and DW_AT_ranges [DW_FORM_sec_offset] is
2254 // relative to DW_AT_GNU_ranges_base.
2255 if (LowForm
== dwarf::DW_FORM_GNU_addr_index
) {
2256 // Ranges are relative to DW_AT_GNU_ranges_base.
2257 uint64_t CurRangeBase
= 0;
2258 if (std::optional
<uint64_t> DWOId
= Unit
.getDWOId()) {
2259 CurRangeBase
= getDwoRangesBase(*DWOId
);
2261 BaseOffset
= CurRangeBase
;
2263 // In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or
2264 // DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is
2265 // when it's absent.
2267 if (LowForm
== dwarf::DW_FORM_addrx
) {
2268 const uint32_t Index
= AddrWriter
->getIndexFromAddress(0, Unit
);
2269 DIEBldr
.replaceValue(&Die
, LowPCAttrInfo
.getAttribute(),
2270 LowPCAttrInfo
.getForm(), DIEInteger(Index
));
2272 DIEBldr
.replaceValue(&Die
, LowPCAttrInfo
.getAttribute(),
2273 LowPCAttrInfo
.getForm(), DIEInteger(0));
2276 // Original CU didn't have DW_AT_*_base. We converted it's children (or
2277 // dwo), so need to insert it into CU.
2279 DIEBldr
.addValue(&Die
, RangeBaseAttribute
, dwarf::DW_FORM_sec_offset
,
2280 DIEInteger(*RangesBase
));
2283 uint64_t RangeAttrVal
= RangesSectionOffset
- BaseOffset
;
2284 if (Unit
.getVersion() >= 5)
2285 RangeAttrVal
= RangesSectionOffset
;
2286 // HighPC was conveted into DW_AT_ranges.
2287 // For DWARF5 we only access ranges through index.
2289 DIEBldr
.replaceValue(&Die
, HighPCAttrInfo
.getAttribute(), dwarf::DW_AT_ranges
,
2290 RangesForm
, DIEInteger(RangeAttrVal
));