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