xref: /llvm-project/bolt/lib/Core/DebugData.cpp (revision 5828b04b0373f10fade7eefbeb181dc8ceb98422)
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/Core/DIEBuilder.h"
16 #include "bolt/Utils/Utils.h"
17 #include "llvm/BinaryFormat/Dwarf.h"
18 #include "llvm/CodeGen/DIE.h"
19 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
20 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
21 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
22 #include "llvm/MC/MCAssembler.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCObjectStreamer.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/EndianStream.h"
27 #include "llvm/Support/LEB128.h"
28 #include "llvm/Support/SHA1.h"
29 #include <algorithm>
30 #include <cassert>
31 #include <cstdint>
32 #include <functional>
33 #include <memory>
34 #include <optional>
35 #include <unordered_map>
36 #include <vector>
37 
38 #define DEBUG_TYPE "bolt-debug-info"
39 
40 namespace opts {
41 extern llvm::cl::opt<unsigned> Verbosity;
42 } // namespace opts
43 
44 namespace llvm {
45 class MCSymbol;
46 
47 namespace bolt {
48 
49 static void replaceLocValbyForm(DIEBuilder &DIEBldr, DIE &Die, DIEValue DIEVal,
50                                 dwarf::Form Format, uint64_t NewVal) {
51   if (Format == dwarf::DW_FORM_loclistx)
52     DIEBldr.replaceValue(&Die, DIEVal.getAttribute(), Format,
53                          DIELocList(NewVal));
54   else
55     DIEBldr.replaceValue(&Die, DIEVal.getAttribute(), Format,
56                          DIEInteger(NewVal));
57 }
58 
59 std::optional<AttrInfo>
60 findAttributeInfo(const DWARFDie DIE,
61                   const DWARFAbbreviationDeclaration *AbbrevDecl,
62                   uint32_t Index) {
63   const DWARFUnit &U = *DIE.getDwarfUnit();
64   uint64_t Offset =
65       AbbrevDecl->getAttributeOffsetFromIndex(Index, DIE.getOffset(), U);
66   std::optional<DWARFFormValue> Value =
67       AbbrevDecl->getAttributeValueFromOffset(Index, Offset, U);
68   if (!Value)
69     return std::nullopt;
70   // AttributeSpec
71   const DWARFAbbreviationDeclaration::AttributeSpec *AttrVal =
72       AbbrevDecl->attributes().begin() + Index;
73   uint32_t ValSize = 0;
74   std::optional<int64_t> ValSizeOpt = AttrVal->getByteSize(U);
75   if (ValSizeOpt) {
76     ValSize = static_cast<uint32_t>(*ValSizeOpt);
77   } else {
78     DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
79     uint64_t NewOffset = Offset;
80     DWARFFormValue::skipValue(Value->getForm(), DebugInfoData, &NewOffset,
81                               U.getFormParams());
82     // This includes entire size of the entry, which might not be just the
83     // encoding part. For example for DW_AT_loc it will include expression
84     // location.
85     ValSize = NewOffset - Offset;
86   }
87   return AttrInfo{*Value, DIE.getAbbreviationDeclarationPtr(), Offset, ValSize};
88 }
89 
90 std::optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
91                                           dwarf::Attribute Attr) {
92   if (!DIE.isValid())
93     return std::nullopt;
94   const DWARFAbbreviationDeclaration *AbbrevDecl =
95       DIE.getAbbreviationDeclarationPtr();
96   if (!AbbrevDecl)
97     return std::nullopt;
98   std::optional<uint32_t> Index = AbbrevDecl->findAttributeIndex(Attr);
99   if (!Index)
100     return std::nullopt;
101   return findAttributeInfo(DIE, AbbrevDecl, *Index);
102 }
103 
104 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0};
105 
106 LLVM_ATTRIBUTE_UNUSED
107 static void printLE64(const std::string &S) {
108   for (uint32_t I = 0, Size = S.size(); I < Size; ++I) {
109     errs() << Twine::utohexstr(S[I]);
110     errs() << Twine::utohexstr((int8_t)S[I]);
111   }
112   errs() << "\n";
113 }
114 
115 // Writes address ranges to Writer as pairs of 64-bit (address, size).
116 // If RelativeRange is true, assumes the address range to be written must be of
117 // the form (begin address, range size), otherwise (begin address, end address).
118 // Terminates the list by writing a pair of two zeroes.
119 // Returns the number of written bytes.
120 static uint64_t
121 writeAddressRanges(raw_svector_ostream &Stream,
122                    const DebugAddressRangesVector &AddressRanges,
123                    const bool WriteRelativeRanges = false) {
124   for (const DebugAddressRange &Range : AddressRanges) {
125     support::endian::write(Stream, Range.LowPC, llvm::endianness::little);
126     support::endian::write(
127         Stream, WriteRelativeRanges ? Range.HighPC - Range.LowPC : Range.HighPC,
128         llvm::endianness::little);
129   }
130   // Finish with 0 entries.
131   support::endian::write(Stream, 0ULL, llvm::endianness::little);
132   support::endian::write(Stream, 0ULL, llvm::endianness::little);
133   return AddressRanges.size() * 16 + 16;
134 }
135 
136 DebugRangesSectionWriter::DebugRangesSectionWriter() {
137   RangesBuffer = std::make_unique<DebugBufferVector>();
138   RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer);
139 
140   // Add an empty range as the first entry;
141   SectionOffset +=
142       writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
143   Kind = RangesWriterKind::DebugRangesWriter;
144 }
145 
146 uint64_t DebugRangesSectionWriter::addRanges(
147     DebugAddressRangesVector &&Ranges,
148     std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
149   if (Ranges.empty())
150     return getEmptyRangesOffset();
151 
152   const auto RI = CachedRanges.find(Ranges);
153   if (RI != CachedRanges.end())
154     return RI->second;
155 
156   const uint64_t EntryOffset = addRanges(Ranges);
157   CachedRanges.emplace(std::move(Ranges), EntryOffset);
158 
159   return EntryOffset;
160 }
161 
162 uint64_t DebugRangesSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
163   if (Ranges.empty())
164     return getEmptyRangesOffset();
165 
166   // Reading the SectionOffset and updating it should be atomic to guarantee
167   // unique and correct offsets in patches.
168   std::lock_guard<std::mutex> Lock(WriterMutex);
169   const uint32_t EntryOffset = SectionOffset;
170   SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges);
171 
172   return EntryOffset;
173 }
174 
175 uint64_t DebugRangesSectionWriter::getSectionOffset() {
176   std::lock_guard<std::mutex> Lock(WriterMutex);
177   return SectionOffset;
178 }
179 
180 void DebugRangesSectionWriter::appendToRangeBuffer(
181     const DebugBufferVector &CUBuffer) {
182   *RangesStream << CUBuffer;
183   SectionOffset = RangesBuffer->size();
184 }
185 
186 DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
187 
188 uint64_t DebugRangeListsSectionWriter::addRanges(
189     DebugAddressRangesVector &&Ranges,
190     std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
191   return addRanges(Ranges);
192 }
193 
194 struct LocListsRangelistsHeader {
195   UnitLengthType UnitLength; // Size of loclist entries section, not including
196                              // size of header.
197   VersionType Version;
198   AddressSizeType AddressSize;
199   SegmentSelectorType SegmentSelector;
200   OffsetEntryCountType OffsetEntryCount;
201 };
202 
203 static std::unique_ptr<DebugBufferVector>
204 getDWARF5Header(const LocListsRangelistsHeader &Header) {
205   std::unique_ptr<DebugBufferVector> HeaderBuffer =
206       std::make_unique<DebugBufferVector>();
207   std::unique_ptr<raw_svector_ostream> HeaderStream =
208       std::make_unique<raw_svector_ostream>(*HeaderBuffer);
209 
210   // 7.29 length of the set of entries for this compilation unit, not including
211   // the length field itself
212   const uint32_t HeaderSize =
213       getDWARF5RngListLocListHeaderSize() - sizeof(UnitLengthType);
214 
215   support::endian::write(*HeaderStream, Header.UnitLength + HeaderSize,
216                          llvm::endianness::little);
217   support::endian::write(*HeaderStream, Header.Version,
218                          llvm::endianness::little);
219   support::endian::write(*HeaderStream, Header.AddressSize,
220                          llvm::endianness::little);
221   support::endian::write(*HeaderStream, Header.SegmentSelector,
222                          llvm::endianness::little);
223   support::endian::write(*HeaderStream, Header.OffsetEntryCount,
224                          llvm::endianness::little);
225   return HeaderBuffer;
226 }
227 
228 struct OffsetEntry {
229   uint32_t Index;
230   uint32_t StartOffset;
231   uint32_t EndOffset;
232 };
233 template <typename DebugVector, typename ListEntry, typename DebugAddressEntry>
234 static bool emitWithBase(raw_ostream &OS, const DebugVector &Entries,
235                          DebugAddrWriter &AddrWriter, DWARFUnit &CU,
236                          uint32_t &Index, const ListEntry BaseAddressx,
237                          const ListEntry OffsetPair,
238                          const std::function<void(uint32_t)> &Func) {
239   if (Entries.size() < 2)
240     return false;
241   uint64_t Base = Entries[Index].LowPC;
242   std::vector<OffsetEntry> Offsets;
243   uint8_t TempBuffer[64];
244   while (Index < Entries.size()) {
245     const DebugAddressEntry &Entry = Entries[Index];
246     if (Entry.LowPC == 0)
247       break;
248     // In case rnglists or loclists are not sorted.
249     if (Base > Entry.LowPC)
250       break;
251     uint32_t StartOffset = Entry.LowPC - Base;
252     uint32_t EndOffset = Entry.HighPC - Base;
253     if (encodeULEB128(EndOffset, TempBuffer) > 2)
254       break;
255     Offsets.push_back({Index, StartOffset, EndOffset});
256     ++Index;
257   }
258 
259   if (Offsets.size() < 2) {
260     Index -= Offsets.size();
261     return false;
262   }
263 
264   support::endian::write(OS, static_cast<uint8_t>(BaseAddressx),
265                          llvm::endianness::little);
266   uint32_t BaseIndex = AddrWriter.getIndexFromAddress(Base, CU);
267   encodeULEB128(BaseIndex, OS);
268   for (auto &OffsetEntry : Offsets) {
269     support::endian::write(OS, static_cast<uint8_t>(OffsetPair),
270                            llvm::endianness::little);
271     encodeULEB128(OffsetEntry.StartOffset, OS);
272     encodeULEB128(OffsetEntry.EndOffset, OS);
273     Func(OffsetEntry.Index);
274   }
275   return true;
276 }
277 
278 uint64_t
279 DebugRangeListsSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
280   std::lock_guard<std::mutex> Lock(WriterMutex);
281 
282   RangeEntries.push_back(CurrentOffset);
283   std::sort(
284       Ranges.begin(), Ranges.end(),
285       [](const DebugAddressRange &R1, const DebugAddressRange &R2) -> bool {
286         return R1.LowPC < R2.LowPC;
287       });
288   for (unsigned I = 0; I < Ranges.size();) {
289     if (emitWithBase<DebugAddressRangesVector, dwarf::RnglistEntries,
290                      DebugAddressRange>(*CUBodyStream, Ranges, *AddrWriter, *CU,
291                                         I, dwarf::DW_RLE_base_addressx,
292                                         dwarf::DW_RLE_offset_pair,
293                                         [](uint32_t Index) -> void {}))
294       continue;
295 
296     const DebugAddressRange &Range = Ranges[I];
297     support::endian::write(*CUBodyStream,
298                            static_cast<uint8_t>(dwarf::DW_RLE_startx_length),
299                            llvm::endianness::little);
300     uint32_t Index = AddrWriter->getIndexFromAddress(Range.LowPC, *CU);
301     encodeULEB128(Index, *CUBodyStream);
302     encodeULEB128(Range.HighPC - Range.LowPC, *CUBodyStream);
303     ++I;
304   }
305 
306   support::endian::write(*CUBodyStream,
307                          static_cast<uint8_t>(dwarf::DW_RLE_end_of_list),
308                          llvm::endianness::little);
309   CurrentOffset = CUBodyBuffer->size();
310   return RangeEntries.size() - 1;
311 }
312 
313 void DebugRangeListsSectionWriter::finalizeSection() {
314   std::unique_ptr<DebugBufferVector> CUArrayBuffer =
315       std::make_unique<DebugBufferVector>();
316   std::unique_ptr<raw_svector_ostream> CUArrayStream =
317       std::make_unique<raw_svector_ostream>(*CUArrayBuffer);
318   constexpr uint32_t SizeOfArrayEntry = 4;
319   const uint32_t SizeOfArraySection = RangeEntries.size() * SizeOfArrayEntry;
320   for (uint32_t Offset : RangeEntries)
321     support::endian::write(*CUArrayStream, Offset + SizeOfArraySection,
322                            llvm::endianness::little);
323 
324   std::unique_ptr<DebugBufferVector> Header = getDWARF5Header(
325       {static_cast<uint32_t>(SizeOfArraySection + CUBodyBuffer.get()->size()),
326        5, 8, 0, static_cast<uint32_t>(RangeEntries.size())});
327   *RangesStream << *Header;
328   *RangesStream << *CUArrayBuffer;
329   *RangesStream << *CUBodyBuffer;
330   SectionOffset = RangesBuffer->size();
331 }
332 
333 void DebugRangeListsSectionWriter::initSection(DWARFUnit &Unit) {
334   CUBodyBuffer = std::make_unique<DebugBufferVector>();
335   CUBodyStream = std::make_unique<raw_svector_ostream>(*CUBodyBuffer);
336   RangeEntries.clear();
337   CurrentOffset = 0;
338   CU = &Unit;
339 }
340 
341 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
342                                             DebugAddressRangesVector &&Ranges) {
343   std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
344   CUAddressRanges.emplace(CUOffset, std::move(Ranges));
345 }
346 
347 void DebugARangesSectionWriter::writeARangesSection(
348     raw_svector_ostream &RangesStream, const CUOffsetMap &CUMap) const {
349   // For reference on the format of the .debug_aranges section, see the DWARF4
350   // specification, section 6.1.4 Lookup by Address
351   // http://www.dwarfstd.org/doc/DWARF4.pdf
352   for (const auto &CUOffsetAddressRangesPair : CUAddressRanges) {
353     const uint64_t Offset = CUOffsetAddressRangesPair.first;
354     const DebugAddressRangesVector &AddressRanges =
355         CUOffsetAddressRangesPair.second;
356 
357     // Emit header.
358 
359     // Size of this set: 8 (size of the header) + 4 (padding after header)
360     // + 2*sizeof(uint64_t) bytes for each of the ranges, plus an extra
361     // pair of uint64_t's for the terminating, zero-length range.
362     // Does not include size field itself.
363     uint32_t Size = 8 + 4 + 2 * sizeof(uint64_t) * (AddressRanges.size() + 1);
364 
365     // Header field #1: set size.
366     support::endian::write(RangesStream, Size, llvm::endianness::little);
367 
368     // Header field #2: version number, 2 as per the specification.
369     support::endian::write(RangesStream, static_cast<uint16_t>(2),
370                            llvm::endianness::little);
371 
372     assert(CUMap.count(Offset) && "Original CU offset is not found in CU Map");
373     // Header field #3: debug info offset of the correspondent compile unit.
374     support::endian::write(
375         RangesStream, static_cast<uint32_t>(CUMap.find(Offset)->second.Offset),
376         llvm::endianness::little);
377 
378     // Header field #4: address size.
379     // 8 since we only write ELF64 binaries for now.
380     RangesStream << char(8);
381 
382     // Header field #5: segment size of target architecture.
383     RangesStream << char(0);
384 
385     // Padding before address table - 4 bytes in the 64-bit-pointer case.
386     support::endian::write(RangesStream, static_cast<uint32_t>(0),
387                            llvm::endianness::little);
388 
389     writeAddressRanges(RangesStream, AddressRanges, true);
390   }
391 }
392 
393 DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
394   Buffer = std::make_unique<AddressSectionBuffer>();
395   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
396 }
397 
398 void DebugAddrWriter::AddressForDWOCU::dump() {
399   std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(),
400                                           indexToAdddessEnd());
401   // Sorting address in increasing order of indices.
402   llvm::sort(SortedMap, llvm::less_first());
403   for (auto &Pair : SortedMap)
404     dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
405 }
406 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
407   std::lock_guard<std::mutex> Lock(WriterMutex);
408   const uint64_t CUID = getCUID(CU);
409   if (!AddressMaps.count(CUID))
410     AddressMaps[CUID] = AddressForDWOCU();
411 
412   AddressForDWOCU &Map = AddressMaps[CUID];
413   auto Entry = Map.find(Address);
414   if (Entry == Map.end()) {
415     auto Index = Map.getNextIndex();
416     Entry = Map.insert(Address, Index).first;
417   }
418   return Entry->second;
419 }
420 
421 static void updateAddressBase(DIEBuilder &DIEBlder, DebugAddrWriter &AddrWriter,
422                               DWARFUnit &CU, const uint64_t Offset) {
423   DIE *Die = DIEBlder.getUnitDIEbyUnit(CU);
424   DIEValue GnuAddrBaseAttrInfo = Die->findAttribute(dwarf::DW_AT_GNU_addr_base);
425   DIEValue AddrBaseAttrInfo = Die->findAttribute(dwarf::DW_AT_addr_base);
426   dwarf::Form BaseAttrForm;
427   dwarf::Attribute BaseAttr;
428   // For cases where Skeleton CU does not have DW_AT_GNU_addr_base
429   if (!GnuAddrBaseAttrInfo && CU.getVersion() < 5)
430     return;
431 
432   if (GnuAddrBaseAttrInfo) {
433     BaseAttrForm = GnuAddrBaseAttrInfo.getForm();
434     BaseAttr = GnuAddrBaseAttrInfo.getAttribute();
435   }
436 
437   if (AddrBaseAttrInfo) {
438     BaseAttrForm = AddrBaseAttrInfo.getForm();
439     BaseAttr = AddrBaseAttrInfo.getAttribute();
440   }
441 
442   if (GnuAddrBaseAttrInfo || AddrBaseAttrInfo) {
443     DIEBlder.replaceValue(Die, BaseAttr, BaseAttrForm, DIEInteger(Offset));
444   } else if (CU.getVersion() >= 5) {
445     // A case where we were not using .debug_addr section, but after update
446     // now using it.
447     DIEBlder.addValue(Die, dwarf::DW_AT_addr_base, dwarf::DW_FORM_sec_offset,
448                       DIEInteger(Offset));
449   }
450 }
451 
452 void DebugAddrWriter::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
453   // Handling the case where debug information is a mix of Debug fission and
454   // monolithic.
455   if (!CU.getDWOId())
456     return;
457   const uint64_t CUID = getCUID(CU);
458   auto AM = AddressMaps.find(CUID);
459   // Adding to map even if it did not contribute to .debug_addr.
460   // The Skeleton CU might still have DW_AT_GNU_addr_base.
461   uint64_t Offset = Buffer->size();
462   // If does not exist this CUs DWO section didn't contribute to .debug_addr.
463   if (AM == AddressMaps.end())
464     return;
465   std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(),
466                                           AM->second.indexToAdddessEnd());
467   // Sorting address in increasing order of indices.
468   llvm::sort(SortedMap, llvm::less_first());
469 
470   uint8_t AddrSize = CU.getAddressByteSize();
471   uint32_t Counter = 0;
472   auto WriteAddress = [&](uint64_t Address) -> void {
473     ++Counter;
474     switch (AddrSize) {
475     default:
476       assert(false && "Address Size is invalid.");
477       break;
478     case 4:
479       support::endian::write(*AddressStream, static_cast<uint32_t>(Address),
480                              llvm::endianness::little);
481       break;
482     case 8:
483       support::endian::write(*AddressStream, Address, llvm::endianness::little);
484       break;
485     }
486   };
487 
488   for (const IndexAddressPair &Val : SortedMap) {
489     while (Val.first > Counter)
490       WriteAddress(0);
491     WriteAddress(Val.second);
492   }
493   updateAddressBase(DIEBlder, *this, CU, Offset);
494 }
495 
496 void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
497   // Need to layout all sections within .debug_addr
498   // Within each section sort Address by index.
499   const endianness Endian = BC->DwCtx->isLittleEndian()
500                                 ? llvm::endianness::little
501                                 : llvm::endianness::big;
502   const DWARFSection &AddrSec = BC->DwCtx->getDWARFObj().getAddrSection();
503   DWARFDataExtractor AddrData(BC->DwCtx->getDWARFObj(), AddrSec,
504                               Endian == llvm::endianness::little, 0);
505   DWARFDebugAddrTable AddrTable;
506   DIDumpOptions DumpOpts;
507   constexpr uint32_t HeaderSize = 8;
508   const uint64_t CUID = getCUID(CU);
509   const uint8_t AddrSize = CU.getAddressByteSize();
510   auto AMIter = AddressMaps.find(CUID);
511   // A case where CU has entry in .debug_addr, but we don't modify addresses
512   // for it.
513   if (AMIter == AddressMaps.end()) {
514     AMIter = AddressMaps.insert({CUID, AddressForDWOCU()}).first;
515     std::optional<uint64_t> BaseOffset = CU.getAddrOffsetSectionBase();
516     if (!BaseOffset)
517       return;
518     // Address base offset is to the first entry.
519     // The size of header is 8 bytes.
520     uint64_t Offset = *BaseOffset - HeaderSize;
521     auto Iter = UnmodifiedAddressOffsets.find(Offset);
522     if (Iter != UnmodifiedAddressOffsets.end()) {
523       updateAddressBase(DIEBlder, *this, CU, Iter->getSecond());
524       return;
525     }
526     UnmodifiedAddressOffsets[Offset] = Buffer->size() + HeaderSize;
527     if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddrSize,
528                                       DumpOpts.WarningHandler)) {
529       DumpOpts.RecoverableErrorHandler(std::move(Err));
530       return;
531     }
532 
533     uint32_t Index = 0;
534     for (uint64_t Addr : AddrTable.getAddressEntries())
535       AMIter->second.insert(Addr, Index++);
536   }
537 
538   updateAddressBase(DIEBlder, *this, CU, Buffer->size() + HeaderSize);
539 
540   std::vector<IndexAddressPair> SortedMap(AMIter->second.indexToAddressBegin(),
541                                           AMIter->second.indexToAdddessEnd());
542   // Sorting address in increasing order of indices.
543   llvm::sort(SortedMap, llvm::less_first());
544   // Writing out Header
545   const uint32_t Length = SortedMap.size() * AddrSize + 4;
546   support::endian::write(*AddressStream, Length, Endian);
547   support::endian::write(*AddressStream, static_cast<uint16_t>(5), Endian);
548   support::endian::write(*AddressStream, static_cast<uint8_t>(AddrSize),
549                          Endian);
550   support::endian::write(*AddressStream, static_cast<uint8_t>(0), Endian);
551 
552   uint32_t Counter = 0;
553   auto writeAddress = [&](uint64_t Address) -> void {
554     ++Counter;
555     switch (AddrSize) {
556     default:
557       llvm_unreachable("Address Size is invalid.");
558       break;
559     case 4:
560       support::endian::write(*AddressStream, static_cast<uint32_t>(Address),
561                              Endian);
562       break;
563     case 8:
564       support::endian::write(*AddressStream, Address, Endian);
565       break;
566     }
567   };
568 
569   for (const IndexAddressPair &Val : SortedMap) {
570     while (Val.first > Counter)
571       writeAddress(0);
572     writeAddress(Val.second);
573   }
574 }
575 
576 void DebugLocWriter::init() {
577   LocBuffer = std::make_unique<DebugBufferVector>();
578   LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
579   // Writing out empty location list to which all references to empty location
580   // lists will point.
581   if (!LocSectionOffset && DwarfVersion < 5) {
582     const char Zeroes[16] = {0};
583     *LocStream << StringRef(Zeroes, 16);
584     LocSectionOffset += 16;
585   }
586 }
587 
588 uint32_t DebugLocWriter::LocSectionOffset = 0;
589 void DebugLocWriter::addList(DIEBuilder &DIEBldr, DIE &Die, DIEValue &AttrInfo,
590                              DebugLocationsVector &LocList) {
591   if (LocList.empty()) {
592     replaceLocValbyForm(DIEBldr, Die, AttrInfo, AttrInfo.getForm(),
593                         DebugLocWriter::EmptyListOffset);
594     return;
595   }
596   // Since there is a separate DebugLocWriter for each thread,
597   // we don't need a lock to read the SectionOffset and update it.
598   const uint32_t EntryOffset = LocSectionOffset;
599 
600   for (const DebugLocationEntry &Entry : LocList) {
601     support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC),
602                            llvm::endianness::little);
603     support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC),
604                            llvm::endianness::little);
605     support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()),
606                            llvm::endianness::little);
607     *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
608                             Entry.Expr.size());
609     LocSectionOffset += 2 * 8 + 2 + Entry.Expr.size();
610   }
611   LocStream->write_zeros(16);
612   LocSectionOffset += 16;
613   LocListDebugInfoPatches.push_back({0xdeadbeee, EntryOffset}); // never seen
614                                                                 // use
615   replaceLocValbyForm(DIEBldr, Die, AttrInfo, AttrInfo.getForm(), EntryOffset);
616 }
617 
618 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() {
619   return std::move(LocBuffer);
620 }
621 
622 // DWARF 4: 2.6.2
623 void DebugLocWriter::finalize(DIEBuilder &DIEBldr, DIE &Die) {}
624 
625 static void writeEmptyListDwarf5(raw_svector_ostream &Stream) {
626   support::endian::write(Stream, static_cast<uint32_t>(4),
627                          llvm::endianness::little);
628   support::endian::write(Stream, static_cast<uint8_t>(dwarf::DW_LLE_start_end),
629                          llvm::endianness::little);
630 
631   const char Zeroes[16] = {0};
632   Stream << StringRef(Zeroes, 16);
633   encodeULEB128(0, Stream);
634   support::endian::write(Stream,
635                          static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
636                          llvm::endianness::little);
637 }
638 
639 static void writeLegacyLocList(DIEValue &AttrInfo,
640                                DebugLocationsVector &LocList,
641                                DIEBuilder &DIEBldr, DIE &Die,
642                                DebugAddrWriter &AddrWriter,
643                                DebugBufferVector &LocBuffer, DWARFUnit &CU,
644                                raw_svector_ostream &LocStream) {
645   if (LocList.empty()) {
646     replaceLocValbyForm(DIEBldr, Die, AttrInfo, AttrInfo.getForm(),
647                         DebugLocWriter::EmptyListOffset);
648     return;
649   }
650 
651   const uint32_t EntryOffset = LocBuffer.size();
652   for (const DebugLocationEntry &Entry : LocList) {
653     support::endian::write(LocStream,
654                            static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
655                            llvm::endianness::little);
656     const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU);
657     encodeULEB128(Index, LocStream);
658 
659     support::endian::write(LocStream,
660                            static_cast<uint32_t>(Entry.HighPC - Entry.LowPC),
661                            llvm::endianness::little);
662     support::endian::write(LocStream, static_cast<uint16_t>(Entry.Expr.size()),
663                            llvm::endianness::little);
664     LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
665                            Entry.Expr.size());
666   }
667   support::endian::write(LocStream,
668                          static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
669                          llvm::endianness::little);
670   replaceLocValbyForm(DIEBldr, Die, AttrInfo, AttrInfo.getForm(), EntryOffset);
671 }
672 
673 static void writeDWARF5LocList(uint32_t &NumberOfEntries, DIEValue &AttrInfo,
674                                DebugLocationsVector &LocList, DIE &Die,
675                                DIEBuilder &DIEBldr, DebugAddrWriter &AddrWriter,
676                                DebugBufferVector &LocBodyBuffer,
677                                std::vector<uint32_t> &RelativeLocListOffsets,
678                                DWARFUnit &CU,
679                                raw_svector_ostream &LocBodyStream) {
680 
681   replaceLocValbyForm(DIEBldr, Die, AttrInfo, dwarf::DW_FORM_loclistx,
682                       NumberOfEntries);
683 
684   RelativeLocListOffsets.push_back(LocBodyBuffer.size());
685   ++NumberOfEntries;
686   if (LocList.empty()) {
687     writeEmptyListDwarf5(LocBodyStream);
688     return;
689   }
690 
691   std::vector<uint64_t> OffsetsArray;
692   auto writeExpression = [&](uint32_t Index) -> void {
693     const DebugLocationEntry &Entry = LocList[Index];
694     encodeULEB128(Entry.Expr.size(), LocBodyStream);
695     LocBodyStream << StringRef(
696         reinterpret_cast<const char *>(Entry.Expr.data()), Entry.Expr.size());
697   };
698   for (unsigned I = 0; I < LocList.size();) {
699     if (emitWithBase<DebugLocationsVector, dwarf::LoclistEntries,
700                      DebugLocationEntry>(LocBodyStream, LocList, AddrWriter, CU,
701                                          I, dwarf::DW_LLE_base_addressx,
702                                          dwarf::DW_LLE_offset_pair,
703                                          writeExpression))
704       continue;
705 
706     const DebugLocationEntry &Entry = LocList[I];
707     support::endian::write(LocBodyStream,
708                            static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
709                            llvm::endianness::little);
710     const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU);
711     encodeULEB128(Index, LocBodyStream);
712     encodeULEB128(Entry.HighPC - Entry.LowPC, LocBodyStream);
713     writeExpression(I);
714     ++I;
715   }
716 
717   support::endian::write(LocBodyStream,
718                          static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
719                          llvm::endianness::little);
720 }
721 
722 void DebugLoclistWriter::addList(DIEBuilder &DIEBldr, DIE &Die,
723                                  DIEValue &AttrInfo,
724                                  DebugLocationsVector &LocList) {
725   if (DwarfVersion < 5)
726     writeLegacyLocList(AttrInfo, LocList, DIEBldr, Die, *AddrWriter, *LocBuffer,
727                        CU, *LocStream);
728   else
729     writeDWARF5LocList(NumberOfEntries, AttrInfo, LocList, Die, DIEBldr,
730                        *AddrWriter, *LocBodyBuffer, RelativeLocListOffsets, CU,
731                        *LocBodyStream);
732 }
733 
734 uint32_t DebugLoclistWriter::LoclistBaseOffset = 0;
735 void DebugLoclistWriter::finalizeDWARF5(DIEBuilder &DIEBldr, DIE &Die) {
736   if (LocBodyBuffer->empty()) {
737     DIEValue LocListBaseAttrInfo =
738         Die.findAttribute(dwarf::DW_AT_loclists_base);
739     // Pointing to first one, because it doesn't matter. There are no uses of it
740     // in this CU.
741     if (!isSplitDwarf() && LocListBaseAttrInfo.getType())
742       DIEBldr.replaceValue(&Die, dwarf::DW_AT_loclists_base,
743                            LocListBaseAttrInfo.getForm(),
744                            DIEInteger(getDWARF5RngListLocListHeaderSize()));
745     return;
746   }
747 
748   std::unique_ptr<DebugBufferVector> LocArrayBuffer =
749       std::make_unique<DebugBufferVector>();
750   std::unique_ptr<raw_svector_ostream> LocArrayStream =
751       std::make_unique<raw_svector_ostream>(*LocArrayBuffer);
752 
753   const uint32_t SizeOfArraySection = NumberOfEntries * sizeof(uint32_t);
754   // Write out IndexArray
755   for (uint32_t RelativeOffset : RelativeLocListOffsets)
756     support::endian::write(
757         *LocArrayStream,
758         static_cast<uint32_t>(SizeOfArraySection + RelativeOffset),
759         llvm::endianness::little);
760 
761   std::unique_ptr<DebugBufferVector> Header = getDWARF5Header(
762       {static_cast<uint32_t>(SizeOfArraySection + LocBodyBuffer.get()->size()),
763        5, 8, 0, NumberOfEntries});
764   *LocStream << *Header;
765   *LocStream << *LocArrayBuffer;
766   *LocStream << *LocBodyBuffer;
767 
768   if (!isSplitDwarf()) {
769     DIEValue LocListBaseAttrInfo =
770         Die.findAttribute(dwarf::DW_AT_loclists_base);
771     if (LocListBaseAttrInfo.getType()) {
772       DIEBldr.replaceValue(
773           &Die, dwarf::DW_AT_loclists_base, LocListBaseAttrInfo.getForm(),
774           DIEInteger(LoclistBaseOffset + getDWARF5RngListLocListHeaderSize()));
775     } else {
776       DIEBldr.addValue(&Die, dwarf::DW_AT_loclists_base,
777                        dwarf::DW_FORM_sec_offset,
778                        DIEInteger(LoclistBaseOffset + Header->size()));
779     }
780     LoclistBaseOffset += LocBuffer->size();
781   }
782   clearList(RelativeLocListOffsets);
783   clearList(*LocArrayBuffer);
784   clearList(*LocBodyBuffer);
785 }
786 
787 void DebugLoclistWriter::finalize(DIEBuilder &DIEBldr, DIE &Die) {
788   if (DwarfVersion >= 5)
789     finalizeDWARF5(DIEBldr, Die);
790 }
791 
792 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
793 
794 static std::string encodeLE(size_t ByteSize, uint64_t NewValue) {
795   std::string LE64(ByteSize, 0);
796   for (size_t I = 0; I < ByteSize; ++I) {
797     LE64[I] = NewValue & 0xff;
798     NewValue >>= 8;
799   }
800   return LE64;
801 }
802 
803 void SimpleBinaryPatcher::addBinaryPatch(uint64_t Offset,
804                                          std::string &&NewValue,
805                                          uint32_t OldValueSize) {
806   Patches.emplace_back(Offset, std::move(NewValue));
807 }
808 
809 void SimpleBinaryPatcher::addBytePatch(uint64_t Offset, uint8_t Value) {
810   auto Str = std::string(1, Value);
811   Patches.emplace_back(Offset, std::move(Str));
812 }
813 
814 void SimpleBinaryPatcher::addLEPatch(uint64_t Offset, uint64_t NewValue,
815                                      size_t ByteSize) {
816   Patches.emplace_back(Offset, encodeLE(ByteSize, NewValue));
817 }
818 
819 void SimpleBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t Value,
820                                         uint32_t OldValueSize) {
821   std::string Buff;
822   raw_string_ostream OS(Buff);
823   encodeULEB128(Value, OS, OldValueSize);
824 
825   Patches.emplace_back(Offset, std::move(Buff));
826 }
827 
828 void SimpleBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) {
829   addLEPatch(Offset, NewValue, 8);
830 }
831 
832 void SimpleBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue,
833                                        uint32_t OldValueSize) {
834   addLEPatch(Offset, NewValue, 4);
835 }
836 
837 std::string SimpleBinaryPatcher::patchBinary(StringRef BinaryContents) {
838   std::string BinaryContentsStr = std::string(BinaryContents);
839   for (const auto &Patch : Patches) {
840     uint32_t Offset = Patch.first;
841     const std::string &ByteSequence = Patch.second;
842     assert(Offset + ByteSequence.size() <= BinaryContents.size() &&
843            "Applied patch runs over binary size.");
844     for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) {
845       BinaryContentsStr[Offset + I] = ByteSequence[I];
846     }
847   }
848   return BinaryContentsStr;
849 }
850 
851 void DebugStrOffsetsWriter::initialize(DWARFUnit &Unit) {
852   if (Unit.getVersion() < 5)
853     return;
854   const DWARFSection &StrOffsetsSection = Unit.getStringOffsetSection();
855   const std::optional<StrOffsetsContributionDescriptor> &Contr =
856       Unit.getStringOffsetsTableContribution();
857   if (!Contr)
858     return;
859   const uint8_t DwarfOffsetByteSize = Contr->getDwarfOffsetByteSize();
860   assert(DwarfOffsetByteSize == 4 &&
861          "Dwarf String Offsets Byte Size is not supported.");
862   StrOffsets.reserve(Contr->Size);
863   for (uint64_t Offset = 0; Offset < Contr->Size; Offset += DwarfOffsetByteSize)
864     StrOffsets.push_back(support::endian::read32le(
865         StrOffsetsSection.Data.data() + Contr->Base + Offset));
866 }
867 
868 void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) {
869   IndexToAddressMap[Index] = Address;
870   StrOffsetSectionWasModified = true;
871 }
872 
873 void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit,
874                                             DIEBuilder &DIEBldr) {
875   std::optional<AttrInfo> AttrVal =
876       findAttributeInfo(Unit.getUnitDIE(), dwarf::DW_AT_str_offsets_base);
877   if (!AttrVal && !Unit.isDWOUnit())
878     return;
879   std::optional<uint64_t> Val = std::nullopt;
880   if (AttrVal) {
881     Val = AttrVal->V.getAsSectionOffset();
882   } else {
883     if (!Unit.isDWOUnit())
884       BC.errs() << "BOLT-WARNING: [internal-dwarf-error]: "
885                    "DW_AT_str_offsets_base Value not present\n";
886     Val = 0;
887   }
888   DIE &Die = *DIEBldr.getUnitDIEbyUnit(Unit);
889   DIEValue StrListBaseAttrInfo =
890       Die.findAttribute(dwarf::DW_AT_str_offsets_base);
891   auto RetVal = ProcessedBaseOffsets.find(*Val);
892   // Handling re-use of str-offsets section.
893   if (RetVal == ProcessedBaseOffsets.end() || StrOffsetSectionWasModified) {
894     initialize(Unit);
895     // Update String Offsets that were modified.
896     for (const auto &Entry : IndexToAddressMap)
897       StrOffsets[Entry.first] = Entry.second;
898     // Writing out the header for each section.
899     support::endian::write(*StrOffsetsStream,
900                            static_cast<uint32_t>(StrOffsets.size() * 4 + 4),
901                            llvm::endianness::little);
902     support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(5),
903                            llvm::endianness::little);
904     support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(0),
905                            llvm::endianness::little);
906 
907     uint64_t BaseOffset = StrOffsetsBuffer->size();
908     ProcessedBaseOffsets[*Val] = BaseOffset;
909     if (StrListBaseAttrInfo.getType())
910       DIEBldr.replaceValue(&Die, dwarf::DW_AT_str_offsets_base,
911                            StrListBaseAttrInfo.getForm(),
912                            DIEInteger(BaseOffset));
913     for (const uint32_t Offset : StrOffsets)
914       support::endian::write(*StrOffsetsStream, Offset,
915                              llvm::endianness::little);
916   } else {
917     DIEBldr.replaceValue(&Die, dwarf::DW_AT_str_offsets_base,
918                          StrListBaseAttrInfo.getForm(),
919                          DIEInteger(RetVal->second));
920   }
921 
922   StrOffsetSectionWasModified = false;
923   clear();
924 }
925 
926 void DebugStrWriter::create() {
927   StrBuffer = std::make_unique<DebugStrBufferVector>();
928   StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer);
929 }
930 
931 void DebugStrWriter::initialize() {
932   StringRef StrSection;
933   if (IsDWO)
934     StrSection = DwCtx.getDWARFObj().getStrDWOSection();
935   else
936     StrSection = DwCtx.getDWARFObj().getStrSection();
937   (*StrStream) << StrSection;
938 }
939 
940 uint32_t DebugStrWriter::addString(StringRef Str) {
941   std::lock_guard<std::mutex> Lock(WriterMutex);
942   if (StrBuffer->empty())
943     initialize();
944   auto Offset = StrBuffer->size();
945   (*StrStream) << Str;
946   StrStream->write_zeros(1);
947   return Offset;
948 }
949 
950 static void emitDwarfSetLineAddrAbs(MCStreamer &OS,
951                                     MCDwarfLineTableParams Params,
952                                     int64_t LineDelta, uint64_t Address,
953                                     int PointerSize) {
954   // emit the sequence to set the address
955   OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
956   OS.emitULEB128IntValue(PointerSize + 1);
957   OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
958   OS.emitIntValue(Address, PointerSize);
959 
960   // emit the sequence for the LineDelta (from 1) and a zero address delta.
961   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
962 }
963 
964 static inline void emitBinaryDwarfLineTable(
965     MCStreamer *MCOS, MCDwarfLineTableParams Params,
966     const DWARFDebugLine::LineTable *Table,
967     const std::vector<DwarfLineTable::RowSequence> &InputSequences) {
968   if (InputSequences.empty())
969     return;
970 
971   constexpr uint64_t InvalidAddress = UINT64_MAX;
972   unsigned FileNum = 1;
973   unsigned LastLine = 1;
974   unsigned Column = 0;
975   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
976   unsigned Isa = 0;
977   unsigned Discriminator = 0;
978   uint64_t LastAddress = InvalidAddress;
979   uint64_t PrevEndOfSequence = InvalidAddress;
980   const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
981 
982   auto emitEndOfSequence = [&](uint64_t Address) {
983     MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress);
984     FileNum = 1;
985     LastLine = 1;
986     Column = 0;
987     Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
988     Isa = 0;
989     Discriminator = 0;
990     LastAddress = InvalidAddress;
991   };
992 
993   for (const DwarfLineTable::RowSequence &Sequence : InputSequences) {
994     const uint64_t SequenceStart =
995         Table->Rows[Sequence.FirstIndex].Address.Address;
996 
997     // Check if we need to mark the end of the sequence.
998     if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress &&
999         PrevEndOfSequence != SequenceStart) {
1000       emitEndOfSequence(PrevEndOfSequence);
1001     }
1002 
1003     for (uint32_t RowIndex = Sequence.FirstIndex;
1004          RowIndex <= Sequence.LastIndex; ++RowIndex) {
1005       const DWARFDebugLine::Row &Row = Table->Rows[RowIndex];
1006       int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine;
1007       const uint64_t Address = Row.Address.Address;
1008 
1009       if (FileNum != Row.File) {
1010         FileNum = Row.File;
1011         MCOS->emitInt8(dwarf::DW_LNS_set_file);
1012         MCOS->emitULEB128IntValue(FileNum);
1013       }
1014       if (Column != Row.Column) {
1015         Column = Row.Column;
1016         MCOS->emitInt8(dwarf::DW_LNS_set_column);
1017         MCOS->emitULEB128IntValue(Column);
1018       }
1019       if (Discriminator != Row.Discriminator &&
1020           MCOS->getContext().getDwarfVersion() >= 4) {
1021         Discriminator = Row.Discriminator;
1022         unsigned Size = getULEB128Size(Discriminator);
1023         MCOS->emitInt8(dwarf::DW_LNS_extended_op);
1024         MCOS->emitULEB128IntValue(Size + 1);
1025         MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
1026         MCOS->emitULEB128IntValue(Discriminator);
1027       }
1028       if (Isa != Row.Isa) {
1029         Isa = Row.Isa;
1030         MCOS->emitInt8(dwarf::DW_LNS_set_isa);
1031         MCOS->emitULEB128IntValue(Isa);
1032       }
1033       if (Row.IsStmt != Flags) {
1034         Flags = Row.IsStmt;
1035         MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
1036       }
1037       if (Row.BasicBlock)
1038         MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
1039       if (Row.PrologueEnd)
1040         MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
1041       if (Row.EpilogueBegin)
1042         MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
1043 
1044       // The end of the sequence is not normal in the middle of the input
1045       // sequence, but could happen, e.g. for assembly code.
1046       if (Row.EndSequence) {
1047         emitEndOfSequence(Address);
1048       } else {
1049         if (LastAddress == InvalidAddress)
1050           emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address,
1051                                   AsmInfo->getCodePointerSize());
1052         else
1053           MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress);
1054 
1055         LastAddress = Address;
1056         LastLine = Row.Line;
1057       }
1058 
1059       Discriminator = 0;
1060     }
1061     PrevEndOfSequence = Sequence.EndAddress;
1062   }
1063 
1064   // Finish with the end of the sequence.
1065   if (LastAddress != InvalidAddress)
1066     emitEndOfSequence(PrevEndOfSequence);
1067 }
1068 
1069 // This function is similar to the one from MCDwarfLineTable, except it handles
1070 // end-of-sequence entries differently by utilizing line entries with
1071 // DWARF2_FLAG_END_SEQUENCE flag.
1072 static inline void emitDwarfLineTable(
1073     MCStreamer *MCOS, MCSection *Section,
1074     const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
1075   unsigned FileNum = 1;
1076   unsigned LastLine = 1;
1077   unsigned Column = 0;
1078   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1079   unsigned Isa = 0;
1080   unsigned Discriminator = 0;
1081   MCSymbol *LastLabel = nullptr;
1082   const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
1083 
1084   // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
1085   for (const MCDwarfLineEntry &LineEntry : LineEntries) {
1086     if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) {
1087       MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(),
1088                                      AsmInfo->getCodePointerSize());
1089       FileNum = 1;
1090       LastLine = 1;
1091       Column = 0;
1092       Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1093       Isa = 0;
1094       Discriminator = 0;
1095       LastLabel = nullptr;
1096       continue;
1097     }
1098 
1099     int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
1100 
1101     if (FileNum != LineEntry.getFileNum()) {
1102       FileNum = LineEntry.getFileNum();
1103       MCOS->emitInt8(dwarf::DW_LNS_set_file);
1104       MCOS->emitULEB128IntValue(FileNum);
1105     }
1106     if (Column != LineEntry.getColumn()) {
1107       Column = LineEntry.getColumn();
1108       MCOS->emitInt8(dwarf::DW_LNS_set_column);
1109       MCOS->emitULEB128IntValue(Column);
1110     }
1111     if (Discriminator != LineEntry.getDiscriminator() &&
1112         MCOS->getContext().getDwarfVersion() >= 2) {
1113       Discriminator = LineEntry.getDiscriminator();
1114       unsigned Size = getULEB128Size(Discriminator);
1115       MCOS->emitInt8(dwarf::DW_LNS_extended_op);
1116       MCOS->emitULEB128IntValue(Size + 1);
1117       MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
1118       MCOS->emitULEB128IntValue(Discriminator);
1119     }
1120     if (Isa != LineEntry.getIsa()) {
1121       Isa = LineEntry.getIsa();
1122       MCOS->emitInt8(dwarf::DW_LNS_set_isa);
1123       MCOS->emitULEB128IntValue(Isa);
1124     }
1125     if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
1126       Flags = LineEntry.getFlags();
1127       MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
1128     }
1129     if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
1130       MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
1131     if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
1132       MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
1133     if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
1134       MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
1135 
1136     MCSymbol *Label = LineEntry.getLabel();
1137 
1138     // At this point we want to emit/create the sequence to encode the delta
1139     // in line numbers and the increment of the address from the previous
1140     // Label and the current Label.
1141     MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
1142                                    AsmInfo->getCodePointerSize());
1143     Discriminator = 0;
1144     LastLine = LineEntry.getLine();
1145     LastLabel = Label;
1146   }
1147 
1148   assert(LastLabel == nullptr && "end of sequence expected");
1149 }
1150 
1151 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
1152                             std::optional<MCDwarfLineStr> &LineStr,
1153                             BinaryContext &BC) const {
1154   if (!RawData.empty()) {
1155     assert(MCLineSections.getMCLineEntries().empty() &&
1156            InputSequences.empty() &&
1157            "cannot combine raw data with new line entries");
1158     MCOS->emitLabel(getLabel());
1159     MCOS->emitBytes(RawData);
1160     return;
1161   }
1162 
1163   MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
1164 
1165   // Put out the line tables.
1166   for (const auto &LineSec : MCLineSections.getMCLineEntries())
1167     emitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
1168 
1169   // Emit line tables for the original code.
1170   emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences);
1171 
1172   // This is the end of the section, so set the value of the symbol at the end
1173   // of this section (that was used in a previous expression).
1174   MCOS->emitLabel(LineEndSym);
1175 }
1176 
1177 // Helper function to parse .debug_line_str, and populate one we are using.
1178 // For functions that we do not modify we output them as raw data.
1179 // Re-constructing .debug_line_str so that offsets are correct for those
1180 // debug line tables.
1181 // Bonus is that when we output a final binary we can re-use .debug_line_str
1182 // section. So we don't have to do the SHF_ALLOC trick we did with
1183 // .debug_line.
1184 static void parseAndPopulateDebugLineStr(BinarySection &LineStrSection,
1185                                          MCDwarfLineStr &LineStr,
1186                                          BinaryContext &BC) {
1187   DataExtractor StrData(LineStrSection.getContents(),
1188                         BC.DwCtx->isLittleEndian(), 0);
1189   uint64_t Offset = 0;
1190   while (StrData.isValidOffset(Offset)) {
1191     const uint64_t StrOffset = Offset;
1192     Error Err = Error::success();
1193     const char *CStr = StrData.getCStr(&Offset, &Err);
1194     if (Err) {
1195       BC.errs() << "BOLT-ERROR: could not extract string from .debug_line_str";
1196       continue;
1197     }
1198     const size_t NewOffset = LineStr.addString(CStr);
1199     assert(StrOffset == NewOffset &&
1200            "New offset in .debug_line_str doesn't match original offset");
1201     (void)StrOffset;
1202     (void)NewOffset;
1203   }
1204 }
1205 
1206 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
1207   MCAssembler &Assembler =
1208       static_cast<MCObjectStreamer *>(&Streamer)->getAssembler();
1209 
1210   MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams();
1211 
1212   auto &LineTables = BC.getDwarfLineTables();
1213 
1214   // Bail out early so we don't switch to the debug_line section needlessly and
1215   // in doing so create an unnecessary (if empty) section.
1216   if (LineTables.empty())
1217     return;
1218   // In a v5 non-split line table, put the strings in a separate section.
1219   std::optional<MCDwarfLineStr> LineStr;
1220   ErrorOr<BinarySection &> LineStrSection =
1221       BC.getUniqueSectionByName(".debug_line_str");
1222 
1223   // Some versions of GCC output DWARF5 .debug_info, but DWARF4 or lower
1224   // .debug_line, so need to check if section exists.
1225   if (LineStrSection) {
1226     LineStr.emplace(*BC.Ctx);
1227     parseAndPopulateDebugLineStr(*LineStrSection, *LineStr, BC);
1228   }
1229 
1230   // Switch to the section where the table will be emitted into.
1231   Streamer.switchSection(BC.MOFI->getDwarfLineSection());
1232 
1233   const uint16_t DwarfVersion = BC.Ctx->getDwarfVersion();
1234   // Handle the rest of the Compile Units.
1235   for (auto &CUIDTablePair : LineTables) {
1236     Streamer.getContext().setDwarfVersion(
1237         CUIDTablePair.second.getDwarfVersion());
1238     CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC);
1239   }
1240 
1241   // Resetting DWARF version for rest of the flow.
1242   BC.Ctx->setDwarfVersion(DwarfVersion);
1243 
1244   // Still need to write the section out for the ExecutionEngine, and temp in
1245   // memory object we are constructing.
1246   if (LineStr)
1247     LineStr->emitSection(&Streamer);
1248 }
1249 
1250 } // namespace bolt
1251 } // namespace llvm
1252