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