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