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