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 //===----------------------------------------------------------------------===//
8 
9 #include "bolt/Rewrite/DWARFRewriter.h"
10 #include "bolt/Core/BinaryContext.h"
11 #include "bolt/Core/BinaryFunction.h"
12 #include "bolt/Core/DebugData.h"
13 #include "bolt/Core/ParallelUtilities.h"
14 #include "bolt/Rewrite/RewriteInstance.h"
15 #include "bolt/Utils/Utils.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/BinaryFormat/Dwarf.h"
18 #include "llvm/DWP/DWP.h"
19 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
20 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
21 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
22 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
23 #include "llvm/MC/MCAsmBackend.h"
24 #include "llvm/MC/MCAsmLayout.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCObjectWriter.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/Object/ObjectFile.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/Endian.h"
33 #include "llvm/Support/Error.h"
34 #include "llvm/Support/FileSystem.h"
35 #include "llvm/Support/LEB128.h"
36 #include "llvm/Support/ThreadPool.h"
37 #include "llvm/Support/ToolOutputFile.h"
38 #include <algorithm>
39 #include <cstdint>
40 #include <string>
41 #include <unordered_map>
42 #include <utility>
43 #include <vector>
44 
45 #undef  DEBUG_TYPE
46 #define DEBUG_TYPE "bolt"
47 
48 LLVM_ATTRIBUTE_UNUSED
49 static void printDie(const DWARFDie &DIE) {
50   DIDumpOptions DumpOpts;
51   DumpOpts.ShowForm = true;
52   DumpOpts.Verbose = true;
53   DumpOpts.ChildRecurseDepth = 0;
54   DumpOpts.ShowChildren = 0;
55   DIE.dump(dbgs(), 0, DumpOpts);
56 }
57 
58 namespace llvm {
59 namespace bolt {
60 /// Finds attributes FormValue and Offset.
61 ///
62 /// \param DIE die to look up in.
63 /// \param Attr the attribute to extract.
64 /// \return an optional AttrInfo with DWARFFormValue and Offset.
65 static Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
66                                             dwarf::Attribute Attr) {
67   if (!DIE.isValid())
68     return None;
69   const DWARFAbbreviationDeclaration *AbbrevDecl =
70       DIE.getAbbreviationDeclarationPtr();
71   if (!AbbrevDecl)
72     return None;
73   Optional<uint32_t> Index = AbbrevDecl->findAttributeIndex(Attr);
74   if (!Index)
75     return None;
76   return findAttributeInfo(DIE, AbbrevDecl, *Index);
77 }
78 
79 /// Finds attributes FormValue and Offset.
80 ///
81 /// \param DIE die to look up in.
82 /// \param Attrs finds the first attribute that matches and extracts it.
83 /// \return an optional AttrInfo with DWARFFormValue and Offset.
84 Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
85                                      std::vector<dwarf::Attribute> Attrs) {
86   for (dwarf::Attribute &Attr : Attrs)
87     if (Optional<AttrInfo> Info = findAttributeInfo(DIE, Attr))
88       return Info;
89   return None;
90 }
91 } // namespace bolt
92 } // namespace llvm
93 
94 using namespace llvm;
95 using namespace llvm::support::endian;
96 using namespace object;
97 using namespace bolt;
98 
99 namespace opts {
100 
101 extern cl::OptionCategory BoltCategory;
102 extern cl::opt<unsigned> Verbosity;
103 extern cl::opt<std::string> OutputFilename;
104 
105 static cl::opt<bool> KeepARanges(
106     "keep-aranges",
107     cl::desc(
108         "keep or generate .debug_aranges section if .gdb_index is written"),
109     cl::Hidden, cl::cat(BoltCategory));
110 
111 static cl::opt<bool>
112 DeterministicDebugInfo("deterministic-debuginfo",
113   cl::desc("disables parallel execution of tasks that may produce"
114            "nondeterministic debug info"),
115   cl::init(true),
116   cl::cat(BoltCategory));
117 
118 static cl::opt<std::string> DwarfOutputPath(
119     "dwarf-output-path",
120     cl::desc("Path to where .dwo files or dwp file will be written out to."),
121     cl::init(""), cl::cat(BoltCategory));
122 
123 static cl::opt<bool>
124     WriteDWP("write-dwp",
125              cl::desc("output a single dwarf package file (dwp) instead of "
126                       "multiple non-relocatable dwarf object files (dwo)."),
127              cl::init(false), cl::cat(BoltCategory));
128 
129 static cl::opt<bool>
130     DebugSkeletonCu("debug-skeleton-cu",
131                     cl::desc("prints out offsetrs for abbrev and debu_info of "
132                              "Skeleton CUs that get patched."),
133                     cl::ZeroOrMore, cl::Hidden, cl::init(false),
134                     cl::cat(BoltCategory));
135 } // namespace opts
136 
137 /// Returns DWO Name to be used. Handles case where user specifies output DWO
138 /// directory, and there are duplicate names. Assumes DWO ID is unique.
139 static std::string
140 getDWOName(llvm::DWARFUnit &CU,
141            std::unordered_map<std::string, uint32_t> *NameToIndexMap,
142            std::unordered_map<uint64_t, std::string> &DWOIdToName) {
143   llvm::Optional<uint64_t> DWOId = CU.getDWOId();
144   assert(DWOId && "DWO ID not found.");
145   (void)DWOId;
146   auto NameIter = DWOIdToName.find(*DWOId);
147   if (NameIter != DWOIdToName.end())
148     return NameIter->second;
149 
150   std::string DWOName = dwarf::toString(
151       CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
152       "");
153   assert(!DWOName.empty() &&
154          "DW_AT_dwo_name/DW_AT_GNU_dwo_name does not exists.");
155   if (NameToIndexMap && !opts::DwarfOutputPath.empty()) {
156     auto Iter = NameToIndexMap->find(DWOName);
157     if (Iter == NameToIndexMap->end())
158       Iter = NameToIndexMap->insert({DWOName, 0}).first;
159     DWOName.append(std::to_string(Iter->second));
160     ++Iter->second;
161   }
162   DWOName.append(".dwo");
163   DWOIdToName[*DWOId] = DWOName;
164   return DWOName;
165 }
166 
167 void DWARFRewriter::addStringHelper(DebugInfoBinaryPatcher &DebugInfoPatcher,
168                                     const DWARFUnit &Unit,
169                                     const AttrInfo &AttrInfoVal,
170                                     StringRef Str) {
171   uint32_t NewOffset = StrWriter->addString(Str);
172   if (Unit.getVersion() == 5) {
173     StrOffstsWriter->updateAddressMap(AttrInfoVal.V.getRawUValue(), NewOffset);
174     return;
175   }
176   DebugInfoPatcher.addLE32Patch(AttrInfoVal.Offset, NewOffset,
177                                 AttrInfoVal.Size);
178 }
179 
180 void DWARFRewriter::updateDebugInfo() {
181   ErrorOr<BinarySection &> DebugInfo = BC.getUniqueSectionByName(".debug_info");
182   if (!DebugInfo)
183     return;
184 
185   auto *DebugInfoPatcher =
186       static_cast<DebugInfoBinaryPatcher *>(DebugInfo->getPatcher());
187 
188   ARangesSectionWriter = std::make_unique<DebugARangesSectionWriter>();
189   StrWriter = std::make_unique<DebugStrWriter>(BC);
190 
191   StrOffstsWriter = std::make_unique<DebugStrOffsetsWriter>();
192 
193   AbbrevWriter = std::make_unique<DebugAbbrevWriter>(*BC.DwCtx);
194 
195   if (BC.isDWARF5Used()) {
196     // Disabling none deterministic mode for dwarf5, to keep implementation
197     // simpler.
198     opts::DeterministicDebugInfo = true;
199     AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
200     RangesSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
201     DebugRangeListsSectionWriter::setAddressWriter(AddrWriter.get());
202   } else {
203     AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
204     RangesSectionWriter = std::make_unique<DebugRangesSectionWriter>();
205   }
206 
207   DebugLoclistWriter::setAddressWriter(AddrWriter.get());
208 
209   size_t CUIndex = 0;
210   for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
211     const uint16_t DwarfVersion = CU->getVersion();
212     if (DwarfVersion >= 5) {
213       uint32_t AttrInfoOffset =
214           DebugLoclistWriter::InvalidLocListsBaseAttrOffset;
215       if (Optional<AttrInfo> AttrInfoVal =
216               findAttributeInfo(CU->getUnitDIE(), dwarf::DW_AT_loclists_base)) {
217         AttrInfoOffset = AttrInfoVal->Offset;
218         LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
219             &BC, *CU.get(), AttrInfoOffset, DwarfVersion, false);
220       }
221       if (Optional<uint64_t> DWOId = CU->getDWOId()) {
222         assert(LocListWritersByCU.count(*DWOId) == 0 &&
223                "RangeLists writer for DWO unit already exists.");
224         auto RangeListsSectionWriter =
225             std::make_unique<DebugRangeListsSectionWriter>();
226         RangeListsSectionWriter->initSection(*CU.get());
227         RangeListsWritersByCU[*DWOId] = std::move(RangeListsSectionWriter);
228       }
229 
230     } else {
231       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>(&BC);
232     }
233 
234     if (Optional<uint64_t> DWOId = CU->getDWOId()) {
235       assert(LocListWritersByCU.count(*DWOId) == 0 &&
236              "LocList writer for DWO unit already exists.");
237       // Work around some bug in llvm-15. If I pass in directly lld reports
238       // undefined symbol.
239       auto constexpr WorkAround =
240           DebugLoclistWriter::InvalidLocListsBaseAttrOffset;
241       LocListWritersByCU[*DWOId] = std::make_unique<DebugLoclistWriter>(
242           &BC, *CU.get(), WorkAround, DwarfVersion, true);
243     }
244     ++CUIndex;
245   }
246 
247   // Unordered maps to handle name collision if output DWO directory is
248   // specified.
249   std::unordered_map<std::string, uint32_t> NameToIndexMap;
250   std::unordered_map<uint64_t, std::string> DWOIdToName;
251   std::mutex AccessMutex;
252 
253   auto updateDWONameCompDir = [&](DWARFUnit &Unit) -> void {
254     const DWARFDie &DIE = Unit.getUnitDIE();
255     Optional<AttrInfo> AttrInfoVal = findAttributeInfo(
256         DIE, {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name});
257     (void)AttrInfoVal;
258     assert(AttrInfoVal && "Skeleton CU doesn't have dwo_name.");
259 
260     std::string ObjectName = "";
261 
262     {
263       std::lock_guard<std::mutex> Lock(AccessMutex);
264       ObjectName = getDWOName(Unit, &NameToIndexMap, DWOIdToName);
265     }
266     addStringHelper(*DebugInfoPatcher, Unit, *AttrInfoVal, ObjectName.c_str());
267 
268     AttrInfoVal = findAttributeInfo(DIE, dwarf::DW_AT_comp_dir);
269     (void)AttrInfoVal;
270     assert(AttrInfoVal && "DW_AT_comp_dir is not in Skeleton CU.");
271 
272     if (!opts::DwarfOutputPath.empty()) {
273       addStringHelper(*DebugInfoPatcher, Unit, *AttrInfoVal,
274                       opts::DwarfOutputPath.c_str());
275     }
276   };
277 
278   auto processUnitDIE = [&](size_t CUIndex, DWARFUnit *Unit) {
279     // Check if the unit is a skeleton and we need special updates for it and
280     // its matching split/DWO CU.
281     Optional<DWARFUnit *> SplitCU;
282     Optional<uint64_t> RangesBase;
283     llvm::Optional<uint64_t> DWOId = Unit->getDWOId();
284     StrOffstsWriter->initialize(Unit->getStringOffsetSection(),
285                                 Unit->getStringOffsetsTableContribution());
286     if (DWOId)
287       SplitCU = BC.getDWOCU(*DWOId);
288 
289     DebugLocWriter *DebugLocWriter = nullptr;
290     // Skipping CUs that failed to load.
291     if (SplitCU) {
292       updateDWONameCompDir(*Unit);
293 
294       DebugInfoBinaryPatcher *DwoDebugInfoPatcher =
295           llvm::cast<DebugInfoBinaryPatcher>(
296               getBinaryDWODebugInfoPatcher(*DWOId));
297       DWARFContext *DWOCtx = BC.getDWOContext();
298       // Setting this CU offset with DWP to normalize DIE offsets to uint32_t
299       if (DWOCtx && !DWOCtx->getCUIndex().getRows().empty())
300         DwoDebugInfoPatcher->setDWPOffset((*SplitCU)->getOffset());
301 
302       {
303         std::lock_guard<std::mutex> Lock(AccessMutex);
304         DebugLocWriter = LocListWritersByCU[*DWOId].get();
305       }
306       DebugRangesSectionWriter *TempRangesSectionWriter =
307           RangesSectionWriter.get();
308       if (Unit->getVersion() >= 5) {
309         TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
310       } else {
311         RangesBase = RangesSectionWriter->getSectionOffset();
312         // For DWARF5 there is now .debug_rnglists.dwo, so don't need to
313         // update rnglists base.
314         DwoDebugInfoPatcher->setRangeBase(*RangesBase);
315       }
316 
317       DwoDebugInfoPatcher->addUnitBaseOffsetLabel((*SplitCU)->getOffset());
318       DebugAbbrevWriter *DWOAbbrevWriter =
319           createBinaryDWOAbbrevWriter((*SplitCU)->getContext(), *DWOId);
320       updateUnitDebugInfo(*(*SplitCU), *DwoDebugInfoPatcher, *DWOAbbrevWriter,
321                           *DebugLocWriter, *TempRangesSectionWriter);
322       DwoDebugInfoPatcher->clearDestinationLabels();
323       if (!DwoDebugInfoPatcher->getWasRangBasedUsed())
324         RangesBase = None;
325       if (Unit->getVersion() >= 5)
326         TempRangesSectionWriter->finalizeSection();
327     }
328 
329     {
330       std::lock_guard<std::mutex> Lock(AccessMutex);
331       auto LocListWriterIter = LocListWritersByCU.find(CUIndex);
332       if (LocListWriterIter != LocListWritersByCU.end())
333         DebugLocWriter = LocListWriterIter->second.get();
334     }
335     if (Unit->getVersion() >= 5) {
336       RangesBase = RangesSectionWriter->getSectionOffset() +
337                    getDWARF5RngListLocListHeaderSize();
338       RangesSectionWriter.get()->initSection(*Unit);
339       StrOffstsWriter->finalizeSection();
340     }
341 
342     DebugInfoPatcher->addUnitBaseOffsetLabel(Unit->getOffset());
343     updateUnitDebugInfo(*Unit, *DebugInfoPatcher, *AbbrevWriter,
344                         *DebugLocWriter, *RangesSectionWriter, RangesBase);
345     if (Unit->getVersion() >= 5)
346       RangesSectionWriter.get()->finalizeSection();
347   };
348 
349   CUIndex = 0;
350   if (opts::NoThreads || opts::DeterministicDebugInfo) {
351     for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
352       processUnitDIE(CUIndex, CU.get());
353       if (CU->getVersion() >= 5)
354         ++CUIndex;
355     }
356   } else {
357     // Update unit debug info in parallel
358     ThreadPool &ThreadPool = ParallelUtilities::getThreadPool();
359     for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
360       ThreadPool.async(processUnitDIE, CUIndex, CU.get());
361       CUIndex++;
362     }
363     ThreadPool.wait();
364   }
365 
366   DebugInfoPatcher->clearDestinationLabels();
367   CUOffsetMap OffsetMap = finalizeDebugSections(*DebugInfoPatcher);
368 
369   if (opts::WriteDWP)
370     writeDWP(DWOIdToName);
371   else
372     writeDWOFiles(DWOIdToName);
373 
374   updateGdbIndexSection(OffsetMap);
375 }
376 
377 void DWARFRewriter::updateUnitDebugInfo(
378     DWARFUnit &Unit, DebugInfoBinaryPatcher &DebugInfoPatcher,
379     DebugAbbrevWriter &AbbrevWriter, DebugLocWriter &DebugLocWriter,
380     DebugRangesSectionWriter &RangesSectionWriter,
381     Optional<uint64_t> RangesBase) {
382   // Cache debug ranges so that the offset for identical ranges could be reused.
383   std::map<DebugAddressRangesVector, uint64_t> CachedRanges;
384 
385   uint64_t DIEOffset = Unit.getOffset() + Unit.getHeaderSize();
386   uint64_t NextCUOffset = Unit.getNextUnitOffset();
387   DWARFDebugInfoEntry Die;
388   DWARFDataExtractor DebugInfoData = Unit.getDebugInfoExtractor();
389   uint32_t Depth = 0;
390 
391   bool IsDWP = false;
392   if (DWARFContext *DWOCtx = BC.getDWOContext())
393     IsDWP = !DWOCtx->getCUIndex().getRows().empty();
394 
395   while (
396       DIEOffset < NextCUOffset &&
397       Die.extractFast(Unit, &DIEOffset, DebugInfoData, NextCUOffset, Depth)) {
398     if (const DWARFAbbreviationDeclaration *AbbrDecl =
399             Die.getAbbreviationDeclarationPtr()) {
400       if (AbbrDecl->hasChildren())
401         ++Depth;
402     } else {
403       // NULL entry.
404       if (Depth > 0)
405         --Depth;
406       if (Depth == 0)
407         break;
408     }
409 
410     DWARFDie DIE(&Unit, &Die);
411 
412     switch (DIE.getTag()) {
413     case dwarf::DW_TAG_compile_unit:
414     case dwarf::DW_TAG_skeleton_unit: {
415       // For dwarf5 section 3.1.3
416       // The following attributes are not part of a split full compilation unit
417       // entry but instead are inherited (if present) from the corresponding
418       // skeleton compilation unit: DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges,
419       // DW_AT_stmt_list, DW_AT_comp_dir, DW_AT_str_offsets_base,
420       // DW_AT_addr_base and DW_AT_rnglists_base.
421       if (Unit.getVersion() == 5 && Unit.isDWOUnit())
422         continue;
423       auto ModuleRangesOrError = DIE.getAddressRanges();
424       if (!ModuleRangesOrError) {
425         consumeError(ModuleRangesOrError.takeError());
426         break;
427       }
428       DWARFAddressRangesVector &ModuleRanges = *ModuleRangesOrError;
429       DebugAddressRangesVector OutputRanges =
430           BC.translateModuleAddressRanges(ModuleRanges);
431       const uint64_t RangesSectionOffset =
432           RangesSectionWriter.addRanges(OutputRanges);
433       if (!Unit.isDWOUnit())
434         ARangesSectionWriter->addCURanges(Unit.getOffset(),
435                                           std::move(OutputRanges));
436       updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher,
437                                      AbbrevWriter, RangesBase);
438       break;
439     }
440     case dwarf::DW_TAG_subprogram: {
441       // Get function address either from ranges or [LowPC, HighPC) pair.
442       uint64_t Address;
443       uint64_t SectionIndex, HighPC;
444       if (!DIE.getLowAndHighPC(Address, HighPC, SectionIndex)) {
445         Expected<DWARFAddressRangesVector> RangesOrError =
446             DIE.getAddressRanges();
447         if (!RangesOrError) {
448           consumeError(RangesOrError.takeError());
449           break;
450         }
451         DWARFAddressRangesVector Ranges = *RangesOrError;
452         // Not a function definition.
453         if (Ranges.empty())
454           break;
455 
456         Address = Ranges.front().LowPC;
457       }
458 
459       // Clear cached ranges as the new function will have its own set.
460       CachedRanges.clear();
461 
462       DebugAddressRangesVector FunctionRanges;
463       if (const BinaryFunction *Function =
464               BC.getBinaryFunctionAtAddress(Address))
465         FunctionRanges = Function->getOutputAddressRanges();
466 
467       if (FunctionRanges.empty())
468         FunctionRanges.push_back({0, 0});
469 
470       updateDWARFObjectAddressRanges(
471           DIE, RangesSectionWriter.addRanges(FunctionRanges), DebugInfoPatcher,
472           AbbrevWriter);
473 
474       break;
475     }
476     case dwarf::DW_TAG_lexical_block:
477     case dwarf::DW_TAG_inlined_subroutine:
478     case dwarf::DW_TAG_try_block:
479     case dwarf::DW_TAG_catch_block: {
480       uint64_t RangesSectionOffset = RangesSectionWriter.getEmptyRangesOffset();
481       Expected<DWARFAddressRangesVector> RangesOrError = DIE.getAddressRanges();
482       const BinaryFunction *Function =
483           RangesOrError && !RangesOrError->empty()
484               ? BC.getBinaryFunctionContainingAddress(
485                     RangesOrError->front().LowPC)
486               : nullptr;
487       if (Function) {
488         DebugAddressRangesVector OutputRanges =
489             Function->translateInputToOutputRanges(*RangesOrError);
490         LLVM_DEBUG(if (OutputRanges.empty() != RangesOrError->empty()) {
491           dbgs() << "BOLT-DEBUG: problem with DIE at 0x"
492                  << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
493                  << Twine::utohexstr(Unit.getOffset()) << '\n';
494         });
495         RangesSectionOffset = RangesSectionWriter.addRanges(
496             std::move(OutputRanges), CachedRanges);
497       } else if (!RangesOrError) {
498         consumeError(RangesOrError.takeError());
499       }
500       updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher,
501                                      AbbrevWriter);
502       break;
503     }
504     default: {
505       // Handle any tag that can have DW_AT_location attribute.
506       DWARFFormValue Value;
507       uint64_t AttrOffset;
508       if (Optional<AttrInfo> AttrVal =
509               findAttributeInfo(DIE, dwarf::DW_AT_location)) {
510         AttrOffset = AttrVal->Offset;
511         Value = AttrVal->V;
512         if (Value.isFormClass(DWARFFormValue::FC_Constant) ||
513             Value.isFormClass(DWARFFormValue::FC_SectionOffset)) {
514           uint64_t Offset = Value.isFormClass(DWARFFormValue::FC_Constant)
515                                 ? Value.getAsUnsignedConstant().getValue()
516                                 : Value.getAsSectionOffset().getValue();
517           DebugLocationsVector InputLL;
518 
519           Optional<object::SectionedAddress> SectionAddress =
520               Unit.getBaseAddress();
521           uint64_t BaseAddress = 0;
522           if (SectionAddress)
523             BaseAddress = SectionAddress->Address;
524 
525           if (Unit.getVersion() >= 5) {
526             Optional<uint64_t> LocOffset = Unit.getLoclistOffset(Offset);
527             assert(LocOffset && "Location Offset is invalid.");
528             Offset = *LocOffset;
529           }
530 
531           Error E = Unit.getLocationTable().visitLocationList(
532               &Offset, [&](const DWARFLocationEntry &Entry) {
533                 switch (Entry.Kind) {
534                 default:
535                   llvm_unreachable("Unsupported DWARFLocationEntry Kind.");
536                 case dwarf::DW_LLE_end_of_list:
537                   return false;
538                 case dwarf::DW_LLE_base_address: {
539                   assert(Entry.SectionIndex == SectionedAddress::UndefSection &&
540                          "absolute address expected");
541                   BaseAddress = Entry.Value0;
542                   break;
543                 }
544                 case dwarf::DW_LLE_offset_pair:
545                   assert(
546                       (Entry.SectionIndex == SectionedAddress::UndefSection &&
547                        (!Unit.isDWOUnit() || Unit.getVersion() == 5)) &&
548                       "absolute address expected");
549                   InputLL.emplace_back(DebugLocationEntry{
550                       BaseAddress + Entry.Value0, BaseAddress + Entry.Value1,
551                       Entry.Loc});
552                   break;
553                 case dwarf::DW_RLE_start_length:
554                   InputLL.emplace_back(DebugLocationEntry{
555                       Entry.Value0, Entry.Value0 + Entry.Value1, Entry.Loc});
556                   break;
557                 case dwarf::DW_LLE_base_addressx: {
558                   Optional<object::SectionedAddress> EntryAddress =
559                       Unit.getAddrOffsetSectionItem(Entry.Value0);
560                   assert(EntryAddress && "base Address not found.");
561                   BaseAddress = EntryAddress->Address;
562                   break;
563                 }
564                 case dwarf::DW_LLE_startx_length: {
565                   Optional<object::SectionedAddress> EntryAddress =
566                       Unit.getAddrOffsetSectionItem(Entry.Value0);
567                   assert(EntryAddress && "Address does not exist.");
568                   InputLL.emplace_back(DebugLocationEntry{
569                       EntryAddress->Address,
570                       EntryAddress->Address + Entry.Value1, Entry.Loc});
571                   break;
572                 }
573                 case dwarf::DW_LLE_startx_endx: {
574                   Optional<object::SectionedAddress> StartAddress =
575                       Unit.getAddrOffsetSectionItem(Entry.Value0);
576                   assert(StartAddress && "Start Address does not exist.");
577                   Optional<object::SectionedAddress> EndAddress =
578                       Unit.getAddrOffsetSectionItem(Entry.Value1);
579                   assert(EndAddress && "Start Address does not exist.");
580                   InputLL.emplace_back(DebugLocationEntry{
581                       StartAddress->Address, EndAddress->Address, Entry.Loc});
582                   break;
583                 }
584                 }
585                 return true;
586               });
587 
588           if (E || InputLL.empty()) {
589             consumeError(std::move(E));
590             errs() << "BOLT-WARNING: empty location list detected at 0x"
591                    << Twine::utohexstr(Offset) << " for DIE at 0x"
592                    << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
593                    << Twine::utohexstr(Unit.getOffset()) << '\n';
594           } else {
595             const uint64_t Address = InputLL.front().LowPC;
596             DebugLocationsVector OutputLL;
597             if (const BinaryFunction *Function =
598                     BC.getBinaryFunctionContainingAddress(Address)) {
599               OutputLL = Function->translateInputToOutputLocationList(InputLL);
600               LLVM_DEBUG(if (OutputLL.empty()) {
601                 dbgs() << "BOLT-DEBUG: location list translated to an empty "
602                           "one at 0x"
603                        << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
604                        << Twine::utohexstr(Unit.getOffset()) << '\n';
605               });
606             } else {
607               // It's possible for a subprogram to be removed and to have
608               // address of 0. Adding this entry to output to preserve debug
609               // information.
610               OutputLL = InputLL;
611             }
612             uint32_t LocListIndex = 0;
613             dwarf::Form Form = Value.getForm();
614             if (Form == dwarf::DW_FORM_sec_offset ||
615                 Form == dwarf::DW_FORM_data4) {
616               // For DWARF5 we can access location list entry either using
617               // index, or offset. If it's offset, then it's from begnning of
618               // the file. This implementation was before we could add entries
619               // to the DIE. For DWARF4 this is no-op.
620               // TODO: For DWARF5 convert all the offset based entries to index
621               // based, and insert loclist_base if necessary.
622               LocListIndex = DebugLoclistWriter::InvalidIndex;
623             } else if (Form == dwarf::DW_FORM_loclistx) {
624               LocListIndex = Value.getRawUValue();
625             } else {
626               llvm_unreachable("Unsupported LocList access Form.");
627             }
628             DebugLocWriter.addList(AttrOffset, LocListIndex,
629                                    std::move(OutputLL));
630           }
631         } else {
632           assert((Value.isFormClass(DWARFFormValue::FC_Exprloc) ||
633                   Value.isFormClass(DWARFFormValue::FC_Block)) &&
634                  "unexpected DW_AT_location form");
635           if (Unit.isDWOUnit() || Unit.getVersion() >= 5) {
636             ArrayRef<uint8_t> Expr = *Value.getAsBlock();
637             DataExtractor Data(
638                 StringRef((const char *)Expr.data(), Expr.size()),
639                 Unit.getContext().isLittleEndian(), 0);
640             DWARFExpression LocExpr(Data, Unit.getAddressByteSize(),
641                                     Unit.getFormParams().Format);
642             uint32_t PrevOffset = 0;
643             constexpr uint32_t SizeOfOpcode = 1;
644             constexpr uint32_t SizeOfForm = 1;
645             for (auto &Expr : LocExpr) {
646               if (!(Expr.getCode() == dwarf::DW_OP_GNU_addr_index ||
647                     Expr.getCode() == dwarf::DW_OP_addrx))
648                 continue;
649 
650               const uint64_t Index = Expr.getRawOperand(0);
651               Optional<object::SectionedAddress> EntryAddress =
652                   Unit.getAddrOffsetSectionItem(Index);
653               assert(EntryAddress && "Address is not found.");
654               assert(Index <= std::numeric_limits<uint32_t>::max() &&
655                      "Invalid Operand Index.");
656               if (Expr.getCode() == dwarf::DW_OP_addrx) {
657                 const uint32_t EncodingSize =
658                     Expr.getOperandEndOffset(0) - PrevOffset - SizeOfOpcode;
659                 const uint32_t Index = AddrWriter->getIndexFromAddress(
660                     EntryAddress->Address, Unit);
661                 // Encoding new size.
662                 SmallString<8> Tmp;
663                 raw_svector_ostream OSE(Tmp);
664                 encodeULEB128(Index, OSE);
665                 DebugInfoPatcher.addUDataPatch(AttrOffset, Tmp.size() + 1, 1);
666                 DebugInfoPatcher.addUDataPatch(AttrOffset + PrevOffset +
667                                                    SizeOfOpcode + SizeOfForm,
668                                                Index, EncodingSize);
669               } else {
670                 // TODO: Re-do this as DWARF5.
671                 AddrWriter->addIndexAddress(EntryAddress->Address,
672                                             static_cast<uint32_t>(Index), Unit);
673               }
674               if (Expr.getDescription().Op[1] ==
675                   DWARFExpression::Operation::SizeNA)
676                 PrevOffset = Expr.getOperandEndOffset(0);
677               else
678                 PrevOffset = Expr.getOperandEndOffset(1);
679             }
680           }
681         }
682       } else if (Optional<AttrInfo> AttrVal =
683                      findAttributeInfo(DIE, dwarf::DW_AT_low_pc)) {
684         AttrOffset = AttrVal->Offset;
685         Value = AttrVal->V;
686         const Optional<uint64_t> Result = Value.getAsAddress();
687         if (Result.hasValue()) {
688           const uint64_t Address = Result.getValue();
689           uint64_t NewAddress = 0;
690           if (const BinaryFunction *Function =
691                   BC.getBinaryFunctionContainingAddress(Address)) {
692             NewAddress = Function->translateInputToOutputAddress(Address);
693             LLVM_DEBUG(dbgs()
694                        << "BOLT-DEBUG: Fixing low_pc 0x"
695                        << Twine::utohexstr(Address) << " for DIE with tag "
696                        << DIE.getTag() << " to 0x"
697                        << Twine::utohexstr(NewAddress) << '\n');
698           }
699 
700           dwarf::Form Form = Value.getForm();
701           assert(Form != dwarf::DW_FORM_LLVM_addrx_offset &&
702                  "DW_FORM_LLVM_addrx_offset is not supported");
703           std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
704           if (Form == dwarf::DW_FORM_GNU_addr_index) {
705             const uint64_t Index = Value.getRawUValue();
706             // If there is no new address, storing old address.
707             // Re-using Index to make implementation easier.
708             // DW_FORM_GNU_addr_index is variable lenght encoding
709             // so we either have to create indices of same sizes, or use same
710             // index.
711             // TODO: We can now re-write .debug_info. This can be simplified to
712             // just getting a new index and creating a patch.
713             AddrWriter->addIndexAddress(NewAddress ? NewAddress : Address,
714                                         Index, Unit);
715           } else if (Form == dwarf::DW_FORM_addrx) {
716             const uint32_t Index = AddrWriter->getIndexFromAddress(
717                 NewAddress ? NewAddress : Address, Unit);
718             DebugInfoPatcher.addUDataPatch(AttrOffset, Index, AttrVal->Size);
719           } else {
720             DebugInfoPatcher.addLE64Patch(AttrOffset, NewAddress);
721           }
722         } else if (opts::Verbosity >= 1) {
723           errs() << "BOLT-WARNING: unexpected form value for attribute at 0x"
724                  << Twine::utohexstr(AttrOffset);
725         }
726       } else if (IsDWP && Unit.isDWOUnit()) {
727         // Not a common path so don't want to search all DIEs all the time.
728         Optional<AttrInfo> SignatureAttrVal =
729             findAttributeInfo(DIE, dwarf::DW_AT_signature);
730         if (!SignatureAttrVal)
731           continue;
732         // If input is DWP file we need to keep track of which TU came from each
733         // CU, so we can write it out correctly.
734         if (Optional<uint64_t> Val = SignatureAttrVal->V.getAsReferenceUVal())
735           TypeSignaturesPerCU[*DIE.getDwarfUnit()->getDWOId()].insert(*Val);
736         else {
737           errs() << "BOT-ERROR: DW_AT_signature form is not supported.\n";
738           exit(1);
739         }
740       }
741     }
742     }
743 
744     // Handling references.
745     assert(DIE.isValid() && "Invalid DIE.");
746     const DWARFAbbreviationDeclaration *AbbrevDecl =
747         DIE.getAbbreviationDeclarationPtr();
748     if (!AbbrevDecl)
749       continue;
750     uint32_t Index = 0;
751     for (const DWARFAbbreviationDeclaration::AttributeSpec &Decl :
752          AbbrevDecl->attributes()) {
753       switch (Decl.Form) {
754       default:
755         break;
756       case dwarf::DW_FORM_ref1:
757       case dwarf::DW_FORM_ref2:
758       case dwarf::DW_FORM_ref4:
759       case dwarf::DW_FORM_ref8:
760       case dwarf::DW_FORM_ref_udata:
761       case dwarf::DW_FORM_ref_addr: {
762         Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, AbbrevDecl, Index);
763         uint32_t DestinationAddress =
764             AttrVal->V.getRawUValue() +
765             (Decl.Form == dwarf::DW_FORM_ref_addr ? 0 : Unit.getOffset());
766         DebugInfoPatcher.addReferenceToPatch(
767             AttrVal->Offset, DestinationAddress, AttrVal->Size, Decl.Form);
768         // We can have only one reference, and it can be backward one.
769         DebugInfoPatcher.addDestinationReferenceLabel(DestinationAddress);
770         break;
771       }
772       }
773       ++Index;
774     }
775   }
776   if (DIEOffset > NextCUOffset)
777     errs() << "BOLT-WARNING: corrupt DWARF detected at 0x"
778            << Twine::utohexstr(Unit.getOffset()) << '\n';
779 }
780 
781 void DWARFRewriter::updateDWARFObjectAddressRanges(
782     const DWARFDie DIE, uint64_t DebugRangesOffset,
783     SimpleBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter,
784     Optional<uint64_t> RangesBase) {
785 
786   // Some objects don't have an associated DIE and cannot be updated (such as
787   // compiler-generated functions).
788   if (!DIE)
789     return;
790 
791   const DWARFAbbreviationDeclaration *AbbreviationDecl =
792       DIE.getAbbreviationDeclarationPtr();
793   if (!AbbreviationDecl) {
794     if (opts::Verbosity >= 1)
795       errs() << "BOLT-WARNING: object's DIE doesn't have an abbreviation: "
796              << "skipping update. DIE at offset 0x"
797              << Twine::utohexstr(DIE.getOffset()) << '\n';
798     return;
799   }
800 
801   if (RangesBase) {
802     // If DW_AT_GNU_ranges_base is present, update it. No further modifications
803     // are needed for ranges base.
804     Optional<AttrInfo> RangesBaseAttrInfo =
805         findAttributeInfo(DIE, dwarf::DW_AT_GNU_ranges_base);
806     if (!RangesBaseAttrInfo)
807       RangesBaseAttrInfo = findAttributeInfo(DIE, dwarf::DW_AT_rnglists_base);
808 
809     if (RangesBaseAttrInfo) {
810       DebugInfoPatcher.addLE32Patch(RangesBaseAttrInfo->Offset,
811                                     static_cast<uint32_t>(*RangesBase),
812                                     RangesBaseAttrInfo->Size);
813       RangesBase = None;
814     }
815   }
816 
817   Optional<AttrInfo> LowPCAttrInfo =
818       findAttributeInfo(DIE, dwarf::DW_AT_low_pc);
819   if (Optional<AttrInfo> AttrVal =
820           findAttributeInfo(DIE, dwarf::DW_AT_ranges)) {
821     // Case 1: The object was already non-contiguous and had DW_AT_ranges.
822     // In this case we simply need to update the value of DW_AT_ranges
823     // and introduce DW_AT_GNU_ranges_base if required.
824     std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
825     // For DWARF5 converting all of DW_AT_ranges into DW_FORM_rnglistx
826     bool Converted = false;
827     if (DIE.getDwarfUnit()->getVersion() >= 5 &&
828         AttrVal->V.getForm() == dwarf::DW_FORM_sec_offset) {
829       AbbrevWriter.addAttributePatch(*DIE.getDwarfUnit(), AbbreviationDecl,
830                                      dwarf::DW_AT_ranges, dwarf::DW_AT_ranges,
831                                      dwarf::DW_FORM_rnglistx);
832       Converted = true;
833     }
834     if (Converted || AttrVal->V.getForm() == dwarf::DW_FORM_rnglistx)
835       DebugInfoPatcher.addUDataPatch(AttrVal->Offset, DebugRangesOffset,
836                                      AttrVal->Size);
837     else
838       DebugInfoPatcher.addLE32Patch(
839           AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(),
840           AttrVal->Size);
841 
842     if (!RangesBase) {
843       if (LowPCAttrInfo &&
844           LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_GNU_addr_index &&
845           LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_addrx)
846         DebugInfoPatcher.addLE64Patch(LowPCAttrInfo->Offset, 0);
847       return;
848     }
849 
850     // Convert DW_AT_low_pc into DW_AT_GNU_ranges_base.
851     if (!LowPCAttrInfo) {
852       errs() << "BOLT-ERROR: skeleton CU at 0x"
853              << Twine::utohexstr(DIE.getOffset())
854              << " does not have DW_AT_GNU_ranges_base or DW_AT_low_pc to"
855                 " convert to update ranges base\n";
856       return;
857     }
858 
859     AbbrevWriter.addAttribute(*DIE.getDwarfUnit(), AbbreviationDecl,
860                               dwarf::DW_AT_GNU_ranges_base,
861                               dwarf::DW_FORM_sec_offset);
862     reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher)
863         .insertNewEntry(DIE, *RangesBase);
864 
865     return;
866   }
867 
868   // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back
869   // to back. Replace with new attributes and patch the DIE.
870   Optional<AttrInfo> HighPCAttrInfo =
871       findAttributeInfo(DIE, dwarf::DW_AT_high_pc);
872   if (LowPCAttrInfo && HighPCAttrInfo) {
873     convertToRangesPatchAbbrev(*DIE.getDwarfUnit(), AbbreviationDecl,
874                                AbbrevWriter, RangesBase);
875     convertToRangesPatchDebugInfo(DIE, DebugRangesOffset, DebugInfoPatcher,
876                                   RangesBase);
877   } else {
878     if (opts::Verbosity >= 1)
879       errs() << "BOLT-ERROR: cannot update ranges for DIE at offset 0x"
880              << Twine::utohexstr(DIE.getOffset()) << '\n';
881   }
882 }
883 
884 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) {
885   ErrorOr<BinarySection &> DbgInfoSection =
886       BC.getUniqueSectionByName(".debug_info");
887   ErrorOr<BinarySection &> TypeInfoSection =
888       BC.getUniqueSectionByName(".debug_types");
889   assert(((BC.DwCtx->getNumTypeUnits() > 0 && TypeInfoSection) ||
890           BC.DwCtx->getNumTypeUnits() == 0) &&
891          "Was not able to retrieve Debug Types section.");
892 
893   // We will be re-writing .debug_info so relocation mechanism doesn't work for
894   // Debug Info Patcher.
895   DebugInfoBinaryPatcher *DebugInfoPatcher = nullptr;
896   if (BC.DwCtx->getNumCompileUnits()) {
897     DbgInfoSection->registerPatcher(std::make_unique<DebugInfoBinaryPatcher>());
898     DebugInfoPatcher =
899         static_cast<DebugInfoBinaryPatcher *>(DbgInfoSection->getPatcher());
900   }
901 
902   // There is no direct connection between CU and TU, but same offsets,
903   // encoded in DW_AT_stmt_list, into .debug_line get modified.
904   // We take advantage of that to map original CU line table offsets to new
905   // ones.
906   std::unordered_map<uint64_t, uint64_t> DebugLineOffsetMap;
907 
908   auto GetStatementListValue = [](DWARFUnit *Unit) {
909     Optional<DWARFFormValue> StmtList =
910         Unit->getUnitDIE().find(dwarf::DW_AT_stmt_list);
911     Optional<uint64_t> Offset = dwarf::toSectionOffset(StmtList);
912     assert(Offset && "Was not able to retreive value of DW_AT_stmt_list.");
913     return *Offset;
914   };
915 
916   const uint64_t Reloc32Type = BC.isAArch64()
917                                    ? static_cast<uint64_t>(ELF::R_AARCH64_ABS32)
918                                    : static_cast<uint64_t>(ELF::R_X86_64_32);
919 
920   for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
921     const unsigned CUID = CU->getOffset();
922     MCSymbol *Label = BC.getDwarfLineTable(CUID).getLabel();
923     if (!Label)
924       continue;
925 
926     Optional<AttrInfo> AttrVal =
927         findAttributeInfo(CU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list);
928     if (!AttrVal)
929       continue;
930 
931     const uint64_t AttributeOffset = AttrVal->Offset;
932     const uint64_t LineTableOffset = Layout.getSymbolOffset(*Label);
933     DebugLineOffsetMap[GetStatementListValue(CU.get())] = LineTableOffset;
934     assert(DbgInfoSection && ".debug_info section must exist");
935     DebugInfoPatcher->addLE32Patch(AttributeOffset, LineTableOffset);
936   }
937 
938   for (const std::unique_ptr<DWARFUnit> &TU : BC.DwCtx->types_section_units()) {
939     DWARFUnit *Unit = TU.get();
940     Optional<AttrInfo> AttrVal =
941         findAttributeInfo(TU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list);
942     if (!AttrVal)
943       continue;
944     const uint64_t AttributeOffset = AttrVal->Offset;
945     auto Iter = DebugLineOffsetMap.find(GetStatementListValue(Unit));
946     assert(Iter != DebugLineOffsetMap.end() &&
947            "Type Unit Updated Line Number Entry does not exist.");
948     TypeInfoSection->addRelocation(AttributeOffset, nullptr, Reloc32Type,
949                                    Iter->second, 0, /*Pending=*/true);
950   }
951 
952   // Set .debug_info as finalized so it won't be skipped over when
953   // we process sections while writing out the new binary. This ensures
954   // that the pending relocations will be processed and not ignored.
955   if (DbgInfoSection)
956     DbgInfoSection->setIsFinalized();
957 
958   if (TypeInfoSection)
959     TypeInfoSection->setIsFinalized();
960 }
961 
962 CUOffsetMap
963 DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
964   if (StrWriter->isInitialized()) {
965     RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
966     std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents =
967         StrWriter->releaseBuffer();
968     BC.registerOrUpdateNoteSection(".debug_str",
969                                    copyByteArray(*DebugStrSectionContents),
970                                    DebugStrSectionContents->size());
971   }
972 
973   if (StrOffstsWriter->isFinalized()) {
974     RewriteInstance::addToDebugSectionsToOverwrite(".debug_str_offsets");
975     std::unique_ptr<DebugStrOffsetsBufferVector>
976         DebugStrOffsetsSectionContents = StrOffstsWriter->releaseBuffer();
977     BC.registerOrUpdateNoteSection(
978         ".debug_str_offsets", copyByteArray(*DebugStrOffsetsSectionContents),
979         DebugStrOffsetsSectionContents->size());
980   }
981 
982   std::unique_ptr<DebugBufferVector> RangesSectionContents =
983       RangesSectionWriter->releaseBuffer();
984   BC.registerOrUpdateNoteSection(
985       llvm::isa<DebugRangeListsSectionWriter>(*RangesSectionWriter)
986           ? ".debug_rnglists"
987           : ".debug_ranges",
988       copyByteArray(*RangesSectionContents), RangesSectionContents->size());
989 
990   if (BC.isDWARF5Used()) {
991     std::unique_ptr<DebugBufferVector> LocationListSectionContents =
992         makeFinalLocListsSection(DebugInfoPatcher, DWARFVersion::DWARF5);
993     BC.registerOrUpdateNoteSection(".debug_loclists",
994                                    copyByteArray(*LocationListSectionContents),
995                                    LocationListSectionContents->size());
996   }
997 
998   if (BC.isDWARFLegacyUsed()) {
999     std::unique_ptr<DebugBufferVector> LocationListSectionContents =
1000         makeFinalLocListsSection(DebugInfoPatcher, DWARFVersion::DWARFLegacy);
1001     BC.registerOrUpdateNoteSection(".debug_loc",
1002                                    copyByteArray(*LocationListSectionContents),
1003                                    LocationListSectionContents->size());
1004   }
1005 
1006   // AddrWriter should be finalized after debug_loc since more addresses can be
1007   // added there.
1008   if (AddrWriter->isInitialized()) {
1009     AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
1010     BC.registerOrUpdateNoteSection(".debug_addr",
1011                                    copyByteArray(AddressSectionContents),
1012                                    AddressSectionContents.size());
1013     for (auto &CU : BC.DwCtx->compile_units()) {
1014       DWARFDie DIE = CU->getUnitDIE();
1015       uint64_t Offset = 0;
1016       uint64_t AttrOffset = 0;
1017       uint32_t Size = 0;
1018       Optional<AttrInfo> AttrValGnu =
1019           findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base);
1020       Optional<AttrInfo> AttrVal =
1021           findAttributeInfo(DIE, dwarf::DW_AT_addr_base);
1022 
1023       // For cases where Skeleton CU does not have DW_AT_GNU_addr_base
1024       if (!AttrValGnu && CU->getVersion() < 5)
1025         continue;
1026 
1027       Offset = AddrWriter->getOffset(*CU);
1028 
1029       if (AttrValGnu) {
1030         AttrOffset = AttrValGnu->Offset;
1031         Size = AttrValGnu->Size;
1032       }
1033 
1034       if (AttrVal) {
1035         AttrOffset = AttrVal->Offset;
1036         Size = AttrVal->Size;
1037       }
1038 
1039       if (AttrValGnu || AttrVal) {
1040         DebugInfoPatcher.addLE32Patch(AttrOffset, static_cast<int32_t>(Offset),
1041                                       Size);
1042       } else if (CU->getVersion() >= 5) {
1043         // A case where we were not using .debug_addr section, but after update
1044         // now using it.
1045         const DWARFAbbreviationDeclaration *Abbrev =
1046             DIE.getAbbreviationDeclarationPtr();
1047         AbbrevWriter->addAttribute(*CU, Abbrev, dwarf::DW_AT_addr_base,
1048                                    dwarf::DW_FORM_sec_offset);
1049         DebugInfoPatcher.insertNewEntry(DIE, static_cast<int32_t>(Offset));
1050       }
1051     }
1052   }
1053 
1054   std::unique_ptr<DebugBufferVector> AbbrevSectionContents =
1055       AbbrevWriter->finalize();
1056   BC.registerOrUpdateNoteSection(".debug_abbrev",
1057                                  copyByteArray(*AbbrevSectionContents),
1058                                  AbbrevSectionContents->size());
1059 
1060   // Update abbreviation offsets for CUs/TUs if they were changed.
1061   SimpleBinaryPatcher *DebugTypesPatcher = nullptr;
1062   for (auto &Unit : BC.DwCtx->normal_units()) {
1063     const uint64_t NewAbbrevOffset =
1064         AbbrevWriter->getAbbreviationsOffsetForUnit(*Unit);
1065     if (Unit->getAbbreviationsOffset() == NewAbbrevOffset)
1066       continue;
1067 
1068     // DWARFv4 or earlier
1069     // unit_length - 4 bytes
1070     // version - 2 bytes
1071     // So + 6 to patch debug_abbrev_offset
1072     constexpr uint64_t AbbrevFieldOffsetLegacy = 6;
1073     // DWARFv5
1074     // unit_length - 4 bytes
1075     // version - 2 bytes
1076     // unit_type - 1 byte
1077     // address_size - 1 byte
1078     // So + 8 to patch debug_abbrev_offset
1079     constexpr uint64_t AbbrevFieldOffsetV5 = 8;
1080     uint64_t AbbrevOffset =
1081         Unit->getVersion() >= 5 ? AbbrevFieldOffsetV5 : AbbrevFieldOffsetLegacy;
1082     if (!Unit->isTypeUnit() || Unit->getVersion() >= 5) {
1083       DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevOffset,
1084                                     static_cast<uint32_t>(NewAbbrevOffset));
1085       continue;
1086     }
1087 
1088     if (!DebugTypesPatcher) {
1089       ErrorOr<BinarySection &> DebugTypes =
1090           BC.getUniqueSectionByName(".debug_types");
1091       DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>());
1092       DebugTypesPatcher =
1093           static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher());
1094     }
1095     DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevOffset,
1096                                     static_cast<uint32_t>(NewAbbrevOffset));
1097   }
1098 
1099   // No more creating new DebugInfoPatches.
1100   CUOffsetMap CUMap =
1101       DebugInfoPatcher.computeNewOffsets(*BC.DwCtx.get(), false);
1102 
1103   // Skip .debug_aranges if we are re-generating .gdb_index.
1104   if (opts::KeepARanges || !BC.getGdbIndexSection()) {
1105     SmallVector<char, 16> ARangesBuffer;
1106     raw_svector_ostream OS(ARangesBuffer);
1107 
1108     auto MAB = std::unique_ptr<MCAsmBackend>(
1109         BC.TheTarget->createMCAsmBackend(*BC.STI, *BC.MRI, MCTargetOptions()));
1110 
1111     ARangesSectionWriter->writeARangesSection(OS, CUMap);
1112     const StringRef &ARangesContents = OS.str();
1113 
1114     BC.registerOrUpdateNoteSection(".debug_aranges",
1115                                    copyByteArray(ARangesContents),
1116                                    ARangesContents.size());
1117   }
1118   return CUMap;
1119 }
1120 
1121 // Creates all the data structures necessary for creating MCStreamer.
1122 // They are passed by reference because they need to be kept around.
1123 // Also creates known debug sections. These are sections handled by
1124 // handleDebugDataPatching.
1125 using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>;
1126 namespace {
1127 
1128 std::unique_ptr<BinaryContext>
1129 createDwarfOnlyBC(const object::ObjectFile &File) {
1130   return cantFail(BinaryContext::createBinaryContext(
1131       &File, false,
1132       DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore,
1133                            nullptr, "", WithColor::defaultErrorHandler,
1134                            WithColor::defaultWarningHandler)));
1135 }
1136 
1137 StringMap<KnownSectionsEntry>
1138 createKnownSectionsMap(const MCObjectFileInfo &MCOFI) {
1139   StringMap<KnownSectionsEntry> KnownSectionsTemp = {
1140       {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
1141       {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
1142       {"debug_str_offsets.dwo",
1143        {MCOFI.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS}},
1144       {"debug_str.dwo", {MCOFI.getDwarfStrDWOSection(), DW_SECT_EXT_unknown}},
1145       {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
1146       {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
1147       {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
1148       {"debug_loclists.dwo",
1149        {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}},
1150       {"debug_rnglists.dwo",
1151        {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}}};
1152   return KnownSectionsTemp;
1153 }
1154 
1155 StringRef getSectionName(const SectionRef &Section) {
1156   Expected<StringRef> SectionName = Section.getName();
1157   assert(SectionName && "Invalid section name.");
1158   StringRef Name = *SectionName;
1159   Name = Name.substr(Name.find_first_not_of("._"));
1160   return Name;
1161 }
1162 
1163 // Exctracts an appropriate slice if input is DWP.
1164 // Applies patches or overwrites the section.
1165 Optional<StringRef>
1166 updateDebugData(DWARFContext &DWCtx, std::string &Storage,
1167                 StringRef SectionName, StringRef SectionContents,
1168                 const StringMap<KnownSectionsEntry> &KnownSections,
1169                 MCStreamer &Streamer, DWARFRewriter &Writer,
1170                 const DWARFUnitIndex::Entry *CUDWOEntry, uint64_t DWOId,
1171                 std::unique_ptr<DebugBufferVector> &OutputBuffer,
1172                 DebugRangeListsSectionWriter *RangeListsWriter) {
1173   auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher,
1174                         StringRef Data) -> StringRef {
1175     Patcher->computeNewOffsets(DWCtx, true);
1176     Storage = Patcher->patchBinary(Data);
1177     return StringRef(Storage.c_str(), Storage.size());
1178   };
1179 
1180   using DWOSectionContribution =
1181       const DWARFUnitIndex::Entry::SectionContribution;
1182   auto getSliceData = [&](const DWARFUnitIndex::Entry *DWOEntry,
1183                           StringRef OutData, DWARFSectionKind Sec,
1184                           uint32_t &DWPOffset) -> StringRef {
1185     if (DWOEntry) {
1186       DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec);
1187       DWPOffset = DWOContrubution->Offset;
1188       OutData = OutData.substr(DWPOffset, DWOContrubution->Length);
1189     }
1190     return OutData;
1191   };
1192 
1193   auto SectionIter = KnownSections.find(SectionName);
1194   if (SectionIter == KnownSections.end())
1195     return None;
1196 
1197   Streamer.SwitchSection(SectionIter->second.first);
1198   StringRef OutData = SectionContents;
1199   uint32_t DWPOffset = 0;
1200 
1201   switch (SectionIter->second.second) {
1202   default: {
1203     if (!SectionName.equals("debug_str.dwo"))
1204       errs() << "BOLT-WARNING: unsupported debug section: " << SectionName
1205              << "\n";
1206     return OutData;
1207   }
1208   case DWARFSectionKind::DW_SECT_INFO: {
1209     OutData = getSliceData(CUDWOEntry, OutData, DWARFSectionKind::DW_SECT_INFO,
1210                            DWPOffset);
1211     DebugInfoBinaryPatcher *Patcher = llvm::cast<DebugInfoBinaryPatcher>(
1212         Writer.getBinaryDWODebugInfoPatcher(DWOId));
1213     return applyPatch(Patcher, OutData);
1214   }
1215   case DWARFSectionKind::DW_SECT_EXT_TYPES: {
1216     return getSliceData(nullptr, OutData, DWARFSectionKind::DW_SECT_EXT_TYPES,
1217                         DWPOffset);
1218   }
1219   case DWARFSectionKind::DW_SECT_STR_OFFSETS: {
1220     return getSliceData(CUDWOEntry, OutData,
1221                         DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset);
1222   }
1223   case DWARFSectionKind::DW_SECT_ABBREV: {
1224     DebugAbbrevWriter *AbbrevWriter = Writer.getBinaryDWOAbbrevWriter(DWOId);
1225     OutputBuffer = AbbrevWriter->finalize();
1226     // Creating explicit StringRef here, otherwise
1227     // with impicit conversion it will take null byte as end of
1228     // string.
1229     return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()),
1230                      OutputBuffer->size());
1231   }
1232   case DWARFSectionKind::DW_SECT_EXT_LOC:
1233   case DWARFSectionKind::DW_SECT_LOCLISTS: {
1234     DebugLocWriter *LocWriter = Writer.getDebugLocWriter(DWOId);
1235     OutputBuffer = LocWriter->getBuffer();
1236     // Creating explicit StringRef here, otherwise
1237     // with impicit conversion it will take null byte as end of
1238     // string.
1239     return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()),
1240                      OutputBuffer->size());
1241   }
1242   case DWARFSectionKind::DW_SECT_LINE: {
1243     return getSliceData(CUDWOEntry, OutData, DWARFSectionKind::DW_SECT_LINE,
1244                         DWPOffset);
1245   }
1246   case DWARFSectionKind::DW_SECT_RNGLISTS: {
1247     OutputBuffer = RangeListsWriter->releaseBuffer();
1248     return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()),
1249                      OutputBuffer->size());
1250   }
1251   }
1252 }
1253 
1254 } // namespace
1255 
1256 struct TUContribution {
1257   uint64_t Signature{0};
1258   uint32_t Length{0};
1259 };
1260 using TUContributionVector = std::vector<TUContribution>;
1261 /// Iterates over all the signatures used in this CU, and
1262 /// uses TU Index to extract their contributions from the DWP file.
1263 /// It stores them in DWOTUSection.
1264 static std::string extractDWOTUFromDWP(
1265     const DWARFRewriter::DebugTypesSignaturesPerCUMap &TypeSignaturesPerCU,
1266     const DWARFUnitIndex &TUIndex, StringRef Contents,
1267     TUContributionVector &TUContributionsToCU, uint64_t DWOId) {
1268   std::string DWOTUSection;
1269   using TUEntry =
1270       std::pair<uint64_t, const DWARFUnitIndex::Entry::SectionContribution *>;
1271   std::vector<TUEntry> TUContributions;
1272   for (const uint64_t TUSignature : TypeSignaturesPerCU.at(DWOId)) {
1273     const DWARFUnitIndex::Entry *TUDWOEntry = TUIndex.getFromHash(TUSignature);
1274     const DWARFUnitIndex::Entry::SectionContribution *C =
1275         TUDWOEntry->getContribution(DW_SECT_EXT_TYPES);
1276     TUContributions.emplace_back(TUSignature, C);
1277   }
1278 
1279   // Sorting so it's easy to compare output.
1280   // They should be sharing the same Abbrev.
1281   std::sort(TUContributions.begin(), TUContributions.end(),
1282             [](const TUEntry &V1, const TUEntry &V2) -> bool {
1283               return V1.second->Offset < V2.second->Offset;
1284             });
1285 
1286   for (auto &PairEntry : TUContributions) {
1287     const DWARFUnitIndex::Entry::SectionContribution *C = PairEntry.second;
1288     const uint64_t TUSignature = PairEntry.first;
1289     DWOTUSection.append(Contents.slice(C->Offset, C->Offset + C->Length).str());
1290     TUContributionsToCU.push_back({TUSignature, C->Length});
1291   }
1292   return DWOTUSection;
1293 }
1294 
1295 static void extractDWOTUFromDWO(StringRef Contents,
1296                                 TUContributionVector &TUContributionsToCU) {
1297   uint64_t Offset = 0;
1298   DataExtractor Data(Contents, true, 0);
1299   while (Data.isValidOffset(Offset)) {
1300     auto PrevOffset = Offset;
1301     // Length of the unit, including the 4 byte length field.
1302     const uint32_t Length = Data.getU32(&Offset) + 4;
1303 
1304     Data.getU16(&Offset); // Version
1305     Data.getU32(&Offset); // Abbrev offset
1306     Data.getU8(&Offset);  // Address size
1307     const auto TUSignature = Data.getU64(&Offset);
1308     Offset = PrevOffset + Length;
1309     TUContributionsToCU.push_back({TUSignature, Length});
1310   }
1311 }
1312 
1313 static void extractTypesFromDWPDWARF5(
1314     const MCObjectFileInfo &MCOFI, const DWARFUnitIndex &TUIndex,
1315     const DWARFRewriter::DebugTypesSignaturesPerCUMap &TypeSignaturesPerCU,
1316     MCStreamer &Streamer, StringRef Contents, uint64_t DWOId) {
1317   std::vector<const DWARFUnitIndex::Entry::SectionContribution *>
1318       TUContributions;
1319   for (const uint64_t Val : TypeSignaturesPerCU.at(DWOId)) {
1320     const DWARFUnitIndex::Entry *TUE = TUIndex.getFromHash(Val);
1321     const DWARFUnitIndex::Entry::SectionContribution *C =
1322         TUE->getContribution(DWARFSectionKind::DW_SECT_INFO);
1323     TUContributions.push_back(C);
1324   }
1325   // Sorting so it's easy to compare output.
1326   // They should be sharing the same Abbrev.
1327   std::sort(TUContributions.begin(), TUContributions.end(),
1328             [](const DWARFUnitIndex::Entry::SectionContribution *V1,
1329                const DWARFUnitIndex::Entry::SectionContribution *V2) -> bool {
1330               return V1->Offset < V2->Offset;
1331             });
1332   Streamer.SwitchSection(MCOFI.getDwarfInfoDWOSection());
1333   for (const auto *C : TUContributions)
1334     Streamer.emitBytes(Contents.slice(C->Offset, C->Offset + C->Length));
1335 }
1336 
1337 void DWARFRewriter::writeDWP(
1338     std::unordered_map<uint64_t, std::string> &DWOIdToName) {
1339   SmallString<0> OutputNameStr;
1340   StringRef OutputName;
1341   if (opts::DwarfOutputPath.empty()) {
1342     OutputName =
1343         Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr);
1344   } else {
1345     StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename);
1346     OutputName = Twine(opts::DwarfOutputPath)
1347                      .concat("/")
1348                      .concat(ExeFileName)
1349                      .concat(".dwp")
1350                      .toStringRef(OutputNameStr);
1351     errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will "
1352               "possibly be written to another location that is not the same as "
1353               "the executable\n";
1354   }
1355   std::error_code EC;
1356   std::unique_ptr<ToolOutputFile> Out =
1357       std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None);
1358 
1359   const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile();
1360   std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File);
1361   std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(Out->os());
1362   const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo();
1363   StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI);
1364   MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
1365   MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
1366 
1367   // Data Structures for DWP book keeping
1368   // Size of array corresponds to the number of sections supported by DWO format
1369   // in DWARF4/5.
1370   uint32_t ContributionOffsets[8] = {};
1371   std::deque<SmallString<32>> UncompressedSections;
1372   DWPStringPool Strings(*Streamer, StrSection);
1373   MapVector<uint64_t, UnitIndexEntry> IndexEntries;
1374   MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
1375   uint16_t Version = 0;
1376   uint32_t IndexVersion = 2;
1377 
1378   // Setup DWP code once.
1379   DWARFContext *DWOCtx = BC.getDWOContext();
1380   const DWARFUnitIndex *CUIndex = nullptr;
1381   const DWARFUnitIndex *TUIndex = nullptr;
1382   bool IsDWP = false;
1383   if (DWOCtx) {
1384     CUIndex = &DWOCtx->getCUIndex();
1385     TUIndex = &DWOCtx->getTUIndex();
1386     IsDWP = !CUIndex->getRows().empty();
1387   }
1388 
1389   for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
1390     Optional<uint64_t> DWOId = CU->getDWOId();
1391     if (!DWOId)
1392       continue;
1393 
1394     // Skipping CUs that we failed to load.
1395     Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId);
1396     if (!DWOCU)
1397       continue;
1398 
1399     if (Version == 0) {
1400       Version = CU->getVersion();
1401       IndexVersion = Version < 5 ? 2 : 5;
1402     } else if (Version != CU->getVersion()) {
1403       errs() << "BOLT-ERROR: Incompatible DWARF compile unit versions.\n";
1404       exit(1);
1405     }
1406 
1407     UnitIndexEntry CurEntry = {};
1408     CurEntry.DWOName =
1409         dwarf::toString(CU->getUnitDIE().find(
1410                             {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
1411                         "");
1412     const char *Name = CU->getUnitDIE().getShortName();
1413     if (Name)
1414       CurEntry.Name = Name;
1415     StringRef CurStrSection;
1416     StringRef CurStrOffsetSection;
1417 
1418     // This maps each section contained in this file to its length.
1419     // This information is later on used to calculate the contributions,
1420     // i.e. offset and length, of each compile/type unit to a section.
1421     std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
1422 
1423     const DWARFUnitIndex::Entry *CUDWOEntry = nullptr;
1424     if (IsDWP)
1425       CUDWOEntry = CUIndex->getFromHash(*DWOId);
1426 
1427     bool StrSectionWrittenOut = false;
1428     const object::ObjectFile *DWOFile =
1429         (*DWOCU)->getContext().getDWARFObj().getFile();
1430 
1431     DebugRangeListsSectionWriter *RangeListssWriter = nullptr;
1432     if (CU->getVersion() == 5) {
1433       assert(RangeListsWritersByCU.count(*DWOId) != 0 &&
1434              "No RangeListsWriter for DWO ID.");
1435       RangeListssWriter = RangeListsWritersByCU[*DWOId].get();
1436     }
1437     std::string DWOTUSection;
1438     TUContributionVector TUContributionsToCU;
1439     for (const SectionRef &Section : DWOFile->sections()) {
1440       std::string DWOTUSection;
1441       std::string Storage = "";
1442       std::unique_ptr<DebugBufferVector> OutputData;
1443       StringRef SectionName = getSectionName(Section);
1444       Expected<StringRef> ContentsExp = Section.getContents();
1445       assert(ContentsExp && "Invalid contents.");
1446       StringRef Contents = *ContentsExp;
1447       const bool IsTypesDWO = SectionName == "debug_types.dwo";
1448       if (IsDWP && IsTypesDWO) {
1449         assert(TUIndex &&
1450                "DWP Input with .debug_types.dwo section with TU Index.");
1451         DWOTUSection =
1452             extractDWOTUFromDWP(TypeSignaturesPerCU, *TUIndex, Contents,
1453                                 TUContributionsToCU, *DWOId);
1454         Contents = DWOTUSection;
1455       } else if (IsTypesDWO) {
1456         extractDWOTUFromDWO(Contents, TUContributionsToCU);
1457       }
1458 
1459       Optional<StringRef> TOutData = updateDebugData(
1460           (*DWOCU)->getContext(), Storage, SectionName, Contents, KnownSections,
1461           *Streamer, *this, CUDWOEntry, *DWOId, OutputData, RangeListssWriter);
1462       if (!TOutData)
1463         continue;
1464 
1465       StringRef OutData = *TOutData;
1466       if (IsTypesDWO) {
1467         Streamer->emitBytes(OutData);
1468         continue;
1469       }
1470 
1471       if (SectionName.equals("debug_str.dwo")) {
1472         CurStrSection = OutData;
1473       } else {
1474         // Since handleDebugDataPatching returned true, we already know this is
1475         // a known section.
1476         auto SectionIter = KnownSections.find(SectionName);
1477         if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS)
1478           CurStrOffsetSection = OutData;
1479         else
1480           Streamer->emitBytes(OutData);
1481         auto Index =
1482             getContributionIndex(SectionIter->second.second, IndexVersion);
1483         CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
1484         CurEntry.Contributions[Index].Length = OutData.size();
1485         ContributionOffsets[Index] += CurEntry.Contributions[Index].Length;
1486       }
1487 
1488       // Strings are combined in to a new string section, and de-duplicated
1489       // based on hash.
1490       if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() &&
1491           !CurStrSection.empty()) {
1492         writeStringsAndOffsets(*Streamer.get(), Strings, StrOffsetSection,
1493                                CurStrSection, CurStrOffsetSection,
1494                                CU->getVersion());
1495         StrSectionWrittenOut = true;
1496       }
1497     }
1498     CompileUnitIdentifiers CUI{*DWOId, CurEntry.Name.c_str(),
1499                                CurEntry.DWOName.c_str()};
1500     auto P = IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry));
1501     if (!P.second) {
1502       Error Err = buildDuplicateError(*P.first, CUI, "");
1503       errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n";
1504       return;
1505     }
1506 
1507     // Handling TU
1508     if (!TUContributionsToCU.empty()) {
1509       const unsigned Index =
1510           getContributionIndex(DW_SECT_EXT_TYPES, IndexVersion);
1511       for (const TUContribution &TUC : TUContributionsToCU) {
1512         UnitIndexEntry TUEntry = CurEntry;
1513         TUEntry.Contributions[0] = {};
1514         TUEntry.Contributions[Index].Offset = ContributionOffsets[Index];
1515         TUEntry.Contributions[Index].Length = TUC.Length;
1516         ContributionOffsets[Index] += TUEntry.Contributions[Index].Length;
1517         TypeIndexEntries.insert(std::make_pair(TUC.Signature, TUEntry));
1518       }
1519     }
1520   }
1521 
1522   if (Version < 5) {
1523     // Lie about there being no info contributions so the TU index only includes
1524     // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
1525     // contribution to the info section, so we do not want to lie about it.
1526     ContributionOffsets[0] = 0;
1527   }
1528   writeIndex(*Streamer.get(), MCOFI.getDwarfTUIndexSection(),
1529              ContributionOffsets, TypeIndexEntries, IndexVersion);
1530 
1531   if (Version < 5) {
1532     // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
1533     // section does not exist, so no need to do anything about this.
1534     ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0;
1535     // Unlie about the info contribution
1536     ContributionOffsets[0] = 1;
1537   }
1538   writeIndex(*Streamer.get(), MCOFI.getDwarfCUIndexSection(),
1539              ContributionOffsets, IndexEntries, IndexVersion);
1540 
1541   Streamer->finish();
1542   Out->keep();
1543 }
1544 
1545 void DWARFRewriter::writeDWOFiles(
1546     std::unordered_map<uint64_t, std::string> &DWOIdToName) {
1547   // Setup DWP code once.
1548   DWARFContext *DWOCtx = BC.getDWOContext();
1549   const DWARFUnitIndex *CUIndex = nullptr;
1550   const DWARFUnitIndex *TUIndex = nullptr;
1551   bool IsDWP = false;
1552   if (DWOCtx) {
1553     CUIndex = &DWOCtx->getCUIndex();
1554     TUIndex = &DWOCtx->getTUIndex();
1555     IsDWP = !CUIndex->getRows().empty();
1556   }
1557 
1558   for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
1559     Optional<uint64_t> DWOId = CU->getDWOId();
1560     if (!DWOId)
1561       continue;
1562 
1563     // Skipping CUs that we failed to load.
1564     Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId);
1565     if (!DWOCU)
1566       continue;
1567 
1568     std::string CompDir = opts::DwarfOutputPath.empty()
1569                               ? CU->getCompilationDir()
1570                               : opts::DwarfOutputPath.c_str();
1571     std::string ObjectName = getDWOName(*CU.get(), nullptr, DWOIdToName);
1572     auto FullPath = CompDir.append("/").append(ObjectName);
1573 
1574     std::error_code EC;
1575     std::unique_ptr<ToolOutputFile> TempOut =
1576         std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None);
1577 
1578     const DWARFUnitIndex::Entry *CUDWOEntry = nullptr;
1579     if (IsDWP)
1580       CUDWOEntry = CUIndex->getFromHash(*DWOId);
1581 
1582     const object::ObjectFile *File =
1583         (*DWOCU)->getContext().getDWARFObj().getFile();
1584     std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File);
1585     std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(TempOut->os());
1586     const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo();
1587     StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI);
1588 
1589     DebugRangeListsSectionWriter *RangeListssWriter = nullptr;
1590     if (CU->getVersion() == 5) {
1591       assert(RangeListsWritersByCU.count(*DWOId) != 0 &&
1592              "No RangeListsWriter for DWO ID.");
1593       RangeListssWriter = RangeListsWritersByCU[*DWOId].get();
1594 
1595       // Handling .debug_rnglists.dwo seperatly. The original .o/.dwo might not
1596       // have .debug_rnglists so won't be part of the loop below.
1597       if (!RangeListssWriter->empty()) {
1598         std::string Storage = "";
1599         std::unique_ptr<DebugBufferVector> OutputData;
1600         if (Optional<StringRef> OutData = updateDebugData(
1601                 (*DWOCU)->getContext(), Storage, "debug_rnglists.dwo", "",
1602                 KnownSections, *Streamer, *this, CUDWOEntry, *DWOId, OutputData,
1603                 RangeListssWriter))
1604           Streamer->emitBytes(*OutData);
1605       }
1606     }
1607 
1608     TUContributionVector TUContributionsToCU;
1609     for (const SectionRef &Section : File->sections()) {
1610       std::string Storage = "";
1611       std::string DWOTUSection;
1612       std::unique_ptr<DebugBufferVector> OutputData;
1613       StringRef SectionName = getSectionName(Section);
1614       if (SectionName == "debug_rnglists.dwo")
1615         continue;
1616       Expected<StringRef> ContentsExp = Section.getContents();
1617       assert(ContentsExp && "Invalid contents.");
1618       StringRef Contents = *ContentsExp;
1619       if (IsDWP && SectionName == "debug_types.dwo") {
1620         assert(TUIndex &&
1621                "DWP Input with .debug_types.dwo section with TU Index.");
1622         DWOTUSection =
1623             extractDWOTUFromDWP(TypeSignaturesPerCU, *TUIndex, Contents,
1624                                 TUContributionsToCU, *DWOId);
1625         Contents = DWOTUSection;
1626       } else if (IsDWP && CU->getVersion() >= 5 &&
1627                  SectionName == "debug_info.dwo") {
1628         assert(TUIndex &&
1629                "DWP Input with .debug_types.dwo section with TU Index.");
1630         extractTypesFromDWPDWARF5(MCOFI, *TUIndex, TypeSignaturesPerCU,
1631                                   *Streamer, Contents, *DWOId);
1632       }
1633 
1634       if (Optional<StringRef> OutData = updateDebugData(
1635               (*DWOCU)->getContext(), Storage, SectionName, Contents,
1636               KnownSections, *Streamer, *this, CUDWOEntry, *DWOId, OutputData,
1637               RangeListssWriter))
1638         Streamer->emitBytes(*OutData);
1639     }
1640     Streamer->finish();
1641     TempOut->keep();
1642   }
1643 }
1644 
1645 void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap) {
1646   if (!BC.getGdbIndexSection())
1647     return;
1648 
1649   // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
1650   // for .gdb_index section format.
1651 
1652   StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents();
1653 
1654   const char *Data = GdbIndexContents.data();
1655 
1656   // Parse the header.
1657   const uint32_t Version = read32le(Data);
1658   if (Version != 7 && Version != 8) {
1659     errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n";
1660     exit(1);
1661   }
1662 
1663   // Some .gdb_index generators use file offsets while others use section
1664   // offsets. Hence we can only rely on offsets relative to each other,
1665   // and ignore their absolute values.
1666   const uint32_t CUListOffset = read32le(Data + 4);
1667   const uint32_t CUTypesOffset = read32le(Data + 8);
1668   const uint32_t AddressTableOffset = read32le(Data + 12);
1669   const uint32_t SymbolTableOffset = read32le(Data + 16);
1670   const uint32_t ConstantPoolOffset = read32le(Data + 20);
1671   Data += 24;
1672 
1673   // Map CUs offsets to indices and verify existing index table.
1674   std::map<uint32_t, uint32_t> OffsetToIndexMap;
1675   const uint32_t CUListSize = CUTypesOffset - CUListOffset;
1676   const unsigned NumCUs = BC.DwCtx->getNumCompileUnits();
1677   if (CUListSize != NumCUs * 16) {
1678     errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n";
1679     exit(1);
1680   }
1681   for (unsigned Index = 0; Index < NumCUs; ++Index, Data += 16) {
1682     const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index);
1683     const uint64_t Offset = read64le(Data);
1684     if (CU->getOffset() != Offset) {
1685       errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n";
1686       exit(1);
1687     }
1688 
1689     OffsetToIndexMap[Offset] = Index;
1690   }
1691 
1692   // Ignore old address table.
1693   const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset;
1694   // Move Data to the beginning of symbol table.
1695   Data += SymbolTableOffset - CUTypesOffset;
1696 
1697   // Calculate the size of the new address table.
1698   uint32_t NewAddressTableSize = 0;
1699   for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) {
1700     const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second;
1701     NewAddressTableSize += Ranges.size() * 20;
1702   }
1703 
1704   // Difference between old and new table (and section) sizes.
1705   // Could be negative.
1706   int32_t Delta = NewAddressTableSize - OldAddressTableSize;
1707 
1708   size_t NewGdbIndexSize = GdbIndexContents.size() + Delta;
1709 
1710   // Free'd by ExecutableFileMemoryManager.
1711   auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize];
1712   uint8_t *Buffer = NewGdbIndexContents;
1713 
1714   write32le(Buffer, Version);
1715   write32le(Buffer + 4, CUListOffset);
1716   write32le(Buffer + 8, CUTypesOffset);
1717   write32le(Buffer + 12, AddressTableOffset);
1718   write32le(Buffer + 16, SymbolTableOffset + Delta);
1719   write32le(Buffer + 20, ConstantPoolOffset + Delta);
1720   Buffer += 24;
1721 
1722   // Writing out CU List <Offset, Size>
1723   for (auto &CUInfo : CUMap) {
1724     write64le(Buffer, CUInfo.second.Offset);
1725     // Length encoded in CU doesn't contain first 4 bytes that encode length.
1726     write64le(Buffer + 8, CUInfo.second.Length + 4);
1727     Buffer += 16;
1728   }
1729 
1730   // Copy over types CU list
1731   // Spec says " triplet, the first value is the CU offset, the second value is
1732   // the type offset in the CU, and the third value is the type signature"
1733   // Looking at what is being generated by gdb-add-index. The first entry is TU
1734   // offset, second entry is offset from it, and third entry is the type
1735   // signature.
1736   memcpy(Buffer, GdbIndexContents.data() + CUTypesOffset,
1737          AddressTableOffset - CUTypesOffset);
1738   Buffer += AddressTableOffset - CUTypesOffset;
1739 
1740   // Generate new address table.
1741   for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair :
1742        ARangesSectionWriter->getCUAddressRanges()) {
1743     const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first];
1744     const DebugAddressRangesVector &Ranges = CURangesPair.second;
1745     for (const DebugAddressRange &Range : Ranges) {
1746       write64le(Buffer, Range.LowPC);
1747       write64le(Buffer + 8, Range.HighPC);
1748       write32le(Buffer + 16, CUIndex);
1749       Buffer += 20;
1750     }
1751   }
1752 
1753   const size_t TrailingSize =
1754       GdbIndexContents.data() + GdbIndexContents.size() - Data;
1755   assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize &&
1756          "size calculation error");
1757 
1758   // Copy over the rest of the original data.
1759   memcpy(Buffer, Data, TrailingSize);
1760 
1761   // Register the new section.
1762   BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents,
1763                                  NewGdbIndexSize);
1764 }
1765 
1766 std::unique_ptr<DebugBufferVector>
1767 DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher,
1768                                         DWARFVersion Version) {
1769   auto LocBuffer = std::make_unique<DebugBufferVector>();
1770   auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
1771   auto Writer =
1772       std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream));
1773 
1774   uint64_t SectionOffset = 0;
1775   // Add an empty list as the first entry;
1776   if (LocListWritersByCU.empty() ||
1777       LocListWritersByCU.begin()->second.get()->getDwarfVersion() < 5) {
1778     // Should be fine for both DWARF4 and DWARF5?
1779     const char Zeroes[16] = {0};
1780     *LocStream << StringRef(Zeroes, 16);
1781     SectionOffset += 2 * 8;
1782   }
1783 
1784   for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc :
1785        LocListWritersByCU) {
1786     DebugLocWriter *LocWriter = Loc.second.get();
1787     auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter);
1788 
1789     if (Version == DWARFVersion::DWARF5 &&
1790         (!LocListWriter || LocListWriter->getDwarfVersion() <= 4))
1791       continue;
1792 
1793     if (Version == DWARFVersion::DWARFLegacy &&
1794         (LocListWriter && LocListWriter->getDwarfVersion() >= 5))
1795       continue;
1796     if (LocListWriter && (LocListWriter->getDwarfVersion() <= 4 ||
1797                           (LocListWriter->getDwarfVersion() >= 5 &&
1798                            LocListWriter->isSplitDwarf()))) {
1799       SimpleBinaryPatcher *Patcher =
1800           getBinaryDWODebugInfoPatcher(LocListWriter->getCUID());
1801       LocListWriter->finalize(0, *Patcher);
1802       continue;
1803     }
1804     LocWriter->finalize(SectionOffset, DebugInfoPatcher);
1805     std::unique_ptr<DebugBufferVector> CurrCULocationLists =
1806         LocWriter->getBuffer();
1807     *LocStream << *CurrCULocationLists;
1808     SectionOffset += CurrCULocationLists->size();
1809   }
1810 
1811   return LocBuffer;
1812 }
1813 
1814 namespace {
1815 
1816 void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
1817                       Optional<AttrInfo> &HighPCVal) {
1818   LowPCVal = findAttributeInfo(DIE, dwarf::DW_AT_low_pc);
1819   HighPCVal = findAttributeInfo(DIE, dwarf::DW_AT_high_pc);
1820   uint64_t LowPCOffset = LowPCVal->Offset;
1821   uint64_t HighPCOffset = HighPCVal->Offset;
1822   dwarf::Form LowPCForm = LowPCVal->V.getForm();
1823   dwarf::Form HighPCForm = HighPCVal->V.getForm();
1824 
1825   if (LowPCForm != dwarf::DW_FORM_addr &&
1826       LowPCForm != dwarf::DW_FORM_GNU_addr_index &&
1827       LowPCForm != dwarf::DW_FORM_addrx) {
1828     errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE "
1829            << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n";
1830     return;
1831   }
1832   if (HighPCForm != dwarf::DW_FORM_addr && HighPCForm != dwarf::DW_FORM_data8 &&
1833       HighPCForm != dwarf::DW_FORM_data4 &&
1834       HighPCForm != dwarf::DW_FORM_data2 &&
1835       HighPCForm != dwarf::DW_FORM_data1 &&
1836       HighPCForm != dwarf::DW_FORM_udata) {
1837     errs() << "BOLT-WARNING: unexpected high_pc form value. Cannot update DIE "
1838            << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n";
1839     return;
1840   }
1841   if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) &&
1842       LowPCForm != dwarf::DW_FORM_GNU_addr_index &&
1843       LowPCForm != dwarf::DW_FORM_addrx) {
1844     errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. "
1845            << "Cannot update DIE at offset 0x"
1846            << Twine::utohexstr(DIE.getOffset()) << '\n';
1847     return;
1848   }
1849 }
1850 
1851 } // namespace
1852 
1853 void DWARFRewriter::convertToRangesPatchAbbrev(
1854     const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev,
1855     DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) {
1856 
1857   dwarf::Attribute RangeBaseAttribute = dwarf::DW_AT_GNU_ranges_base;
1858   dwarf::Form RangesForm = dwarf::DW_FORM_sec_offset;
1859 
1860   if (Unit.getVersion() >= 5) {
1861     RangeBaseAttribute = dwarf::DW_AT_rnglists_base;
1862     RangesForm = dwarf::DW_FORM_rnglistx;
1863   }
1864   // If we hit this point it means we converted subprogram DIEs from
1865   // low_pc/high_pc into ranges. The CU originally didn't have DW_AT_*_base, so
1866   // we are adding it here.
1867   if (RangesBase)
1868     AbbrevWriter.addAttribute(Unit, Abbrev, RangeBaseAttribute,
1869                               dwarf::DW_FORM_sec_offset);
1870 
1871   // Converting DW_AT_high_pc into DW_AT_ranges.
1872   // For DWARF4 it's DW_FORM_sec_offset.
1873   // For DWARF5 it can be either DW_FORM_sec_offset or DW_FORM_rnglistx.
1874   // For consistency for DWARF5 we always use DW_FORM_rnglistx.
1875   AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc,
1876                                  dwarf::DW_AT_ranges, RangesForm);
1877 }
1878 
1879 void DWARFRewriter::convertToRangesPatchDebugInfo(
1880     DWARFDie DIE, uint64_t RangesSectionOffset,
1881     SimpleBinaryPatcher &DebugInfoPatcher, Optional<uint64_t> RangesBase) {
1882   Optional<AttrInfo> LowPCVal = None;
1883   Optional<AttrInfo> HighPCVal = None;
1884   getRangeAttrData(DIE, LowPCVal, HighPCVal);
1885   uint64_t LowPCOffset = LowPCVal->Offset;
1886   uint64_t HighPCOffset = HighPCVal->Offset;
1887 
1888   std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
1889   uint32_t BaseOffset = 0;
1890   dwarf::Form LowForm = LowPCVal->V.getForm();
1891 
1892   // In DWARF4 for DW_AT_low_pc in binary DW_FORM_addr is used. In the DWO
1893   // section DW_FORM_GNU_addr_index is used. So for if we are converting
1894   // DW_AT_low_pc/DW_AT_high_pc and see DW_FORM_GNU_addr_index. We are
1895   // converting in DWO section, and DW_AT_ranges [DW_FORM_sec_offset] is
1896   // relative to DW_AT_GNU_ranges_base.
1897   if (LowForm == dwarf::DW_FORM_GNU_addr_index) {
1898     // Use ULEB128 for the value.
1899     DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, LowPCVal->Size);
1900     // Ranges are relative to DW_AT_GNU_ranges_base.
1901     BaseOffset = DebugInfoPatcher.getRangeBase();
1902   } else {
1903     // In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or
1904     // DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is
1905     // when it's absent.
1906     if (LowForm == dwarf::DW_FORM_addrx) {
1907       const uint32_t Index =
1908           AddrWriter->getIndexFromAddress(0, *DIE.getDwarfUnit());
1909       DebugInfoPatcher.addUDataPatch(LowPCOffset, Index, LowPCVal->Size);
1910     } else
1911       DebugInfoPatcher.addLE64Patch(LowPCOffset, 0);
1912 
1913     // Original CU didn't have DW_AT_*_base. We converted it's children (or
1914     // dwo), so need to insert it into CU.
1915     if (RangesBase)
1916       reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher)
1917           .insertNewEntry(DIE, *RangesBase);
1918   }
1919 
1920   // HighPC was conveted into DW_AT_ranges.
1921   // For DWARF5 we only access ranges throught index.
1922   if (DIE.getDwarfUnit()->getVersion() >= 5)
1923     DebugInfoPatcher.addUDataPatch(HighPCOffset, RangesSectionOffset,
1924                                    HighPCVal->Size);
1925   else
1926     DebugInfoPatcher.addLE32Patch(
1927         HighPCOffset, RangesSectionOffset - BaseOffset, HighPCVal->Size);
1928 }
1929