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