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