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