xref: /llvm-project/bolt/lib/Core/DebugData.cpp (revision be2f67c4d87deb513ba200ab3f4dba385faf709a)
1 //===- bolt/Core/DebugData.cpp - Debugging information handling -----------===//
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 // This file implements functions and classes for handling debug info.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "bolt/Core/DebugData.h"
14 #include "bolt/Core/BinaryContext.h"
15 #include "bolt/Rewrite/RewriteInstance.h"
16 #include "bolt/Utils/Utils.h"
17 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
20 #include "llvm/MC/MCAssembler.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCObjectStreamer.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/EndianStream.h"
25 #include "llvm/Support/LEB128.h"
26 #include "llvm/Support/SHA1.h"
27 #include <algorithm>
28 #include <cassert>
29 #include <cstdint>
30 #include <functional>
31 #include <limits>
32 #include <unordered_map>
33 #include <vector>
34 
35 #define DEBUG_TYPE "bolt-debug-info"
36 
37 namespace opts {
38 extern llvm::cl::opt<unsigned> Verbosity;
39 } // namespace opts
40 
41 namespace llvm {
42 class MCSymbol;
43 
44 namespace bolt {
45 
46 std::optional<AttrInfo>
47 findAttributeInfo(const DWARFDie DIE,
48                   const DWARFAbbreviationDeclaration *AbbrevDecl,
49                   uint32_t Index) {
50   const DWARFUnit &U = *DIE.getDwarfUnit();
51   uint64_t Offset =
52       AbbrevDecl->getAttributeOffsetFromIndex(Index, DIE.getOffset(), U);
53   std::optional<DWARFFormValue> Value =
54       AbbrevDecl->getAttributeValueFromOffset(Index, Offset, U);
55   if (!Value)
56     return std::nullopt;
57   // AttributeSpec
58   const DWARFAbbreviationDeclaration::AttributeSpec *AttrVal =
59       AbbrevDecl->attributes().begin() + Index;
60   uint32_t ValSize = 0;
61   std::optional<int64_t> ValSizeOpt = AttrVal->getByteSize(U);
62   if (ValSizeOpt) {
63     ValSize = static_cast<uint32_t>(*ValSizeOpt);
64   } else {
65     DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
66     uint64_t NewOffset = Offset;
67     DWARFFormValue::skipValue(Value->getForm(), DebugInfoData, &NewOffset,
68                               U.getFormParams());
69     // This includes entire size of the entry, which might not be just the
70     // encoding part. For example for DW_AT_loc it will include expression
71     // location.
72     ValSize = NewOffset - Offset;
73   }
74   return AttrInfo{*Value, DIE.getAbbreviationDeclarationPtr(), Offset, ValSize};
75 }
76 
77 std::optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
78                                           dwarf::Attribute Attr) {
79   if (!DIE.isValid())
80     return std::nullopt;
81   const DWARFAbbreviationDeclaration *AbbrevDecl =
82       DIE.getAbbreviationDeclarationPtr();
83   if (!AbbrevDecl)
84     return std::nullopt;
85   std::optional<uint32_t> Index = AbbrevDecl->findAttributeIndex(Attr);
86   if (!Index)
87     return std::nullopt;
88   return findAttributeInfo(DIE, AbbrevDecl, *Index);
89 }
90 
91 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0};
92 
93 LLVM_ATTRIBUTE_UNUSED
94 static void printLE64(const std::string &S) {
95   for (uint32_t I = 0, Size = S.size(); I < Size; ++I) {
96     errs() << Twine::utohexstr(S[I]);
97     errs() << Twine::utohexstr((int8_t)S[I]);
98   }
99   errs() << "\n";
100 }
101 
102 // Writes address ranges to Writer as pairs of 64-bit (address, size).
103 // If RelativeRange is true, assumes the address range to be written must be of
104 // the form (begin address, range size), otherwise (begin address, end address).
105 // Terminates the list by writing a pair of two zeroes.
106 // Returns the number of written bytes.
107 static uint64_t
108 writeAddressRanges(raw_svector_ostream &Stream,
109                    const DebugAddressRangesVector &AddressRanges,
110                    const bool WriteRelativeRanges = false) {
111   for (const DebugAddressRange &Range : AddressRanges) {
112     support::endian::write(Stream, Range.LowPC, support::little);
113     support::endian::write(
114         Stream, WriteRelativeRanges ? Range.HighPC - Range.LowPC : Range.HighPC,
115         support::little);
116   }
117   // Finish with 0 entries.
118   support::endian::write(Stream, 0ULL, support::little);
119   support::endian::write(Stream, 0ULL, support::little);
120   return AddressRanges.size() * 16 + 16;
121 }
122 
123 DebugRangesSectionWriter::DebugRangesSectionWriter() {
124   RangesBuffer = std::make_unique<DebugBufferVector>();
125   RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer);
126 
127   // Add an empty range as the first entry;
128   SectionOffset +=
129       writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
130   Kind = RangesWriterKind::DebugRangesWriter;
131 }
132 
133 uint64_t DebugRangesSectionWriter::addRanges(
134     DebugAddressRangesVector &&Ranges,
135     std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
136   if (Ranges.empty())
137     return getEmptyRangesOffset();
138 
139   const auto RI = CachedRanges.find(Ranges);
140   if (RI != CachedRanges.end())
141     return RI->second;
142 
143   const uint64_t EntryOffset = addRanges(Ranges);
144   CachedRanges.emplace(std::move(Ranges), EntryOffset);
145 
146   return EntryOffset;
147 }
148 
149 uint64_t DebugRangesSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
150   if (Ranges.empty())
151     return getEmptyRangesOffset();
152 
153   // Reading the SectionOffset and updating it should be atomic to guarantee
154   // unique and correct offsets in patches.
155   std::lock_guard<std::mutex> Lock(WriterMutex);
156   const uint32_t EntryOffset = SectionOffset;
157   SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges);
158 
159   return EntryOffset;
160 }
161 
162 uint64_t DebugRangesSectionWriter::getSectionOffset() {
163   std::lock_guard<std::mutex> Lock(WriterMutex);
164   return SectionOffset;
165 }
166 
167 DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
168 
169 uint64_t DebugRangeListsSectionWriter::addRanges(
170     DebugAddressRangesVector &&Ranges,
171     std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
172   return addRanges(Ranges);
173 }
174 
175 struct LocListsRangelistsHeader {
176   UnitLengthType UnitLength; // Size of loclist entris section, not including
177                              // size of header.
178   VersionType Version;
179   AddressSizeType AddressSize;
180   SegmentSelectorType SegmentSelector;
181   OffsetEntryCountType OffsetEntryCount;
182 };
183 
184 static std::unique_ptr<DebugBufferVector>
185 getDWARF5Header(const LocListsRangelistsHeader &Header) {
186   std::unique_ptr<DebugBufferVector> HeaderBuffer =
187       std::make_unique<DebugBufferVector>();
188   std::unique_ptr<raw_svector_ostream> HeaderStream =
189       std::make_unique<raw_svector_ostream>(*HeaderBuffer);
190 
191   // 7.29 length of the set of entries for this compilation unit, not including
192   // the length field itself
193   const uint32_t HeaderSize =
194       getDWARF5RngListLocListHeaderSize() - sizeof(UnitLengthType);
195 
196   support::endian::write(*HeaderStream, Header.UnitLength + HeaderSize,
197                          support::little);
198   support::endian::write(*HeaderStream, Header.Version, support::little);
199   support::endian::write(*HeaderStream, Header.AddressSize, support::little);
200   support::endian::write(*HeaderStream, Header.SegmentSelector,
201                          support::little);
202   support::endian::write(*HeaderStream, Header.OffsetEntryCount,
203                          support::little);
204   return HeaderBuffer;
205 }
206 
207 struct OffsetEntry {
208   uint32_t Index;
209   uint32_t StartOffset;
210   uint32_t EndOffset;
211 };
212 template <typename DebugVector, typename ListEntry, typename DebugAddressEntry>
213 static bool emitWithBase(raw_ostream &OS, const DebugVector &Entries,
214                          DebugAddrWriter &AddrWriter, DWARFUnit &CU,
215                          uint32_t &Index, const ListEntry BaseAddressx,
216                          const ListEntry OffsetPair, const ListEntry EndOfList,
217                          const std::function<void(uint32_t)> &Func) {
218   if (Entries.size() < 2)
219     return false;
220   uint64_t Base = Entries[Index].LowPC;
221   std::vector<OffsetEntry> Offsets;
222   uint8_t TempBuffer[64];
223   while (Index < Entries.size()) {
224     const DebugAddressEntry &Entry = Entries[Index];
225     if (Entry.LowPC == 0)
226       break;
227     assert(Base <= Entry.LowPC && "Entry base is higher than low PC");
228     uint32_t StartOffset = Entry.LowPC - Base;
229     uint32_t EndOffset = Entry.HighPC - Base;
230     if (encodeULEB128(EndOffset, TempBuffer) > 2)
231       break;
232     Offsets.push_back({Index, StartOffset, EndOffset});
233     ++Index;
234   }
235 
236   if (Offsets.size() < 2) {
237     Index -= Offsets.size();
238     return false;
239   }
240 
241   support::endian::write(OS, static_cast<uint8_t>(BaseAddressx),
242                          support::little);
243   uint32_t BaseIndex = AddrWriter.getIndexFromAddress(Base, CU);
244   encodeULEB128(BaseIndex, OS);
245   for (auto &OffsetEntry : Offsets) {
246     support::endian::write(OS, static_cast<uint8_t>(OffsetPair),
247                            support::little);
248     encodeULEB128(OffsetEntry.StartOffset, OS);
249     encodeULEB128(OffsetEntry.EndOffset, OS);
250     Func(OffsetEntry.Index);
251   }
252   support::endian::write(OS, static_cast<uint8_t>(EndOfList), support::little);
253   return true;
254 }
255 
256 uint64_t
257 DebugRangeListsSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
258   std::lock_guard<std::mutex> Lock(WriterMutex);
259 
260   RangeEntries.push_back(CurrentOffset);
261   bool WrittenStartxLength = false;
262   std::sort(
263       Ranges.begin(), Ranges.end(),
264       [](const DebugAddressRange &R1, const DebugAddressRange &R2) -> bool {
265         return R1.LowPC < R2.LowPC;
266       });
267   for (unsigned I = 0; I < Ranges.size();) {
268     WrittenStartxLength = false;
269     if (emitWithBase<DebugAddressRangesVector, dwarf::RnglistEntries,
270                      DebugAddressRange>(
271             *CUBodyStream, Ranges, *AddrWriter, *CU, I,
272             dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
273             dwarf::DW_RLE_end_of_list, [](uint32_t Index) -> void {}))
274       continue;
275 
276     const DebugAddressRange &Range = Ranges[I];
277     support::endian::write(*CUBodyStream,
278                            static_cast<uint8_t>(dwarf::DW_RLE_startx_length),
279                            support::little);
280     uint32_t Index = AddrWriter->getIndexFromAddress(Range.LowPC, *CU);
281     encodeULEB128(Index, *CUBodyStream);
282     encodeULEB128(Range.HighPC - Range.LowPC, *CUBodyStream);
283     ++I;
284     WrittenStartxLength = true;
285   }
286   if (WrittenStartxLength)
287     support::endian::write(*CUBodyStream,
288                            static_cast<uint8_t>(dwarf::DW_RLE_end_of_list),
289                            support::little);
290   CurrentOffset = CUBodyBuffer->size();
291   return RangeEntries.size() - 1;
292 }
293 
294 void DebugRangeListsSectionWriter::finalizeSection() {
295   std::unique_ptr<DebugBufferVector> CUArrayBuffer =
296       std::make_unique<DebugBufferVector>();
297   std::unique_ptr<raw_svector_ostream> CUArrayStream =
298       std::make_unique<raw_svector_ostream>(*CUArrayBuffer);
299   constexpr uint32_t SizeOfArrayEntry = 4;
300   const uint32_t SizeOfArraySection = RangeEntries.size() * SizeOfArrayEntry;
301   for (uint32_t Offset : RangeEntries)
302     support::endian::write(*CUArrayStream, Offset + SizeOfArraySection,
303                            support::little);
304 
305   std::unique_ptr<DebugBufferVector> Header = getDWARF5Header(
306       {static_cast<uint32_t>(SizeOfArraySection + CUBodyBuffer.get()->size()),
307        5, 8, 0, static_cast<uint32_t>(RangeEntries.size())});
308   *RangesStream << *Header;
309   *RangesStream << *CUArrayBuffer;
310   *RangesStream << *CUBodyBuffer;
311   SectionOffset = RangesBuffer->size();
312 }
313 
314 void DebugRangeListsSectionWriter::initSection(DWARFUnit &Unit) {
315   CUBodyBuffer = std::make_unique<DebugBufferVector>();
316   CUBodyStream = std::make_unique<raw_svector_ostream>(*CUBodyBuffer);
317   RangeEntries.clear();
318   CurrentOffset = 0;
319   CU = &Unit;
320 }
321 
322 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
323                                             DebugAddressRangesVector &&Ranges) {
324   std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
325   CUAddressRanges.emplace(CUOffset, std::move(Ranges));
326 }
327 
328 void DebugARangesSectionWriter::writeARangesSection(
329     raw_svector_ostream &RangesStream, const CUOffsetMap &CUMap) const {
330   // For reference on the format of the .debug_aranges section, see the DWARF4
331   // specification, section 6.1.4 Lookup by Address
332   // http://www.dwarfstd.org/doc/DWARF4.pdf
333   for (const auto &CUOffsetAddressRangesPair : CUAddressRanges) {
334     const uint64_t Offset = CUOffsetAddressRangesPair.first;
335     const DebugAddressRangesVector &AddressRanges =
336         CUOffsetAddressRangesPair.second;
337 
338     // Emit header.
339 
340     // Size of this set: 8 (size of the header) + 4 (padding after header)
341     // + 2*sizeof(uint64_t) bytes for each of the ranges, plus an extra
342     // pair of uint64_t's for the terminating, zero-length range.
343     // Does not include size field itself.
344     uint32_t Size = 8 + 4 + 2 * sizeof(uint64_t) * (AddressRanges.size() + 1);
345 
346     // Header field #1: set size.
347     support::endian::write(RangesStream, Size, support::little);
348 
349     // Header field #2: version number, 2 as per the specification.
350     support::endian::write(RangesStream, static_cast<uint16_t>(2),
351                            support::little);
352 
353     assert(CUMap.count(Offset) && "Original CU offset is not found in CU Map");
354     // Header field #3: debug info offset of the correspondent compile unit.
355     support::endian::write(
356         RangesStream, static_cast<uint32_t>(CUMap.find(Offset)->second.Offset),
357         support::little);
358 
359     // Header field #4: address size.
360     // 8 since we only write ELF64 binaries for now.
361     RangesStream << char(8);
362 
363     // Header field #5: segment size of target architecture.
364     RangesStream << char(0);
365 
366     // Padding before address table - 4 bytes in the 64-bit-pointer case.
367     support::endian::write(RangesStream, static_cast<uint32_t>(0),
368                            support::little);
369 
370     writeAddressRanges(RangesStream, AddressRanges, true);
371   }
372 }
373 
374 DebugAddrWriter::DebugAddrWriter(BinaryContext *Bc) { BC = Bc; }
375 
376 void DebugAddrWriter::AddressForDWOCU::dump() {
377   std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(),
378                                           indexToAdddessEnd());
379   // Sorting address in increasing order of indices.
380   llvm::sort(SortedMap, llvm::less_first());
381   for (auto &Pair : SortedMap)
382     dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
383 }
384 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
385   std::lock_guard<std::mutex> Lock(WriterMutex);
386   const uint64_t CUID = getCUID(CU);
387   if (!AddressMaps.count(CUID))
388     AddressMaps[CUID] = AddressForDWOCU();
389 
390   AddressForDWOCU &Map = AddressMaps[CUID];
391   auto Entry = Map.find(Address);
392   if (Entry == Map.end()) {
393     auto Index = Map.getNextIndex();
394     Entry = Map.insert(Address, Index).first;
395   }
396   return Entry->second;
397 }
398 
399 // Case1) Address is not in map insert in to AddresToIndex and IndexToAddres
400 // Case2) Address is in the map but Index is higher or equal. Need to update
401 // IndexToAddrss. Case3) Address is in the map but Index is lower. Need to
402 // update AddressToIndex and IndexToAddress
403 void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index,
404                                       DWARFUnit &CU) {
405   std::lock_guard<std::mutex> Lock(WriterMutex);
406   const uint64_t CUID = getCUID(CU);
407   AddressForDWOCU &Map = AddressMaps[CUID];
408   auto Entry = Map.find(Address);
409   if (Entry != Map.end()) {
410     if (Entry->second > Index)
411       Map.updateAddressToIndex(Address, Index);
412     Map.updateIndexToAddrss(Address, Index);
413   } else {
414     Map.insert(Address, Index);
415   }
416 }
417 
418 AddressSectionBuffer DebugAddrWriter::finalize() {
419   // Need to layout all sections within .debug_addr
420   // Within each section sort Address by index.
421   AddressSectionBuffer Buffer;
422   raw_svector_ostream AddressStream(Buffer);
423   for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) {
424     // Handling the case wehre debug information is a mix of Debug fission and
425     // monolitic.
426     if (!CU->getDWOId())
427       continue;
428     const uint64_t CUID = getCUID(*CU.get());
429     auto AM = AddressMaps.find(CUID);
430     // Adding to map even if it did not contribute to .debug_addr.
431     // The Skeleton CU might still have DW_AT_GNU_addr_base.
432     DWOIdToOffsetMap[CUID] = Buffer.size();
433     // If does not exist this CUs DWO section didn't contribute to .debug_addr.
434     if (AM == AddressMaps.end())
435       continue;
436     std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(),
437                                             AM->second.indexToAdddessEnd());
438     // Sorting address in increasing order of indices.
439     llvm::sort(SortedMap, llvm::less_first());
440 
441     uint8_t AddrSize = CU->getAddressByteSize();
442     uint32_t Counter = 0;
443     auto WriteAddress = [&](uint64_t Address) -> void {
444       ++Counter;
445       switch (AddrSize) {
446       default:
447         assert(false && "Address Size is invalid.");
448         break;
449       case 4:
450         support::endian::write(AddressStream, static_cast<uint32_t>(Address),
451                                support::little);
452         break;
453       case 8:
454         support::endian::write(AddressStream, Address, support::little);
455         break;
456       }
457     };
458 
459     for (const IndexAddressPair &Val : SortedMap) {
460       while (Val.first > Counter)
461         WriteAddress(0);
462       WriteAddress(Val.second);
463     }
464   }
465 
466   return Buffer;
467 }
468 AddressSectionBuffer DebugAddrWriterDwarf5::finalize() {
469   // Need to layout all sections within .debug_addr
470   // Within each section sort Address by index.
471   AddressSectionBuffer Buffer;
472   raw_svector_ostream AddressStream(Buffer);
473   const endianness Endian =
474       BC->DwCtx->isLittleEndian() ? support::little : support::big;
475   const DWARFSection &AddrSec = BC->DwCtx->getDWARFObj().getAddrSection();
476   DWARFDataExtractor AddrData(BC->DwCtx->getDWARFObj(), AddrSec, Endian, 0);
477   DWARFDebugAddrTable AddrTable;
478   DIDumpOptions DumpOpts;
479   constexpr uint32_t HeaderSize = 8;
480   DenseMap<uint64_t, uint64_t> UnmodifiedAddressOffsets;
481   for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) {
482     const uint64_t CUID = getCUID(*CU.get());
483     const uint8_t AddrSize = CU->getAddressByteSize();
484     auto AMIter = AddressMaps.find(CUID);
485     // A case where CU has entry in .debug_addr, but we don't modify addresses
486     // for it.
487     if (AMIter == AddressMaps.end()) {
488       AMIter = AddressMaps.insert({CUID, AddressForDWOCU()}).first;
489       std::optional<uint64_t> BaseOffset = CU->getAddrOffsetSectionBase();
490       if (!BaseOffset)
491         continue;
492       // Address base offset is to the first entry.
493       // The size of header is 8 bytes.
494       uint64_t Offset = *BaseOffset - HeaderSize;
495       auto Iter = UnmodifiedAddressOffsets.find(Offset);
496       if (Iter != UnmodifiedAddressOffsets.end()) {
497         DWOIdToOffsetMap[CUID] = Iter->getSecond();
498         continue;
499       }
500       UnmodifiedAddressOffsets[Offset] = Buffer.size() + HeaderSize;
501       if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddrSize,
502                                         DumpOpts.WarningHandler)) {
503         DumpOpts.RecoverableErrorHandler(std::move(Err));
504         continue;
505       }
506 
507       uint32_t Index = 0;
508       for (uint64_t Addr : AddrTable.getAddressEntries())
509         AMIter->second.insert(Addr, Index++);
510     }
511 
512     DWOIdToOffsetMap[CUID] = Buffer.size() + HeaderSize;
513 
514     std::vector<IndexAddressPair> SortedMap(
515         AMIter->second.indexToAddressBegin(),
516         AMIter->second.indexToAdddessEnd());
517     // Sorting address in increasing order of indices.
518     llvm::sort(SortedMap, llvm::less_first());
519     // Writing out Header
520     const uint32_t Length = SortedMap.size() * AddrSize + 4;
521     support::endian::write(AddressStream, Length, Endian);
522     support::endian::write(AddressStream, static_cast<uint16_t>(5), Endian);
523     support::endian::write(AddressStream, static_cast<uint8_t>(AddrSize),
524                            Endian);
525     support::endian::write(AddressStream, static_cast<uint8_t>(0), Endian);
526 
527     uint32_t Counter = 0;
528     auto writeAddress = [&](uint64_t Address) -> void {
529       ++Counter;
530       switch (AddrSize) {
531       default:
532         llvm_unreachable("Address Size is invalid.");
533         break;
534       case 4:
535         support::endian::write(AddressStream, static_cast<uint32_t>(Address),
536                                Endian);
537         break;
538       case 8:
539         support::endian::write(AddressStream, Address, Endian);
540         break;
541       }
542     };
543 
544     for (const IndexAddressPair &Val : SortedMap) {
545       while (Val.first > Counter)
546         writeAddress(0);
547       writeAddress(Val.second);
548     }
549   }
550 
551   return Buffer;
552 }
553 
554 uint64_t DebugAddrWriter::getOffset(DWARFUnit &Unit) {
555   const uint64_t CUID = getCUID(Unit);
556   assert(CUID && "Can't get offset, not a skeleton CU.");
557   auto Iter = DWOIdToOffsetMap.find(CUID);
558   assert(Iter != DWOIdToOffsetMap.end() &&
559          "Offset in to.debug_addr was not found for DWO ID.");
560   return Iter->second;
561 }
562 
563 uint64_t DebugAddrWriterDwarf5::getOffset(DWARFUnit &Unit) {
564   auto Iter = DWOIdToOffsetMap.find(getCUID(Unit));
565   assert(Iter != DWOIdToOffsetMap.end() &&
566          "Offset in to.debug_addr was not found for CU ID.");
567   return Iter->second;
568 }
569 
570 void DebugLocWriter::init() {
571   LocBuffer = std::make_unique<DebugBufferVector>();
572   LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
573   // Writing out empty location list to which all references to empty location
574   // lists will point.
575   if (!LocSectionOffset && DwarfVersion < 5) {
576     const char Zeroes[16] = {0};
577     *LocStream << StringRef(Zeroes, 16);
578     LocSectionOffset += 16;
579   }
580 }
581 
582 uint32_t DebugLocWriter::LocSectionOffset = 0;
583 void DebugLocWriter::addList(AttrInfo &AttrVal, DebugLocationsVector &LocList,
584                              DebugInfoBinaryPatcher &DebugInfoPatcher,
585                              DebugAbbrevWriter &AbbrevWriter) {
586   const uint64_t AttrOffset = AttrVal.Offset;
587   if (LocList.empty()) {
588     DebugInfoPatcher.addLE32Patch(AttrOffset, DebugLocWriter::EmptyListOffset);
589     return;
590   }
591   // Since there is a separate DebugLocWriter for each thread,
592   // we don't need a lock to read the SectionOffset and update it.
593   const uint32_t EntryOffset = LocSectionOffset;
594 
595   for (const DebugLocationEntry &Entry : LocList) {
596     support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC),
597                            support::little);
598     support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC),
599                            support::little);
600     support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()),
601                            support::little);
602     *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
603                             Entry.Expr.size());
604     LocSectionOffset += 2 * 8 + 2 + Entry.Expr.size();
605   }
606   LocStream->write_zeros(16);
607   LocSectionOffset += 16;
608   LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset});
609   DebugInfoPatcher.addLE32Patch(AttrOffset, EntryOffset);
610 }
611 
612 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() {
613   return std::move(LocBuffer);
614 }
615 
616 // DWARF 4: 2.6.2
617 void DebugLocWriter::finalize(DebugInfoBinaryPatcher &DebugInfoPatcher,
618                               DebugAbbrevWriter &AbbrevWriter) {}
619 
620 static void writeEmptyListDwarf5(raw_svector_ostream &Stream) {
621   support::endian::write(Stream, static_cast<uint32_t>(4), support::little);
622   support::endian::write(Stream, static_cast<uint8_t>(dwarf::DW_LLE_start_end),
623                          support::little);
624 
625   const char Zeroes[16] = {0};
626   Stream << StringRef(Zeroes, 16);
627   encodeULEB128(0, Stream);
628   support::endian::write(
629       Stream, static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), support::little);
630 }
631 
632 static void writeLegacyLocList(AttrInfo &AttrVal, DebugLocationsVector &LocList,
633                                DebugInfoBinaryPatcher &DebugInfoPatcher,
634                                DebugAddrWriter &AddrWriter,
635                                DebugBufferVector &LocBuffer, DWARFUnit &CU,
636                                raw_svector_ostream &LocStream) {
637   const uint64_t AttrOffset = AttrVal.Offset;
638   if (LocList.empty()) {
639     DebugInfoPatcher.addLE32Patch(AttrOffset, DebugLocWriter::EmptyListOffset);
640     return;
641   }
642 
643   const uint32_t EntryOffset = LocBuffer.size();
644   for (const DebugLocationEntry &Entry : LocList) {
645     support::endian::write(LocStream,
646                            static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
647                            support::little);
648     const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU);
649     encodeULEB128(Index, LocStream);
650 
651     support::endian::write(LocStream,
652                            static_cast<uint32_t>(Entry.HighPC - Entry.LowPC),
653                            support::little);
654     support::endian::write(LocStream, static_cast<uint16_t>(Entry.Expr.size()),
655                            support::little);
656     LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
657                            Entry.Expr.size());
658   }
659   support::endian::write(LocStream,
660                          static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
661                          support::little);
662   DebugInfoPatcher.addLE32Patch(AttrOffset, EntryOffset);
663 }
664 
665 static void writeDWARF5LocList(
666     uint32_t &NumberOfEntries, AttrInfo &AttrVal, DebugLocationsVector &LocList,
667     DebugInfoBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter,
668     DebugAddrWriter &AddrWriter, DebugBufferVector &LocBodyBuffer,
669     std::vector<uint32_t> &RelativeLocListOffsets, DWARFUnit &CU,
670     raw_svector_ostream &LocBodyStream) {
671   if (AttrVal.V.getForm() != dwarf::DW_FORM_loclistx) {
672     AbbrevWriter.addAttributePatch(CU, AttrVal.AbbrevDecl,
673                                    dwarf::DW_AT_location, dwarf::DW_AT_location,
674                                    dwarf::DW_FORM_loclistx);
675   }
676   DebugInfoPatcher.addUDataPatch(AttrVal.Offset, NumberOfEntries, AttrVal.Size);
677   RelativeLocListOffsets.push_back(LocBodyBuffer.size());
678   ++NumberOfEntries;
679   if (LocList.empty()) {
680     writeEmptyListDwarf5(LocBodyStream);
681     return;
682   }
683 
684   std::vector<uint64_t> OffsetsArray;
685   bool WrittenStartxLength = false;
686   auto writeExpression = [&](uint32_t Index) -> void {
687     const DebugLocationEntry &Entry = LocList[Index];
688     encodeULEB128(Entry.Expr.size(), LocBodyStream);
689     LocBodyStream << StringRef(
690         reinterpret_cast<const char *>(Entry.Expr.data()), Entry.Expr.size());
691   };
692   for (unsigned I = 0; I < LocList.size();) {
693     WrittenStartxLength = false;
694     if (emitWithBase<DebugLocationsVector, dwarf::LoclistEntries,
695                      DebugLocationEntry>(
696             LocBodyStream, LocList, AddrWriter, CU, I,
697             dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
698             dwarf::DW_LLE_end_of_list, writeExpression))
699       continue;
700 
701     const DebugLocationEntry &Entry = LocList[I];
702     support::endian::write(LocBodyStream,
703                            static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
704                            support::little);
705     const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU);
706     encodeULEB128(Index, LocBodyStream);
707     encodeULEB128(Entry.HighPC - Entry.LowPC, LocBodyStream);
708     writeExpression(I);
709     ++I;
710     WrittenStartxLength = true;
711   }
712 
713   if (WrittenStartxLength)
714     support::endian::write(LocBodyStream,
715                            static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
716                            support::little);
717 }
718 
719 void DebugLoclistWriter::addList(AttrInfo &AttrVal,
720                                  DebugLocationsVector &LocList,
721                                  DebugInfoBinaryPatcher &DebugInfoPatcher,
722                                  DebugAbbrevWriter &AbbrevWriter) {
723   if (DwarfVersion < 5)
724     writeLegacyLocList(AttrVal, LocList, DebugInfoPatcher, *AddrWriter,
725                        *LocBuffer, CU, *LocStream);
726   else
727     writeDWARF5LocList(NumberOfEntries, AttrVal, LocList, DebugInfoPatcher,
728                        AbbrevWriter, *AddrWriter, *LocBodyBuffer,
729                        RelativeLocListOffsets, CU, *LocBodyStream);
730 }
731 
732 uint32_t DebugLoclistWriter::LoclistBaseOffset = 0;
733 void DebugLoclistWriter::finalizeDWARF5(
734     DebugInfoBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter) {
735   if (LocBodyBuffer->empty())
736     return;
737 
738   std::unique_ptr<DebugBufferVector> LocArrayBuffer =
739       std::make_unique<DebugBufferVector>();
740   std::unique_ptr<raw_svector_ostream> LocArrayStream =
741       std::make_unique<raw_svector_ostream>(*LocArrayBuffer);
742 
743   const uint32_t SizeOfArraySection = NumberOfEntries * sizeof(uint32_t);
744   // Write out IndexArray
745   for (uint32_t RelativeOffset : RelativeLocListOffsets)
746     support::endian::write(
747         *LocArrayStream,
748         static_cast<uint32_t>(SizeOfArraySection + RelativeOffset),
749         support::little);
750 
751   std::unique_ptr<DebugBufferVector> Header = getDWARF5Header(
752       {static_cast<uint32_t>(SizeOfArraySection + LocBodyBuffer.get()->size()),
753        5, 8, 0, NumberOfEntries});
754   *LocStream << *Header;
755   *LocStream << *LocArrayBuffer;
756   *LocStream << *LocBodyBuffer;
757 
758   if (!isSplitDwarf()) {
759     if (std::optional<AttrInfo> AttrInfoVal =
760             findAttributeInfo(CU.getUnitDIE(), dwarf::DW_AT_loclists_base))
761       DebugInfoPatcher.addLE32Patch(AttrInfoVal->Offset,
762                                     LoclistBaseOffset +
763                                         getDWARF5RngListLocListHeaderSize());
764     else {
765       AbbrevWriter.addAttribute(
766           CU, CU.getUnitDIE().getAbbreviationDeclarationPtr(),
767           dwarf::DW_AT_loclists_base, dwarf::DW_FORM_sec_offset);
768       DebugInfoPatcher.insertNewEntry(CU.getUnitDIE(),
769                                       LoclistBaseOffset + Header->size());
770     }
771     LoclistBaseOffset += LocBuffer->size();
772   }
773   clearList(RelativeLocListOffsets);
774   clearList(*LocArrayBuffer);
775   clearList(*LocBodyBuffer);
776 }
777 
778 void DebugLoclistWriter::finalize(DebugInfoBinaryPatcher &DebugInfoPatcher,
779                                   DebugAbbrevWriter &AbbrevWriter) {
780   if (DwarfVersion >= 5)
781     finalizeDWARF5(DebugInfoPatcher, AbbrevWriter);
782 }
783 
784 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
785 
786 void DebugInfoBinaryPatcher::addUnitBaseOffsetLabel(uint64_t Offset) {
787   Offset -= DWPUnitOffset;
788   std::lock_guard<std::mutex> Lock(WriterMutex);
789   DebugPatches.emplace_back(new DWARFUnitOffsetBaseLabel(Offset));
790 }
791 
792 void DebugInfoBinaryPatcher::addDestinationReferenceLabel(uint64_t Offset) {
793   Offset -= DWPUnitOffset;
794   std::lock_guard<std::mutex> Lock(WriterMutex);
795   auto RetVal = DestinationLabels.insert(Offset);
796   if (!RetVal.second)
797     return;
798 
799   DebugPatches.emplace_back(new DestinationReferenceLabel(Offset));
800 }
801 
802 static std::string encodeLE(size_t ByteSize, uint64_t NewValue) {
803   std::string LE64(ByteSize, 0);
804   for (size_t I = 0; I < ByteSize; ++I) {
805     LE64[I] = NewValue & 0xff;
806     NewValue >>= 8;
807   }
808   return LE64;
809 }
810 
811 void DebugInfoBinaryPatcher::insertNewEntry(const DWARFDie &DIE,
812                                             uint32_t Value) {
813   std::string StrValue = encodeLE(4, Value);
814   insertNewEntry(DIE, std::move(StrValue));
815 }
816 
817 void DebugInfoBinaryPatcher::insertNewEntry(const DWARFDie &DIE,
818                                             std::string &&Value) {
819   const DWARFAbbreviationDeclaration *AbbrevDecl =
820       DIE.getAbbreviationDeclarationPtr();
821 
822   // In case this DIE has no attributes.
823   uint32_t Offset = DIE.getOffset() + 1;
824   size_t NumOfAttributes = AbbrevDecl->getNumAttributes();
825   if (NumOfAttributes) {
826     std::optional<AttrInfo> Val =
827         findAttributeInfo(DIE, AbbrevDecl, NumOfAttributes - 1);
828     assert(Val && "Invalid Value.");
829 
830     Offset = Val->Offset + Val->Size - DWPUnitOffset;
831   }
832   std::lock_guard<std::mutex> Lock(WriterMutex);
833   DebugPatches.emplace_back(new NewDebugEntry(Offset, std::move(Value)));
834 }
835 
836 void DebugInfoBinaryPatcher::addReferenceToPatch(uint64_t Offset,
837                                                  uint32_t DestinationOffset,
838                                                  uint32_t OldValueSize,
839                                                  dwarf::Form Form) {
840   Offset -= DWPUnitOffset;
841   DestinationOffset -= DWPUnitOffset;
842   std::lock_guard<std::mutex> Lock(WriterMutex);
843   DebugPatches.emplace_back(
844       new DebugPatchReference(Offset, OldValueSize, DestinationOffset, Form));
845 }
846 
847 void DebugInfoBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t NewValue,
848                                            uint32_t OldValueSize) {
849   Offset -= DWPUnitOffset;
850   std::lock_guard<std::mutex> Lock(WriterMutex);
851   DebugPatches.emplace_back(
852       new DebugPatchVariableSize(Offset, OldValueSize, NewValue));
853 }
854 
855 void DebugInfoBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) {
856   Offset -= DWPUnitOffset;
857   std::lock_guard<std::mutex> Lock(WriterMutex);
858   DebugPatches.emplace_back(new DebugPatch64(Offset, NewValue));
859 }
860 
861 void DebugInfoBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue,
862                                           uint32_t OldValueSize) {
863   Offset -= DWPUnitOffset;
864   std::lock_guard<std::mutex> Lock(WriterMutex);
865   if (OldValueSize == 4)
866     DebugPatches.emplace_back(new DebugPatch32(Offset, NewValue));
867   else if (OldValueSize == 8)
868     DebugPatches.emplace_back(new DebugPatch64to32(Offset, NewValue));
869   else
870     DebugPatches.emplace_back(
871         new DebugPatch32GenericSize(Offset, NewValue, OldValueSize));
872 }
873 
874 void SimpleBinaryPatcher::addBinaryPatch(uint64_t Offset,
875                                          std::string &&NewValue,
876                                          uint32_t OldValueSize) {
877   Patches.emplace_back(Offset, std::move(NewValue));
878 }
879 
880 void SimpleBinaryPatcher::addBytePatch(uint64_t Offset, uint8_t Value) {
881   auto Str = std::string(1, Value);
882   Patches.emplace_back(Offset, std::move(Str));
883 }
884 
885 void SimpleBinaryPatcher::addLEPatch(uint64_t Offset, uint64_t NewValue,
886                                      size_t ByteSize) {
887   Patches.emplace_back(Offset, encodeLE(ByteSize, NewValue));
888 }
889 
890 void SimpleBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t Value,
891                                         uint32_t OldValueSize) {
892   std::string Buff;
893   raw_string_ostream OS(Buff);
894   encodeULEB128(Value, OS, OldValueSize);
895 
896   Patches.emplace_back(Offset, std::move(Buff));
897 }
898 
899 void SimpleBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) {
900   addLEPatch(Offset, NewValue, 8);
901 }
902 
903 void SimpleBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue,
904                                        uint32_t OldValueSize) {
905   addLEPatch(Offset, NewValue, 4);
906 }
907 
908 std::string SimpleBinaryPatcher::patchBinary(StringRef BinaryContents) {
909   std::string BinaryContentsStr = std::string(BinaryContents);
910   for (const auto &Patch : Patches) {
911     uint32_t Offset = Patch.first;
912     const std::string &ByteSequence = Patch.second;
913     assert(Offset + ByteSequence.size() <= BinaryContents.size() &&
914            "Applied patch runs over binary size.");
915     for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) {
916       BinaryContentsStr[Offset + I] = ByteSequence[I];
917     }
918   }
919   return BinaryContentsStr;
920 }
921 
922 CUOffsetMap DebugInfoBinaryPatcher::computeNewOffsets(DWARFContext &DWCtx,
923                                                       bool IsDWOContext) {
924   CUOffsetMap CUMap;
925   llvm::sort(DebugPatches, [](const UniquePatchPtrType &V1,
926                               const UniquePatchPtrType &V2) {
927     if (V1.get()->Offset == V2.get()->Offset) {
928       if (V1->Kind == DebugPatchKind::NewDebugEntry &&
929           V2->Kind == DebugPatchKind::NewDebugEntry)
930         return reinterpret_cast<const NewDebugEntry *>(V1.get())->CurrentOrder <
931                reinterpret_cast<const NewDebugEntry *>(V2.get())->CurrentOrder;
932 
933       // This is a case where we are modifying first entry of next
934       // DIE, and adding a new one.
935       return V1->Kind == DebugPatchKind::NewDebugEntry;
936     }
937     return V1.get()->Offset < V2.get()->Offset;
938   });
939 
940   DWARFUnitVector::compile_unit_range CompileUnits =
941       IsDWOContext ? DWCtx.dwo_compile_units() : DWCtx.compile_units();
942 
943   for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits)
944     CUMap[CU->getOffset()] = {static_cast<uint32_t>(CU->getOffset()),
945                               static_cast<uint32_t>(CU->getLength())};
946 
947   // Calculating changes in .debug_info size from Patches to build a map of old
948   // to updated reference destination offsets.
949   uint32_t PreviousOffset = 0;
950   int32_t PreviousChangeInSize = 0;
951   for (UniquePatchPtrType &PatchBase : DebugPatches) {
952     Patch *P = PatchBase.get();
953     switch (P->Kind) {
954     default:
955       continue;
956     case DebugPatchKind::PatchValue64to32: {
957       PreviousChangeInSize -= 4;
958       break;
959     }
960     case DebugPatchKind::PatchValue32GenericSize: {
961       DebugPatch32GenericSize *DPVS =
962           reinterpret_cast<DebugPatch32GenericSize *>(P);
963       PreviousChangeInSize += 4 - DPVS->OldValueSize;
964       break;
965     }
966     case DebugPatchKind::PatchValueVariable: {
967       DebugPatchVariableSize *DPV =
968           reinterpret_cast<DebugPatchVariableSize *>(P);
969       std::string Temp;
970       raw_string_ostream OS(Temp);
971       encodeULEB128(DPV->Value, OS);
972       PreviousChangeInSize += Temp.size() - DPV->OldValueSize;
973       break;
974     }
975     case DebugPatchKind::DestinationReferenceLabel: {
976       DestinationReferenceLabel *DRL =
977           reinterpret_cast<DestinationReferenceLabel *>(P);
978       OldToNewOffset[DRL->Offset] =
979           DRL->Offset + ChangeInSize + PreviousChangeInSize;
980       break;
981     }
982     case DebugPatchKind::ReferencePatchValue: {
983       // This doesn't look to be a common case, so will always encode as 4 bytes
984       // to reduce algorithmic complexity.
985       DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P);
986       if (RDP->PatchInfo.IndirectRelative) {
987         PreviousChangeInSize += 4 - RDP->PatchInfo.OldValueSize;
988         assert(RDP->PatchInfo.OldValueSize <= 4 &&
989                "Variable encoding reference greater than 4 bytes.");
990       }
991       break;
992     }
993     case DebugPatchKind::DWARFUnitOffsetBaseLabel: {
994       DWARFUnitOffsetBaseLabel *BaseLabel =
995           reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P);
996       uint32_t CUOffset = BaseLabel->Offset;
997       ChangeInSize += PreviousChangeInSize;
998       uint32_t CUOffsetUpdate = CUOffset + ChangeInSize;
999       CUMap[CUOffset].Offset = CUOffsetUpdate;
1000       CUMap[PreviousOffset].Length += PreviousChangeInSize;
1001       PreviousChangeInSize = 0;
1002       PreviousOffset = CUOffset;
1003       break;
1004     }
1005     case DebugPatchKind::NewDebugEntry: {
1006       NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P);
1007       PreviousChangeInSize += NDE->Value.size();
1008       break;
1009     }
1010     }
1011   }
1012   CUMap[PreviousOffset].Length += PreviousChangeInSize;
1013   return CUMap;
1014 }
1015 uint32_t DebugInfoBinaryPatcher::NewDebugEntry::OrderCounter = 0;
1016 
1017 std::string DebugInfoBinaryPatcher::patchBinary(StringRef BinaryContents) {
1018   std::string NewBinaryContents;
1019   NewBinaryContents.reserve(BinaryContents.size() + ChangeInSize);
1020   uint32_t StartOffset = 0;
1021   uint32_t DwarfUnitBaseOffset = 0;
1022   uint32_t OldValueSize = 0;
1023   uint32_t Offset = 0;
1024   std::string ByteSequence;
1025   std::vector<std::pair<uint32_t, uint32_t>> LengthPatches;
1026   // Wasting one entry to avoid checks for first.
1027   LengthPatches.push_back({0, 0});
1028 
1029   // Applying all the patches replacing current entry.
1030   // This might change the size of .debug_info section.
1031   for (const UniquePatchPtrType &PatchBase : DebugPatches) {
1032     Patch *P = PatchBase.get();
1033     switch (P->Kind) {
1034     default:
1035       continue;
1036     case DebugPatchKind::ReferencePatchValue: {
1037       DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P);
1038       uint32_t DestinationOffset = RDP->DestinationOffset;
1039       assert(OldToNewOffset.count(DestinationOffset) &&
1040              "Destination Offset for reference not updated.");
1041       uint32_t UpdatedOffset = OldToNewOffset[DestinationOffset];
1042       Offset = RDP->Offset;
1043       OldValueSize = RDP->PatchInfo.OldValueSize;
1044       if (RDP->PatchInfo.DirectRelative) {
1045         UpdatedOffset -= DwarfUnitBaseOffset;
1046         ByteSequence = encodeLE(OldValueSize, UpdatedOffset);
1047         // In theory reference for DW_FORM_ref{1,2,4,8} can be right on the edge
1048         // and overflow if later debug information grows.
1049         if (ByteSequence.size() > OldValueSize)
1050           errs() << "BOLT-ERROR: Relative reference of size "
1051                  << Twine::utohexstr(OldValueSize)
1052                  << " overflows with the new encoding.\n";
1053       } else if (RDP->PatchInfo.DirectAbsolute) {
1054         ByteSequence = encodeLE(OldValueSize, UpdatedOffset);
1055       } else if (RDP->PatchInfo.IndirectRelative) {
1056         UpdatedOffset -= DwarfUnitBaseOffset;
1057         ByteSequence.clear();
1058         raw_string_ostream OS(ByteSequence);
1059         encodeULEB128(UpdatedOffset, OS, 4);
1060       } else {
1061         llvm_unreachable("Invalid Reference form.");
1062       }
1063       break;
1064     }
1065     case DebugPatchKind::PatchValue32: {
1066       DebugPatch32 *P32 = reinterpret_cast<DebugPatch32 *>(P);
1067       Offset = P32->Offset;
1068       OldValueSize = 4;
1069       ByteSequence = encodeLE(4, P32->Value);
1070       break;
1071     }
1072     case DebugPatchKind::PatchValue64to32: {
1073       DebugPatch64to32 *P64to32 = reinterpret_cast<DebugPatch64to32 *>(P);
1074       Offset = P64to32->Offset;
1075       OldValueSize = 8;
1076       ByteSequence = encodeLE(4, P64to32->Value);
1077       break;
1078     }
1079     case DebugPatchKind::PatchValue32GenericSize: {
1080       DebugPatch32GenericSize *DPVS =
1081           reinterpret_cast<DebugPatch32GenericSize *>(P);
1082       Offset = DPVS->Offset;
1083       OldValueSize = DPVS->OldValueSize;
1084       ByteSequence = encodeLE(4, DPVS->Value);
1085       break;
1086     }
1087     case DebugPatchKind::PatchValueVariable: {
1088       DebugPatchVariableSize *PV =
1089           reinterpret_cast<DebugPatchVariableSize *>(P);
1090       Offset = PV->Offset;
1091       OldValueSize = PV->OldValueSize;
1092       ByteSequence.clear();
1093       raw_string_ostream OS(ByteSequence);
1094       encodeULEB128(PV->Value, OS);
1095       break;
1096     }
1097     case DebugPatchKind::PatchValue64: {
1098       DebugPatch64 *P64 = reinterpret_cast<DebugPatch64 *>(P);
1099       Offset = P64->Offset;
1100       OldValueSize = 8;
1101       ByteSequence = encodeLE(8, P64->Value);
1102       break;
1103     }
1104     case DebugPatchKind::DWARFUnitOffsetBaseLabel: {
1105       DWARFUnitOffsetBaseLabel *BaseLabel =
1106           reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P);
1107       Offset = BaseLabel->Offset;
1108       OldValueSize = 0;
1109       ByteSequence.clear();
1110       auto &Patch = LengthPatches.back();
1111       // Length to copy between last patch entry and next compile unit.
1112       uint32_t RemainingLength = Offset - StartOffset;
1113       uint32_t NewCUOffset = NewBinaryContents.size() + RemainingLength;
1114       DwarfUnitBaseOffset = NewCUOffset;
1115       // Length of previous CU = This CU Offset - sizeof(length) - last CU
1116       // Offset.
1117       Patch.second = NewCUOffset - 4 - Patch.first;
1118       LengthPatches.push_back({NewCUOffset, 0});
1119       break;
1120     }
1121     case DebugPatchKind::NewDebugEntry: {
1122       NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P);
1123       Offset = NDE->Offset;
1124       OldValueSize = 0;
1125       ByteSequence = NDE->Value;
1126       break;
1127     }
1128     }
1129 
1130     assert((P->Kind == DebugPatchKind::NewDebugEntry ||
1131             Offset + ByteSequence.size() <= BinaryContents.size()) &&
1132            "Applied patch runs over binary size.");
1133     uint32_t Length = Offset - StartOffset;
1134     NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(),
1135                              Length);
1136     NewBinaryContents.append(ByteSequence.data(), ByteSequence.size());
1137     StartOffset = Offset + OldValueSize;
1138   }
1139   uint32_t Length = BinaryContents.size() - StartOffset;
1140   NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(),
1141                            Length);
1142   DebugPatches.clear();
1143 
1144   // Patching lengths of CUs
1145   auto &Patch = LengthPatches.back();
1146   Patch.second = NewBinaryContents.size() - 4 - Patch.first;
1147   for (uint32_t J = 1, Size = LengthPatches.size(); J < Size; ++J) {
1148     const auto &Patch = LengthPatches[J];
1149     ByteSequence = encodeLE(4, Patch.second);
1150     Offset = Patch.first;
1151     for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I)
1152       NewBinaryContents[Offset + I] = ByteSequence[I];
1153   }
1154 
1155   return NewBinaryContents;
1156 }
1157 
1158 void DebugStrOffsetsWriter::initialize(
1159     const DWARFSection &StrOffsetsSection,
1160     const std::optional<StrOffsetsContributionDescriptor> Contr) {
1161   if (!Contr)
1162     return;
1163 
1164   const uint8_t DwarfOffsetByteSize = Contr->getDwarfOffsetByteSize();
1165   assert(DwarfOffsetByteSize == 4 &&
1166          "Dwarf String Offsets Byte Size is not supported.");
1167   uint32_t Index = 0;
1168   for (uint64_t Offset = 0; Offset < Contr->Size; Offset += DwarfOffsetByteSize)
1169     IndexToAddressMap[Index++] = *reinterpret_cast<const uint32_t *>(
1170         StrOffsetsSection.Data.data() + Contr->Base + Offset);
1171 }
1172 
1173 void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) {
1174   assert(IndexToAddressMap.count(Index) > 0 && "Index is not found.");
1175   IndexToAddressMap[Index] = Address;
1176   StrOffsetSectionWasModified = true;
1177 }
1178 
1179 void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit) {
1180   if (IndexToAddressMap.empty())
1181     return;
1182 
1183   std::optional<AttrInfo> AttrVal =
1184       findAttributeInfo(Unit.getUnitDIE(), dwarf::DW_AT_str_offsets_base);
1185   assert(AttrVal && "DW_AT_str_offsets_base not present.");
1186   std::optional<uint64_t> Val = AttrVal->V.getAsSectionOffset();
1187   assert(Val && "DW_AT_str_offsets_base Value not present.");
1188   auto RetVal = ProcessedBaseOffsets.insert(*Val);
1189   if (RetVal.second) {
1190     // Writing out the header for each section.
1191     support::endian::write(*StrOffsetsStream, CurrentSectionSize + 4,
1192                            support::little);
1193     support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(5),
1194                            support::little);
1195     support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(0),
1196                            support::little);
1197     for (const auto &Entry : IndexToAddressMap)
1198       support::endian::write(*StrOffsetsStream, Entry.second, support::little);
1199   }
1200   // Will print error if we already processed this contribution, and now
1201   // skipping it, but it was modified.
1202   if (!RetVal.second && StrOffsetSectionWasModified)
1203     errs() << "BOLT-WARNING: skipping string offsets section for CU at offset "
1204            << Twine::utohexstr(Unit.getOffset()) << ", but it was modified\n";
1205 
1206   StrOffsetSectionWasModified = false;
1207   IndexToAddressMap.clear();
1208 }
1209 
1210 void DebugStrWriter::create() {
1211   StrBuffer = std::make_unique<DebugStrBufferVector>();
1212   StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer);
1213 }
1214 
1215 void DebugStrWriter::initialize() {
1216   auto StrSection = BC.DwCtx->getDWARFObj().getStrSection();
1217   (*StrStream) << StrSection;
1218 }
1219 
1220 uint32_t DebugStrWriter::addString(StringRef Str) {
1221   std::lock_guard<std::mutex> Lock(WriterMutex);
1222   if (StrBuffer->empty())
1223     initialize();
1224   auto Offset = StrBuffer->size();
1225   (*StrStream) << Str;
1226   StrStream->write_zeros(1);
1227   return Offset;
1228 }
1229 
1230 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) {
1231   const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations();
1232   if (!Abbrevs)
1233     return;
1234 
1235   const PatchesTy &UnitPatches = Patches[&Unit];
1236   const AbbrevEntryTy &AbbrevEntries = NewAbbrevEntries[&Unit];
1237 
1238   // We are duplicating abbrev sections, to handle the case where for one CU we
1239   // modify it, but for another we don't.
1240   auto UnitDataPtr = std::make_unique<AbbrevData>();
1241   AbbrevData &UnitData = *UnitDataPtr.get();
1242   UnitData.Buffer = std::make_unique<DebugBufferVector>();
1243   UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer);
1244 
1245   raw_svector_ostream &OS = *UnitData.Stream.get();
1246 
1247   // Returns true if AbbrevData is re-used, false otherwise.
1248   auto hashAndAddAbbrev = [&](StringRef AbbrevData) -> bool {
1249     llvm::SHA1 Hasher;
1250     Hasher.update(AbbrevData);
1251     std::array<uint8_t, 20> Hash = Hasher.final();
1252     StringRef Key((const char *)Hash.data(), Hash.size());
1253     auto Iter = AbbrevDataCache.find(Key);
1254     if (Iter != AbbrevDataCache.end()) {
1255       UnitsAbbrevData[&Unit] = Iter->second.get();
1256       return true;
1257     }
1258     AbbrevDataCache[Key] = std::move(UnitDataPtr);
1259     UnitsAbbrevData[&Unit] = &UnitData;
1260     return false;
1261   };
1262   // Take a fast path if there are no patches to apply. Simply copy the original
1263   // contents.
1264   if (UnitPatches.empty() && AbbrevEntries.empty()) {
1265     StringRef AbbrevSectionContents =
1266         Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection()
1267                          : Unit.getContext().getDWARFObj().getAbbrevSection();
1268     StringRef AbbrevContents;
1269 
1270     const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex();
1271     if (!CUIndex.getRows().empty()) {
1272       // Handle DWP section contribution.
1273       const DWARFUnitIndex::Entry *DWOEntry =
1274           CUIndex.getFromHash(*Unit.getDWOId());
1275       if (!DWOEntry)
1276         return;
1277 
1278       const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution =
1279           DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV);
1280       AbbrevContents = AbbrevSectionContents.substr(
1281           DWOContrubution->getOffset(), DWOContrubution->getLength());
1282     } else if (!Unit.isDWOUnit()) {
1283       const uint64_t StartOffset = Unit.getAbbreviationsOffset();
1284 
1285       // We know where the unit's abbreviation set starts, but not where it ends
1286       // as such data is not readily available. Hence, we have to build a sorted
1287       // list of start addresses and find the next starting address to determine
1288       // the set boundaries.
1289       //
1290       // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets
1291       // we wouldn't have to build our own sorted list for the quick lookup.
1292       if (AbbrevSetOffsets.empty()) {
1293         for (const std::pair<const uint64_t, DWARFAbbreviationDeclarationSet>
1294                  &P : *Unit.getContext().getDebugAbbrev())
1295           AbbrevSetOffsets.push_back(P.first);
1296         sort(AbbrevSetOffsets);
1297       }
1298       auto It = upper_bound(AbbrevSetOffsets, StartOffset);
1299       const uint64_t EndOffset =
1300           It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It;
1301       AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset);
1302     } else {
1303       // For DWO unit outside of DWP, we expect the entire section to hold
1304       // abbreviations for this unit only.
1305       AbbrevContents = AbbrevSectionContents;
1306     }
1307 
1308     if (!hashAndAddAbbrev(AbbrevContents)) {
1309       OS.reserveExtraSpace(AbbrevContents.size());
1310       OS << AbbrevContents;
1311     }
1312     return;
1313   }
1314 
1315   for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) {
1316     const DWARFAbbreviationDeclaration &Abbrev = *I;
1317     auto Patch = UnitPatches.find(&Abbrev);
1318 
1319     encodeULEB128(Abbrev.getCode(), OS);
1320     encodeULEB128(Abbrev.getTag(), OS);
1321     encodeULEB128(Abbrev.hasChildren(), OS);
1322     for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec :
1323          Abbrev.attributes()) {
1324       if (Patch != UnitPatches.end()) {
1325         bool Patched = false;
1326         // Patches added later take a precedence over earlier ones.
1327         for (const PatchInfo &PI : llvm::reverse(Patch->second)) {
1328           if (PI.OldAttr != AttrSpec.Attr)
1329             continue;
1330 
1331           encodeULEB128(PI.NewAttr, OS);
1332           encodeULEB128(PI.NewAttrForm, OS);
1333           Patched = true;
1334           break;
1335         }
1336         if (Patched)
1337           continue;
1338       }
1339 
1340       encodeULEB128(AttrSpec.Attr, OS);
1341       encodeULEB128(AttrSpec.Form, OS);
1342       if (AttrSpec.isImplicitConst())
1343         encodeSLEB128(AttrSpec.getImplicitConstValue(), OS);
1344     }
1345     const auto Entries = AbbrevEntries.find(&Abbrev);
1346     // Adding new Abbrevs for inserted entries.
1347     if (Entries != AbbrevEntries.end()) {
1348       for (const AbbrevEntry &Entry : Entries->second) {
1349         encodeULEB128(Entry.Attr, OS);
1350         encodeULEB128(Entry.Form, OS);
1351       }
1352     }
1353     encodeULEB128(0, OS);
1354     encodeULEB128(0, OS);
1355   }
1356   encodeULEB128(0, OS);
1357 
1358   hashAndAddAbbrev(OS.str());
1359 }
1360 
1361 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() {
1362   // Used to create determinism for writing out abbrevs.
1363   std::vector<AbbrevData *> Abbrevs;
1364   if (DWOId) {
1365     // We expect abbrev_offset to always be zero for DWO units as there
1366     // should be one CU per DWO, and TUs should share the same abbreviation
1367     // set with the CU.
1368     // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so
1369     // can be none zero. Thus we are skipping the check for DWP.
1370     bool IsDWP = !Context.getCUIndex().getRows().empty();
1371     if (!IsDWP) {
1372       for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) {
1373         if (Unit->getAbbreviationsOffset() != 0) {
1374           errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. "
1375                     "Unable to update debug info.\n";
1376           exit(1);
1377         }
1378       }
1379     }
1380 
1381     DWARFUnit *Unit = Context.getDWOCompileUnitForHash(*DWOId);
1382     // Issue abbreviations for the DWO CU only.
1383     addUnitAbbreviations(*Unit);
1384     AbbrevData *Abbrev = UnitsAbbrevData[Unit];
1385     Abbrevs.push_back(Abbrev);
1386   } else {
1387     Abbrevs.reserve(Context.getNumCompileUnits() + Context.getNumTypeUnits());
1388     std::unordered_set<AbbrevData *> ProcessedAbbrevs;
1389     // Add abbreviations from compile and type non-DWO units.
1390     for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) {
1391       addUnitAbbreviations(*Unit);
1392       AbbrevData *Abbrev = UnitsAbbrevData[Unit.get()];
1393       if (!ProcessedAbbrevs.insert(Abbrev).second)
1394         continue;
1395       Abbrevs.push_back(Abbrev);
1396     }
1397   }
1398 
1399   DebugBufferVector ReturnBuffer;
1400   // Pre-calculate the total size of abbrev section.
1401   uint64_t Size = 0;
1402   for (const AbbrevData *UnitData : Abbrevs)
1403     Size += UnitData->Buffer->size();
1404 
1405   ReturnBuffer.reserve(Size);
1406 
1407   uint64_t Pos = 0;
1408   for (AbbrevData *UnitData : Abbrevs) {
1409     ReturnBuffer.append(*UnitData->Buffer);
1410     UnitData->Offset = Pos;
1411     Pos += UnitData->Buffer->size();
1412 
1413     UnitData->Buffer.reset();
1414     UnitData->Stream.reset();
1415   }
1416 
1417   return std::make_unique<DebugBufferVector>(ReturnBuffer);
1418 }
1419 
1420 static void emitDwarfSetLineAddrAbs(MCStreamer &OS,
1421                                     MCDwarfLineTableParams Params,
1422                                     int64_t LineDelta, uint64_t Address,
1423                                     int PointerSize) {
1424   // emit the sequence to set the address
1425   OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
1426   OS.emitULEB128IntValue(PointerSize + 1);
1427   OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
1428   OS.emitIntValue(Address, PointerSize);
1429 
1430   // emit the sequence for the LineDelta (from 1) and a zero address delta.
1431   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
1432 }
1433 
1434 static inline void emitBinaryDwarfLineTable(
1435     MCStreamer *MCOS, MCDwarfLineTableParams Params,
1436     const DWARFDebugLine::LineTable *Table,
1437     const std::vector<DwarfLineTable::RowSequence> &InputSequences) {
1438   if (InputSequences.empty())
1439     return;
1440 
1441   constexpr uint64_t InvalidAddress = UINT64_MAX;
1442   unsigned FileNum = 1;
1443   unsigned LastLine = 1;
1444   unsigned Column = 0;
1445   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1446   unsigned Isa = 0;
1447   unsigned Discriminator = 0;
1448   uint64_t LastAddress = InvalidAddress;
1449   uint64_t PrevEndOfSequence = InvalidAddress;
1450   const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
1451 
1452   auto emitEndOfSequence = [&](uint64_t Address) {
1453     MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress);
1454     FileNum = 1;
1455     LastLine = 1;
1456     Column = 0;
1457     Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1458     Isa = 0;
1459     Discriminator = 0;
1460     LastAddress = InvalidAddress;
1461   };
1462 
1463   for (const DwarfLineTable::RowSequence &Sequence : InputSequences) {
1464     const uint64_t SequenceStart =
1465         Table->Rows[Sequence.FirstIndex].Address.Address;
1466 
1467     // Check if we need to mark the end of the sequence.
1468     if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress &&
1469         PrevEndOfSequence != SequenceStart) {
1470       emitEndOfSequence(PrevEndOfSequence);
1471     }
1472 
1473     for (uint32_t RowIndex = Sequence.FirstIndex;
1474          RowIndex <= Sequence.LastIndex; ++RowIndex) {
1475       const DWARFDebugLine::Row &Row = Table->Rows[RowIndex];
1476       int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine;
1477       const uint64_t Address = Row.Address.Address;
1478 
1479       if (FileNum != Row.File) {
1480         FileNum = Row.File;
1481         MCOS->emitInt8(dwarf::DW_LNS_set_file);
1482         MCOS->emitULEB128IntValue(FileNum);
1483       }
1484       if (Column != Row.Column) {
1485         Column = Row.Column;
1486         MCOS->emitInt8(dwarf::DW_LNS_set_column);
1487         MCOS->emitULEB128IntValue(Column);
1488       }
1489       if (Discriminator != Row.Discriminator &&
1490           MCOS->getContext().getDwarfVersion() >= 4) {
1491         Discriminator = Row.Discriminator;
1492         unsigned Size = getULEB128Size(Discriminator);
1493         MCOS->emitInt8(dwarf::DW_LNS_extended_op);
1494         MCOS->emitULEB128IntValue(Size + 1);
1495         MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
1496         MCOS->emitULEB128IntValue(Discriminator);
1497       }
1498       if (Isa != Row.Isa) {
1499         Isa = Row.Isa;
1500         MCOS->emitInt8(dwarf::DW_LNS_set_isa);
1501         MCOS->emitULEB128IntValue(Isa);
1502       }
1503       if (Row.IsStmt != Flags) {
1504         Flags = Row.IsStmt;
1505         MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
1506       }
1507       if (Row.BasicBlock)
1508         MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
1509       if (Row.PrologueEnd)
1510         MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
1511       if (Row.EpilogueBegin)
1512         MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
1513 
1514       // The end of the sequence is not normal in the middle of the input
1515       // sequence, but could happen, e.g. for assembly code.
1516       if (Row.EndSequence) {
1517         emitEndOfSequence(Address);
1518       } else {
1519         if (LastAddress == InvalidAddress)
1520           emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address,
1521                                   AsmInfo->getCodePointerSize());
1522         else
1523           MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress);
1524 
1525         LastAddress = Address;
1526         LastLine = Row.Line;
1527       }
1528 
1529       Discriminator = 0;
1530     }
1531     PrevEndOfSequence = Sequence.EndAddress;
1532   }
1533 
1534   // Finish with the end of the sequence.
1535   if (LastAddress != InvalidAddress)
1536     emitEndOfSequence(PrevEndOfSequence);
1537 }
1538 
1539 // This function is similar to the one from MCDwarfLineTable, except it handles
1540 // end-of-sequence entries differently by utilizing line entries with
1541 // DWARF2_FLAG_END_SEQUENCE flag.
1542 static inline void emitDwarfLineTable(
1543     MCStreamer *MCOS, MCSection *Section,
1544     const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
1545   unsigned FileNum = 1;
1546   unsigned LastLine = 1;
1547   unsigned Column = 0;
1548   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1549   unsigned Isa = 0;
1550   unsigned Discriminator = 0;
1551   MCSymbol *LastLabel = nullptr;
1552   const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
1553 
1554   // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
1555   for (const MCDwarfLineEntry &LineEntry : LineEntries) {
1556     if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) {
1557       MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(),
1558                                      AsmInfo->getCodePointerSize());
1559       FileNum = 1;
1560       LastLine = 1;
1561       Column = 0;
1562       Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1563       Isa = 0;
1564       Discriminator = 0;
1565       LastLabel = nullptr;
1566       continue;
1567     }
1568 
1569     int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
1570 
1571     if (FileNum != LineEntry.getFileNum()) {
1572       FileNum = LineEntry.getFileNum();
1573       MCOS->emitInt8(dwarf::DW_LNS_set_file);
1574       MCOS->emitULEB128IntValue(FileNum);
1575     }
1576     if (Column != LineEntry.getColumn()) {
1577       Column = LineEntry.getColumn();
1578       MCOS->emitInt8(dwarf::DW_LNS_set_column);
1579       MCOS->emitULEB128IntValue(Column);
1580     }
1581     if (Discriminator != LineEntry.getDiscriminator() &&
1582         MCOS->getContext().getDwarfVersion() >= 2) {
1583       Discriminator = LineEntry.getDiscriminator();
1584       unsigned Size = getULEB128Size(Discriminator);
1585       MCOS->emitInt8(dwarf::DW_LNS_extended_op);
1586       MCOS->emitULEB128IntValue(Size + 1);
1587       MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
1588       MCOS->emitULEB128IntValue(Discriminator);
1589     }
1590     if (Isa != LineEntry.getIsa()) {
1591       Isa = LineEntry.getIsa();
1592       MCOS->emitInt8(dwarf::DW_LNS_set_isa);
1593       MCOS->emitULEB128IntValue(Isa);
1594     }
1595     if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
1596       Flags = LineEntry.getFlags();
1597       MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
1598     }
1599     if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
1600       MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
1601     if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
1602       MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
1603     if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
1604       MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
1605 
1606     MCSymbol *Label = LineEntry.getLabel();
1607 
1608     // At this point we want to emit/create the sequence to encode the delta
1609     // in line numbers and the increment of the address from the previous
1610     // Label and the current Label.
1611     MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
1612                                    AsmInfo->getCodePointerSize());
1613     Discriminator = 0;
1614     LastLine = LineEntry.getLine();
1615     LastLabel = Label;
1616   }
1617 
1618   assert(LastLabel == nullptr && "end of sequence expected");
1619 }
1620 
1621 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
1622                             std::optional<MCDwarfLineStr> &LineStr,
1623                             BinaryContext &BC) const {
1624   if (!RawData.empty()) {
1625     assert(MCLineSections.getMCLineEntries().empty() &&
1626            InputSequences.empty() &&
1627            "cannot combine raw data with new line entries");
1628     MCOS->emitLabel(getLabel());
1629     MCOS->emitBytes(RawData);
1630 
1631     // Emit fake relocation for RuntimeDyld to always allocate the section.
1632     //
1633     // FIXME: remove this once RuntimeDyld stops skipping allocatable sections
1634     //        without relocations.
1635     MCOS->emitRelocDirective(
1636         *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE",
1637         MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI);
1638 
1639     return;
1640   }
1641 
1642   MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
1643 
1644   // Put out the line tables.
1645   for (const auto &LineSec : MCLineSections.getMCLineEntries())
1646     emitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
1647 
1648   // Emit line tables for the original code.
1649   emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences);
1650 
1651   // This is the end of the section, so set the value of the symbol at the end
1652   // of this section (that was used in a previous expression).
1653   MCOS->emitLabel(LineEndSym);
1654 }
1655 
1656 // Helper function to parse .debug_line_str, and populate one we are using.
1657 // For functions that we do not modify we output them as raw data.
1658 // Re-constructing .debug_line_str so that offsets are correct for those
1659 // debut line tables.
1660 // Bonus is that when we output a final binary we can re-use .debug_line_str
1661 // section. So we don't have to do the SHF_ALLOC trick we did with
1662 // .debug_line.
1663 static void parseAndPopulateDebugLineStr(BinarySection &LineStrSection,
1664                                          MCDwarfLineStr &LineStr,
1665                                          BinaryContext &BC,
1666                                          MCStreamer &Streamer) {
1667   DataExtractor StrData(LineStrSection.getContents(),
1668                         BC.DwCtx->isLittleEndian(), 0);
1669   uint64_t Offset = 0;
1670   while (StrData.isValidOffset(Offset)) {
1671     Error Err = Error::success();
1672     const char *CStr = StrData.getCStr(&Offset, &Err);
1673     if (Err) {
1674       errs() << "BOLT-ERROR: could not extract string from .debug_line_str";
1675       continue;
1676     }
1677     LineStr.emitRef(&Streamer, CStr);
1678   }
1679 }
1680 
1681 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
1682   MCAssembler &Assembler =
1683       static_cast<MCObjectStreamer *>(&Streamer)->getAssembler();
1684 
1685   MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams();
1686 
1687   auto &LineTables = BC.getDwarfLineTables();
1688 
1689   // Bail out early so we don't switch to the debug_line section needlessly and
1690   // in doing so create an unnecessary (if empty) section.
1691   if (LineTables.empty())
1692     return;
1693   // In a v5 non-split line table, put the strings in a separate section.
1694   std::optional<MCDwarfLineStr> LineStr;
1695   ErrorOr<BinarySection &> LineStrSection =
1696       BC.getUniqueSectionByName(".debug_line_str");
1697   // Some versions of GCC output DWARF5 .debug_info, but DWARF4 or lower
1698   // .debug_line
1699   if (LineStrSection) {
1700     LineStr.emplace(*BC.Ctx);
1701     parseAndPopulateDebugLineStr(*LineStrSection, *LineStr, BC, Streamer);
1702   }
1703 
1704   // Switch to the section where the table will be emitted into.
1705   Streamer.switchSection(BC.MOFI->getDwarfLineSection());
1706 
1707   const uint16_t DwarfVersion = BC.Ctx->getDwarfVersion();
1708   // Handle the rest of the Compile Units.
1709   for (auto &CUIDTablePair : LineTables) {
1710     Streamer.getContext().setDwarfVersion(
1711         CUIDTablePair.second.getDwarfVersion());
1712     CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC);
1713   }
1714 
1715   // Resetting DWARF version for rest of the flow.
1716   BC.Ctx->setDwarfVersion(DwarfVersion);
1717 
1718   // Still need to write the section out for the ExecutionEngine, and temp in
1719   // memory object we are constructing.
1720   if (LineStr) {
1721     LineStr->emitSection(&Streamer);
1722     SmallString<0> Data = LineStr->getFinalizedData();
1723     BC.registerOrUpdateNoteSection(".debug_line_str", copyByteArray(Data.str()),
1724                                    Data.size());
1725   }
1726 }
1727 
1728 } // namespace bolt
1729 } // namespace llvm
1730