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