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