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