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