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