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