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/BinaryBasicBlock.h"
15 #include "bolt/Core/BinaryFunction.h"
16 #include "bolt/Utils/Utils.h"
17 #include "llvm/MC/MCObjectStreamer.h"
18 #include "llvm/MC/MCSymbol.h"
19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/Support/EndianStream.h"
21 #include "llvm/Support/LEB128.h"
22 #include <algorithm>
23 #include <cassert>
24 #include <cstdint>
25 #include <limits>
26 
27 #define DEBUG_TYPE "bolt-debug-info"
28 
29 namespace opts {
30 extern llvm::cl::opt<unsigned> Verbosity;
31 }
32 
33 namespace llvm {
34 namespace bolt {
35 
36 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0};
37 
38 namespace {
39 
40 // Writes address ranges to Writer as pairs of 64-bit (address, size).
41 // If RelativeRange is true, assumes the address range to be written must be of
42 // the form (begin address, range size), otherwise (begin address, end address).
43 // Terminates the list by writing a pair of two zeroes.
44 // Returns the number of written bytes.
45 uint64_t writeAddressRanges(raw_svector_ostream &Stream,
46                             const DebugAddressRangesVector &AddressRanges,
47                             const bool WriteRelativeRanges = false) {
48   for (const DebugAddressRange &Range : AddressRanges) {
49     support::endian::write(Stream, Range.LowPC, support::little);
50     support::endian::write(
51         Stream, WriteRelativeRanges ? Range.HighPC - Range.LowPC : Range.HighPC,
52         support::little);
53   }
54   // Finish with 0 entries.
55   support::endian::write(Stream, 0ULL, support::little);
56   support::endian::write(Stream, 0ULL, support::little);
57   return AddressRanges.size() * 16 + 16;
58 }
59 
60 } // namespace
61 
62 DebugRangesSectionWriter::DebugRangesSectionWriter() {
63   RangesBuffer = std::make_unique<DebugBufferVector>();
64   RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer);
65 
66   // Add an empty range as the first entry;
67   SectionOffset +=
68       writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
69 }
70 
71 uint64_t DebugRangesSectionWriter::addRanges(
72     DebugAddressRangesVector &&Ranges,
73     std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
74   if (Ranges.empty())
75     return getEmptyRangesOffset();
76 
77   const auto RI = CachedRanges.find(Ranges);
78   if (RI != CachedRanges.end())
79     return RI->second;
80 
81   const uint64_t EntryOffset = addRanges(Ranges);
82   CachedRanges.emplace(std::move(Ranges), EntryOffset);
83 
84   return EntryOffset;
85 }
86 
87 uint64_t
88 DebugRangesSectionWriter::addRanges(const DebugAddressRangesVector &Ranges) {
89   if (Ranges.empty())
90     return getEmptyRangesOffset();
91 
92   // Reading the SectionOffset and updating it should be atomic to guarantee
93   // unique and correct offsets in patches.
94   std::lock_guard<std::mutex> Lock(WriterMutex);
95   const uint32_t EntryOffset = SectionOffset;
96   SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges);
97 
98   return EntryOffset;
99 }
100 
101 uint64_t DebugRangesSectionWriter::getSectionOffset() {
102   std::lock_guard<std::mutex> Lock(WriterMutex);
103   return SectionOffset;
104 }
105 
106 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
107                                             DebugAddressRangesVector &&Ranges) {
108   std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
109   CUAddressRanges.emplace(CUOffset, std::move(Ranges));
110 }
111 
112 void DebugARangesSectionWriter::writeARangesSection(
113     raw_svector_ostream &RangesStream) const {
114   // For reference on the format of the .debug_aranges section, see the DWARF4
115   // specification, section 6.1.4 Lookup by Address
116   // http://www.dwarfstd.org/doc/DWARF4.pdf
117   for (const auto &CUOffsetAddressRangesPair : CUAddressRanges) {
118     const uint64_t Offset = CUOffsetAddressRangesPair.first;
119     const DebugAddressRangesVector &AddressRanges =
120         CUOffsetAddressRangesPair.second;
121 
122     // Emit header.
123 
124     // Size of this set: 8 (size of the header) + 4 (padding after header)
125     // + 2*sizeof(uint64_t) bytes for each of the ranges, plus an extra
126     // pair of uint64_t's for the terminating, zero-length range.
127     // Does not include size field itself.
128     uint32_t Size = 8 + 4 + 2 * sizeof(uint64_t) * (AddressRanges.size() + 1);
129 
130     // Header field #1: set size.
131     support::endian::write(RangesStream, Size, support::little);
132 
133     // Header field #2: version number, 2 as per the specification.
134     support::endian::write(RangesStream, static_cast<uint16_t>(2),
135                            support::little);
136 
137     // Header field #3: debug info offset of the correspondent compile unit.
138     support::endian::write(RangesStream, static_cast<uint32_t>(Offset),
139                            support::little);
140 
141     // Header field #4: address size.
142     // 8 since we only write ELF64 binaries for now.
143     RangesStream << char(8);
144 
145     // Header field #5: segment size of target architecture.
146     RangesStream << char(0);
147 
148     // Padding before address table - 4 bytes in the 64-bit-pointer case.
149     support::endian::write(RangesStream, static_cast<uint32_t>(0),
150                            support::little);
151 
152     writeAddressRanges(RangesStream, AddressRanges, true);
153   }
154 }
155 
156 DebugAddrWriter::DebugAddrWriter(BinaryContext *Bc) { BC = Bc; }
157 
158 void DebugAddrWriter::AddressForDWOCU::dump() {
159   std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(),
160                                           indexToAdddessEnd());
161   // Sorting address in increasing order of indices.
162   std::sort(SortedMap.begin(), SortedMap.end(),
163             [](const IndexAddressPair &A, const IndexAddressPair &B) {
164               return A.first < B.first;
165             });
166   for (auto &Pair : SortedMap)
167     dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
168 }
169 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address,
170                                               uint64_t DWOId) {
171   if (!AddressMaps.count(DWOId))
172     AddressMaps[DWOId] = AddressForDWOCU();
173 
174   AddressForDWOCU &Map = AddressMaps[DWOId];
175   auto Entry = Map.find(Address);
176   if (Entry == Map.end()) {
177     auto Index = Map.getNextIndex();
178     Entry = Map.insert(Address, Index).first;
179   }
180   return Entry->second;
181 }
182 
183 // Case1) Address is not in map insert in to AddresToIndex and IndexToAddres
184 // Case2) Address is in the map but Index is higher or equal. Need to update
185 // IndexToAddrss. Case3) Address is in the map but Index is lower. Need to
186 // update AddressToIndex and IndexToAddress
187 void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index,
188                                       uint64_t DWOId) {
189   AddressForDWOCU &Map = AddressMaps[DWOId];
190   auto Entry = Map.find(Address);
191   if (Entry != Map.end()) {
192     if (Entry->second > Index)
193       Map.updateAddressToIndex(Address, Index);
194     Map.updateIndexToAddrss(Address, Index);
195   } else {
196     Map.insert(Address, Index);
197   }
198 }
199 
200 AddressSectionBuffer DebugAddrWriter::finalize() {
201   // Need to layout all sections within .debug_addr
202   // Within each section sort Address by index.
203   AddressSectionBuffer Buffer;
204   raw_svector_ostream AddressStream(Buffer);
205   for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) {
206     Optional<uint64_t> DWOId = CU->getDWOId();
207     // Handling the case wehre debug information is a mix of Debug fission and
208     // monolitic.
209     if (!DWOId)
210       continue;
211     auto AM = AddressMaps.find(*DWOId);
212     // Adding to map even if it did not contribute to .debug_addr.
213     // The Skeleton CU will still have DW_AT_GNU_addr_base.
214     DWOIdToOffsetMap[*DWOId] = Buffer.size();
215     // If does not exist this CUs DWO section didn't contribute to .debug_addr.
216     if (AM == AddressMaps.end())
217       continue;
218     std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(),
219                                             AM->second.indexToAdddessEnd());
220     // Sorting address in increasing order of indices.
221     std::sort(SortedMap.begin(), SortedMap.end(),
222               [](const IndexAddressPair &A, const IndexAddressPair &B) {
223                 return A.first < B.first;
224               });
225 
226     uint8_t AddrSize = CU->getAddressByteSize();
227     uint32_t Counter = 0;
228     auto WriteAddress = [&](uint64_t Address) -> void {
229       ++Counter;
230       switch (AddrSize) {
231       default:
232         assert(false && "Address Size is invalid.");
233         break;
234       case 4:
235         support::endian::write(AddressStream, static_cast<uint32_t>(Address),
236                                support::little);
237         break;
238       case 8:
239         support::endian::write(AddressStream, Address, support::little);
240         break;
241       }
242     };
243 
244     for (const IndexAddressPair &Val : SortedMap) {
245       while (Val.first > Counter)
246         WriteAddress(0);
247       WriteAddress(Val.second);
248     }
249   }
250 
251   return Buffer;
252 }
253 
254 uint64_t DebugAddrWriter::getOffset(uint64_t DWOId) {
255   auto Iter = DWOIdToOffsetMap.find(DWOId);
256   assert(Iter != DWOIdToOffsetMap.end() &&
257          "Offset in to.debug_addr was not found for DWO ID.");
258   return Iter->second;
259 }
260 
261 DebugLocWriter::DebugLocWriter(BinaryContext *BC) {
262   LocBuffer = std::make_unique<DebugBufferVector>();
263   LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
264 }
265 
266 void DebugLocWriter::addList(uint64_t AttrOffset,
267                              DebugLocationsVector &&LocList) {
268   if (LocList.empty()) {
269     EmptyAttrLists.push_back(AttrOffset);
270     return;
271   }
272   // Since there is a separate DebugLocWriter for each thread,
273   // we don't need a lock to read the SectionOffset and update it.
274   const uint32_t EntryOffset = SectionOffset;
275 
276   for (const DebugLocationEntry &Entry : LocList) {
277     support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC),
278                            support::little);
279     support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC),
280                            support::little);
281     support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()),
282                            support::little);
283     *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
284                             Entry.Expr.size());
285     SectionOffset += 2 * 8 + 2 + Entry.Expr.size();
286   }
287   LocStream->write_zeros(16);
288   SectionOffset += 16;
289   LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset});
290 }
291 
292 void DebugLoclistWriter::addList(uint64_t AttrOffset,
293                                  DebugLocationsVector &&LocList) {
294   Patches.push_back({AttrOffset, std::move(LocList)});
295 }
296 
297 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() {
298   return std::move(LocBuffer);
299 }
300 
301 // DWARF 4: 2.6.2
302 void DebugLocWriter::finalize(uint64_t SectionOffset,
303                               SimpleBinaryPatcher &DebugInfoPatcher) {
304   for (const auto LocListDebugInfoPatchType : LocListDebugInfoPatches) {
305     uint64_t Offset = SectionOffset + LocListDebugInfoPatchType.LocListOffset;
306     DebugInfoPatcher.addLE32Patch(LocListDebugInfoPatchType.DebugInfoAttrOffset,
307                                   Offset);
308   }
309 
310   for (uint64_t DebugInfoAttrOffset : EmptyAttrLists)
311     DebugInfoPatcher.addLE32Patch(DebugInfoAttrOffset,
312                                   DebugLocWriter::EmptyListOffset);
313 }
314 
315 void DebugLoclistWriter::finalize(uint64_t SectionOffset,
316                                   SimpleBinaryPatcher &DebugInfoPatcher) {
317   for (LocPatch &Patch : Patches) {
318     if (Patch.LocList.empty()) {
319       DebugInfoPatcher.addLE32Patch(Patch.AttrOffset,
320                                     DebugLocWriter::EmptyListOffset);
321       continue;
322     }
323     const uint32_t EntryOffset = LocBuffer->size();
324     for (const DebugLocationEntry &Entry : Patch.LocList) {
325       support::endian::write(*LocStream,
326                              static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
327                              support::little);
328       uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, DWOId);
329       encodeULEB128(Index, *LocStream);
330 
331       // TODO: Support DWARF5
332       support::endian::write(*LocStream,
333                              static_cast<uint32_t>(Entry.HighPC - Entry.LowPC),
334                              support::little);
335       support::endian::write(*LocStream,
336                              static_cast<uint16_t>(Entry.Expr.size()),
337                              support::little);
338       *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
339                               Entry.Expr.size());
340     }
341     support::endian::write(*LocStream,
342                            static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
343                            support::little);
344     DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, EntryOffset);
345     clearList(Patch.LocList);
346   }
347   clearList(Patches);
348 }
349 
350 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
351 
352 void SimpleBinaryPatcher::addBinaryPatch(uint32_t Offset,
353                                          const std::string &NewValue) {
354   Patches.emplace_back(Offset, NewValue);
355 }
356 
357 void SimpleBinaryPatcher::addBytePatch(uint32_t Offset, uint8_t Value) {
358   Patches.emplace_back(Offset, std::string(1, Value));
359 }
360 
361 void SimpleBinaryPatcher::addLEPatch(uint32_t Offset, uint64_t NewValue,
362                                      size_t ByteSize) {
363   std::string LE64(ByteSize, 0);
364   for (size_t I = 0; I < ByteSize; ++I) {
365     LE64[I] = NewValue & 0xff;
366     NewValue >>= 8;
367   }
368   Patches.emplace_back(Offset, LE64);
369 }
370 
371 void SimpleBinaryPatcher::addUDataPatch(uint32_t Offset, uint64_t Value,
372                                         uint64_t Size) {
373   std::string Buff;
374   raw_string_ostream OS(Buff);
375   encodeULEB128(Value, OS, Size);
376 
377   Patches.emplace_back(Offset, OS.str());
378 }
379 
380 void SimpleBinaryPatcher::addLE64Patch(uint32_t Offset, uint64_t NewValue) {
381   addLEPatch(Offset, NewValue, 8);
382 }
383 
384 void SimpleBinaryPatcher::addLE32Patch(uint32_t Offset, uint32_t NewValue) {
385   addLEPatch(Offset, NewValue, 4);
386 }
387 
388 void SimpleBinaryPatcher::patchBinary(std::string &BinaryContents,
389                                       uint32_t DWPOffset = 0) {
390   for (const auto &Patch : Patches) {
391     uint32_t Offset = Patch.first - DWPOffset;
392     const std::string &ByteSequence = Patch.second;
393     assert(Offset + ByteSequence.size() <= BinaryContents.size() &&
394            "Applied patch runs over binary size.");
395     for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) {
396       BinaryContents[Offset + I] = ByteSequence[I];
397     }
398   }
399 }
400 
401 void DebugStrWriter::create() {
402   StrBuffer = std::make_unique<DebugStrBufferVector>();
403   StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer);
404 }
405 
406 void DebugStrWriter::initialize() {
407   auto StrSection = BC->DwCtx->getDWARFObj().getStrSection();
408   (*StrStream) << StrSection;
409 }
410 
411 uint32_t DebugStrWriter::addString(StringRef Str) {
412   if (StrBuffer->empty())
413     initialize();
414   auto Offset = StrBuffer->size();
415   (*StrStream) << Str;
416   StrStream->write_zeros(1);
417   return Offset;
418 }
419 
420 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) {
421   const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations();
422   if (!Abbrevs)
423     return;
424 
425   // Multiple units may share the same abbreviations. Only add abbreviations
426   // for the first unit and reuse them.
427   const uint64_t AbbrevOffset = Unit.getAbbreviationsOffset();
428   if (UnitsAbbrevData.find(AbbrevOffset) != UnitsAbbrevData.end())
429     return;
430 
431   AbbrevData &UnitData = UnitsAbbrevData[AbbrevOffset];
432   UnitData.Buffer = std::make_unique<DebugBufferVector>();
433   UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer);
434 
435   const PatchesTy &UnitPatches = Patches[&Unit];
436 
437   raw_svector_ostream &OS = *UnitData.Stream.get();
438 
439   // Take a fast path if there are no patches to apply. Simply copy the original
440   // contents.
441   if (UnitPatches.empty()) {
442     StringRef AbbrevSectionContents =
443         Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection()
444                          : Unit.getContext().getDWARFObj().getAbbrevSection();
445     StringRef AbbrevContents;
446 
447     const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex();
448     if (!CUIndex.getRows().empty()) {
449       // Handle DWP section contribution.
450       const DWARFUnitIndex::Entry *DWOEntry =
451           CUIndex.getFromHash(*Unit.getDWOId());
452       if (!DWOEntry)
453         return;
454 
455       const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution =
456           DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV);
457       AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset,
458                                                     DWOContrubution->Length);
459     } else if (!Unit.isDWOUnit()) {
460       const uint64_t StartOffset = Unit.getAbbreviationsOffset();
461 
462       // We know where the unit's abbreviation set starts, but not where it ends
463       // as such data is not readily available. Hence, we have to build a sorted
464       // list of start addresses and find the next starting address to determine
465       // the set boundaries.
466       //
467       // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets
468       // we wouldn't have to build our own sorted list for the quick lookup.
469       if (AbbrevSetOffsets.empty()) {
470         llvm::for_each(
471             *Unit.getContext().getDebugAbbrev(),
472             [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) {
473               AbbrevSetOffsets.push_back(P.first);
474             });
475         llvm::sort(AbbrevSetOffsets);
476       }
477       auto It = llvm::upper_bound(AbbrevSetOffsets, StartOffset);
478       const uint64_t EndOffset =
479           It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It;
480       AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset);
481     } else {
482       // For DWO unit outside of DWP, we expect the entire section to hold
483       // abbreviations for this unit only.
484       AbbrevContents = AbbrevSectionContents;
485     }
486 
487     OS.reserveExtraSpace(AbbrevContents.size());
488     OS << AbbrevContents;
489 
490     return;
491   }
492 
493   for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) {
494     const DWARFAbbreviationDeclaration &Abbrev = *I;
495     auto Patch = UnitPatches.find(&Abbrev);
496 
497     encodeULEB128(Abbrev.getCode(), OS);
498     encodeULEB128(Abbrev.getTag(), OS);
499     encodeULEB128(Abbrev.hasChildren(), OS);
500     for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec :
501          Abbrev.attributes()) {
502       if (Patch != UnitPatches.end()) {
503         bool Patched = false;
504         // Patches added later take a precedence over earlier ones.
505         for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E;
506              ++I) {
507           if (I->OldAttr != AttrSpec.Attr)
508             continue;
509 
510           encodeULEB128(I->NewAttr, OS);
511           encodeULEB128(I->NewAttrForm, OS);
512           Patched = true;
513           break;
514         }
515         if (Patched)
516           continue;
517       }
518 
519       encodeULEB128(AttrSpec.Attr, OS);
520       encodeULEB128(AttrSpec.Form, OS);
521       if (AttrSpec.isImplicitConst())
522         encodeSLEB128(AttrSpec.getImplicitConstValue(), OS);
523     }
524 
525     encodeULEB128(0, OS);
526     encodeULEB128(0, OS);
527   }
528   encodeULEB128(0, OS);
529 }
530 
531 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() {
532   if (DWOId) {
533     // We expect abbrev_offset to always be zero for DWO units as there
534     // should be one CU per DWO, and TUs should share the same abbreviation
535     // set with the CU.
536     // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so
537     // can be none zero. Thus we are skipping the check for DWP.
538     bool IsDWP = !Context.getCUIndex().getRows().empty();
539     if (!IsDWP) {
540       for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) {
541         if (Unit->getAbbreviationsOffset() != 0) {
542           errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. "
543                     "Unable to update debug info.\n";
544           exit(1);
545         }
546       }
547     }
548 
549     // Issue abbreviations for the DWO CU only.
550     addUnitAbbreviations(*Context.getDWOCompileUnitForHash(*DWOId));
551   } else {
552     // Add abbreviations from compile and type non-DWO units.
553     for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units())
554       addUnitAbbreviations(*Unit);
555   }
556 
557   DebugBufferVector ReturnBuffer;
558 
559   // Pre-calculate the total size of abbrev section.
560   uint64_t Size = 0;
561   for (const auto &KV : UnitsAbbrevData) {
562     const AbbrevData &UnitData = KV.second;
563     Size += UnitData.Buffer->size();
564   }
565   ReturnBuffer.reserve(Size);
566 
567   uint64_t Pos = 0;
568   for (auto &KV : UnitsAbbrevData) {
569     AbbrevData &UnitData = KV.second;
570     ReturnBuffer.append(*UnitData.Buffer);
571     UnitData.Offset = Pos;
572     Pos += UnitData.Buffer->size();
573 
574     UnitData.Buffer.reset();
575     UnitData.Stream.reset();
576   }
577 
578   return std::make_unique<DebugBufferVector>(ReturnBuffer);
579 }
580 
581 static void emitDwarfSetLineAddrAbs(MCStreamer &OS,
582                                     MCDwarfLineTableParams Params,
583                                     int64_t LineDelta, uint64_t Address,
584                                     int PointerSize) {
585   // emit the sequence to set the address
586   OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
587   OS.emitULEB128IntValue(PointerSize + 1);
588   OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
589   OS.emitIntValue(Address, PointerSize);
590 
591   // emit the sequence for the LineDelta (from 1) and a zero address delta.
592   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
593 }
594 
595 static inline void emitBinaryDwarfLineTable(
596     MCStreamer *MCOS, MCDwarfLineTableParams Params,
597     const DWARFDebugLine::LineTable *Table,
598     const std::vector<DwarfLineTable::RowSequence> &InputSequences) {
599   if (InputSequences.empty())
600     return;
601 
602   constexpr uint64_t InvalidAddress = UINT64_MAX;
603   unsigned FileNum = 1;
604   unsigned LastLine = 1;
605   unsigned Column = 0;
606   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
607   unsigned Isa = 0;
608   unsigned Discriminator = 0;
609   uint64_t LastAddress = InvalidAddress;
610   uint64_t PrevEndOfSequence = InvalidAddress;
611   const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
612 
613   auto emitEndOfSequence = [&](uint64_t Address) {
614     MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress);
615     FileNum = 1;
616     LastLine = 1;
617     Column = 0;
618     Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
619     Isa = 0;
620     Discriminator = 0;
621     LastAddress = InvalidAddress;
622   };
623 
624   for (const DwarfLineTable::RowSequence &Sequence : InputSequences) {
625     const uint64_t SequenceStart =
626         Table->Rows[Sequence.FirstIndex].Address.Address;
627 
628     // Check if we need to mark the end of the sequence.
629     if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress &&
630         PrevEndOfSequence != SequenceStart) {
631       emitEndOfSequence(PrevEndOfSequence);
632     }
633 
634     for (uint32_t RowIndex = Sequence.FirstIndex;
635          RowIndex <= Sequence.LastIndex; ++RowIndex) {
636       const DWARFDebugLine::Row &Row = Table->Rows[RowIndex];
637       int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine;
638       const uint64_t Address = Row.Address.Address;
639 
640       if (FileNum != Row.File) {
641         FileNum = Row.File;
642         MCOS->emitInt8(dwarf::DW_LNS_set_file);
643         MCOS->emitULEB128IntValue(FileNum);
644       }
645       if (Column != Row.Column) {
646         Column = Row.Column;
647         MCOS->emitInt8(dwarf::DW_LNS_set_column);
648         MCOS->emitULEB128IntValue(Column);
649       }
650       if (Discriminator != Row.Discriminator &&
651           MCOS->getContext().getDwarfVersion() >= 4) {
652         Discriminator = Row.Discriminator;
653         unsigned Size = getULEB128Size(Discriminator);
654         MCOS->emitInt8(dwarf::DW_LNS_extended_op);
655         MCOS->emitULEB128IntValue(Size + 1);
656         MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
657         MCOS->emitULEB128IntValue(Discriminator);
658       }
659       if (Isa != Row.Isa) {
660         Isa = Row.Isa;
661         MCOS->emitInt8(dwarf::DW_LNS_set_isa);
662         MCOS->emitULEB128IntValue(Isa);
663       }
664       if (Row.IsStmt != Flags) {
665         Flags = Row.IsStmt;
666         MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
667       }
668       if (Row.BasicBlock)
669         MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
670       if (Row.PrologueEnd)
671         MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
672       if (Row.EpilogueBegin)
673         MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
674 
675       // The end of the sequence is not normal in the middle of the input
676       // sequence, but could happen, e.g. for assembly code.
677       if (Row.EndSequence) {
678         emitEndOfSequence(Address);
679       } else {
680         if (LastAddress == InvalidAddress)
681           emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address,
682                                   AsmInfo->getCodePointerSize());
683         else
684           MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress);
685 
686         LastAddress = Address;
687         LastLine = Row.Line;
688       }
689 
690       Discriminator = 0;
691     }
692     PrevEndOfSequence = Sequence.EndAddress;
693   }
694 
695   // Finish with the end of the sequence.
696   if (LastAddress != InvalidAddress)
697     emitEndOfSequence(PrevEndOfSequence);
698 }
699 
700 // This function is similar to the one from MCDwarfLineTable, except it handles
701 // end-of-sequence entries differently by utilizing line entries with
702 // DWARF2_FLAG_END_SEQUENCE flag.
703 static inline void emitDwarfLineTable(
704     MCStreamer *MCOS, MCSection *Section,
705     const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
706   unsigned FileNum = 1;
707   unsigned LastLine = 1;
708   unsigned Column = 0;
709   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
710   unsigned Isa = 0;
711   unsigned Discriminator = 0;
712   MCSymbol *LastLabel = nullptr;
713   const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
714 
715   // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
716   for (const MCDwarfLineEntry &LineEntry : LineEntries) {
717     if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) {
718       MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(),
719                                      AsmInfo->getCodePointerSize());
720       FileNum = 1;
721       LastLine = 1;
722       Column = 0;
723       Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
724       Isa = 0;
725       Discriminator = 0;
726       LastLabel = nullptr;
727       continue;
728     }
729 
730     int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
731 
732     if (FileNum != LineEntry.getFileNum()) {
733       FileNum = LineEntry.getFileNum();
734       MCOS->emitInt8(dwarf::DW_LNS_set_file);
735       MCOS->emitULEB128IntValue(FileNum);
736     }
737     if (Column != LineEntry.getColumn()) {
738       Column = LineEntry.getColumn();
739       MCOS->emitInt8(dwarf::DW_LNS_set_column);
740       MCOS->emitULEB128IntValue(Column);
741     }
742     if (Discriminator != LineEntry.getDiscriminator() &&
743         MCOS->getContext().getDwarfVersion() >= 4) {
744       Discriminator = LineEntry.getDiscriminator();
745       unsigned Size = getULEB128Size(Discriminator);
746       MCOS->emitInt8(dwarf::DW_LNS_extended_op);
747       MCOS->emitULEB128IntValue(Size + 1);
748       MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
749       MCOS->emitULEB128IntValue(Discriminator);
750     }
751     if (Isa != LineEntry.getIsa()) {
752       Isa = LineEntry.getIsa();
753       MCOS->emitInt8(dwarf::DW_LNS_set_isa);
754       MCOS->emitULEB128IntValue(Isa);
755     }
756     if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
757       Flags = LineEntry.getFlags();
758       MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
759     }
760     if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
761       MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
762     if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
763       MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
764     if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
765       MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
766 
767     MCSymbol *Label = LineEntry.getLabel();
768 
769     // At this point we want to emit/create the sequence to encode the delta
770     // in line numbers and the increment of the address from the previous
771     // Label and the current Label.
772     MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
773                                    AsmInfo->getCodePointerSize());
774     Discriminator = 0;
775     LastLine = LineEntry.getLine();
776     LastLabel = Label;
777   }
778 
779   assert(LastLabel == nullptr && "end of sequence expected");
780 }
781 
782 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
783                             Optional<MCDwarfLineStr> &LineStr,
784                             BinaryContext &BC) const {
785   if (!RawData.empty()) {
786     assert(MCLineSections.getMCLineEntries().empty() &&
787            InputSequences.empty() &&
788            "cannot combine raw data with new line entries");
789     MCOS->emitLabel(getLabel());
790     MCOS->emitBytes(RawData);
791 
792     // Emit fake relocation for RuntimeDyld to always allocate the section.
793     //
794     // FIXME: remove this once RuntimeDyld stops skipping allocatable sections
795     //        without relocations.
796     MCOS->emitRelocDirective(
797         *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE",
798         MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI);
799 
800     return;
801   }
802 
803   MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
804 
805   // Put out the line tables.
806   for (const auto &LineSec : MCLineSections.getMCLineEntries())
807     emitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
808 
809   // Emit line tables for the original code.
810   emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences);
811 
812   // This is the end of the section, so set the value of the symbol at the end
813   // of this section (that was used in a previous expression).
814   MCOS->emitLabel(LineEndSym);
815 }
816 
817 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
818   MCAssembler &Assembler =
819       static_cast<MCObjectStreamer *>(&Streamer)->getAssembler();
820 
821   MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams();
822 
823   auto &LineTables = BC.getDwarfLineTables();
824 
825   // Bail out early so we don't switch to the debug_line section needlessly and
826   // in doing so create an unnecessary (if empty) section.
827   if (LineTables.empty())
828     return;
829 
830   // In a v5 non-split line table, put the strings in a separate section.
831   Optional<MCDwarfLineStr> LineStr(None);
832   if (BC.Ctx->getDwarfVersion() >= 5)
833     LineStr = MCDwarfLineStr(*BC.Ctx);
834 
835   // Switch to the section where the table will be emitted into.
836   Streamer.SwitchSection(BC.MOFI->getDwarfLineSection());
837 
838   // Handle the rest of the Compile Units.
839   for (auto &CUIDTablePair : LineTables) {
840     CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC);
841   }
842 }
843 
844 } // namespace bolt
845 } // namespace llvm
846