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