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/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 /// Emits debug information into .debug_info or .debug_types section.
94 class DIEStreamer
: public DwarfStreamer
{
96 DWARFRewriter
&Rewriter
;
99 /// Emit the compilation unit header for \p Unit in the debug_info
102 /// A Dwarf 4 section header is encoded as:
103 /// uint32_t Unit length (omitting this field)
105 /// uint32_t Abbreviation table offset
106 /// uint8_t Address size
107 /// Leading to a total of 11 bytes.
109 /// A Dwarf 5 section header is encoded as:
110 /// uint32_t Unit length (omitting this field)
112 /// uint8_t Unit type
113 /// uint8_t Address size
114 /// uint32_t Abbreviation table offset
115 /// Leading to a total of 12 bytes.
116 void emitCompileUnitHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
,
117 unsigned DwarfVersion
) {
119 AsmPrinter
&Asm
= getAsmPrinter();
120 switchToDebugInfoSection(DwarfVersion
);
122 emitCommonHeader(Unit
, UnitDIE
, DwarfVersion
);
124 if (DwarfVersion
>= 5 &&
125 Unit
.getUnitType() != dwarf::UnitType::DW_UT_compile
) {
126 std::optional
<uint64_t> DWOId
= Unit
.getDWOId();
128 "DWOId does not exist and this is not a DW_UT_compile Unit");
129 Asm
.emitInt64(*DWOId
);
133 void emitCommonHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
, uint16_t Version
) {
134 dwarf::UnitType UT
= dwarf::UnitType(Unit
.getUnitType());
135 llvm::AsmPrinter
&Asm
= getAsmPrinter();
137 // Emit size of content not including length itself
138 Asm
.emitInt32(Unit
.getHeaderSize() + UnitDIE
.getSize() - 4);
139 Asm
.emitInt16(Version
);
141 // DWARF v5 reorders the address size and adds a unit type.
144 Asm
.emitInt8(Asm
.MAI
->getCodePointerSize());
149 Asm
.emitInt8(Asm
.MAI
->getCodePointerSize());
153 void emitTypeUnitHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
,
154 unsigned DwarfVersion
) {
155 AsmPrinter
&Asm
= getAsmPrinter();
156 const uint64_t TypeSignature
= cast
<DWARFTypeUnit
>(Unit
).getTypeHash();
157 DIE
*TypeDIE
= DIEBldr
->getTypeDIE(Unit
);
158 const DIEBuilder::DWARFUnitInfo
&UI
= DIEBldr
->getUnitInfoByDwarfUnit(Unit
);
159 Rewriter
.addGDBTypeUnitEntry(
160 {UI
.UnitOffset
, TypeSignature
, TypeDIE
->getOffset()});
161 if (Unit
.getVersion() < 5) {
162 // Switch the section to .debug_types section.
163 std::unique_ptr
<MCStreamer
> &MS
= Asm
.OutStreamer
;
164 llvm::MCContext
&MC
= Asm
.OutContext
;
165 const llvm::MCObjectFileInfo
*MOFI
= MC
.getObjectFileInfo();
167 MS
->switchSection(MOFI
->getDwarfTypesSection(0));
168 MC
.setDwarfVersion(DwarfVersion
);
170 switchToDebugInfoSection(DwarfVersion
);
172 emitCommonHeader(Unit
, UnitDIE
, DwarfVersion
);
173 Asm
.OutStreamer
->emitIntValue(TypeSignature
, sizeof(TypeSignature
));
174 Asm
.emitDwarfLengthOrOffset(TypeDIE
? TypeDIE
->getOffset() : 0);
177 void emitUnitHeader(DWARFUnit
&Unit
, DIE
&UnitDIE
) {
178 if (Unit
.isTypeUnit())
179 emitTypeUnitHeader(Unit
, UnitDIE
, Unit
.getVersion());
181 emitCompileUnitHeader(Unit
, UnitDIE
, Unit
.getVersion());
184 void emitDIE(DIE
&Die
) override
{
185 AsmPrinter
&Asm
= getAsmPrinter();
186 Asm
.emitDwarfDIE(Die
);
190 DIEStreamer(DIEBuilder
*DIEBldr
, DWARFRewriter
&Rewriter
,
191 DWARFLinker::OutputFileType OutFileType
,
192 raw_pwrite_stream
&OutFile
,
193 std::function
<StringRef(StringRef Input
)> Translator
,
194 DWARFLinker::messageHandler Warning
)
195 : DwarfStreamer(OutFileType
, OutFile
, Translator
, Warning
),
196 DIEBldr(DIEBldr
), Rewriter(Rewriter
){};
198 using DwarfStreamer::emitCompileUnitHeader
;
200 void emitUnit(DWARFUnit
&Unit
, DIE
&UnitDIE
) {
201 emitUnitHeader(Unit
, UnitDIE
);
206 /// Finds attributes FormValue and Offset.
208 /// \param DIE die to look up in.
209 /// \param Attrs finds the first attribute that matches and extracts it.
210 /// \return an optional AttrInfo with DWARFFormValue and Offset.
211 std::optional
<AttrInfo
> findAttributeInfo(const DWARFDie DIE
,
212 std::vector
<dwarf::Attribute
> Attrs
) {
213 for (dwarf::Attribute
&Attr
: Attrs
)
214 if (std::optional
<AttrInfo
> Info
= findAttributeInfo(DIE
, Attr
))
222 using namespace llvm
;
223 using namespace llvm::support::endian
;
224 using namespace object
;
225 using namespace bolt
;
229 extern cl::OptionCategory BoltCategory
;
230 extern cl::opt
<unsigned> Verbosity
;
231 extern cl::opt
<std::string
> OutputFilename
;
233 static cl::opt
<bool> KeepARanges(
236 "keep or generate .debug_aranges section if .gdb_index is written"),
237 cl::Hidden
, cl::cat(BoltCategory
));
240 DeterministicDebugInfo("deterministic-debuginfo",
241 cl::desc("disables parallel execution of tasks that may produce "
242 "nondeterministic debug info"),
244 cl::cat(BoltCategory
));
246 static cl::opt
<std::string
> DwarfOutputPath(
248 cl::desc("Path to where .dwo files or dwp file will be written out to."),
249 cl::init(""), cl::cat(BoltCategory
));
252 WriteDWP("write-dwp",
253 cl::desc("output a single dwarf package file (dwp) instead of "
254 "multiple non-relocatable dwarf object files (dwo)."),
255 cl::init(false), cl::cat(BoltCategory
));
258 DebugSkeletonCu("debug-skeleton-cu",
259 cl::desc("prints out offsetrs for abbrev and debu_info of "
260 "Skeleton CUs that get patched."),
261 cl::ZeroOrMore
, cl::Hidden
, cl::init(false),
262 cl::cat(BoltCategory
));
264 static cl::opt
<unsigned> BatchSize(
265 "cu-processing-batch-size",
267 "Specifies the size of batches for processing CUs. Higher number has "
268 "better performance, but more memory usage. Default value is 1."),
269 cl::Hidden
, cl::init(1), cl::cat(BoltCategory
));
271 static cl::opt
<bool> AlwaysConvertToRanges(
272 "always-convert-to-ranges",
273 cl::desc("This option is for testing purposes only. It forces BOLT to "
274 "convert low_pc/high_pc to ranges always."),
275 cl::ReallyHidden
, cl::init(false), cl::cat(BoltCategory
));
278 static bool getLowAndHighPC(const DIE
&Die
, const DWARFUnit
&DU
,
279 uint64_t &LowPC
, uint64_t &HighPC
,
280 uint64_t &SectionIndex
) {
281 DIEValue DvalLowPc
= Die
.findAttribute(dwarf::DW_AT_low_pc
);
282 DIEValue DvalHighPc
= Die
.findAttribute(dwarf::DW_AT_high_pc
);
283 if (!DvalLowPc
|| !DvalHighPc
)
286 dwarf::Form Form
= DvalLowPc
.getForm();
287 bool AddrOffset
= Form
== dwarf::DW_FORM_LLVM_addrx_offset
;
288 uint64_t LowPcValue
= DvalLowPc
.getDIEInteger().getValue();
289 if (Form
== dwarf::DW_FORM_GNU_addr_index
|| Form
== dwarf::DW_FORM_addrx
||
292 uint32_t Index
= AddrOffset
? (LowPcValue
>> 32) : LowPcValue
;
293 std::optional
<object::SectionedAddress
> SA
=
294 DU
.getAddrOffsetSectionItem(Index
);
298 SA
->Address
+= (LowPcValue
& 0xffffffff);
301 SectionIndex
= SA
->SectionIndex
;
306 if (DvalHighPc
.getForm() == dwarf::DW_FORM_addr
)
307 HighPC
= DvalHighPc
.getDIEInteger().getValue();
309 HighPC
= LowPC
+ DvalHighPc
.getDIEInteger().getValue();
314 static Expected
<llvm::DWARFAddressRangesVector
>
315 getDIEAddressRanges(const DIE
&Die
, DWARFUnit
&DU
) {
316 uint64_t LowPC
, HighPC
, Index
;
317 if (getLowAndHighPC(Die
, DU
, LowPC
, HighPC
, Index
))
318 return DWARFAddressRangesVector
{{LowPC
, HighPC
, Index
}};
319 if (DIEValue Dval
= Die
.findAttribute(dwarf::DW_AT_ranges
)) {
320 if (Dval
.getForm() == dwarf::DW_FORM_rnglistx
)
321 return DU
.findRnglistFromIndex(Dval
.getDIEInteger().getValue());
323 return DU
.findRnglistFromOffset(Dval
.getDIEInteger().getValue());
326 return DWARFAddressRangesVector();
329 static std::optional
<uint64_t> getAsAddress(const DWARFUnit
&DU
,
330 const DIEValue
&AttrVal
) {
331 DWARFFormValue::ValueType
Value(AttrVal
.getDIEInteger().getValue());
332 if (std::optional
<object::SectionedAddress
> SA
=
333 DWARFFormValue::getAsSectionedAddress(Value
, AttrVal
.getForm(), &DU
))
338 /// Returns DWO Name to be used. Handles case where user specifies output DWO
339 /// directory, and there are duplicate names. Assumes DWO ID is unique.
341 getDWOName(llvm::DWARFUnit
&CU
,
342 std::unordered_map
<std::string
, uint32_t> &NameToIndexMap
) {
343 std::optional
<uint64_t> DWOId
= CU
.getDWOId();
344 assert(DWOId
&& "DWO ID not found.");
347 std::string DWOName
= dwarf::toString(
348 CU
.getUnitDIE().find({dwarf::DW_AT_dwo_name
, dwarf::DW_AT_GNU_dwo_name
}),
350 assert(!DWOName
.empty() &&
351 "DW_AT_dwo_name/DW_AT_GNU_dwo_name does not exists.");
352 if (!opts::DwarfOutputPath
.empty()) {
353 auto Iter
= NameToIndexMap
.find(DWOName
);
354 if (Iter
== NameToIndexMap
.end())
355 Iter
= NameToIndexMap
.insert({DWOName
, 0}).first
;
356 DWOName
.append(std::to_string(Iter
->second
));
359 DWOName
.append(".dwo");
363 static std::unique_ptr
<DIEStreamer
>
364 createDIEStreamer(const Triple
&TheTriple
, raw_pwrite_stream
&OutFile
,
365 StringRef Swift5ReflectionSegmentName
, DIEBuilder
&DIEBldr
,
366 DWARFRewriter
&Rewriter
) {
368 std::unique_ptr
<DIEStreamer
> Streamer
= std::make_unique
<DIEStreamer
>(
369 &DIEBldr
, Rewriter
, llvm::DWARFLinker::OutputFileType::Object
, OutFile
,
370 [](StringRef Input
) -> StringRef
{ return Input
; },
371 [&](const Twine
&Warning
, StringRef Context
, const DWARFDie
*) {});
372 Error Err
= Streamer
->init(TheTriple
, Swift5ReflectionSegmentName
);
375 << "BOLT-WARNING: [internal-dwarf-error]: Could not init DIEStreamer!"
376 << toString(std::move(Err
)) << "\n";
380 static DWARFRewriter::UnitMeta
381 emitUnit(DIEBuilder
&DIEBldr
, DIEStreamer
&Streamer
, DWARFUnit
&Unit
) {
382 DIE
*UnitDIE
= DIEBldr
.getUnitDIEbyUnit(Unit
);
383 const DIEBuilder::DWARFUnitInfo
&U
= DIEBldr
.getUnitInfoByDwarfUnit(Unit
);
384 Streamer
.emitUnit(Unit
, *UnitDIE
);
385 uint64_t TypeHash
= 0;
386 if (DWARFTypeUnit
*DTU
= dyn_cast_or_null
<DWARFTypeUnit
>(&Unit
))
387 TypeHash
= DTU
->getTypeHash();
388 return {U
.UnitOffset
, U
.UnitLength
, TypeHash
};
391 static void emitDWOBuilder(const std::string
&DWOName
,
392 DIEBuilder
&DWODIEBuilder
, DWARFRewriter
&Rewriter
,
393 const DWARFUnit
&SplitCU
, DWARFUnit
&CU
,
394 DWARFRewriter::DWPState
&State
,
395 DebugLocWriter
&LocWriter
) {
396 // Populate debug_info and debug_abbrev for current dwo into StringRef.
397 DWODIEBuilder
.generateAbbrevs();
398 DWODIEBuilder
.finish();
400 SmallVector
<char, 20> OutBuffer
;
401 std::shared_ptr
<raw_svector_ostream
> ObjOS
=
402 std::make_shared
<raw_svector_ostream
>(OutBuffer
);
403 const object::ObjectFile
*File
= SplitCU
.getContext().getDWARFObj().getFile();
404 auto TheTriple
= std::make_unique
<Triple
>(File
->makeTriple());
405 std::unique_ptr
<DIEStreamer
> Streamer
= createDIEStreamer(
406 *TheTriple
, *ObjOS
, "DwoStreamerInitAug2", DWODIEBuilder
, Rewriter
);
407 DWARFRewriter::UnitMetaVectorType TUMetaVector
;
408 DWARFRewriter::UnitMeta CUMI
= {0, 0, 0};
409 if (SplitCU
.getContext().getMaxDWOVersion() >= 5) {
410 // TODO: Handle DWP as input. Right now it will iterate over all of CUs and
412 for (std::unique_ptr
<llvm::DWARFUnit
> &CU
:
413 SplitCU
.getContext().dwo_info_section_units()) {
414 DWARFRewriter::UnitMeta MI
=
415 emitUnit(DWODIEBuilder
, *Streamer
, *CU
.get());
416 if (CU
->isTypeUnit())
417 TUMetaVector
.emplace_back(MI
);
422 for (std::unique_ptr
<llvm::DWARFUnit
> &CU
:
423 SplitCU
.getContext().dwo_compile_units())
424 emitUnit(DWODIEBuilder
, *Streamer
, *CU
.get());
426 // emit debug_types sections for dwarf4
427 for (DWARFUnit
*CU
: DWODIEBuilder
.getDWARF4TUVector()) {
428 DWARFRewriter::UnitMeta MI
= emitUnit(DWODIEBuilder
, *Streamer
, *CU
);
429 TUMetaVector
.emplace_back(MI
);
433 Streamer
->emitAbbrevs(DWODIEBuilder
.getAbbrevs(),
434 SplitCU
.getContext().getMaxVersion());
437 std::unique_ptr
<MemoryBuffer
> ObjectMemBuffer
=
438 MemoryBuffer::getMemBuffer(ObjOS
->str(), "in-memory object file", false);
439 std::unique_ptr
<object::ObjectFile
> Obj
= cantFail(
440 object::ObjectFile::createObjectFile(ObjectMemBuffer
->getMemBufferRef()),
441 "error creating in-memory object");
443 DWARFRewriter::OverriddenSectionsMap OverriddenSections
;
444 for (const SectionRef
&Secs
: Obj
->sections()) {
445 StringRef Contents
= cantFail(Secs
.getContents());
446 StringRef Name
= cantFail(Secs
.getName());
447 DWARFSectionKind Kind
=
448 StringSwitch
<DWARFSectionKind
>(Name
)
449 .Case(".debug_abbrev", DWARFSectionKind::DW_SECT_ABBREV
)
450 .Case(".debug_info", DWARFSectionKind::DW_SECT_INFO
)
451 .Case(".debug_types", DWARFSectionKind::DW_SECT_EXT_TYPES
)
452 .Default(DWARFSectionKind::DW_SECT_EXT_unknown
);
453 if (Kind
== DWARFSectionKind::DW_SECT_EXT_unknown
)
455 OverriddenSections
[Kind
] = Contents
;
458 Rewriter
.updateDWP(CU
, OverriddenSections
, CUMI
, TUMetaVector
, State
,
461 Rewriter
.writeDWOFiles(CU
, OverriddenSections
, DWOName
, LocWriter
);
464 void DWARFRewriter::addStringHelper(DIEBuilder
&DIEBldr
, DIE
&Die
,
465 const DWARFUnit
&Unit
,
466 DIEValue
&DIEAttrInfo
, StringRef Str
) {
467 uint32_t NewOffset
= StrWriter
->addString(Str
);
468 if (Unit
.getVersion() == 5) {
469 StrOffstsWriter
->updateAddressMap(DIEAttrInfo
.getDIEInteger().getValue(),
473 DIEBldr
.replaceValue(&Die
, DIEAttrInfo
.getAttribute(), DIEAttrInfo
.getForm(),
474 DIEInteger(NewOffset
));
477 using DWARFUnitVec
= std::vector
<DWARFUnit
*>;
478 using CUPartitionVector
= std::vector
<DWARFUnitVec
>;
479 /// Partitions CUs in to buckets. Bucket size is controlled by
480 /// cu-processing-batch-size. All the CUs that have cross CU reference reference
481 /// as a source are put in to the same initial bucket.
482 static CUPartitionVector
partitionCUs(DWARFContext
&DwCtx
) {
483 CUPartitionVector
Vec(2);
484 unsigned Counter
= 0;
485 const DWARFDebugAbbrev
*Abbr
= DwCtx
.getDebugAbbrev();
486 for (std::unique_ptr
<DWARFUnit
> &CU
: DwCtx
.compile_units()) {
487 Expected
<const DWARFAbbreviationDeclarationSet
*> AbbrDeclSet
=
488 Abbr
->getAbbreviationDeclarationSet(CU
->getAbbreviationsOffset());
490 consumeError(AbbrDeclSet
.takeError());
493 bool CrossCURefFound
= false;
494 for (const DWARFAbbreviationDeclaration
&Decl
: *AbbrDeclSet
.get()) {
495 for (const DWARFAbbreviationDeclaration::AttributeSpec
&Attr
:
497 if (Attr
.Form
== dwarf::DW_FORM_ref_addr
) {
498 CrossCURefFound
= true;
505 if (CrossCURefFound
) {
506 Vec
[0].push_back(CU
.get());
509 Vec
.back().push_back(CU
.get());
511 if (Counter
% opts::BatchSize
== 0 && !Vec
.back().empty())
517 void DWARFRewriter::updateDebugInfo() {
518 ErrorOr
<BinarySection
&> DebugInfo
= BC
.getUniqueSectionByName(".debug_info");
522 ARangesSectionWriter
= std::make_unique
<DebugARangesSectionWriter
>();
523 StrWriter
= std::make_unique
<DebugStrWriter
>(BC
);
525 StrOffstsWriter
= std::make_unique
<DebugStrOffsetsWriter
>();
527 if (!opts::DeterministicDebugInfo
) {
528 opts::DeterministicDebugInfo
= true;
529 errs() << "BOLT-WARNING: --deterministic-debuginfo is being deprecated\n";
532 if (BC
.isDWARF5Used()) {
533 AddrWriter
= std::make_unique
<DebugAddrWriterDwarf5
>(&BC
);
534 RangeListsSectionWriter
= std::make_unique
<DebugRangeListsSectionWriter
>();
535 DebugRangeListsSectionWriter::setAddressWriter(AddrWriter
.get());
537 AddrWriter
= std::make_unique
<DebugAddrWriter
>(&BC
);
540 if (BC
.isDWARFLegacyUsed())
541 LegacyRangesSectionWriter
= std::make_unique
<DebugRangesSectionWriter
>();
543 DebugLoclistWriter::setAddressWriter(AddrWriter
.get());
545 uint32_t CUIndex
= 0;
546 std::mutex AccessMutex
;
547 // Needs to be invoked in the same order as CUs are processed.
548 auto createRangeLocList
= [&](DWARFUnit
&CU
) -> DebugLocWriter
* {
549 std::lock_guard
<std::mutex
> Lock(AccessMutex
);
550 const uint16_t DwarfVersion
= CU
.getVersion();
551 if (DwarfVersion
>= 5) {
552 LocListWritersByCU
[CUIndex
] =
553 std::make_unique
<DebugLoclistWriter
>(CU
, DwarfVersion
, false);
555 if (std::optional
<uint64_t> DWOId
= CU
.getDWOId()) {
556 assert(RangeListsWritersByCU
.count(*DWOId
) == 0 &&
557 "RangeLists writer for DWO unit already exists.");
558 auto RangeListsSectionWriter
=
559 std::make_unique
<DebugRangeListsSectionWriter
>();
560 RangeListsSectionWriter
->initSection(CU
);
561 RangeListsWritersByCU
[*DWOId
] = std::move(RangeListsSectionWriter
);
565 LocListWritersByCU
[CUIndex
] = std::make_unique
<DebugLocWriter
>();
567 return LocListWritersByCU
[CUIndex
++].get();
570 // Unordered maps to handle name collision if output DWO directory is
572 std::unordered_map
<std::string
, uint32_t> NameToIndexMap
;
574 auto updateDWONameCompDir
= [&](DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
,
575 DIE
&UnitDIE
) -> std::string
{
576 DIEValue DWONameAttrInfo
= UnitDIE
.findAttribute(dwarf::DW_AT_dwo_name
);
577 if (!DWONameAttrInfo
)
578 DWONameAttrInfo
= UnitDIE
.findAttribute(dwarf::DW_AT_GNU_dwo_name
);
579 assert(DWONameAttrInfo
&& "DW_AT_dwo_name is not in Skeleton CU.");
580 std::string ObjectName
;
583 std::lock_guard
<std::mutex
> Lock(AccessMutex
);
584 ObjectName
= getDWOName(Unit
, NameToIndexMap
);
586 addStringHelper(DIEBldr
, UnitDIE
, Unit
, DWONameAttrInfo
,
589 DIEValue CompDirAttrInfo
= UnitDIE
.findAttribute(dwarf::DW_AT_comp_dir
);
590 assert(CompDirAttrInfo
&& "DW_AT_comp_dir is not in Skeleton CU.");
592 if (!opts::DwarfOutputPath
.empty()) {
593 addStringHelper(DIEBldr
, UnitDIE
, Unit
, CompDirAttrInfo
,
594 opts::DwarfOutputPath
.c_str());
602 auto processUnitDIE
= [&](DWARFUnit
*Unit
, DIEBuilder
*DIEBlder
) {
603 // Check if the unit is a skeleton and we need special updates for it and
604 // its matching split/DWO CU.
605 std::optional
<DWARFUnit
*> SplitCU
;
606 std::optional
<uint64_t> RangesBase
;
607 std::optional
<uint64_t> DWOId
= Unit
->getDWOId();
608 StrOffstsWriter
->initialize(Unit
->getStringOffsetSection(),
609 Unit
->getStringOffsetsTableContribution());
611 SplitCU
= BC
.getDWOCU(*DWOId
);
612 DebugLocWriter
*DebugLocWriter
= createRangeLocList(*Unit
);
613 DebugRangesSectionWriter
*RangesSectionWriter
=
614 Unit
->getVersion() >= 5 ? RangeListsSectionWriter
.get()
615 : LegacyRangesSectionWriter
.get();
616 // Skipping CUs that failed to load.
618 DIEBuilder
DWODIEBuilder(&(*SplitCU
)->getContext(), true);
619 DWODIEBuilder
.buildBoth();
620 std::string DWOName
= updateDWONameCompDir(
621 *Unit
, *DIEBlder
, *DIEBlder
->getUnitDIEbyUnit(*Unit
));
623 DebugLoclistWriter
DebugLocDWoWriter(*Unit
, Unit
->getVersion(), true);
624 DebugRangesSectionWriter
*TempRangesSectionWriter
= RangesSectionWriter
;
625 if (Unit
->getVersion() >= 5) {
626 TempRangesSectionWriter
= RangeListsWritersByCU
[*DWOId
].get();
628 RangesBase
= RangesSectionWriter
->getSectionOffset();
629 // For DWARF5 there is now .debug_rnglists.dwo, so don't need to
630 // update rnglists base.
632 DwoRangesBase
[*DWOId
] = *RangesBase
;
633 setDwoRangesBase(*DWOId
, *RangesBase
);
637 updateUnitDebugInfo(*(*SplitCU
), DWODIEBuilder
, DebugLocDWoWriter
,
638 *TempRangesSectionWriter
);
639 DebugLocDWoWriter
.finalize(DWODIEBuilder
,
640 *DWODIEBuilder
.getUnitDIEbyUnit(**SplitCU
));
641 if (Unit
->getVersion() >= 5)
642 TempRangesSectionWriter
->finalizeSection();
644 emitDWOBuilder(DWOName
, DWODIEBuilder
, *this, **SplitCU
, *Unit
, State
,
648 if (Unit
->getVersion() >= 5) {
649 RangesBase
= RangesSectionWriter
->getSectionOffset() +
650 getDWARF5RngListLocListHeaderSize();
651 RangesSectionWriter
->initSection(*Unit
);
652 StrOffstsWriter
->finalizeSection(*Unit
, *DIEBlder
);
655 updateUnitDebugInfo(*Unit
, *DIEBlder
, *DebugLocWriter
, *RangesSectionWriter
,
657 DebugLocWriter
->finalize(*DIEBlder
, *DIEBlder
->getUnitDIEbyUnit(*Unit
));
658 if (Unit
->getVersion() >= 5)
659 RangesSectionWriter
->finalizeSection();
660 AddrWriter
->update(*DIEBlder
, *Unit
);
663 DIEBuilder
DIEBlder(BC
.DwCtx
.get());
664 DIEBlder
.buildTypeUnits();
665 SmallVector
<char, 20> OutBuffer
;
666 std::unique_ptr
<raw_svector_ostream
> ObjOS
=
667 std::make_unique
<raw_svector_ostream
>(OutBuffer
);
668 const object::ObjectFile
*File
= BC
.DwCtx
->getDWARFObj().getFile();
669 auto TheTriple
= std::make_unique
<Triple
>(File
->makeTriple());
670 std::unique_ptr
<DIEStreamer
> Streamer
=
671 createDIEStreamer(*TheTriple
, *ObjOS
, "TypeStreamer", DIEBlder
, *this);
672 CUOffsetMap OffsetMap
= finalizeTypeSections(DIEBlder
, *Streamer
);
674 const bool SingleThreadedMode
=
675 opts::NoThreads
|| opts::DeterministicDebugInfo
;
676 if (!SingleThreadedMode
)
677 DIEBlder
.buildCompileUnits();
678 if (SingleThreadedMode
) {
679 CUPartitionVector PartVec
= partitionCUs(*BC
.DwCtx
);
680 for (std::vector
<DWARFUnit
*> &Vec
: PartVec
) {
681 DIEBlder
.buildCompileUnits(Vec
);
682 for (DWARFUnit
*CU
: DIEBlder
.getProcessedCUs())
683 processUnitDIE(CU
, &DIEBlder
);
684 finalizeCompileUnits(DIEBlder
, *Streamer
, OffsetMap
,
685 DIEBlder
.getProcessedCUs());
688 // Update unit debug info in parallel
689 ThreadPool
&ThreadPool
= ParallelUtilities::getThreadPool();
690 for (std::unique_ptr
<DWARFUnit
> &CU
: BC
.DwCtx
->compile_units())
691 ThreadPool
.async(processUnitDIE
, CU
.get(), &DIEBlder
);
698 finalizeDebugSections(DIEBlder
, *Streamer
, *ObjOS
, OffsetMap
);
699 updateGdbIndexSection(OffsetMap
, CUIndex
);
702 void DWARFRewriter::updateUnitDebugInfo(
703 DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
, DebugLocWriter
&DebugLocWriter
,
704 DebugRangesSectionWriter
&RangesSectionWriter
,
705 std::optional
<uint64_t> RangesBase
) {
706 // Cache debug ranges so that the offset for identical ranges could be reused.
707 std::map
<DebugAddressRangesVector
, uint64_t> CachedRanges
;
709 uint64_t DIEOffset
= Unit
.getOffset() + Unit
.getHeaderSize();
710 uint64_t NextCUOffset
= Unit
.getNextUnitOffset();
711 const std::vector
<std::unique_ptr
<DIEBuilder::DIEInfo
>> &DIs
=
712 DIEBldr
.getDIEsByUnit(Unit
);
714 // Either updates or normalizes DW_AT_range to DW_AT_low_pc and DW_AT_high_pc.
715 auto updateLowPCHighPC
= [&](DIE
*Die
, const DIEValue
&LowPCVal
,
716 const DIEValue
&HighPCVal
, uint64_t LowPC
,
717 const uint64_t HighPC
) {
718 dwarf::Attribute AttrLowPC
= dwarf::DW_AT_low_pc
;
719 dwarf::Form FormLowPC
= dwarf::DW_FORM_addr
;
720 dwarf::Attribute AttrHighPC
= dwarf::DW_AT_high_pc
;
721 dwarf::Form FormHighPC
= dwarf::DW_FORM_data4
;
722 const uint32_t Size
= HighPC
- LowPC
;
723 // Whatever was generated is not low_pc/high_pc, so will reset to
724 // default for size 1.
725 if (!LowPCVal
|| !HighPCVal
) {
726 if (Unit
.getVersion() >= 5)
727 FormLowPC
= dwarf::DW_FORM_addrx
;
728 else if (Unit
.isDWOUnit())
729 FormLowPC
= dwarf::DW_FORM_GNU_addr_index
;
731 AttrLowPC
= LowPCVal
.getAttribute();
732 FormLowPC
= LowPCVal
.getForm();
733 AttrHighPC
= HighPCVal
.getAttribute();
734 FormHighPC
= HighPCVal
.getForm();
737 if (FormLowPC
== dwarf::DW_FORM_addrx
||
738 FormLowPC
== dwarf::DW_FORM_GNU_addr_index
)
739 LowPC
= AddrWriter
->getIndexFromAddress(LowPC
, Unit
);
742 DIEBldr
.replaceValue(Die
, AttrLowPC
, FormLowPC
, DIEInteger(LowPC
));
744 DIEBldr
.addValue(Die
, AttrLowPC
, FormLowPC
, DIEInteger(LowPC
));
746 DIEBldr
.replaceValue(Die
, AttrHighPC
, FormHighPC
, DIEInteger(Size
));
748 DIEBldr
.deleteValue(Die
, dwarf::DW_AT_ranges
);
749 DIEBldr
.addValue(Die
, AttrHighPC
, FormHighPC
, DIEInteger(Size
));
753 for (const std::unique_ptr
<DIEBuilder::DIEInfo
> &DI
: DIs
) {
755 switch (Die
->getTag()) {
756 case dwarf::DW_TAG_compile_unit
:
757 case dwarf::DW_TAG_skeleton_unit
: {
758 // For dwarf5 section 3.1.3
759 // The following attributes are not part of a split full compilation unit
760 // entry but instead are inherited (if present) from the corresponding
761 // skeleton compilation unit: DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges,
762 // DW_AT_stmt_list, DW_AT_comp_dir, DW_AT_str_offsets_base,
763 // DW_AT_addr_base and DW_AT_rnglists_base.
764 if (Unit
.getVersion() == 5 && Unit
.isDWOUnit())
766 auto ModuleRangesOrError
= getDIEAddressRanges(*Die
, Unit
);
767 if (!ModuleRangesOrError
) {
768 consumeError(ModuleRangesOrError
.takeError());
771 DWARFAddressRangesVector
&ModuleRanges
= *ModuleRangesOrError
;
772 DebugAddressRangesVector OutputRanges
=
773 BC
.translateModuleAddressRanges(ModuleRanges
);
774 DIEValue LowPCAttrInfo
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
775 // For a case where LLD GCs only function used in the CU.
776 // If CU doesn't have DW_AT_low_pc we are not going to convert,
777 // so don't need to do anything.
778 if (OutputRanges
.empty() && !Unit
.isDWOUnit() && LowPCAttrInfo
)
779 OutputRanges
.push_back({0, 0});
780 const uint64_t RangesSectionOffset
=
781 RangesSectionWriter
.addRanges(OutputRanges
);
782 if (!Unit
.isDWOUnit())
783 ARangesSectionWriter
->addCURanges(Unit
.getOffset(),
784 std::move(OutputRanges
));
785 updateDWARFObjectAddressRanges(Unit
, DIEBldr
, *Die
, RangesSectionOffset
,
787 DIEValue StmtListAttrVal
= Die
->findAttribute(dwarf::DW_AT_stmt_list
);
788 if (LineTablePatchMap
.count(&Unit
))
789 DIEBldr
.replaceValue(Die
, dwarf::DW_AT_stmt_list
,
790 StmtListAttrVal
.getForm(),
791 DIEInteger(LineTablePatchMap
[&Unit
]));
795 case dwarf::DW_TAG_subprogram
: {
796 // Get function address either from ranges or [LowPC, HighPC) pair.
797 uint64_t Address
= UINT64_MAX
;
798 uint64_t SectionIndex
, HighPC
;
799 DebugAddressRangesVector FunctionRanges
;
800 if (!getLowAndHighPC(*Die
, Unit
, Address
, HighPC
, SectionIndex
)) {
801 Expected
<DWARFAddressRangesVector
> RangesOrError
=
802 getDIEAddressRanges(*Die
, Unit
);
803 if (!RangesOrError
) {
804 consumeError(RangesOrError
.takeError());
807 DWARFAddressRangesVector Ranges
= *RangesOrError
;
808 // Not a function definition.
812 for (const DWARFAddressRange
&Range
: Ranges
) {
813 if (const BinaryFunction
*Function
=
814 BC
.getBinaryFunctionAtAddress(Range
.LowPC
))
815 FunctionRanges
.append(Function
->getOutputAddressRanges());
818 if (const BinaryFunction
*Function
=
819 BC
.getBinaryFunctionAtAddress(Address
))
820 FunctionRanges
= Function
->getOutputAddressRanges();
823 // Clear cached ranges as the new function will have its own set.
824 CachedRanges
.clear();
825 DIEValue LowPCVal
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
826 DIEValue HighPCVal
= Die
->findAttribute(dwarf::DW_AT_high_pc
);
827 if (FunctionRanges
.empty()) {
828 if (LowPCVal
&& HighPCVal
) {
829 FunctionRanges
.push_back({0, HighPCVal
.getDIEInteger().getValue()});
831 // I haven't seen this case, but who knows what other compilers
833 FunctionRanges
.push_back({0, 1});
834 errs() << "BOLT-WARNING: [internal-dwarf-error]: subprogram got GCed "
835 "by the linker, DW_AT_ranges is used\n";
839 if (FunctionRanges
.size() == 1 && !opts::AlwaysConvertToRanges
) {
840 updateLowPCHighPC(Die
, LowPCVal
, HighPCVal
, FunctionRanges
.back().LowPC
,
841 FunctionRanges
.back().HighPC
);
845 updateDWARFObjectAddressRanges(
846 Unit
, DIEBldr
, *Die
, RangesSectionWriter
.addRanges(FunctionRanges
));
850 case dwarf::DW_TAG_lexical_block
:
851 case dwarf::DW_TAG_inlined_subroutine
:
852 case dwarf::DW_TAG_try_block
:
853 case dwarf::DW_TAG_catch_block
: {
854 uint64_t RangesSectionOffset
= 0;
855 Expected
<DWARFAddressRangesVector
> RangesOrError
=
856 getDIEAddressRanges(*Die
, Unit
);
857 const BinaryFunction
*Function
=
858 RangesOrError
&& !RangesOrError
->empty()
859 ? BC
.getBinaryFunctionContainingAddress(
860 RangesOrError
->front().LowPC
)
862 DebugAddressRangesVector OutputRanges
;
864 OutputRanges
= Function
->translateInputToOutputRanges(*RangesOrError
);
865 LLVM_DEBUG(if (OutputRanges
.empty() != RangesOrError
->empty()) {
866 dbgs() << "BOLT-DEBUG: problem with DIE at 0x"
867 << Twine::utohexstr(Die
->getOffset()) << " in CU at 0x"
868 << Twine::utohexstr(Unit
.getOffset()) << '\n';
870 if (opts::AlwaysConvertToRanges
|| OutputRanges
.size() > 1) {
871 RangesSectionOffset
= RangesSectionWriter
.addRanges(
872 std::move(OutputRanges
), CachedRanges
);
873 OutputRanges
.clear();
874 } else if (OutputRanges
.empty()) {
875 OutputRanges
.push_back({RangesOrError
.get().front().LowPC
,
876 RangesOrError
.get().front().HighPC
});
878 } else if (!RangesOrError
) {
879 consumeError(RangesOrError
.takeError());
881 OutputRanges
.push_back({0, !RangesOrError
->empty()
882 ? RangesOrError
.get().front().HighPC
885 DIEValue LowPCVal
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
886 DIEValue HighPCVal
= Die
->findAttribute(dwarf::DW_AT_high_pc
);
887 if (OutputRanges
.size() == 1) {
888 updateLowPCHighPC(Die
, LowPCVal
, HighPCVal
, OutputRanges
.back().LowPC
,
889 OutputRanges
.back().HighPC
);
892 updateDWARFObjectAddressRanges(Unit
, DIEBldr
, *Die
, RangesSectionOffset
);
895 case dwarf::DW_TAG_call_site
: {
896 auto patchPC
= [&](DIE
*Die
, DIEValue
&AttrVal
, StringRef Entry
) -> void {
897 std::optional
<uint64_t> Address
= getAsAddress(Unit
, AttrVal
);
898 const BinaryFunction
*Function
=
899 BC
.getBinaryFunctionContainingAddress(*Address
);
900 uint64_t UpdatedAddress
= *Address
;
903 Function
->translateInputToOutputAddress(UpdatedAddress
);
905 if (AttrVal
.getForm() == dwarf::DW_FORM_addrx
) {
906 const uint32_t Index
=
907 AddrWriter
->getIndexFromAddress(UpdatedAddress
, Unit
);
908 DIEBldr
.replaceValue(Die
, AttrVal
.getAttribute(), AttrVal
.getForm(),
910 } else if (AttrVal
.getForm() == dwarf::DW_FORM_addr
) {
911 DIEBldr
.replaceValue(Die
, AttrVal
.getAttribute(), AttrVal
.getForm(),
912 DIEInteger(UpdatedAddress
));
914 errs() << "BOLT-ERROR: unsupported form for " << Entry
<< "\n";
917 DIEValue CallPcAttrVal
= Die
->findAttribute(dwarf::DW_AT_call_pc
);
919 patchPC(Die
, CallPcAttrVal
, "DW_AT_call_pc");
921 DIEValue CallRetPcAttrVal
=
922 Die
->findAttribute(dwarf::DW_AT_call_return_pc
);
923 if (CallRetPcAttrVal
)
924 patchPC(Die
, CallRetPcAttrVal
, "DW_AT_call_return_pc");
929 // Handle any tag that can have DW_AT_location attribute.
930 DIEValue LocAttrInfo
= Die
->findAttribute(dwarf::DW_AT_location
);
931 DIEValue LowPCAttrInfo
= Die
->findAttribute(dwarf::DW_AT_low_pc
);
933 if (doesFormBelongToClass(LocAttrInfo
.getForm(),
934 DWARFFormValue::FC_Constant
,
935 Unit
.getVersion()) ||
936 doesFormBelongToClass(LocAttrInfo
.getForm(),
937 DWARFFormValue::FC_SectionOffset
,
938 Unit
.getVersion())) {
939 uint64_t Offset
= LocAttrInfo
.getForm() == dwarf::DW_FORM_loclistx
940 ? LocAttrInfo
.getDIELocList().getValue()
941 : LocAttrInfo
.getDIEInteger().getValue();
942 DebugLocationsVector InputLL
;
944 std::optional
<object::SectionedAddress
> SectionAddress
=
945 Unit
.getBaseAddress();
946 uint64_t BaseAddress
= 0;
948 BaseAddress
= SectionAddress
->Address
;
950 if (Unit
.getVersion() >= 5 &&
951 LocAttrInfo
.getForm() == dwarf::DW_FORM_loclistx
) {
952 std::optional
<uint64_t> LocOffset
= Unit
.getLoclistOffset(Offset
);
953 assert(LocOffset
&& "Location Offset is invalid.");
957 Error E
= Unit
.getLocationTable().visitLocationList(
958 &Offset
, [&](const DWARFLocationEntry
&Entry
) {
959 switch (Entry
.Kind
) {
961 llvm_unreachable("Unsupported DWARFLocationEntry Kind.");
962 case dwarf::DW_LLE_end_of_list
:
964 case dwarf::DW_LLE_base_address
: {
965 assert(Entry
.SectionIndex
== SectionedAddress::UndefSection
&&
966 "absolute address expected");
967 BaseAddress
= Entry
.Value0
;
970 case dwarf::DW_LLE_offset_pair
:
972 (Entry
.SectionIndex
== SectionedAddress::UndefSection
&&
973 (!Unit
.isDWOUnit() || Unit
.getVersion() == 5)) &&
974 "absolute address expected");
975 InputLL
.emplace_back(DebugLocationEntry
{
976 BaseAddress
+ Entry
.Value0
, BaseAddress
+ Entry
.Value1
,
979 case dwarf::DW_LLE_start_length
:
980 InputLL
.emplace_back(DebugLocationEntry
{
981 Entry
.Value0
, Entry
.Value0
+ Entry
.Value1
, Entry
.Loc
});
983 case dwarf::DW_LLE_base_addressx
: {
984 std::optional
<object::SectionedAddress
> EntryAddress
=
985 Unit
.getAddrOffsetSectionItem(Entry
.Value0
);
986 assert(EntryAddress
&& "base Address not found.");
987 BaseAddress
= EntryAddress
->Address
;
990 case dwarf::DW_LLE_startx_length
: {
991 std::optional
<object::SectionedAddress
> EntryAddress
=
992 Unit
.getAddrOffsetSectionItem(Entry
.Value0
);
993 assert(EntryAddress
&& "Address does not exist.");
994 InputLL
.emplace_back(DebugLocationEntry
{
995 EntryAddress
->Address
,
996 EntryAddress
->Address
+ Entry
.Value1
, Entry
.Loc
});
999 case dwarf::DW_LLE_startx_endx
: {
1000 std::optional
<object::SectionedAddress
> StartAddress
=
1001 Unit
.getAddrOffsetSectionItem(Entry
.Value0
);
1002 assert(StartAddress
&& "Start Address does not exist.");
1003 std::optional
<object::SectionedAddress
> EndAddress
=
1004 Unit
.getAddrOffsetSectionItem(Entry
.Value1
);
1005 assert(EndAddress
&& "Start Address does not exist.");
1006 InputLL
.emplace_back(DebugLocationEntry
{
1007 StartAddress
->Address
, EndAddress
->Address
, Entry
.Loc
});
1014 if (E
|| InputLL
.empty()) {
1015 consumeError(std::move(E
));
1016 errs() << "BOLT-WARNING: empty location list detected at 0x"
1017 << Twine::utohexstr(Offset
) << " for DIE at 0x" << Die
1018 << " in CU at 0x" << Twine::utohexstr(Unit
.getOffset())
1021 const uint64_t Address
= InputLL
.front().LowPC
;
1022 DebugLocationsVector OutputLL
;
1023 if (const BinaryFunction
*Function
=
1024 BC
.getBinaryFunctionContainingAddress(Address
)) {
1025 OutputLL
= Function
->translateInputToOutputLocationList(InputLL
);
1026 LLVM_DEBUG(if (OutputLL
.empty()) {
1027 dbgs() << "BOLT-DEBUG: location list translated to an empty "
1029 << Die
<< " in CU at 0x"
1030 << Twine::utohexstr(Unit
.getOffset()) << '\n';
1033 // It's possible for a subprogram to be removed and to have
1034 // address of 0. Adding this entry to output to preserve debug
1038 DebugLocWriter
.addList(DIEBldr
, *Die
, LocAttrInfo
, OutputLL
);
1041 assert((doesFormBelongToClass(LocAttrInfo
.getForm(),
1042 DWARFFormValue::FC_Exprloc
,
1043 Unit
.getVersion()) ||
1044 doesFormBelongToClass(LocAttrInfo
.getForm(),
1045 DWARFFormValue::FC_Block
,
1046 Unit
.getVersion())) &&
1047 "unexpected DW_AT_location form");
1048 if (Unit
.isDWOUnit() || Unit
.getVersion() >= 5) {
1049 std::vector
<uint8_t> Sblock
;
1050 DIEValueList
*AttrLocValList
;
1051 if (doesFormBelongToClass(LocAttrInfo
.getForm(),
1052 DWARFFormValue::FC_Exprloc
,
1053 Unit
.getVersion())) {
1054 for (const DIEValue
&Val
: LocAttrInfo
.getDIELoc().values()) {
1055 Sblock
.push_back(Val
.getDIEInteger().getValue());
1057 DIELoc
*LocAttr
= const_cast<DIELoc
*>(&LocAttrInfo
.getDIELoc());
1058 AttrLocValList
= static_cast<DIEValueList
*>(LocAttr
);
1060 for (const DIEValue
&Val
: LocAttrInfo
.getDIEBlock().values()) {
1061 Sblock
.push_back(Val
.getDIEInteger().getValue());
1063 DIEBlock
*BlockAttr
=
1064 const_cast<DIEBlock
*>(&LocAttrInfo
.getDIEBlock());
1065 AttrLocValList
= static_cast<DIEValueList
*>(BlockAttr
);
1067 ArrayRef
<uint8_t> Expr
= ArrayRef
<uint8_t>(Sblock
);
1069 StringRef((const char *)Expr
.data(), Expr
.size()),
1070 Unit
.getContext().isLittleEndian(), 0);
1071 DWARFExpression
LocExpr(Data
, Unit
.getAddressByteSize(),
1072 Unit
.getFormParams().Format
);
1073 uint32_t PrevOffset
= 0;
1074 DIEValueList
*NewAttr
;
1076 uint32_t NewExprSize
= 0;
1077 DIELoc
*Loc
= nullptr;
1078 DIEBlock
*Block
= nullptr;
1079 if (LocAttrInfo
.getForm() == dwarf::DW_FORM_exprloc
) {
1080 Loc
= DIEBldr
.allocateDIEValue
<DIELoc
>();
1082 Value
= DIEValue(LocAttrInfo
.getAttribute(),
1083 LocAttrInfo
.getForm(), Loc
);
1084 } else if (doesFormBelongToClass(LocAttrInfo
.getForm(),
1085 DWARFFormValue::FC_Block
,
1086 Unit
.getVersion())) {
1087 Block
= DIEBldr
.allocateDIEValue
<DIEBlock
>();
1089 Value
= DIEValue(LocAttrInfo
.getAttribute(),
1090 LocAttrInfo
.getForm(), Block
);
1092 errs() << "BOLT-WARNING: Unexpected Form value in Updating "
1097 for (const DWARFExpression::Operation
&Expr
: LocExpr
) {
1098 uint32_t CurEndOffset
= PrevOffset
+ 1;
1099 if (Expr
.getDescription().Op
.size() == 1)
1100 CurEndOffset
= Expr
.getOperandEndOffset(0);
1101 if (Expr
.getDescription().Op
.size() == 2)
1102 CurEndOffset
= Expr
.getOperandEndOffset(1);
1103 if (Expr
.getDescription().Op
.size() > 2)
1104 errs() << "BOLT-WARNING: [internal-dwarf-error]: Unsupported "
1105 "number of operands.\n";
1106 // not addr index, just copy.
1107 if (!(Expr
.getCode() == dwarf::DW_OP_GNU_addr_index
||
1108 Expr
.getCode() == dwarf::DW_OP_addrx
)) {
1109 auto Itr
= AttrLocValList
->values().begin();
1110 std::advance(Itr
, PrevOffset
);
1111 uint32_t CopyNum
= CurEndOffset
- PrevOffset
;
1112 NewExprSize
+= CopyNum
;
1114 DIEBldr
.addValue(NewAttr
, *Itr
);
1115 std::advance(Itr
, 1);
1118 const uint64_t Index
= Expr
.getRawOperand(0);
1119 std::optional
<object::SectionedAddress
> EntryAddress
=
1120 Unit
.getAddrOffsetSectionItem(Index
);
1121 assert(EntryAddress
&& "Address is not found.");
1122 assert(Index
<= std::numeric_limits
<uint32_t>::max() &&
1123 "Invalid Operand Index.");
1124 const uint32_t AddrIndex
= AddrWriter
->getIndexFromAddress(
1125 EntryAddress
->Address
, Unit
);
1126 // update Index into .debug_address section for DW_AT_location.
1127 // The Size field is not stored in IR, we need to minus 1 in
1128 // offset for each expr.
1130 raw_svector_ostream
OSE(Tmp
);
1131 encodeULEB128(AddrIndex
, OSE
);
1133 DIEBldr
.addValue(NewAttr
, static_cast<dwarf::Attribute
>(0),
1134 dwarf::DW_FORM_data1
,
1135 DIEInteger(Expr
.getCode()));
1137 for (uint8_t Byte
: Tmp
) {
1138 DIEBldr
.addValue(NewAttr
, static_cast<dwarf::Attribute
>(0),
1139 dwarf::DW_FORM_data1
, DIEInteger(Byte
));
1143 PrevOffset
= CurEndOffset
;
1146 // update the size since the index might be changed
1148 Loc
->setSize(NewExprSize
);
1150 Block
->setSize(NewExprSize
);
1151 DIEBldr
.replaceValue(Die
, LocAttrInfo
.getAttribute(),
1152 LocAttrInfo
.getForm(), Value
);
1155 } else if (LowPCAttrInfo
) {
1156 const std::optional
<uint64_t> Result
=
1157 LowPCAttrInfo
.getDIEInteger().getValue();
1158 if (Result
.has_value()) {
1159 const uint64_t Address
= Result
.value();
1160 uint64_t NewAddress
= 0;
1161 if (const BinaryFunction
*Function
=
1162 BC
.getBinaryFunctionContainingAddress(Address
)) {
1163 NewAddress
= Function
->translateInputToOutputAddress(Address
);
1165 << "BOLT-DEBUG: Fixing low_pc 0x"
1166 << Twine::utohexstr(Address
) << " for DIE with tag "
1167 << Die
->getTag() << " to 0x"
1168 << Twine::utohexstr(NewAddress
) << '\n');
1171 dwarf::Form Form
= LowPCAttrInfo
.getForm();
1172 assert(Form
!= dwarf::DW_FORM_LLVM_addrx_offset
&&
1173 "DW_FORM_LLVM_addrx_offset is not supported");
1174 std::lock_guard
<std::mutex
> Lock(DWARFRewriterMutex
);
1175 if (Form
== dwarf::DW_FORM_addrx
||
1176 Form
== dwarf::DW_FORM_GNU_addr_index
) {
1177 const uint32_t Index
= AddrWriter
->getIndexFromAddress(
1178 NewAddress
? NewAddress
: Address
, Unit
);
1179 DIEBldr
.replaceValue(Die
, LowPCAttrInfo
.getAttribute(),
1180 LowPCAttrInfo
.getForm(), DIEInteger(Index
));
1182 DIEBldr
.replaceValue(Die
, LowPCAttrInfo
.getAttribute(),
1183 LowPCAttrInfo
.getForm(),
1184 DIEInteger(NewAddress
));
1186 } else if (opts::Verbosity
>= 1) {
1187 errs() << "BOLT-WARNING: unexpected form value for attribute "
1194 if (DIEOffset
> NextCUOffset
)
1195 errs() << "BOLT-WARNING: corrupt DWARF detected at 0x"
1196 << Twine::utohexstr(Unit
.getOffset()) << '\n';
1199 void DWARFRewriter::updateDWARFObjectAddressRanges(
1200 DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
, DIE
&Die
, uint64_t DebugRangesOffset
,
1201 std::optional
<uint64_t> RangesBase
) {
1204 // If DW_AT_GNU_ranges_base is present, update it. No further modifications
1205 // are needed for ranges base.
1207 DIEValue RangesBaseInfo
= Die
.findAttribute(dwarf::DW_AT_GNU_ranges_base
);
1208 if (!RangesBaseInfo
) {
1209 RangesBaseInfo
= Die
.findAttribute(dwarf::DW_AT_rnglists_base
);
1212 if (RangesBaseInfo
) {
1213 DIEBldr
.replaceValue(&Die
, RangesBaseInfo
.getAttribute(),
1214 RangesBaseInfo
.getForm(),
1215 DIEInteger(static_cast<uint32_t>(*RangesBase
)));
1216 RangesBase
= std::nullopt
;
1220 DIEValue LowPCAttrInfo
= Die
.findAttribute(dwarf::DW_AT_low_pc
);
1221 DIEValue RangesAttrInfo
= Die
.findAttribute(dwarf::DW_AT_ranges
);
1222 if (RangesAttrInfo
) {
1223 // Case 1: The object was already non-contiguous and had DW_AT_ranges.
1224 // In this case we simply need to update the value of DW_AT_ranges
1225 // and introduce DW_AT_GNU_ranges_base if required.
1226 // For DWARF5 converting all of DW_AT_ranges into DW_FORM_rnglistx
1227 bool NeedConverted
= false;
1229 if (Unit
.getVersion() >= 5 &&
1230 RangesAttrInfo
.getForm() == dwarf::DW_FORM_sec_offset
)
1231 NeedConverted
= true;
1233 uint64_t CurRangeBase
= 0;
1234 if (Unit
.isDWOUnit()) {
1235 if (std::optional
<uint64_t> DWOId
= Unit
.getDWOId())
1236 CurRangeBase
= getDwoRangesBase(*DWOId
);
1238 errs() << "BOLT-WARNING: [internal-dwarf-error]: DWOId is not found "
1241 if (NeedConverted
|| RangesAttrInfo
.getForm() == dwarf::DW_FORM_rnglistx
)
1242 DIEBldr
.replaceValue(&Die
, dwarf::DW_AT_ranges
, dwarf::DW_FORM_rnglistx
,
1243 DIEInteger(DebugRangesOffset
));
1245 DIEBldr
.replaceValue(&Die
, dwarf::DW_AT_ranges
, RangesAttrInfo
.getForm(),
1246 DIEInteger(DebugRangesOffset
- CurRangeBase
));
1249 if (LowPCAttrInfo
&&
1250 LowPCAttrInfo
.getForm() != dwarf::DW_FORM_GNU_addr_index
&&
1251 LowPCAttrInfo
.getForm() != dwarf::DW_FORM_addrx
)
1252 DIEBldr
.replaceValue(&Die
, dwarf::DW_AT_low_pc
, LowPCAttrInfo
.getForm(),
1257 if (!(Die
.getTag() == dwarf::DW_TAG_compile_unit
||
1258 Die
.getTag() == dwarf::DW_TAG_skeleton_unit
))
1261 // If we are at this point we are in the CU/Skeleton CU, and
1262 // DW_AT_GNU_ranges_base or DW_AT_rnglists_base doesn't exist.
1263 if (Unit
.getVersion() <= 4)
1264 DIEBldr
.addValue(&Die
, dwarf::DW_AT_GNU_ranges_base
, dwarf::DW_FORM_data4
,
1265 DIEInteger(*RangesBase
));
1266 else if (Unit
.getVersion() == 5)
1267 DIEBldr
.addValue(&Die
, dwarf::DW_AT_rnglists_base
,
1268 dwarf::DW_FORM_sec_offset
, DIEInteger(*RangesBase
));
1270 DIEBldr
.addValue(&Die
, dwarf::DW_AT_rnglists_base
,
1271 dwarf::DW_FORM_sec_offset
, DIEInteger(*RangesBase
));
1275 // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back
1276 // to back. Replace with new attributes and patch the DIE.
1277 DIEValue HighPCAttrInfo
= Die
.findAttribute(dwarf::DW_AT_high_pc
);
1278 if (LowPCAttrInfo
&& HighPCAttrInfo
) {
1280 convertToRangesPatchDebugInfo(Unit
, DIEBldr
, Die
, DebugRangesOffset
,
1281 LowPCAttrInfo
, HighPCAttrInfo
, RangesBase
);
1282 } else if (!(Unit
.isDWOUnit() &&
1283 Die
.getTag() == dwarf::DW_TAG_compile_unit
)) {
1284 if (opts::Verbosity
>= 1)
1285 errs() << "BOLT-WARNING: cannot update ranges for DIE in Unit offset 0x"
1286 << Unit
.getOffset() << '\n';
1290 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout
&Layout
) {
1291 ErrorOr
<BinarySection
&> DbgInfoSection
=
1292 BC
.getUniqueSectionByName(".debug_info");
1293 ErrorOr
<BinarySection
&> TypeInfoSection
=
1294 BC
.getUniqueSectionByName(".debug_types");
1295 assert(((BC
.DwCtx
->getNumTypeUnits() > 0 && TypeInfoSection
) ||
1296 BC
.DwCtx
->getNumTypeUnits() == 0) &&
1297 "Was not able to retrieve Debug Types section.");
1299 // There is no direct connection between CU and TU, but same offsets,
1300 // encoded in DW_AT_stmt_list, into .debug_line get modified.
1301 // We take advantage of that to map original CU line table offsets to new
1303 std::unordered_map
<uint64_t, uint64_t> DebugLineOffsetMap
;
1305 auto GetStatementListValue
= [](DWARFUnit
*Unit
) {
1306 std::optional
<DWARFFormValue
> StmtList
=
1307 Unit
->getUnitDIE().find(dwarf::DW_AT_stmt_list
);
1308 std::optional
<uint64_t> Offset
= dwarf::toSectionOffset(StmtList
);
1309 assert(Offset
&& "Was not able to retreive value of DW_AT_stmt_list.");
1313 for (const std::unique_ptr
<DWARFUnit
> &CU
: BC
.DwCtx
->compile_units()) {
1314 const unsigned CUID
= CU
->getOffset();
1315 MCSymbol
*Label
= BC
.getDwarfLineTable(CUID
).getLabel();
1319 std::optional
<AttrInfo
> AttrVal
=
1320 findAttributeInfo(CU
.get()->getUnitDIE(), dwarf::DW_AT_stmt_list
);
1324 const uint64_t LineTableOffset
= Layout
.getSymbolOffset(*Label
);
1325 DebugLineOffsetMap
[GetStatementListValue(CU
.get())] = LineTableOffset
;
1326 assert(DbgInfoSection
&& ".debug_info section must exist");
1327 LineTablePatchMap
[CU
.get()] = LineTableOffset
;
1330 for (const std::unique_ptr
<DWARFUnit
> &TU
: BC
.DwCtx
->types_section_units()) {
1331 DWARFUnit
*Unit
= TU
.get();
1332 std::optional
<AttrInfo
> AttrVal
=
1333 findAttributeInfo(TU
.get()->getUnitDIE(), dwarf::DW_AT_stmt_list
);
1336 auto Iter
= DebugLineOffsetMap
.find(GetStatementListValue(Unit
));
1337 assert(Iter
!= DebugLineOffsetMap
.end() &&
1338 "Type Unit Updated Line Number Entry does not exist.");
1339 TypeUnitRelocMap
[Unit
] = Iter
->second
;
1342 // Set .debug_info as finalized so it won't be skipped over when
1343 // we process sections while writing out the new binary. This ensures
1344 // that the pending relocations will be processed and not ignored.
1346 DbgInfoSection
->setIsFinalized();
1348 if (TypeInfoSection
)
1349 TypeInfoSection
->setIsFinalized();
1352 CUOffsetMap
DWARFRewriter::finalizeTypeSections(DIEBuilder
&DIEBlder
,
1353 DIEStreamer
&Streamer
) {
1354 // update TypeUnit DW_AT_stmt_list with new .debug_line information.
1355 for (const std::unique_ptr
<DWARFUnit
> &TU
: BC
.DwCtx
->types_section_units()) {
1356 DIE
*UnitDIE
= DIEBlder
.getUnitDIEbyUnit(*TU
.get());
1357 DIEValue StmtAttrInfo
= UnitDIE
->findAttribute(dwarf::DW_AT_stmt_list
);
1358 if (!StmtAttrInfo
|| !TypeUnitRelocMap
.count(TU
.get()))
1360 DIEBlder
.replaceValue(UnitDIE
, dwarf::DW_AT_stmt_list
,
1361 StmtAttrInfo
.getForm(),
1362 DIEInteger(TypeUnitRelocMap
[TU
.get()]));
1365 // generate and populate abbrevs here
1366 DIEBlder
.generateAbbrevs();
1368 SmallVector
<char, 20> OutBuffer
;
1369 std::shared_ptr
<raw_svector_ostream
> ObjOS
=
1370 std::make_shared
<raw_svector_ostream
>(OutBuffer
);
1371 const object::ObjectFile
*File
= BC
.DwCtx
->getDWARFObj().getFile();
1372 auto TheTriple
= std::make_unique
<Triple
>(File
->makeTriple());
1373 std::unique_ptr
<DIEStreamer
> TypeStreamer
=
1374 createDIEStreamer(*TheTriple
, *ObjOS
, "TypeStreamer", DIEBlder
, *this);
1376 // generate debug_info and CUMap
1378 for (std::unique_ptr
<llvm::DWARFUnit
> &CU
: BC
.DwCtx
->info_section_units()) {
1379 if (!CU
->isTypeUnit())
1381 emitUnit(DIEBlder
, Streamer
, *CU
.get());
1382 uint32_t StartOffset
= CUOffset
;
1383 DIE
*UnitDIE
= DIEBlder
.getUnitDIEbyUnit(*CU
.get());
1384 CUOffset
+= CU
.get()->getHeaderSize();
1385 CUOffset
+= UnitDIE
->getSize();
1386 CUMap
[CU
.get()->getOffset()] = {StartOffset
, CUOffset
- StartOffset
- 4};
1389 // Emit Type Unit of DWARF 4 to .debug_type section
1390 for (DWARFUnit
*TU
: DIEBlder
.getDWARF4TUVector())
1391 emitUnit(DIEBlder
, *TypeStreamer
, *TU
);
1393 TypeStreamer
->finish();
1395 std::unique_ptr
<MemoryBuffer
> ObjectMemBuffer
=
1396 MemoryBuffer::getMemBuffer(ObjOS
->str(), "in-memory object file", false);
1397 std::unique_ptr
<object::ObjectFile
> Obj
= cantFail(
1398 object::ObjectFile::createObjectFile(ObjectMemBuffer
->getMemBufferRef()),
1399 "error creating in-memory object");
1401 for (const SectionRef
&Section
: Obj
->sections()) {
1402 StringRef Contents
= cantFail(Section
.getContents());
1403 StringRef Name
= cantFail(Section
.getName());
1404 if (Name
.equals(".debug_types"))
1405 BC
.registerOrUpdateNoteSection(".debug_types", copyByteArray(Contents
),
1411 void DWARFRewriter::finalizeDebugSections(DIEBuilder
&DIEBlder
,
1412 DIEStreamer
&Streamer
,
1413 raw_svector_ostream
&ObjOS
,
1414 CUOffsetMap
&CUMap
) {
1415 if (StrWriter
->isInitialized()) {
1416 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
1417 std::unique_ptr
<DebugStrBufferVector
> DebugStrSectionContents
=
1418 StrWriter
->releaseBuffer();
1419 BC
.registerOrUpdateNoteSection(".debug_str",
1420 copyByteArray(*DebugStrSectionContents
),
1421 DebugStrSectionContents
->size());
1424 if (StrOffstsWriter
->isFinalized()) {
1425 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str_offsets");
1426 std::unique_ptr
<DebugStrOffsetsBufferVector
>
1427 DebugStrOffsetsSectionContents
= StrOffstsWriter
->releaseBuffer();
1428 BC
.registerOrUpdateNoteSection(
1429 ".debug_str_offsets", copyByteArray(*DebugStrOffsetsSectionContents
),
1430 DebugStrOffsetsSectionContents
->size());
1433 if (BC
.isDWARFLegacyUsed()) {
1434 std::unique_ptr
<DebugBufferVector
> RangesSectionContents
=
1435 LegacyRangesSectionWriter
->releaseBuffer();
1436 BC
.registerOrUpdateNoteSection(".debug_ranges",
1437 copyByteArray(*RangesSectionContents
),
1438 RangesSectionContents
->size());
1441 if (BC
.isDWARF5Used()) {
1442 std::unique_ptr
<DebugBufferVector
> RangesSectionContents
=
1443 RangeListsSectionWriter
->releaseBuffer();
1444 BC
.registerOrUpdateNoteSection(".debug_rnglists",
1445 copyByteArray(*RangesSectionContents
),
1446 RangesSectionContents
->size());
1449 if (BC
.isDWARF5Used()) {
1450 std::unique_ptr
<DebugBufferVector
> LocationListSectionContents
=
1451 makeFinalLocListsSection(DWARFVersion::DWARF5
);
1452 if (!LocationListSectionContents
->empty())
1453 BC
.registerOrUpdateNoteSection(
1454 ".debug_loclists", copyByteArray(*LocationListSectionContents
),
1455 LocationListSectionContents
->size());
1458 if (BC
.isDWARFLegacyUsed()) {
1459 std::unique_ptr
<DebugBufferVector
> LocationListSectionContents
=
1460 makeFinalLocListsSection(DWARFVersion::DWARFLegacy
);
1461 if (!LocationListSectionContents
->empty())
1462 BC
.registerOrUpdateNoteSection(
1463 ".debug_loc", copyByteArray(*LocationListSectionContents
),
1464 LocationListSectionContents
->size());
1467 // AddrWriter should be finalized after debug_loc since more addresses can be
1469 if (AddrWriter
->isInitialized()) {
1470 AddressSectionBuffer AddressSectionContents
= AddrWriter
->finalize();
1471 BC
.registerOrUpdateNoteSection(".debug_addr",
1472 copyByteArray(AddressSectionContents
),
1473 AddressSectionContents
.size());
1476 Streamer
.emitAbbrevs(DIEBlder
.getAbbrevs(), BC
.DwCtx
->getMaxVersion());
1479 std::unique_ptr
<MemoryBuffer
> ObjectMemBuffer
=
1480 MemoryBuffer::getMemBuffer(ObjOS
.str(), "in-memory object file", false);
1481 std::unique_ptr
<object::ObjectFile
> Obj
= cantFail(
1482 object::ObjectFile::createObjectFile(ObjectMemBuffer
->getMemBufferRef()),
1483 "error creating in-memory object");
1485 for (const SectionRef
&Secs
: Obj
->sections()) {
1486 StringRef Contents
= cantFail(Secs
.getContents());
1487 StringRef Name
= cantFail(Secs
.getName());
1488 if (Name
.equals(".debug_abbrev")) {
1489 BC
.registerOrUpdateNoteSection(".debug_abbrev", copyByteArray(Contents
),
1491 } else if (Name
.equals(".debug_info")) {
1492 BC
.registerOrUpdateNoteSection(".debug_info", copyByteArray(Contents
),
1497 // Skip .debug_aranges if we are re-generating .gdb_index.
1498 if (opts::KeepARanges
|| !BC
.getGdbIndexSection()) {
1499 SmallVector
<char, 16> ARangesBuffer
;
1500 raw_svector_ostream
OS(ARangesBuffer
);
1502 auto MAB
= std::unique_ptr
<MCAsmBackend
>(
1503 BC
.TheTarget
->createMCAsmBackend(*BC
.STI
, *BC
.MRI
, MCTargetOptions()));
1505 ARangesSectionWriter
->writeARangesSection(OS
, CUMap
);
1506 const StringRef
&ARangesContents
= OS
.str();
1508 BC
.registerOrUpdateNoteSection(".debug_aranges",
1509 copyByteArray(ARangesContents
),
1510 ARangesContents
.size());
1514 void DWARFRewriter::finalizeCompileUnits(DIEBuilder
&DIEBlder
,
1515 DIEStreamer
&Streamer
,
1517 const std::list
<DWARFUnit
*> &CUs
) {
1518 DIEBlder
.generateAbbrevs();
1520 // generate debug_info and CUMap
1521 for (DWARFUnit
*CU
: CUs
) {
1522 emitUnit(DIEBlder
, Streamer
, *CU
);
1523 const uint32_t StartOffset
= CUOffset
;
1524 DIE
*UnitDIE
= DIEBlder
.getUnitDIEbyUnit(*CU
);
1525 CUOffset
+= CU
->getHeaderSize();
1526 CUOffset
+= UnitDIE
->getSize();
1527 CUMap
[CU
->getOffset()] = {StartOffset
, CUOffset
- StartOffset
- 4};
1531 // Creates all the data structures necessary for creating MCStreamer.
1532 // They are passed by reference because they need to be kept around.
1533 // Also creates known debug sections. These are sections handled by
1534 // handleDebugDataPatching.
1537 std::unique_ptr
<BinaryContext
>
1538 createDwarfOnlyBC(const object::ObjectFile
&File
) {
1539 return cantFail(BinaryContext::createBinaryContext(
1541 DWARFContext::create(File
, DWARFContext::ProcessDebugRelocations::Ignore
,
1542 nullptr, "", WithColor::defaultErrorHandler
,
1543 WithColor::defaultWarningHandler
)));
1546 StringMap
<DWARFRewriter::KnownSectionsEntry
>
1547 createKnownSectionsMap(const MCObjectFileInfo
&MCOFI
) {
1548 StringMap
<DWARFRewriter::KnownSectionsEntry
> KnownSectionsTemp
= {
1549 {"debug_info.dwo", {MCOFI
.getDwarfInfoDWOSection(), DW_SECT_INFO
}},
1550 {"debug_types.dwo", {MCOFI
.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES
}},
1551 {"debug_str_offsets.dwo",
1552 {MCOFI
.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS
}},
1553 {"debug_str.dwo", {MCOFI
.getDwarfStrDWOSection(), DW_SECT_EXT_unknown
}},
1554 {"debug_loc.dwo", {MCOFI
.getDwarfLocDWOSection(), DW_SECT_EXT_LOC
}},
1555 {"debug_abbrev.dwo", {MCOFI
.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV
}},
1556 {"debug_line.dwo", {MCOFI
.getDwarfLineDWOSection(), DW_SECT_LINE
}},
1557 {"debug_loclists.dwo",
1558 {MCOFI
.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS
}},
1559 {"debug_rnglists.dwo",
1560 {MCOFI
.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS
}}};
1561 return KnownSectionsTemp
;
1564 StringRef
getSectionName(const SectionRef
&Section
) {
1565 Expected
<StringRef
> SectionName
= Section
.getName();
1566 assert(SectionName
&& "Invalid section name.");
1567 StringRef Name
= *SectionName
;
1568 Name
= Name
.substr(Name
.find_first_not_of("._"));
1572 // Exctracts an appropriate slice if input is DWP.
1573 // Applies patches or overwrites the section.
1574 std::optional
<StringRef
> updateDebugData(
1575 DWARFContext
&DWCtx
, StringRef SectionName
, StringRef SectionContents
,
1576 const StringMap
<DWARFRewriter::KnownSectionsEntry
> &KnownSections
,
1577 MCStreamer
&Streamer
, DWARFRewriter
&Writer
,
1578 const DWARFUnitIndex::Entry
*CUDWOEntry
, uint64_t DWOId
,
1579 std::unique_ptr
<DebugBufferVector
> &OutputBuffer
,
1580 DebugRangeListsSectionWriter
*RangeListsWriter
, DebugLocWriter
&LocWriter
,
1581 const llvm::bolt::DWARFRewriter::OverriddenSectionsMap
&OverridenSections
) {
1583 using DWOSectionContribution
=
1584 const DWARFUnitIndex::Entry::SectionContribution
;
1585 auto getSliceData
= [&](const DWARFUnitIndex::Entry
*DWOEntry
,
1586 StringRef OutData
, DWARFSectionKind Sec
,
1587 uint64_t &DWPOffset
) -> StringRef
{
1589 DWOSectionContribution
*DWOContrubution
= DWOEntry
->getContribution(Sec
);
1590 DWPOffset
= DWOContrubution
->getOffset();
1591 OutData
= OutData
.substr(DWPOffset
, DWOContrubution
->getLength());
1596 auto SectionIter
= KnownSections
.find(SectionName
);
1597 if (SectionIter
== KnownSections
.end())
1598 return std::nullopt
;
1599 Streamer
.switchSection(SectionIter
->second
.first
);
1600 uint64_t DWPOffset
= 0;
1602 auto getOverridenSection
=
1603 [&](DWARFSectionKind Kind
) -> std::optional
<StringRef
> {
1604 auto Iter
= OverridenSections
.find(Kind
);
1605 if (Iter
== OverridenSections
.end()) {
1607 << "BOLT-WARNING: [internal-dwarf-error]: Could not find overriden "
1609 << Twine::utohexstr(DWOId
) << ".\n";
1610 return std::nullopt
;
1612 return Iter
->second
;
1614 switch (SectionIter
->second
.second
) {
1616 if (!SectionName
.equals("debug_str.dwo"))
1617 errs() << "BOLT-WARNING: unsupported debug section: " << SectionName
1619 return SectionContents
;
1621 case DWARFSectionKind::DW_SECT_INFO
: {
1622 return getOverridenSection(DWARFSectionKind::DW_SECT_INFO
);
1624 case DWARFSectionKind::DW_SECT_EXT_TYPES
: {
1625 return getOverridenSection(DWARFSectionKind::DW_SECT_EXT_TYPES
);
1627 case DWARFSectionKind::DW_SECT_STR_OFFSETS
: {
1628 return getSliceData(CUDWOEntry
, SectionContents
,
1629 DWARFSectionKind::DW_SECT_STR_OFFSETS
, DWPOffset
);
1631 case DWARFSectionKind::DW_SECT_ABBREV
: {
1632 return getOverridenSection(DWARFSectionKind::DW_SECT_ABBREV
);
1634 case DWARFSectionKind::DW_SECT_EXT_LOC
:
1635 case DWARFSectionKind::DW_SECT_LOCLISTS
: {
1636 OutputBuffer
= LocWriter
.getBuffer();
1637 // Creating explicit StringRef here, otherwise
1638 // with impicit conversion it will take null byte as end of
1640 return StringRef(reinterpret_cast<const char *>(OutputBuffer
->data()),
1641 OutputBuffer
->size());
1643 case DWARFSectionKind::DW_SECT_LINE
: {
1644 return getSliceData(CUDWOEntry
, SectionContents
,
1645 DWARFSectionKind::DW_SECT_LINE
, DWPOffset
);
1647 case DWARFSectionKind::DW_SECT_RNGLISTS
: {
1648 assert(RangeListsWriter
&& "RangeListsWriter was not created.");
1649 OutputBuffer
= RangeListsWriter
->releaseBuffer();
1650 return StringRef(reinterpret_cast<const char *>(OutputBuffer
->data()),
1651 OutputBuffer
->size());
1658 void DWARFRewriter::initDWPState(DWPState
&State
) {
1659 SmallString
<0> OutputNameStr
;
1660 StringRef OutputName
;
1661 if (opts::DwarfOutputPath
.empty()) {
1663 Twine(opts::OutputFilename
).concat(".dwp").toStringRef(OutputNameStr
);
1665 StringRef ExeFileName
= llvm::sys::path::filename(opts::OutputFilename
);
1666 OutputName
= Twine(opts::DwarfOutputPath
)
1668 .concat(ExeFileName
)
1670 .toStringRef(OutputNameStr
);
1671 errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will "
1672 "possibly be written to another location that is not the same as "
1677 std::make_unique
<ToolOutputFile
>(OutputName
, EC
, sys::fs::OF_None
);
1678 const object::ObjectFile
*File
= BC
.DwCtx
->getDWARFObj().getFile();
1679 State
.TmpBC
= createDwarfOnlyBC(*File
);
1680 State
.Streamer
= State
.TmpBC
->createStreamer(State
.Out
->os());
1681 State
.MCOFI
= State
.Streamer
->getContext().getObjectFileInfo();
1682 State
.KnownSections
= createKnownSectionsMap(*State
.MCOFI
);
1683 MCSection
*const StrSection
= State
.MCOFI
->getDwarfStrDWOSection();
1685 // Data Structures for DWP book keeping
1686 // Size of array corresponds to the number of sections supported by DWO format
1689 State
.Strings
= std::make_unique
<DWPStringPool
>(*State
.Streamer
, StrSection
);
1691 // Setup DWP code once.
1692 DWARFContext
*DWOCtx
= BC
.getDWOContext();
1695 State
.CUIndex
= &DWOCtx
->getCUIndex();
1696 State
.IsDWP
= !State
.CUIndex
->getRows().empty();
1700 void DWARFRewriter::finalizeDWP(DWPState
&State
) {
1701 if (State
.Version
< 5) {
1702 // Lie about there being no info contributions so the TU index only includes
1703 // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
1704 // contribution to the info section, so we do not want to lie about it.
1705 State
.ContributionOffsets
[0] = 0;
1707 writeIndex(*State
.Streamer
.get(), State
.MCOFI
->getDwarfTUIndexSection(),
1708 State
.ContributionOffsets
, State
.TypeIndexEntries
,
1709 State
.IndexVersion
);
1711 if (State
.Version
< 5) {
1712 // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
1713 // section does not exist, so no need to do anything about this.
1714 State
.ContributionOffsets
[getContributionIndex(DW_SECT_EXT_TYPES
, 2)] = 0;
1715 // Unlie about the info contribution
1716 State
.ContributionOffsets
[0] = 1;
1718 writeIndex(*State
.Streamer
.get(), State
.MCOFI
->getDwarfCUIndexSection(),
1719 State
.ContributionOffsets
, State
.IndexEntries
, State
.IndexVersion
);
1721 State
.Streamer
->finish();
1725 void DWARFRewriter::updateDWP(DWARFUnit
&CU
,
1726 const OverriddenSectionsMap
&OverridenSections
,
1727 const DWARFRewriter::UnitMeta
&CUMI
,
1728 DWARFRewriter::UnitMetaVectorType
&TUMetaVector
,
1729 DWPState
&State
, DebugLocWriter
&LocWriter
) {
1730 const uint64_t DWOId
= *CU
.getDWOId();
1731 MCSection
*const StrOffsetSection
= State
.MCOFI
->getDwarfStrOffDWOSection();
1732 assert(StrOffsetSection
&& "StrOffsetSection does not exist.");
1733 // Skipping CUs that we failed to load.
1734 std::optional
<DWARFUnit
*> DWOCU
= BC
.getDWOCU(DWOId
);
1738 if (State
.Version
== 0) {
1739 State
.Version
= CU
.getVersion();
1740 State
.IndexVersion
= State
.Version
< 5 ? 2 : 5;
1741 } else if (State
.Version
!= CU
.getVersion()) {
1742 errs() << "BOLT-ERROR: incompatible DWARF compile unit versions\n";
1746 UnitIndexEntry CurEntry
= {};
1747 CurEntry
.DWOName
= dwarf::toString(
1748 CU
.getUnitDIE().find({dwarf::DW_AT_dwo_name
, dwarf::DW_AT_GNU_dwo_name
}),
1750 const char *Name
= CU
.getUnitDIE().getShortName();
1752 CurEntry
.Name
= Name
;
1753 StringRef CurStrSection
;
1754 StringRef CurStrOffsetSection
;
1756 // This maps each section contained in this file to its length.
1757 // This information is later on used to calculate the contributions,
1758 // i.e. offset and length, of each compile/type unit to a section.
1759 std::vector
<std::pair
<DWARFSectionKind
, uint32_t>> SectionLength
;
1761 const DWARFUnitIndex::Entry
*CUDWOEntry
= nullptr;
1763 CUDWOEntry
= State
.CUIndex
->getFromHash(DWOId
);
1765 bool StrSectionWrittenOut
= false;
1766 const object::ObjectFile
*DWOFile
=
1767 (*DWOCU
)->getContext().getDWARFObj().getFile();
1769 DebugRangeListsSectionWriter
*RangeListssWriter
= nullptr;
1770 if (CU
.getVersion() == 5) {
1771 assert(RangeListsWritersByCU
.count(DWOId
) != 0 &&
1772 "No RangeListsWriter for DWO ID.");
1773 RangeListssWriter
= RangeListsWritersByCU
[DWOId
].get();
1775 auto AddType
= [&](unsigned int Index
, uint32_t IndexVersion
, uint64_t Offset
,
1776 uint64_t Length
, uint64_t Hash
) -> void {
1777 UnitIndexEntry TUEntry
= CurEntry
;
1778 if (IndexVersion
< 5)
1779 TUEntry
.Contributions
[0] = {};
1780 TUEntry
.Contributions
[Index
].setOffset(Offset
);
1781 TUEntry
.Contributions
[Index
].setLength(Length
);
1782 State
.ContributionOffsets
[Index
] +=
1783 TUEntry
.Contributions
[Index
].getLength32();
1784 State
.TypeIndexEntries
.insert(std::make_pair(Hash
, TUEntry
));
1786 for (const SectionRef
&Section
: DWOFile
->sections()) {
1787 std::unique_ptr
<DebugBufferVector
> OutputData
;
1788 StringRef SectionName
= getSectionName(Section
);
1789 Expected
<StringRef
> ContentsExp
= Section
.getContents();
1790 assert(ContentsExp
&& "Invalid contents.");
1791 std::optional
<StringRef
> TOutData
= updateDebugData(
1792 (*DWOCU
)->getContext(), SectionName
, *ContentsExp
, State
.KnownSections
,
1793 *State
.Streamer
, *this, CUDWOEntry
, DWOId
, OutputData
,
1794 RangeListssWriter
, LocWriter
, OverridenSections
);
1798 StringRef OutData
= *TOutData
;
1799 if (SectionName
== "debug_types.dwo") {
1800 State
.Streamer
->emitBytes(OutData
);
1804 if (SectionName
.equals("debug_str.dwo")) {
1805 CurStrSection
= OutData
;
1807 // Since handleDebugDataPatching returned true, we already know this is
1809 auto SectionIter
= State
.KnownSections
.find(SectionName
);
1810 if (SectionIter
->second
.second
== DWARFSectionKind::DW_SECT_STR_OFFSETS
)
1811 CurStrOffsetSection
= OutData
;
1813 State
.Streamer
->emitBytes(OutData
);
1814 unsigned int Index
=
1815 getContributionIndex(SectionIter
->second
.second
, State
.IndexVersion
);
1816 uint64_t Offset
= State
.ContributionOffsets
[Index
];
1817 uint64_t Length
= OutData
.size();
1818 if (CU
.getVersion() >= 5 &&
1819 SectionIter
->second
.second
== DWARFSectionKind::DW_SECT_INFO
) {
1820 for (UnitMeta
&MI
: TUMetaVector
)
1821 MI
.Offset
+= State
.DebugInfoSize
;
1823 Offset
= State
.DebugInfoSize
+ CUMI
.Offset
;
1824 Length
= CUMI
.Length
;
1825 State
.DebugInfoSize
+= OutData
.size();
1827 CurEntry
.Contributions
[Index
].setOffset(Offset
);
1828 CurEntry
.Contributions
[Index
].setLength(Length
);
1829 State
.ContributionOffsets
[Index
] +=
1830 CurEntry
.Contributions
[Index
].getLength32();
1833 // Strings are combined in to a new string section, and de-duplicated
1835 if (!StrSectionWrittenOut
&& !CurStrOffsetSection
.empty() &&
1836 !CurStrSection
.empty()) {
1837 writeStringsAndOffsets(*State
.Streamer
.get(), *State
.Strings
.get(),
1838 StrOffsetSection
, CurStrSection
,
1839 CurStrOffsetSection
, CU
.getVersion());
1840 StrSectionWrittenOut
= true;
1843 CompileUnitIdentifiers CUI
{DWOId
, CurEntry
.Name
.c_str(),
1844 CurEntry
.DWOName
.c_str()};
1845 auto P
= State
.IndexEntries
.insert(std::make_pair(CUI
.Signature
, CurEntry
));
1847 Error Err
= buildDuplicateError(*P
.first
, CUI
, "");
1848 errs() << "BOLT-ERROR: " << toString(std::move(Err
)) << "\n";
1853 const unsigned Index
= getContributionIndex(
1854 State
.IndexVersion
< 5 ? DW_SECT_EXT_TYPES
: DW_SECT_INFO
,
1855 State
.IndexVersion
);
1856 for (UnitMeta
&MI
: TUMetaVector
)
1857 AddType(Index
, State
.IndexVersion
, MI
.Offset
, MI
.Length
, MI
.TUHash
);
1860 void DWARFRewriter::writeDWOFiles(
1861 DWARFUnit
&CU
, const OverriddenSectionsMap
&OverridenSections
,
1862 const std::string
&DWOName
, DebugLocWriter
&LocWriter
) {
1863 // Setup DWP code once.
1864 DWARFContext
*DWOCtx
= BC
.getDWOContext();
1865 const uint64_t DWOId
= *CU
.getDWOId();
1866 const DWARFUnitIndex
*CUIndex
= nullptr;
1869 CUIndex
= &DWOCtx
->getCUIndex();
1870 IsDWP
= !CUIndex
->getRows().empty();
1873 // Skipping CUs that we failed to load.
1874 std::optional
<DWARFUnit
*> DWOCU
= BC
.getDWOCU(DWOId
);
1876 errs() << "BOLT-WARNING: [internal-dwarf-error]: CU for DWO_ID "
1877 << Twine::utohexstr(DWOId
) << " is not found.\n";
1881 std::string CompDir
= opts::DwarfOutputPath
.empty()
1882 ? CU
.getCompilationDir()
1883 : opts::DwarfOutputPath
.c_str();
1884 auto FullPath
= CompDir
.append("/").append(DWOName
);
1887 std::unique_ptr
<ToolOutputFile
> TempOut
=
1888 std::make_unique
<ToolOutputFile
>(FullPath
, EC
, sys::fs::OF_None
);
1890 const DWARFUnitIndex::Entry
*CUDWOEntry
= nullptr;
1892 CUDWOEntry
= CUIndex
->getFromHash(DWOId
);
1894 const object::ObjectFile
*File
=
1895 (*DWOCU
)->getContext().getDWARFObj().getFile();
1896 std::unique_ptr
<BinaryContext
> TmpBC
= createDwarfOnlyBC(*File
);
1897 std::unique_ptr
<MCStreamer
> Streamer
= TmpBC
->createStreamer(TempOut
->os());
1898 const MCObjectFileInfo
&MCOFI
= *Streamer
->getContext().getObjectFileInfo();
1899 StringMap
<KnownSectionsEntry
> KnownSections
= createKnownSectionsMap(MCOFI
);
1901 DebugRangeListsSectionWriter
*RangeListssWriter
= nullptr;
1902 if (CU
.getVersion() == 5) {
1903 assert(RangeListsWritersByCU
.count(DWOId
) != 0 &&
1904 "No RangeListsWriter for DWO ID.");
1905 RangeListssWriter
= RangeListsWritersByCU
[DWOId
].get();
1907 // Handling .debug_rnglists.dwo seperatly. The original .o/.dwo might not
1908 // have .debug_rnglists so won't be part of the loop below.
1909 if (!RangeListssWriter
->empty()) {
1910 std::unique_ptr
<DebugBufferVector
> OutputData
;
1911 if (std::optional
<StringRef
> OutData
= updateDebugData(
1912 (*DWOCU
)->getContext(), "debug_rnglists.dwo", "", KnownSections
,
1913 *Streamer
, *this, CUDWOEntry
, DWOId
, OutputData
,
1914 RangeListssWriter
, LocWriter
, OverridenSections
))
1915 Streamer
->emitBytes(*OutData
);
1919 for (const SectionRef
&Section
: File
->sections()) {
1920 std::unique_ptr
<DebugBufferVector
> OutputData
;
1921 StringRef SectionName
= getSectionName(Section
);
1922 if (SectionName
== "debug_rnglists.dwo")
1924 Expected
<StringRef
> ContentsExp
= Section
.getContents();
1925 assert(ContentsExp
&& "Invalid contents.");
1926 if (std::optional
<StringRef
> OutData
= updateDebugData(
1927 (*DWOCU
)->getContext(), SectionName
, *ContentsExp
, KnownSections
,
1928 *Streamer
, *this, CUDWOEntry
, DWOId
, OutputData
, RangeListssWriter
,
1929 LocWriter
, OverridenSections
))
1930 Streamer
->emitBytes(*OutData
);
1936 void DWARFRewriter::addGDBTypeUnitEntry(const GDBIndexTUEntry
&&Entry
) {
1937 std::lock_guard
<std::mutex
> Lock(DWARFRewriterMutex
);
1938 if (!BC
.getGdbIndexSection())
1940 GDBIndexTUEntryVector
.emplace_back(Entry
);
1943 void DWARFRewriter::updateGdbIndexSection(CUOffsetMap
&CUMap
, uint32_t NumCUs
) {
1944 if (!BC
.getGdbIndexSection())
1947 // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
1948 // for .gdb_index section format.
1950 StringRef GdbIndexContents
= BC
.getGdbIndexSection()->getContents();
1952 const char *Data
= GdbIndexContents
.data();
1954 // Parse the header.
1955 const uint32_t Version
= read32le(Data
);
1956 if (Version
!= 7 && Version
!= 8) {
1957 errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n";
1961 // Some .gdb_index generators use file offsets while others use section
1962 // offsets. Hence we can only rely on offsets relative to each other,
1963 // and ignore their absolute values.
1964 const uint32_t CUListOffset
= read32le(Data
+ 4);
1965 const uint32_t CUTypesOffset
= read32le(Data
+ 8);
1966 const uint32_t AddressTableOffset
= read32le(Data
+ 12);
1967 const uint32_t SymbolTableOffset
= read32le(Data
+ 16);
1968 const uint32_t ConstantPoolOffset
= read32le(Data
+ 20);
1971 // Map CUs offsets to indices and verify existing index table.
1972 std::map
<uint32_t, uint32_t> OffsetToIndexMap
;
1973 const uint32_t CUListSize
= CUTypesOffset
- CUListOffset
;
1974 const uint32_t TUListSize
= AddressTableOffset
- CUTypesOffset
;
1975 const unsigned NUmCUsEncoded
= CUListSize
/ 16;
1976 unsigned MaxDWARFVersion
= BC
.DwCtx
->getMaxVersion();
1977 unsigned NumDWARF5TUs
=
1978 getGDBIndexTUEntryVector().size() - BC
.DwCtx
->getNumTypeUnits();
1979 bool SkipTypeUnits
= false;
1980 // For DWARF5 Types are in .debug_info.
1981 // LLD doesn't generate Types CU List, and in CU list offset
1982 // only includes CUs.
1983 // GDB 11+ includes only CUs in CU list and generates Types
1985 // GDB 9 includes CUs and TUs in CU list and generates TYpes
1986 // list. The NumCUs is CUs + TUs, so need to modify the check.
1988 // GDB-11, DWARF5: TU units from dwo are not included.
1989 // GDB-11, DWARF4: TU units from dwo are included.
1990 if (MaxDWARFVersion
>= 5)
1991 SkipTypeUnits
= !TUListSize
? true
1992 : ((NUmCUsEncoded
+ NumDWARF5TUs
) ==
1993 BC
.DwCtx
->getNumCompileUnits());
1995 if (!((CUListSize
== NumCUs
* 16) ||
1996 (CUListSize
== (NumCUs
+ NumDWARF5TUs
) * 16))) {
1997 errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n";
2000 DenseSet
<uint64_t> OriginalOffsets
;
2001 for (unsigned Index
= 0, Units
= BC
.DwCtx
->getNumCompileUnits();
2002 Index
< Units
; ++Index
) {
2003 const DWARFUnit
*CU
= BC
.DwCtx
->getUnitAtIndex(Index
);
2004 if (SkipTypeUnits
&& CU
->isTypeUnit())
2006 const uint64_t Offset
= read64le(Data
);
2008 if (CU
->getOffset() != Offset
) {
2009 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n";
2013 OriginalOffsets
.insert(Offset
);
2014 OffsetToIndexMap
[Offset
] = Index
;
2017 // Ignore old address table.
2018 const uint32_t OldAddressTableSize
= SymbolTableOffset
- AddressTableOffset
;
2019 // Move Data to the beginning of symbol table.
2020 Data
+= SymbolTableOffset
- CUTypesOffset
;
2022 // Calculate the size of the new address table.
2023 uint32_t NewAddressTableSize
= 0;
2024 for (const auto &CURangesPair
: ARangesSectionWriter
->getCUAddressRanges()) {
2025 const SmallVector
<DebugAddressRange
, 2> &Ranges
= CURangesPair
.second
;
2026 NewAddressTableSize
+= Ranges
.size() * 20;
2029 // Difference between old and new table (and section) sizes.
2030 // Could be negative.
2031 int32_t Delta
= NewAddressTableSize
- OldAddressTableSize
;
2033 size_t NewGdbIndexSize
= GdbIndexContents
.size() + Delta
;
2035 // Free'd by ExecutableFileMemoryManager.
2036 auto *NewGdbIndexContents
= new uint8_t[NewGdbIndexSize
];
2037 uint8_t *Buffer
= NewGdbIndexContents
;
2039 write32le(Buffer
, Version
);
2040 write32le(Buffer
+ 4, CUListOffset
);
2041 write32le(Buffer
+ 8, CUTypesOffset
);
2042 write32le(Buffer
+ 12, AddressTableOffset
);
2043 write32le(Buffer
+ 16, SymbolTableOffset
+ Delta
);
2044 write32le(Buffer
+ 20, ConstantPoolOffset
+ Delta
);
2047 using MapEntry
= std::pair
<uint32_t, CUInfo
>;
2048 std::vector
<MapEntry
> CUVector(CUMap
.begin(), CUMap
.end());
2049 // Need to sort since we write out all of TUs in .debug_info before CUs.
2050 std::sort(CUVector
.begin(), CUVector
.end(),
2051 [](const MapEntry
&E1
, const MapEntry
&E2
) -> bool {
2052 return E1
.second
.Offset
< E2
.second
.Offset
;
2054 // Writing out CU List <Offset, Size>
2055 for (auto &CUInfo
: CUVector
) {
2056 // Skipping TU for DWARF5 when they are not included in CU list.
2057 if (!OriginalOffsets
.count(CUInfo
.first
))
2059 write64le(Buffer
, CUInfo
.second
.Offset
);
2060 // Length encoded in CU doesn't contain first 4 bytes that encode length.
2061 write64le(Buffer
+ 8, CUInfo
.second
.Length
+ 4);
2065 // Rewrite TU CU List, since abbrevs can be different.
2067 // 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature =
2068 // 0x418503b8111e9a7b Spec says " triplet, the first value is the CU offset,
2069 // the second value is the type offset in the CU, and the third value is the
2070 // type signature" Looking at what is being generated by gdb-add-index. The
2071 // first entry is TU offset, second entry is offset from it, and third entry
2072 // is the type signature.
2074 for (const GDBIndexTUEntry
&Entry
: getGDBIndexTUEntryVector()) {
2075 write64le(Buffer
, Entry
.UnitOffset
);
2076 write64le(Buffer
+ 8, Entry
.TypeDIERelativeOffset
);
2077 write64le(Buffer
+ 16, Entry
.TypeHash
);
2078 Buffer
+= sizeof(GDBIndexTUEntry
);
2081 // Generate new address table.
2082 for (const std::pair
<const uint64_t, DebugAddressRangesVector
> &CURangesPair
:
2083 ARangesSectionWriter
->getCUAddressRanges()) {
2084 const uint32_t CUIndex
= OffsetToIndexMap
[CURangesPair
.first
];
2085 const DebugAddressRangesVector
&Ranges
= CURangesPair
.second
;
2086 for (const DebugAddressRange
&Range
: Ranges
) {
2087 write64le(Buffer
, Range
.LowPC
);
2088 write64le(Buffer
+ 8, Range
.HighPC
);
2089 write32le(Buffer
+ 16, CUIndex
);
2094 const size_t TrailingSize
=
2095 GdbIndexContents
.data() + GdbIndexContents
.size() - Data
;
2096 assert(Buffer
+ TrailingSize
== NewGdbIndexContents
+ NewGdbIndexSize
&&
2097 "size calculation error");
2099 // Copy over the rest of the original data.
2100 memcpy(Buffer
, Data
, TrailingSize
);
2102 // Register the new section.
2103 BC
.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents
,
2107 std::unique_ptr
<DebugBufferVector
>
2108 DWARFRewriter::makeFinalLocListsSection(DWARFVersion Version
) {
2109 auto LocBuffer
= std::make_unique
<DebugBufferVector
>();
2110 auto LocStream
= std::make_unique
<raw_svector_ostream
>(*LocBuffer
);
2112 std::unique_ptr
<MCObjectWriter
>(BC
.createObjectWriter(*LocStream
));
2114 for (std::pair
<const uint64_t, std::unique_ptr
<DebugLocWriter
>> &Loc
:
2115 LocListWritersByCU
) {
2116 DebugLocWriter
*LocWriter
= Loc
.second
.get();
2117 auto *LocListWriter
= llvm::dyn_cast
<DebugLoclistWriter
>(LocWriter
);
2119 // Filter out DWARF4, writing out DWARF5
2120 if (Version
== DWARFVersion::DWARF5
&&
2121 (!LocListWriter
|| LocListWriter
->getDwarfVersion() <= 4))
2124 // Filter out DWARF5, writing out DWARF4
2125 if (Version
== DWARFVersion::DWARFLegacy
&&
2126 (LocListWriter
&& LocListWriter
->getDwarfVersion() >= 5))
2129 // Skipping DWARF4/5 split dwarf.
2130 if (LocListWriter
&& LocListWriter
->getDwarfVersion() <= 4)
2132 std::unique_ptr
<DebugBufferVector
> CurrCULocationLists
=
2133 LocWriter
->getBuffer();
2134 *LocStream
<< *CurrCULocationLists
;
2140 void DWARFRewriter::convertToRangesPatchDebugInfo(
2141 DWARFUnit
&Unit
, DIEBuilder
&DIEBldr
, DIE
&Die
,
2142 uint64_t RangesSectionOffset
, DIEValue
&LowPCAttrInfo
,
2143 DIEValue
&HighPCAttrInfo
, std::optional
<uint64_t> RangesBase
) {
2144 uint32_t BaseOffset
= 0;
2145 dwarf::Form LowForm
= LowPCAttrInfo
.getForm();
2146 dwarf::Attribute RangeBaseAttribute
= dwarf::DW_AT_GNU_ranges_base
;
2147 dwarf::Form RangesForm
= dwarf::DW_FORM_sec_offset
;
2149 if (Unit
.getVersion() >= 5) {
2150 RangeBaseAttribute
= dwarf::DW_AT_rnglists_base
;
2151 RangesForm
= dwarf::DW_FORM_rnglistx
;
2152 } else if (Unit
.getVersion() < 4) {
2153 RangesForm
= dwarf::DW_FORM_data4
;
2155 bool IsUnitDie
= Die
.getTag() == dwarf::DW_TAG_compile_unit
||
2156 Die
.getTag() == dwarf::DW_TAG_skeleton_unit
;
2158 DIEBldr
.deleteValue(&Die
, LowPCAttrInfo
.getAttribute());
2159 // In DWARF4 for DW_AT_low_pc in binary DW_FORM_addr is used. In the DWO
2160 // section DW_FORM_GNU_addr_index is used. So for if we are converting
2161 // DW_AT_low_pc/DW_AT_high_pc and see DW_FORM_GNU_addr_index. We are
2162 // converting in DWO section, and DW_AT_ranges [DW_FORM_sec_offset] is
2163 // relative to DW_AT_GNU_ranges_base.
2164 if (LowForm
== dwarf::DW_FORM_GNU_addr_index
) {
2165 // Ranges are relative to DW_AT_GNU_ranges_base.
2166 uint64_t CurRangeBase
= 0;
2167 if (std::optional
<uint64_t> DWOId
= Unit
.getDWOId()) {
2168 CurRangeBase
= getDwoRangesBase(*DWOId
);
2170 BaseOffset
= CurRangeBase
;
2172 // In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or
2173 // DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is
2174 // when it's absent.
2176 if (LowForm
== dwarf::DW_FORM_addrx
) {
2177 const uint32_t Index
= AddrWriter
->getIndexFromAddress(0, Unit
);
2178 DIEBldr
.replaceValue(&Die
, LowPCAttrInfo
.getAttribute(),
2179 LowPCAttrInfo
.getForm(), DIEInteger(Index
));
2181 DIEBldr
.replaceValue(&Die
, LowPCAttrInfo
.getAttribute(),
2182 LowPCAttrInfo
.getForm(), DIEInteger(0));
2185 // Original CU didn't have DW_AT_*_base. We converted it's children (or
2186 // dwo), so need to insert it into CU.
2188 DIEBldr
.addValue(&Die
, RangeBaseAttribute
, dwarf::DW_FORM_sec_offset
,
2189 DIEInteger(*RangesBase
));
2192 uint64_t RangeAttrVal
= RangesSectionOffset
- BaseOffset
;
2193 if (Unit
.getVersion() >= 5)
2194 RangeAttrVal
= RangesSectionOffset
;
2195 // HighPC was conveted into DW_AT_ranges.
2196 // For DWARF5 we only access ranges through index.
2198 DIEBldr
.replaceValue(&Die
, HighPCAttrInfo
.getAttribute(), dwarf::DW_AT_ranges
,
2199 RangesForm
, DIEInteger(RangeAttrVal
));