[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / bolt / lib / Rewrite / DWARFRewriter.cpp
blob8e20306925feac3e2b49ce4061a9886968b0d6c3
1 //===- bolt/Rewrite/DWARFRewriter.cpp -------------------------------------===//
2 //
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
6 //
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"
46 #include <algorithm>
47 #include <cstdint>
48 #include <functional>
49 #include <iterator>
50 #include <memory>
51 #include <optional>
52 #include <string>
53 #include <unordered_map>
54 #include <utility>
55 #include <vector>
57 #undef DEBUG_TYPE
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.
70 LLVM_ATTRIBUTE_UNUSED
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);
80 printDie(DDie);
81 } else {
82 dbgs() << "Failed to extract abbreviation for"
83 << Twine::utohexstr(OriginalOffsets) << "\n";
85 } else {
86 dbgs() << "Failed to extract DIE for " << Twine::utohexstr(OriginalOffsets)
87 << " \n";
91 using namespace bolt;
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);
107 return OutputRanges;
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);
122 } else {
123 MergedRanges.emplace_back(Range.LowPC, Range.HighPC);
125 PrevHighPC = MergedRanges.back().HighPC;
128 return MergedRanges;
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.
138 if (!BF.isEmitted())
139 return InputLL;
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.
159 llvm::stable_sort(
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);
169 } else {
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;
178 return MergedLL;
181 using namespace dwarf_linker;
182 using namespace dwarf_linker::classic;
184 namespace llvm {
185 namespace bolt {
186 /// Emits debug information into .debug_info or .debug_types section.
187 class DIEStreamer : public DwarfStreamer {
188 DIEBuilder *DIEBldr;
189 DWARFRewriter &Rewriter;
191 private:
192 /// Emit the compilation unit header for \p Unit in the debug_info
193 /// section.
195 /// A Dwarf 4 section header is encoded as:
196 /// uint32_t Unit length (omitting this field)
197 /// uint16_t Version
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)
204 /// uint16_t Version
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();
220 assert(DWOId &&
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.
235 if (Version >= 5) {
236 Asm.emitInt8(UT);
237 Asm.emitInt8(Asm.MAI->getCodePointerSize());
240 Asm.emitInt32(0);
241 if (Version <= 4) {
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);
262 } else
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());
273 else
274 emitCompileUnitHeader(Unit, UnitDIE, Unit.getVersion());
277 void emitDIE(DIE &Die) override {
278 AsmPrinter &Asm = getAsmPrinter();
279 Asm.emitDwarfDIE(Die);
282 public:
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);
295 emitDIE(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))
308 return Info;
309 return std::nullopt;
312 } // namespace bolt
313 } // namespace llvm
315 using namespace llvm;
316 using namespace llvm::support::endian;
317 using namespace object;
318 using namespace bolt;
320 namespace opts {
322 extern cl::OptionCategory BoltCategory;
323 extern cl::opt<unsigned> Verbosity;
324 extern cl::opt<std::string> OutputFilename;
326 static cl::opt<bool> KeepARanges(
327 "keep-aranges",
328 cl::desc(
329 "keep or generate .debug_aranges section if .gdb_index is written"),
330 cl::Hidden, cl::cat(BoltCategory));
332 static cl::opt<bool>
333 DeterministicDebugInfo("deterministic-debuginfo",
334 cl::desc("disables parallel execution of tasks that may produce "
335 "nondeterministic debug info"),
336 cl::init(true),
337 cl::cat(BoltCategory));
339 static cl::opt<std::string> DwarfOutputPath(
340 "dwarf-output-path",
341 cl::desc("Path to where .dwo files or dwp file will be written out to."),
342 cl::init(""), cl::cat(BoltCategory));
344 static cl::opt<bool>
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));
350 static cl::opt<bool>
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",
359 cl::desc(
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));
369 } // namespace opts
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)
377 return false;
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 ||
383 AddrOffset) {
385 uint32_t Index = AddrOffset ? (LowPcValue >> 32) : LowPcValue;
386 std::optional<object::SectionedAddress> SA =
387 DU.getAddrOffsetSectionItem(Index);
388 if (!SA)
389 return false;
390 if (AddrOffset)
391 SA->Address += (LowPcValue & 0xffffffff);
393 LowPC = SA->Address;
394 SectionIndex = SA->SectionIndex;
395 } else {
396 LowPC = LowPcValue;
397 SectionIndex = 0;
399 if (DvalHighPc.getForm() == dwarf::DW_FORM_addr)
400 HighPC = DvalHighPc.getDIEInteger().getValue();
401 else
402 HighPC = LowPC + DvalHighPc.getDIEInteger().getValue();
404 return true;
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))
427 return SA->Address;
428 return std::nullopt;
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.
433 static std::string
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.");
438 (void)DWOId;
440 std::string DWOName = dwarf::toString(
441 CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
442 "");
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));
451 ++Iter->second;
453 DWOName.append(".dwo");
454 return DWOName;
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);
467 if (Err)
468 errs()
469 << "BOLT-WARNING: [internal-dwarf-error]: Could not init DIEStreamer!"
470 << toString(std::move(Err)) << "\n";
471 return Streamer;
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())
507 continue;
508 DWARFRewriter::UnitMeta MI =
509 emitUnit(DWODIEBuilder, *Streamer, *CU.get());
510 TUMetaVector.emplace_back(MI);
512 CUMI = emitUnit(DWODIEBuilder, *Streamer, SplitCU);
513 } else {
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());
527 Streamer->finish();
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)
546 continue;
547 OverriddenSections[Kind] = Contents;
549 if (opts::WriteDWP)
550 Rewriter.updateDWP(CU, OverriddenSections, CUMI, TUMetaVector, State,
551 LocWriter);
552 else
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(),
562 NewOffset);
563 return;
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());
581 if (!AbbrDeclSet) {
582 consumeError(AbbrDeclSet.takeError());
583 return Vec;
585 bool CrossCURefFound = false;
586 for (const DWARFAbbreviationDeclaration &Decl : *AbbrDeclSet.get()) {
587 for (const DWARFAbbreviationDeclaration::AttributeSpec &Attr :
588 Decl.attributes()) {
589 if (Attr.Form == dwarf::DW_FORM_ref_addr) {
590 CrossCURefFound = true;
591 break;
594 if (CrossCURefFound)
595 break;
597 if (CrossCURefFound) {
598 Vec[0].push_back(CU.get());
599 } else {
600 ++Counter;
601 Vec.back().push_back(CU.get());
603 if (Counter % opts::BatchSize == 0 && !Vec.back().empty())
604 Vec.push_back({});
606 return Vec;
609 void DWARFRewriter::updateDebugInfo() {
610 ErrorOr<BinarySection &> DebugInfo = BC.getUniqueSectionByName(".debug_info");
611 if (!DebugInfo)
612 return;
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());
628 } else {
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);
656 } else {
657 LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
659 return LocListWritersByCU[CUIndex++].get();
662 // Unordered maps to handle name collision if output DWO directory is
663 // specified.
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,
679 ObjectName.c_str());
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());
690 return ObjectName;
693 DWPState State;
694 if (opts::WriteDWP)
695 initDWPState(State);
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();
702 if (DWOId)
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.
709 if (SplitCU) {
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();
719 } else {
720 RangesBase = RangesSectionWriter->getSectionOffset();
721 // For DWARF5 there is now .debug_rnglists.dwo, so don't need to
722 // update rnglists base.
723 if (RangesBase) {
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,
737 DebugLocDWoWriter);
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,
748 RangesBase);
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());
779 } else {
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);
784 ThreadPool.wait();
787 if (opts::WriteDWP)
788 finalizeDWP(State);
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;
822 } else {
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);
833 if (LowPCVal)
834 DIEBldr.replaceValue(Die, AttrLowPC, FormLowPC, DIEInteger(LowPC));
835 else
836 DIEBldr.addValue(Die, AttrLowPC, FormLowPC, DIEInteger(LowPC));
837 if (HighPCVal) {
838 DIEBldr.replaceValue(Die, AttrHighPC, FormHighPC, DIEInteger(Size));
839 } else {
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) {
846 DIE *Die = DI->Die;
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())
857 continue;
858 auto ModuleRangesOrError = getDIEAddressRanges(*Die, Unit);
859 if (!ModuleRangesOrError) {
860 consumeError(ModuleRangesOrError.takeError());
861 break;
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,
878 RangesBase);
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]));
884 break;
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());
897 break;
899 DWARFAddressRangesVector Ranges = *RangesOrError;
900 // Not a function definition.
901 if (Ranges.empty())
902 break;
904 for (const DWARFAddressRange &Range : Ranges) {
905 if (const BinaryFunction *Function =
906 BC.getBinaryFunctionAtAddress(Range.LowPC))
907 FunctionRanges.append(Function->getOutputAddressRanges());
909 } else {
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()});
922 } else {
923 // I haven't seen this case, but who knows what other compilers
924 // generate.
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);
934 break;
937 updateDWARFObjectAddressRanges(
938 Unit, DIEBldr, *Die, RangesSectionWriter.addRanges(FunctionRanges));
940 break;
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)
953 : nullptr;
954 DebugAddressRangesVector OutputRanges;
955 if (Function) {
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());
971 } else {
972 OutputRanges.push_back({0, !RangesOrError->empty()
973 ? RangesOrError.get().front().HighPC
974 : 0});
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);
981 break;
983 updateDWARFObjectAddressRanges(Unit, DIEBldr, *Die, RangesSectionOffset);
984 break;
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;
992 if (Function)
993 UpdatedAddress =
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(),
1000 DIEInteger(Index));
1001 } else if (AttrVal.getForm() == dwarf::DW_FORM_addr) {
1002 DIEBldr.replaceValue(Die, AttrVal.getAttribute(), AttrVal.getForm(),
1003 DIEInteger(UpdatedAddress));
1004 } else {
1005 errs() << "BOLT-ERROR: unsupported form for " << Entry << "\n";
1008 DIEValue CallPcAttrVal = Die->findAttribute(dwarf::DW_AT_call_pc);
1009 if (CallPcAttrVal)
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");
1017 break;
1019 default: {
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);
1023 if (LocAttrInfo) {
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;
1038 if (SectionAddress)
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) {
1051 default:
1052 llvm_unreachable("Unsupported DWARFLocationEntry Kind.");
1053 case dwarf::DW_LLE_end_of_list:
1054 return false;
1055 case dwarf::DW_LLE_base_address: {
1056 assert(Entry.SectionIndex == SectionedAddress::UndefSection &&
1057 "absolute address expected");
1058 BaseAddress = Entry.Value0;
1059 break;
1061 case dwarf::DW_LLE_offset_pair:
1062 assert(
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,
1068 Entry.Loc});
1069 break;
1070 case dwarf::DW_LLE_start_length:
1071 InputLL.emplace_back(DebugLocationEntry{
1072 Entry.Value0, Entry.Value0 + Entry.Value1, Entry.Loc});
1073 break;
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;
1079 break;
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});
1088 break;
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});
1099 break;
1102 return true;
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())
1110 << '\n';
1111 } else {
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 "
1119 "one at 0x"
1120 << Die << " in CU at 0x"
1121 << Twine::utohexstr(Unit.getOffset()) << '\n';
1123 } else {
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
1126 // information.
1127 OutputLL = InputLL;
1129 DebugLocWriter.addList(DIEBldr, *Die, LocAttrInfo, OutputLL);
1131 } else {
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);
1150 } else {
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);
1159 DataExtractor Data(
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;
1166 DIEValue Value;
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>();
1172 NewAttr = Loc;
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>();
1179 NewAttr = Block;
1180 Value = DIEValue(LocAttrInfo.getAttribute(),
1181 LocAttrInfo.getForm(), Block);
1182 } else {
1183 errs() << "BOLT-WARNING: Unexpected Form value in Updating "
1184 "DW_AT_Location\n";
1185 continue;
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;
1204 while (CopyNum--) {
1205 DIEBldr.addValue(NewAttr, *Itr);
1206 std::advance(Itr, 1);
1208 } else {
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.
1220 SmallString<8> Tmp;
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()));
1227 NewExprSize += 1;
1228 for (uint8_t Byte : Tmp) {
1229 DIEBldr.addValue(NewAttr, static_cast<dwarf::Attribute>(0),
1230 dwarf::DW_FORM_data1, DIEInteger(Byte));
1231 NewExprSize += 1;
1234 PrevOffset = CurEndOffset;
1237 // update the size since the index might be changed
1238 if (Loc)
1239 Loc->setSize(NewExprSize);
1240 else
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);
1255 LLVM_DEBUG(dbgs()
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));
1272 } else {
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 "
1279 "LowPCAttrInfo\n";
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) {
1294 if (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);
1328 else
1329 errs() << "BOLT-WARNING: [internal-dwarf-error]: DWOId is not found "
1330 "for DWO Unit.";
1332 if (NeedConverted || RangesAttrInfo.getForm() == dwarf::DW_FORM_rnglistx)
1333 DIEBldr.replaceValue(&Die, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx,
1334 DIEInteger(DebugRangesOffset));
1335 else
1336 DIEBldr.replaceValue(&Die, dwarf::DW_AT_ranges, RangesAttrInfo.getForm(),
1337 DIEInteger(DebugRangesOffset - CurRangeBase));
1339 if (!RangesBase) {
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(),
1344 DIEInteger(0));
1345 return;
1348 if (!(Die.getTag() == dwarf::DW_TAG_compile_unit ||
1349 Die.getTag() == dwarf::DW_TAG_skeleton_unit))
1350 return;
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));
1360 else
1361 DIEBldr.addValue(&Die, dwarf::DW_AT_rnglists_base,
1362 dwarf::DW_FORM_sec_offset, DIEInteger(*RangesBase));
1363 return;
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
1393 // ones.
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.");
1401 return *Offset;
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();
1407 if (!Label)
1408 continue;
1410 std::optional<AttrInfo> AttrVal =
1411 findAttributeInfo(CU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list);
1412 if (!AttrVal)
1413 continue;
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);
1425 if (!AttrVal)
1426 continue;
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.
1436 if (DbgInfoSection)
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()))
1450 continue;
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();
1458 DIEBlder.finish();
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
1468 CUOffsetMap CUMap;
1469 for (std::unique_ptr<llvm::DWARFUnit> &CU : BC.DwCtx->info_section_units()) {
1470 if (!CU->isTypeUnit())
1471 continue;
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),
1497 Contents.size());
1499 return CUMap;
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
1559 // added there.
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());
1568 Streamer.finish();
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),
1581 Contents.size());
1582 } else if (Name.equals(".debug_info")) {
1583 BC.registerOrUpdateNoteSection(".debug_info", copyByteArray(Contents),
1584 Contents.size());
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,
1607 CUOffsetMap &CUMap,
1608 const std::list<DWARFUnit *> &CUs) {
1609 DIEBlder.generateAbbrevs();
1610 DIEBlder.finish();
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.
1626 namespace {
1628 std::unique_ptr<BinaryContext>
1629 createDwarfOnlyBC(const object::ObjectFile &File) {
1630 return cantFail(BinaryContext::createBinaryContext(
1631 &File, false,
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("._"));
1660 return Name;
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 {
1679 if (DWOEntry) {
1680 DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec);
1681 DWPOffset = DWOContrubution->getOffset();
1682 OutData = OutData.substr(DWPOffset, DWOContrubution->getLength());
1684 return OutData;
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()) {
1697 errs()
1698 << "BOLT-WARNING: [internal-dwarf-error]: Could not find overriden "
1699 "section for: "
1700 << Twine::utohexstr(DWOId) << ".\n";
1701 return std::nullopt;
1703 return Iter->second;
1705 switch (SectionIter->second.second) {
1706 default: {
1707 if (!SectionName.equals("debug_str.dwo"))
1708 errs() << "BOLT-WARNING: unsupported debug section: " << SectionName
1709 << "\n";
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
1730 // string.
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());
1747 } // namespace
1749 void DWARFRewriter::initDWPState(DWPState &State) {
1750 SmallString<0> OutputNameStr;
1751 StringRef OutputName;
1752 if (opts::DwarfOutputPath.empty()) {
1753 OutputName =
1754 Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr);
1755 } else {
1756 StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename);
1757 OutputName = Twine(opts::DwarfOutputPath)
1758 .concat("/")
1759 .concat(ExeFileName)
1760 .concat(".dwp")
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 "
1764 "the executable\n";
1766 std::error_code EC;
1767 State.Out =
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
1778 // in DWARF4/5.
1780 State.Strings = std::make_unique<DWPStringPool>(*State.Streamer, StrSection);
1782 // Setup DWP code once.
1783 DWARFContext *DWOCtx = BC.getDWOContext();
1785 if (DWOCtx) {
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();
1813 State.Out->keep();
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);
1826 if (!DWOCU)
1827 return;
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";
1834 exit(1);
1837 UnitIndexEntry CurEntry = {};
1838 CurEntry.DWOName = dwarf::toString(
1839 CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
1840 "");
1841 const char *Name = CU.getUnitDIE().getShortName();
1842 if (Name)
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;
1853 if (State.IsDWP)
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);
1886 if (!TOutData)
1887 continue;
1889 StringRef OutData = *TOutData;
1890 if (SectionName == "debug_types.dwo") {
1891 State.Streamer->emitBytes(OutData);
1892 continue;
1895 if (SectionName.equals("debug_str.dwo")) {
1896 CurStrSection = OutData;
1897 } else {
1898 // Since handleDebugDataPatching returned true, we already know this is
1899 // a known section.
1900 auto SectionIter = State.KnownSections.find(SectionName);
1901 if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS)
1902 CurStrOffsetSection = OutData;
1903 else
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
1925 // based on hash.
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));
1937 if (!P.second) {
1938 Error Err = buildDuplicateError(*P.first, CUI, "");
1939 errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n";
1940 return;
1943 // Handling TU
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;
1958 bool IsDWP = false;
1959 if (DWOCtx) {
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);
1966 if (!DWOCU) {
1967 errs() << "BOLT-WARNING: [internal-dwarf-error]: CU for DWO_ID "
1968 << Twine::utohexstr(DWOId) << " is not found.\n";
1969 return;
1972 std::string CompDir = opts::DwarfOutputPath.empty()
1973 ? CU.getCompilationDir()
1974 : opts::DwarfOutputPath.c_str();
1975 auto FullPath = CompDir.append("/").append(DWOName);
1977 std::error_code EC;
1978 std::unique_ptr<ToolOutputFile> TempOut =
1979 std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None);
1981 const DWARFUnitIndex::Entry *CUDWOEntry = nullptr;
1982 if (IsDWP)
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")
2014 continue;
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);
2023 Streamer->finish();
2024 TempOut->keep();
2027 void DWARFRewriter::addGDBTypeUnitEntry(const GDBIndexTUEntry &&Entry) {
2028 std::lock_guard<std::mutex> Lock(DWARFRewriterMutex);
2029 if (!BC.getGdbIndexSection())
2030 return;
2031 GDBIndexTUEntryVector.emplace_back(Entry);
2034 void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap, uint32_t NumCUs) {
2035 if (!BC.getGdbIndexSection())
2036 return;
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";
2049 exit(1);
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);
2060 Data += 24;
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
2075 // list.
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.
2078 // For split-dwarf
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";
2089 exit(1);
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())
2096 continue;
2097 const uint64_t Offset = read64le(Data);
2098 Data += 16;
2099 if (CU->getOffset() != Offset) {
2100 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n";
2101 exit(1);
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);
2136 Buffer += 24;
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))
2149 continue;
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);
2153 Buffer += 16;
2156 // Rewrite TU CU List, since abbrevs can be different.
2157 // Entry example:
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.
2164 if (TUListSize)
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);
2181 Buffer += 20;
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,
2195 NewGdbIndexSize);
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);
2202 auto Writer =
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))
2213 continue;
2215 // Filter out DWARF5, writing out DWARF4
2216 if (Version == DWARFVersion::DWARFLegacy &&
2217 (LocListWriter && LocListWriter->getDwarfVersion() >= 5))
2218 continue;
2220 // Skipping DWARF4/5 split dwarf.
2221 if (LocListWriter && LocListWriter->getDwarfVersion() <= 4)
2222 continue;
2223 std::unique_ptr<DebugBufferVector> CurrCULocationLists =
2224 LocWriter->getBuffer();
2225 *LocStream << *CurrCULocationLists;
2228 return LocBuffer;
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;
2248 if (!IsUnitDie)
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;
2262 } else {
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.
2266 if (IsUnitDie) {
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));
2271 } else {
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.
2278 if (RangesBase)
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));