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