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   Optional<AttrInfo> LowPCAttrInfo =
693       findAttributeInfo(DIE, dwarf::DW_AT_low_pc);
694   if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_ranges)) {
695     // Case 1: The object was already non-contiguous and had DW_AT_ranges.
696     // In this case we simply need to update the value of DW_AT_ranges
697     // and introduce DW_AT_GNU_ranges_base if required.
698     Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, dwarf::DW_AT_ranges);
699     std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
700     DebugInfoPatcher.addLE32Patch(
701         AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(),
702         AttrVal->Size);
703 
704     if (!RangesBase) {
705       if (LowPCAttrInfo &&
706           LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_GNU_addr_index &&
707           LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_addrx)
708         DebugInfoPatcher.addLE64Patch(LowPCAttrInfo->Offset, 0);
709       return;
710     }
711 
712     // Convert DW_AT_low_pc into DW_AT_GNU_ranges_base.
713     if (!LowPCAttrInfo) {
714       errs() << "BOLT-ERROR: skeleton CU at 0x"
715              << Twine::utohexstr(DIE.getOffset())
716              << " does not have DW_AT_GNU_ranges_base or DW_AT_low_pc to"
717                 " convert to update ranges base\n";
718       return;
719     }
720 
721     AbbrevWriter.addAttributePatch(
722         *DIE.getDwarfUnit(), AbbreviationDecl, dwarf::DW_AT_low_pc,
723         dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_indirect);
724     DebugInfoPatcher.addUDataPatch(LowPCAttrInfo->Offset, dwarf::DW_FORM_udata,
725                                    1);
726     DebugInfoPatcher.addUDataPatch(LowPCAttrInfo->Offset + 1, *RangesBase, 7);
727 
728     return;
729   }
730 
731   // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back
732   // to back. Replace with new attributes and patch the DIE.
733   Optional<AttrInfo> HighPCAttrInfo =
734       findAttributeInfo(DIE, dwarf::DW_AT_high_pc);
735   if (LowPCAttrInfo && HighPCAttrInfo) {
736     convertToRangesPatchAbbrev(*DIE.getDwarfUnit(), AbbreviationDecl,
737                                AbbrevWriter, RangesBase);
738     convertToRangesPatchDebugInfo(DIE, DebugRangesOffset, DebugInfoPatcher,
739                                   RangesBase);
740   } else {
741     if (opts::Verbosity >= 1)
742       errs() << "BOLT-ERROR: cannot update ranges for DIE at offset 0x"
743              << Twine::utohexstr(DIE.getOffset()) << '\n';
744   }
745 }
746 
747 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) {
748   ErrorOr<BinarySection &> DbgInfoSection =
749       BC.getUniqueSectionByName(".debug_info");
750   ErrorOr<BinarySection &> TypeInfoSection =
751       BC.getUniqueSectionByName(".debug_types");
752   assert(((BC.DwCtx->getNumTypeUnits() > 0 && TypeInfoSection) ||
753           BC.DwCtx->getNumTypeUnits() == 0) &&
754          "Was not able to retrieve Debug Types section.");
755 
756   // We will be re-writing .debug_info so relocation mechanism doesn't work for
757   // Debug Info Patcher.
758   DebugInfoBinaryPatcher *DebugInfoPatcher = nullptr;
759   if (BC.DwCtx->getNumCompileUnits()) {
760     DbgInfoSection->registerPatcher(std::make_unique<DebugInfoBinaryPatcher>());
761     DebugInfoPatcher =
762         static_cast<DebugInfoBinaryPatcher *>(DbgInfoSection->getPatcher());
763   }
764 
765   // There is no direct connection between CU and TU, but same offsets,
766   // encoded in DW_AT_stmt_list, into .debug_line get modified.
767   // We take advantage of that to map original CU line table offsets to new
768   // ones.
769   std::unordered_map<uint64_t, uint64_t> DebugLineOffsetMap;
770 
771   auto GetStatementListValue = [](DWARFUnit *Unit) {
772     Optional<DWARFFormValue> StmtList =
773         Unit->getUnitDIE().find(dwarf::DW_AT_stmt_list);
774     Optional<uint64_t> Offset = dwarf::toSectionOffset(StmtList);
775     assert(Offset && "Was not able to retreive value of DW_AT_stmt_list.");
776     return *Offset;
777   };
778 
779   const uint64_t Reloc32Type = BC.isAArch64()
780                                    ? static_cast<uint64_t>(ELF::R_AARCH64_ABS32)
781                                    : static_cast<uint64_t>(ELF::R_X86_64_32);
782 
783   for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
784     const unsigned CUID = CU->getOffset();
785     MCSymbol *Label = BC.getDwarfLineTable(CUID).getLabel();
786     if (!Label)
787       continue;
788 
789     Optional<AttrInfo> AttrVal =
790         findAttributeInfo(CU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list);
791     if (!AttrVal)
792       continue;
793 
794     const uint64_t AttributeOffset = AttrVal->Offset;
795     const uint64_t LineTableOffset = Layout.getSymbolOffset(*Label);
796     DebugLineOffsetMap[GetStatementListValue(CU.get())] = LineTableOffset;
797     assert(DbgInfoSection && ".debug_info section must exist");
798     DebugInfoPatcher->addLE32Patch(AttributeOffset, LineTableOffset);
799   }
800 
801   for (const std::unique_ptr<DWARFUnit> &TU : BC.DwCtx->types_section_units()) {
802     DWARFUnit *Unit = TU.get();
803     Optional<AttrInfo> AttrVal =
804         findAttributeInfo(TU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list);
805     if (!AttrVal)
806       continue;
807     const uint64_t AttributeOffset = AttrVal->Offset;
808     auto Iter = DebugLineOffsetMap.find(GetStatementListValue(Unit));
809     assert(Iter != DebugLineOffsetMap.end() &&
810            "Type Unit Updated Line Number Entry does not exist.");
811     TypeInfoSection->addRelocation(AttributeOffset, nullptr, Reloc32Type,
812                                    Iter->second, 0, /*Pending=*/true);
813   }
814 
815   // Set .debug_info as finalized so it won't be skipped over when
816   // we process sections while writing out the new binary. This ensures
817   // that the pending relocations will be processed and not ignored.
818   if (DbgInfoSection)
819     DbgInfoSection->setIsFinalized();
820 
821   if (TypeInfoSection)
822     TypeInfoSection->setIsFinalized();
823 }
824 
825 void DWARFRewriter::finalizeDebugSections(
826     DebugInfoBinaryPatcher &DebugInfoPatcher) {
827   if (StrWriter->isInitialized()) {
828     RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
829     std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents =
830         StrWriter->finalize();
831     BC.registerOrUpdateNoteSection(".debug_str",
832                                    copyByteArray(*DebugStrSectionContents),
833                                    DebugStrSectionContents->size());
834   }
835 
836   std::unique_ptr<DebugBufferVector> RangesSectionContents =
837       RangesSectionWriter->finalize();
838   BC.registerOrUpdateNoteSection(".debug_ranges",
839                                  copyByteArray(*RangesSectionContents),
840                                  RangesSectionContents->size());
841 
842   std::unique_ptr<DebugBufferVector> LocationListSectionContents =
843       makeFinalLocListsSection(DebugInfoPatcher);
844   BC.registerOrUpdateNoteSection(".debug_loc",
845                                  copyByteArray(*LocationListSectionContents),
846                                  LocationListSectionContents->size());
847 
848   // AddrWriter should be finalized after debug_loc since more addresses can be
849   // added there.
850   if (AddrWriter->isInitialized()) {
851     AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
852     BC.registerOrUpdateNoteSection(".debug_addr",
853                                    copyByteArray(AddressSectionContents),
854                                    AddressSectionContents.size());
855     for (auto &CU : BC.DwCtx->compile_units()) {
856       DWARFDie DIE = CU->getUnitDIE();
857       if (Optional<AttrInfo> AttrVal =
858               findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base)) {
859         uint64_t Offset = AddrWriter->getOffset(*CU->getDWOId());
860         DebugInfoPatcher.addLE32Patch(
861             AttrVal->Offset, static_cast<int32_t>(Offset), AttrVal->Size);
862       }
863     }
864   }
865 
866   std::unique_ptr<DebugBufferVector> AbbrevSectionContents =
867       AbbrevWriter->finalize();
868   BC.registerOrUpdateNoteSection(".debug_abbrev",
869                                  copyByteArray(*AbbrevSectionContents),
870                                  AbbrevSectionContents->size());
871 
872   // Update abbreviation offsets for CUs/TUs if they were changed.
873   SimpleBinaryPatcher *DebugTypesPatcher = nullptr;
874   for (auto &Unit : BC.DwCtx->normal_units()) {
875     const uint64_t NewAbbrevOffset =
876         AbbrevWriter->getAbbreviationsOffsetForUnit(*Unit);
877     if (Unit->getAbbreviationsOffset() == NewAbbrevOffset)
878       continue;
879 
880     // DWARFv4
881     // unit_length - 4 bytes
882     // version - 2 bytes
883     // So + 6 to patch debug_abbrev_offset
884     constexpr uint64_t AbbrevFieldOffset = 6;
885     if (!Unit->isTypeUnit()) {
886       DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevFieldOffset,
887                                     static_cast<uint32_t>(NewAbbrevOffset));
888       continue;
889     }
890 
891     if (!DebugTypesPatcher) {
892       ErrorOr<BinarySection &> DebugTypes =
893           BC.getUniqueSectionByName(".debug_types");
894       DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>());
895       DebugTypesPatcher =
896           static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher());
897     }
898     DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevFieldOffset,
899                                     static_cast<uint32_t>(NewAbbrevOffset));
900   }
901 
902   // No more creating new DebugInfoPatches.
903   std::unordered_map<uint32_t, uint32_t> CUMap =
904       DebugInfoPatcher.computeNewOffsets();
905 
906   // Skip .debug_aranges if we are re-generating .gdb_index.
907   if (opts::KeepARanges || !BC.getGdbIndexSection()) {
908     SmallVector<char, 16> ARangesBuffer;
909     raw_svector_ostream OS(ARangesBuffer);
910 
911     auto MAB = std::unique_ptr<MCAsmBackend>(
912         BC.TheTarget->createMCAsmBackend(*BC.STI, *BC.MRI, MCTargetOptions()));
913 
914     ARangesSectionWriter->writeARangesSection(OS, CUMap);
915     const StringRef &ARangesContents = OS.str();
916 
917     BC.registerOrUpdateNoteSection(".debug_aranges",
918                                    copyByteArray(ARangesContents),
919                                    ARangesContents.size());
920   }
921 }
922 
923 // Creates all the data structures necessary for creating MCStreamer.
924 // They are passed by reference because they need to be kept around.
925 // Also creates known debug sections. These are sections handled by
926 // handleDebugDataPatching.
927 using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>;
928 namespace {
929 
930 std::unique_ptr<BinaryContext>
931 createDwarfOnlyBC(const object::ObjectFile &File) {
932   return BinaryContext::createBinaryContext(
933       &File, false,
934       DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore,
935                            nullptr, "", WithColor::defaultErrorHandler,
936                            WithColor::defaultWarningHandler));
937 }
938 
939 StringMap<KnownSectionsEntry>
940 createKnownSectionsMap(const MCObjectFileInfo &MCOFI) {
941   StringMap<KnownSectionsEntry> KnownSectionsTemp = {
942       {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
943       {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
944       {"debug_str_offsets.dwo",
945        {MCOFI.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS}},
946       {"debug_str.dwo", {MCOFI.getDwarfStrDWOSection(), DW_SECT_EXT_unknown}},
947       {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
948       {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
949       {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}}};
950   return KnownSectionsTemp;
951 }
952 
953 StringRef getSectionName(const SectionRef &Section) {
954   Expected<StringRef> SectionName = Section.getName();
955   assert(SectionName && "Invalid section name.");
956   StringRef Name = *SectionName;
957   Name = Name.substr(Name.find_first_not_of("._"));
958   return Name;
959 }
960 
961 // Exctracts an appropriate slice if input is DWP.
962 // Applies patches or overwrites the section.
963 Optional<StringRef>
964 updateDebugData(std::string &Storage, const SectionRef &Section,
965                 const StringMap<KnownSectionsEntry> &KnownSections,
966                 MCStreamer &Streamer, DWARFRewriter &Writer,
967                 const DWARFUnitIndex::Entry *DWOEntry, uint64_t DWOId,
968                 std::unique_ptr<DebugBufferVector> &OutputBuffer) {
969   auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher,
970                         StringRef Data) -> StringRef {
971     Patcher->computeNewOffsets();
972     Storage = Patcher->patchBinary(Data);
973     return StringRef(Storage.c_str(), Storage.size());
974   };
975 
976   using DWOSectionContribution =
977       const DWARFUnitIndex::Entry::SectionContribution;
978   auto getSliceData = [&](const DWARFUnitIndex::Entry *DWOEntry,
979                           StringRef OutData, DWARFSectionKind Sec,
980                           uint32_t &DWPOffset) -> StringRef {
981     if (DWOEntry) {
982       DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec);
983       DWPOffset = DWOContrubution->Offset;
984       OutData = OutData.substr(DWPOffset, DWOContrubution->Length);
985     }
986     return OutData;
987   };
988 
989   StringRef Name = getSectionName(Section);
990   auto SectionIter = KnownSections.find(Name);
991   if (SectionIter == KnownSections.end())
992     return None;
993   Streamer.SwitchSection(SectionIter->second.first);
994   Expected<StringRef> Contents = Section.getContents();
995   assert(Contents && "Invalid contents.");
996   StringRef OutData = *Contents;
997   uint32_t DWPOffset = 0;
998 
999   switch (SectionIter->second.second) {
1000   default: {
1001     if (!Name.equals("debug_str.dwo"))
1002       errs() << "BOLT-WARNING: Unsupported Debug section: " << Name << "\n";
1003     return OutData;
1004   }
1005   case DWARFSectionKind::DW_SECT_INFO: {
1006     OutData = getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_INFO,
1007                            DWPOffset);
1008     DebugInfoBinaryPatcher *Patcher = llvm::cast<DebugInfoBinaryPatcher>(
1009         Writer.getBinaryDWODebugInfoPatcher(DWOId));
1010     return applyPatch(Patcher, OutData);
1011   }
1012   case DWARFSectionKind::DW_SECT_EXT_TYPES: {
1013     return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_EXT_TYPES,
1014                         DWPOffset);
1015   }
1016   case DWARFSectionKind::DW_SECT_STR_OFFSETS: {
1017     return getSliceData(DWOEntry, OutData,
1018                         DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset);
1019   }
1020   case DWARFSectionKind::DW_SECT_ABBREV: {
1021     DebugAbbrevWriter *AbbrevWriter = Writer.getBinaryDWOAbbrevWriter(DWOId);
1022     OutputBuffer = AbbrevWriter->finalize();
1023     // Creating explicit StringRef here, otherwise
1024     // with impicit conversion it will take null byte as end of
1025     // string.
1026     return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()),
1027                      OutputBuffer->size());
1028   }
1029   case DWARFSectionKind::DW_SECT_EXT_LOC: {
1030     DebugLocWriter *LocWriter = Writer.getDebugLocWriter(DWOId);
1031     OutputBuffer = LocWriter->getBuffer();
1032     // Creating explicit StringRef here, otherwise
1033     // with impicit conversion it will take null byte as end of
1034     // string.
1035     return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()),
1036                      OutputBuffer->size());
1037   }
1038   case DWARFSectionKind::DW_SECT_LINE: {
1039     return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_LINE,
1040                         DWPOffset);
1041   }
1042   }
1043 }
1044 
1045 } // namespace
1046 
1047 void DWARFRewriter::writeDWP(
1048     std::unordered_map<uint64_t, std::string> &DWOIdToName) {
1049   SmallString<0> OutputNameStr;
1050   StringRef OutputName;
1051   if (opts::DwarfOutputPath.empty()) {
1052     OutputName =
1053         Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr);
1054   } else {
1055     StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename);
1056     OutputName = Twine(opts::DwarfOutputPath)
1057                      .concat("/")
1058                      .concat(ExeFileName)
1059                      .concat(".dwp")
1060                      .toStringRef(OutputNameStr);
1061     errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will "
1062               "possibly be written to another location that is not the same as "
1063               "the executable\n";
1064   }
1065   std::error_code EC;
1066   std::unique_ptr<ToolOutputFile> Out =
1067       std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None);
1068 
1069   const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile();
1070   std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File);
1071   std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(Out->os());
1072   const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo();
1073   StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI);
1074   MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
1075   MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
1076 
1077   // Data Structures for DWP book keeping
1078   // Size of array corresponds to the number of sections supported by DWO format
1079   // in DWARF4/5.
1080   uint32_t ContributionOffsets[8] = {};
1081   std::deque<SmallString<32>> UncompressedSections;
1082   DWPStringPool Strings(*Streamer, StrSection);
1083   MapVector<uint64_t, UnitIndexEntry> IndexEntries;
1084   constexpr uint32_t IndexVersion = 2;
1085 
1086   // Setup DWP code once.
1087   DWARFContext *DWOCtx = BC.getDWOContext();
1088   const DWARFUnitIndex *CUIndex = nullptr;
1089   bool IsDWP = false;
1090   if (DWOCtx) {
1091     CUIndex = &DWOCtx->getCUIndex();
1092     IsDWP = !CUIndex->getRows().empty();
1093   }
1094 
1095   for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
1096     Optional<uint64_t> DWOId = CU->getDWOId();
1097     if (!DWOId)
1098       continue;
1099 
1100     // Skipping CUs that we failed to load.
1101     Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId);
1102     if (!DWOCU)
1103       continue;
1104 
1105     assert(CU->getVersion() == 4 && "For DWP output only DWARF4 is supported");
1106     UnitIndexEntry CurEntry = {};
1107     CurEntry.DWOName =
1108         dwarf::toString(CU->getUnitDIE().find(
1109                             {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
1110                         "");
1111     const char *Name = CU->getUnitDIE().getShortName();
1112     if (Name)
1113       CurEntry.Name = Name;
1114     StringRef CurStrSection;
1115     StringRef CurStrOffsetSection;
1116 
1117     // This maps each section contained in this file to its length.
1118     // This information is later on used to calculate the contributions,
1119     // i.e. offset and length, of each compile/type unit to a section.
1120     std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
1121 
1122     const DWARFUnitIndex::Entry *DWOEntry = nullptr;
1123     if (IsDWP)
1124       DWOEntry = CUIndex->getFromHash(*DWOId);
1125 
1126     bool StrSectionWrittenOut = false;
1127     const object::ObjectFile *DWOFile =
1128         (*DWOCU)->getContext().getDWARFObj().getFile();
1129     for (const SectionRef &Section : DWOFile->sections()) {
1130       std::string Storage = "";
1131       std::unique_ptr<DebugBufferVector> OutputData;
1132       Optional<StringRef> TOutData =
1133           updateDebugData(Storage, Section, KnownSections, *Streamer, *this,
1134                           DWOEntry, *DWOId, OutputData);
1135       if (!TOutData)
1136         continue;
1137 
1138       StringRef OutData = *TOutData;
1139       StringRef Name = getSectionName(Section);
1140       if (Name.equals("debug_str.dwo")) {
1141         CurStrSection = OutData;
1142       } else {
1143         // Since handleDebugDataPatching returned true, we already know this is
1144         // a known section.
1145         auto SectionIter = KnownSections.find(Name);
1146         if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS)
1147           CurStrOffsetSection = OutData;
1148         else
1149           Streamer->emitBytes(OutData);
1150         auto Index =
1151             getContributionIndex(SectionIter->second.second, IndexVersion);
1152         CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
1153         CurEntry.Contributions[Index].Length = OutData.size();
1154         ContributionOffsets[Index] += CurEntry.Contributions[Index].Length;
1155       }
1156 
1157       // Strings are combined in to a new string section, and de-duplicated
1158       // based on hash.
1159       if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() &&
1160           !CurStrSection.empty()) {
1161         writeStringsAndOffsets(*Streamer.get(), Strings, StrOffsetSection,
1162                                CurStrSection, CurStrOffsetSection,
1163                                CU->getVersion());
1164         StrSectionWrittenOut = true;
1165       }
1166     }
1167     CompileUnitIdentifiers CUI{*DWOId, CurEntry.Name.c_str(),
1168                                CurEntry.DWOName.c_str()};
1169     auto P = IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry));
1170     if (!P.second) {
1171       Error Err = buildDuplicateError(*P.first, CUI, "");
1172       errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n";
1173       return;
1174     }
1175   }
1176 
1177   // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
1178   // section does not exist, so no need to do anything about this.
1179   ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0;
1180   writeIndex(*Streamer.get(), MCOFI.getDwarfCUIndexSection(),
1181              ContributionOffsets, IndexEntries, IndexVersion);
1182 
1183   Streamer->Finish();
1184   Out->keep();
1185 }
1186 
1187 void DWARFRewriter::writeDWOFiles(
1188     std::unordered_map<uint64_t, std::string> &DWOIdToName) {
1189   // Setup DWP code once.
1190   DWARFContext *DWOCtx = BC.getDWOContext();
1191   const DWARFUnitIndex *CUIndex = nullptr;
1192   bool IsDWP = false;
1193   if (DWOCtx) {
1194     CUIndex = &DWOCtx->getCUIndex();
1195     IsDWP = !CUIndex->getRows().empty();
1196   }
1197 
1198   for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
1199     Optional<uint64_t> DWOId = CU->getDWOId();
1200     if (!DWOId)
1201       continue;
1202 
1203     // Skipping CUs that we failed to load.
1204     Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId);
1205     if (!DWOCU)
1206       continue;
1207 
1208     std::string CompDir = opts::DwarfOutputPath.empty()
1209                               ? CU->getCompilationDir()
1210                               : opts::DwarfOutputPath.c_str();
1211     std::string ObjectName = getDWOName(*CU.get(), nullptr, DWOIdToName);
1212     auto FullPath = CompDir.append("/").append(ObjectName);
1213 
1214     std::error_code EC;
1215     std::unique_ptr<ToolOutputFile> TempOut =
1216         std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None);
1217 
1218     const DWARFUnitIndex::Entry *DWOEntry = nullptr;
1219     if (IsDWP)
1220       DWOEntry = CUIndex->getFromHash(*DWOId);
1221 
1222     const object::ObjectFile *File =
1223         (*DWOCU)->getContext().getDWARFObj().getFile();
1224     std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File);
1225     std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(TempOut->os());
1226     StringMap<KnownSectionsEntry> KnownSections =
1227         createKnownSectionsMap(*Streamer->getContext().getObjectFileInfo());
1228 
1229     for (const SectionRef &Section : File->sections()) {
1230       std::string Storage = "";
1231       std::unique_ptr<DebugBufferVector> OutputData;
1232       if (Optional<StringRef> OutData =
1233               updateDebugData(Storage, Section, KnownSections, *Streamer, *this,
1234                               DWOEntry, *DWOId, OutputData))
1235         Streamer->emitBytes(*OutData);
1236     }
1237     Streamer->Finish();
1238     TempOut->keep();
1239   }
1240 }
1241 
1242 void DWARFRewriter::updateGdbIndexSection() {
1243   if (!BC.getGdbIndexSection())
1244     return;
1245 
1246   // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
1247   // for .gdb_index section format.
1248 
1249   StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents();
1250 
1251   const char *Data = GdbIndexContents.data();
1252 
1253   // Parse the header.
1254   const uint32_t Version = read32le(Data);
1255   if (Version != 7 && Version != 8) {
1256     errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n";
1257     exit(1);
1258   }
1259 
1260   // Some .gdb_index generators use file offsets while others use section
1261   // offsets. Hence we can only rely on offsets relative to each other,
1262   // and ignore their absolute values.
1263   const uint32_t CUListOffset = read32le(Data + 4);
1264   const uint32_t CUTypesOffset = read32le(Data + 8);
1265   const uint32_t AddressTableOffset = read32le(Data + 12);
1266   const uint32_t SymbolTableOffset = read32le(Data + 16);
1267   const uint32_t ConstantPoolOffset = read32le(Data + 20);
1268   Data += 24;
1269 
1270   // Map CUs offsets to indices and verify existing index table.
1271   std::map<uint32_t, uint32_t> OffsetToIndexMap;
1272   const uint32_t CUListSize = CUTypesOffset - CUListOffset;
1273   const unsigned NumCUs = BC.DwCtx->getNumCompileUnits();
1274   if (CUListSize != NumCUs * 16) {
1275     errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n";
1276     exit(1);
1277   }
1278   for (unsigned Index = 0; Index < NumCUs; ++Index, Data += 16) {
1279     const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index);
1280     const uint64_t Offset = read64le(Data);
1281     if (CU->getOffset() != Offset) {
1282       errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n";
1283       exit(1);
1284     }
1285 
1286     OffsetToIndexMap[Offset] = Index;
1287   }
1288 
1289   // Ignore old address table.
1290   const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset;
1291   // Move Data to the beginning of symbol table.
1292   Data += SymbolTableOffset - CUTypesOffset;
1293 
1294   // Calculate the size of the new address table.
1295   uint32_t NewAddressTableSize = 0;
1296   for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) {
1297     const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second;
1298     NewAddressTableSize += Ranges.size() * 20;
1299   }
1300 
1301   // Difference between old and new table (and section) sizes.
1302   // Could be negative.
1303   int32_t Delta = NewAddressTableSize - OldAddressTableSize;
1304 
1305   size_t NewGdbIndexSize = GdbIndexContents.size() + Delta;
1306 
1307   // Free'd by ExecutableFileMemoryManager.
1308   auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize];
1309   uint8_t *Buffer = NewGdbIndexContents;
1310 
1311   write32le(Buffer, Version);
1312   write32le(Buffer + 4, CUListOffset);
1313   write32le(Buffer + 8, CUTypesOffset);
1314   write32le(Buffer + 12, AddressTableOffset);
1315   write32le(Buffer + 16, SymbolTableOffset + Delta);
1316   write32le(Buffer + 20, ConstantPoolOffset + Delta);
1317   Buffer += 24;
1318 
1319   // Copy over CU list and types CU list.
1320   memcpy(Buffer, GdbIndexContents.data() + 24,
1321          AddressTableOffset - CUListOffset);
1322   Buffer += AddressTableOffset - CUListOffset;
1323 
1324   // Generate new address table.
1325   for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair :
1326        ARangesSectionWriter->getCUAddressRanges()) {
1327     const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first];
1328     const DebugAddressRangesVector &Ranges = CURangesPair.second;
1329     for (const DebugAddressRange &Range : Ranges) {
1330       write64le(Buffer, Range.LowPC);
1331       write64le(Buffer + 8, Range.HighPC);
1332       write32le(Buffer + 16, CUIndex);
1333       Buffer += 20;
1334     }
1335   }
1336 
1337   const size_t TrailingSize =
1338       GdbIndexContents.data() + GdbIndexContents.size() - Data;
1339   assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize &&
1340          "size calculation error");
1341 
1342   // Copy over the rest of the original data.
1343   memcpy(Buffer, Data, TrailingSize);
1344 
1345   // Register the new section.
1346   BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents,
1347                                  NewGdbIndexSize);
1348 }
1349 
1350 void DWARFRewriter::convertToRanges(DWARFDie DIE,
1351                                     const DebugAddressRangesVector &Ranges,
1352                                     SimpleBinaryPatcher &DebugInfoPatcher) {
1353   uint64_t RangesSectionOffset;
1354   if (Ranges.empty())
1355     RangesSectionOffset = RangesSectionWriter->getEmptyRangesOffset();
1356   else
1357     RangesSectionOffset = RangesSectionWriter->addRanges(Ranges);
1358 
1359   convertToRangesPatchDebugInfo(DIE, RangesSectionOffset, DebugInfoPatcher);
1360 }
1361 
1362 void DWARFRewriter::convertPending(const DWARFUnit &Unit,
1363                                    const DWARFAbbreviationDeclaration *Abbrev,
1364                                    SimpleBinaryPatcher &DebugInfoPatcher,
1365                                    DebugAbbrevWriter &AbbrevWriter) {
1366   if (ConvertedRangesAbbrevs.count(Abbrev))
1367     return;
1368 
1369   convertToRangesPatchAbbrev(Unit, Abbrev, AbbrevWriter);
1370 
1371   auto I = PendingRanges.find(Abbrev);
1372   if (I != PendingRanges.end()) {
1373     for (std::pair<DWARFDieWrapper, DebugAddressRange> &Pair : I->second)
1374       convertToRanges(Pair.first, {Pair.second}, DebugInfoPatcher);
1375     PendingRanges.erase(I);
1376   }
1377 
1378   ConvertedRangesAbbrevs.emplace(Abbrev);
1379 }
1380 
1381 void DWARFRewriter::addToPendingRanges(
1382     const DWARFAbbreviationDeclaration *Abbrev, DWARFDie DIE,
1383     DebugAddressRangesVector &FunctionRanges, Optional<uint64_t> DWOId) {
1384   Optional<DWARFFormValue> LowPcValue = DIE.find(dwarf::DW_AT_low_pc);
1385   Optional<DWARFFormValue> HighPcValue = DIE.find(dwarf::DW_AT_high_pc);
1386   if (LowPcValue &&
1387       LowPcValue->getForm() == dwarf::Form::DW_FORM_GNU_addr_index) {
1388     assert(DWOId && "Invalid DWO ID.");
1389     (void)DWOId;
1390     assert(HighPcValue && "Low PC exists, but not High PC.");
1391     (void)HighPcValue;
1392     uint64_t IndexL = LowPcValue->getRawUValue();
1393     uint64_t IndexH = HighPcValue->getRawUValue();
1394     for (auto Address : FunctionRanges) {
1395       AddrWriter->addIndexAddress(Address.LowPC, IndexL, *DWOId);
1396       // 2.17.2
1397       // If the value of the DW_AT_high_pc is of class address, it is the
1398       // relocated address of the first location past the last instruction
1399       // associated with the entity; if it is of class constant, the value is
1400       // an unsigned integer offset which when added to the low PC gives the
1401       // address of the first location past the last instruction associated
1402       // with the entity.
1403       if (!HighPcValue->isFormClass(DWARFFormValue::FC_Constant))
1404         AddrWriter->addIndexAddress(Address.HighPC, IndexH, *DWOId);
1405     }
1406   }
1407   PendingRanges[Abbrev].emplace_back(
1408       std::make_pair(DWARFDieWrapper(DIE), FunctionRanges.front()));
1409 }
1410 
1411 std::unique_ptr<DebugBufferVector>
1412 DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher) {
1413   auto LocBuffer = std::make_unique<DebugBufferVector>();
1414   auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
1415   auto Writer =
1416       std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream));
1417 
1418   uint64_t SectionOffset = 0;
1419 
1420   // Add an empty list as the first entry;
1421   const char Zeroes[16] = {0};
1422   *LocStream << StringRef(Zeroes, 16);
1423   SectionOffset += 2 * 8;
1424 
1425   for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc :
1426        LocListWritersByCU) {
1427     DebugLocWriter *LocWriter = Loc.second.get();
1428     if (auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter)) {
1429       SimpleBinaryPatcher *Patcher =
1430           getBinaryDWODebugInfoPatcher(LocListWriter->getDWOID());
1431       LocListWriter->finalize(0, *Patcher);
1432       continue;
1433     }
1434     LocWriter->finalize(SectionOffset, DebugInfoPatcher);
1435     std::unique_ptr<DebugBufferVector> CurrCULocationLists =
1436         LocWriter->getBuffer();
1437     *LocStream << *CurrCULocationLists;
1438     SectionOffset += CurrCULocationLists->size();
1439   }
1440 
1441   return LocBuffer;
1442 }
1443 
1444 void DWARFRewriter::flushPendingRanges(SimpleBinaryPatcher &DebugInfoPatcher) {
1445   for (std::pair<const DWARFAbbreviationDeclaration *const,
1446                  std::vector<std::pair<DWARFDieWrapper, DebugAddressRange>>>
1447            &I : PendingRanges)
1448     for (std::pair<DWARFDieWrapper, DebugAddressRange> &RangePair : I.second)
1449       patchLowHigh(RangePair.first, RangePair.second, DebugInfoPatcher);
1450   clearList(PendingRanges);
1451 }
1452 
1453 namespace {
1454 
1455 void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
1456                       Optional<AttrInfo> &HighPCVal) {
1457   LowPCVal = findAttributeInfo(DIE, dwarf::DW_AT_low_pc);
1458   HighPCVal = findAttributeInfo(DIE, dwarf::DW_AT_high_pc);
1459   uint64_t LowPCOffset = LowPCVal->Offset;
1460   uint64_t HighPCOffset = HighPCVal->Offset;
1461   dwarf::Form LowPCForm = LowPCVal->V.getForm();
1462   dwarf::Form HighPCForm = HighPCVal->V.getForm();
1463 
1464   if (LowPCForm != dwarf::DW_FORM_addr &&
1465       LowPCForm != dwarf::DW_FORM_GNU_addr_index) {
1466     errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE "
1467            << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n";
1468     return;
1469   }
1470   if (HighPCForm != dwarf::DW_FORM_addr && HighPCForm != dwarf::DW_FORM_data8 &&
1471       HighPCForm != dwarf::DW_FORM_data4 &&
1472       HighPCForm != dwarf::DW_FORM_data2 &&
1473       HighPCForm != dwarf::DW_FORM_data1 &&
1474       HighPCForm != dwarf::DW_FORM_udata) {
1475     errs() << "BOLT-WARNING: unexpected high_pc form value. Cannot update DIE "
1476            << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n";
1477     return;
1478   }
1479   if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) &&
1480       LowPCForm != dwarf::DW_FORM_GNU_addr_index) {
1481     errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. "
1482            << "Cannot update DIE at offset 0x"
1483            << Twine::utohexstr(DIE.getOffset()) << '\n';
1484     return;
1485   }
1486 }
1487 
1488 } // namespace
1489 
1490 void DWARFRewriter::patchLowHigh(DWARFDie DIE, DebugAddressRange Range,
1491                                  SimpleBinaryPatcher &DebugInfoPatcher) {
1492   Optional<AttrInfo> LowPCVal = None;
1493   Optional<AttrInfo> HighPCVal = None;
1494   getRangeAttrData(DIE, LowPCVal, HighPCVal);
1495   uint64_t LowPCOffset = LowPCVal->Offset;
1496   uint64_t HighPCOffset = HighPCVal->Offset;
1497   auto *TempDebugPatcher = &DebugInfoPatcher;
1498   if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) {
1499     DWARFUnit *Unit = DIE.getDwarfUnit();
1500     assert(Unit->isDWOUnit() && "DW_FORM_GNU_addr_index not part of DWO.");
1501     uint32_t AddressIndex =
1502         AddrWriter->getIndexFromAddress(Range.LowPC, *Unit->getDWOId());
1503     TempDebugPatcher = getBinaryDWODebugInfoPatcher(*Unit->getDWOId());
1504     TempDebugPatcher->addUDataPatch(LowPCOffset, AddressIndex,
1505                                     std::abs(int(HighPCOffset - LowPCOffset)));
1506     // TODO: In DWARF5 support ULEB128 for high_pc
1507   } else {
1508     TempDebugPatcher->addLE64Patch(LowPCOffset, Range.LowPC);
1509   }
1510 
1511   uint64_t HighPC = Range.HighPC;
1512   // The DW_FORM_data* is delta between high and low pc
1513   if (HighPCVal->V.getForm() != dwarf::Form::DW_FORM_addr)
1514     HighPC -= Range.LowPC;
1515 
1516   if (isHighPcFormEightBytes(HighPCVal->V.getForm()))
1517     TempDebugPatcher->addLE64Patch(HighPCOffset, HighPC);
1518   else
1519     TempDebugPatcher->addLE32Patch(HighPCOffset, HighPC);
1520 }
1521 
1522 void DWARFRewriter::convertToRangesPatchAbbrev(
1523     const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev,
1524     DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) {
1525   auto getAttributeForm = [&Abbrev](const dwarf::Attribute Attr) {
1526     Optional<uint32_t> Index = Abbrev->findAttributeIndex(Attr);
1527     assert(Index && "attribute not found");
1528     return Abbrev->getFormByIndex(*Index);
1529   };
1530   dwarf::Form LowPCForm = getAttributeForm(dwarf::DW_AT_low_pc);
1531 
1532   // DW_FORM_GNU_addr_index is already variable encoding so nothing to do
1533   // there.
1534   if (RangesBase) {
1535     assert(LowPCForm != dwarf::DW_FORM_GNU_addr_index);
1536     AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_low_pc,
1537                                    dwarf::DW_AT_GNU_ranges_base,
1538                                    dwarf::DW_FORM_sec_offset);
1539   }
1540 
1541   AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc,
1542                                  dwarf::DW_AT_ranges,
1543                                  dwarf::DW_FORM_sec_offset);
1544 }
1545 
1546 void DWARFRewriter::convertToRangesPatchDebugInfo(
1547     DWARFDie DIE, uint64_t RangesSectionOffset,
1548     SimpleBinaryPatcher &DebugInfoPatcher, Optional<uint64_t> RangesBase) {
1549   Optional<AttrInfo> LowPCVal = None;
1550   Optional<AttrInfo> HighPCVal = None;
1551   getRangeAttrData(DIE, LowPCVal, HighPCVal);
1552   uint64_t LowPCOffset = LowPCVal->Offset;
1553   uint64_t HighPCOffset = HighPCVal->Offset;
1554 
1555   std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
1556   uint32_t BaseOffset = 0;
1557   if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) {
1558     // Use ULEB128 for the value.
1559     DebugInfoPatcher.addUDataPatch(LowPCOffset, 0,
1560                                    std::abs(int(HighPCOffset - LowPCOffset)));
1561     // Ranges are relative to DW_AT_GNU_ranges_base.
1562     BaseOffset = DebugInfoPatcher.getRangeBase();
1563   } else {
1564     // If case DW_AT_low_pc was converted into DW_AT_GNU_ranges_base
1565     if (RangesBase)
1566       DebugInfoPatcher.addLE32Patch(LowPCOffset, *RangesBase, 8);
1567     else
1568       DebugInfoPatcher.addLE64Patch(LowPCOffset, 0);
1569   }
1570   DebugInfoPatcher.addLE32Patch(HighPCOffset, RangesSectionOffset - BaseOffset,
1571                                 HighPCVal->Size);
1572 }
1573