1 //===--- unittests/DebugInfo/DWARF/DwarfGenerator.cpp -----------*- C++ -*-===//
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 #include "DwarfGenerator.h"
10 #include "../lib/CodeGen/AsmPrinter/DwarfStringPool.h"
11 #include "llvm/ADT/Triple.h"
12 #include "llvm/BinaryFormat/Dwarf.h"
13 #include "llvm/CodeGen/AsmPrinter.h"
14 #include "llvm/CodeGen/DIE.h"
15 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
16 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
17 #include "llvm/MC/MCAsmBackend.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCDwarf.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCObjectWriter.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
29 #include "llvm/PassAnalysisSupport.h"
30 #include "llvm/Support/LEB128.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Target/TargetLoweringObjectFile.h"
34 #include "llvm/Target/TargetMachine.h"
35 #include "llvm/Target/TargetOptions.h"
36 
37 using namespace llvm;
38 using namespace dwarf;
39 
40 mc::RegisterMCTargetOptionsFlags MOF;
41 
42 namespace {} // end anonymous namespace
43 
44 //===----------------------------------------------------------------------===//
45 /// dwarfgen::DIE implementation.
46 //===----------------------------------------------------------------------===//
47 unsigned dwarfgen::DIE::computeSizeAndOffsets(unsigned Offset) {
48   auto &DG = CU->getGenerator();
49   return Die->computeOffsetsAndAbbrevs(DG.getAsmPrinter(), DG.getAbbrevSet(),
50                                        Offset);
51 }
52 
53 void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form, uint64_t U) {
54   auto &DG = CU->getGenerator();
55   Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
56                 DIEInteger(U));
57 }
58 
59 void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form, const MCExpr &Expr) {
60   auto &DG = CU->getGenerator();
61   Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
62                 DIEExpr(&Expr));
63 }
64 
65 void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form,
66                                  StringRef String) {
67   auto &DG = CU->getGenerator();
68   switch (Form) {
69   case DW_FORM_string:
70     Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
71                   new (DG.getAllocator())
72                       DIEInlineString(String, DG.getAllocator()));
73     break;
74 
75   case DW_FORM_strp:
76     Die->addValue(
77         DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
78         DIEString(DG.getStringPool().getEntry(*DG.getAsmPrinter(), String)));
79     break;
80 
81   case DW_FORM_GNU_str_index:
82   case DW_FORM_strx:
83   case DW_FORM_strx1:
84   case DW_FORM_strx2:
85   case DW_FORM_strx3:
86   case DW_FORM_strx4:
87     Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
88                   DIEString(DG.getStringPool().getIndexedEntry(
89                       *DG.getAsmPrinter(), String)));
90     break;
91 
92   default:
93     llvm_unreachable("Unhandled form!");
94   }
95 }
96 
97 void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form,
98                                  dwarfgen::DIE &RefDie) {
99   auto &DG = CU->getGenerator();
100   Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
101                 DIEEntry(*RefDie.Die));
102 }
103 
104 void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form, const void *P,
105                                  size_t S) {
106   auto &DG = CU->getGenerator();
107   DIEBlock *Block = new (DG.getAllocator()) DIEBlock;
108   for (size_t I = 0; I < S; ++I)
109     Block->addValue(
110         DG.getAllocator(), (dwarf::Attribute)0, dwarf::DW_FORM_data1,
111         DIEInteger(
112             (const_cast<uint8_t *>(static_cast<const uint8_t *>(P)))[I]));
113 
114   Block->ComputeSize(DG.getAsmPrinter());
115   Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
116                 Block);
117 }
118 
119 void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form) {
120   auto &DG = CU->getGenerator();
121   assert(Form == DW_FORM_flag_present);
122   Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form,
123                 DIEInteger(1));
124 }
125 
126 void dwarfgen::DIE::addStrOffsetsBaseAttribute() {
127   auto &DG = CU->getGenerator();
128   auto &MC = *DG.getMCContext();
129   AsmPrinter *Asm = DG.getAsmPrinter();
130 
131   const MCSymbol *SectionStart =
132       Asm->getObjFileLowering().getDwarfStrOffSection()->getBeginSymbol();
133 
134   const MCExpr *Expr =
135       MCSymbolRefExpr::create(DG.getStringOffsetsStartSym(), MC);
136 
137   if (!Asm->MAI->doesDwarfUseRelocationsAcrossSections())
138     Expr = MCBinaryExpr::createSub(
139         Expr, MCSymbolRefExpr::create(SectionStart, MC), MC);
140 
141   addAttribute(dwarf::DW_AT_str_offsets_base, DW_FORM_sec_offset, *Expr);
142 }
143 
144 dwarfgen::DIE dwarfgen::DIE::addChild(dwarf::Tag Tag) {
145   auto &DG = CU->getGenerator();
146   return dwarfgen::DIE(CU,
147                        &Die->addChild(llvm::DIE::get(DG.getAllocator(), Tag)));
148 }
149 
150 dwarfgen::DIE dwarfgen::CompileUnit::getUnitDIE() {
151   return dwarfgen::DIE(this, &DU.getUnitDie());
152 }
153 
154 //===----------------------------------------------------------------------===//
155 /// dwarfgen::LineTable implementation.
156 //===----------------------------------------------------------------------===//
157 DWARFDebugLine::Prologue dwarfgen::LineTable::createBasicPrologue() const {
158   DWARFDebugLine::Prologue P;
159   switch (Version) {
160   case 2:
161   case 3:
162     P.TotalLength = 41;
163     P.PrologueLength = 35;
164     break;
165   case 4:
166     P.TotalLength = 42;
167     P.PrologueLength = 36;
168     break;
169   case 5:
170     P.TotalLength = 50;
171     P.PrologueLength = 42;
172     P.FormParams.AddrSize = AddrSize;
173     break;
174   default:
175     llvm_unreachable("unsupported version");
176   }
177   if (Format == DWARF64) {
178     P.TotalLength += 4;
179     P.FormParams.Format = DWARF64;
180   }
181   P.TotalLength += getContentsSize();
182   P.FormParams.Version = Version;
183   P.MinInstLength = 1;
184   P.MaxOpsPerInst = 1;
185   P.DefaultIsStmt = 1;
186   P.LineBase = -5;
187   P.LineRange = 14;
188   P.OpcodeBase = 13;
189   P.StandardOpcodeLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1};
190   P.IncludeDirectories.push_back(
191       DWARFFormValue::createFromPValue(DW_FORM_string, "a dir"));
192   P.FileNames.push_back(DWARFDebugLine::FileNameEntry());
193   P.FileNames.back().Name =
194       DWARFFormValue::createFromPValue(DW_FORM_string, "a file");
195   return P;
196 }
197 
198 void dwarfgen::LineTable::setPrologue(DWARFDebugLine::Prologue NewPrologue) {
199   Prologue = NewPrologue;
200   CustomPrologue.clear();
201 }
202 
203 void dwarfgen::LineTable::setCustomPrologue(
204     ArrayRef<ValueAndLength> NewPrologue) {
205   Prologue.reset();
206   CustomPrologue = NewPrologue;
207 }
208 
209 void dwarfgen::LineTable::addByte(uint8_t Value) {
210   Contents.push_back({Value, Byte});
211 }
212 
213 void dwarfgen::LineTable::addStandardOpcode(uint8_t Opcode,
214                                             ArrayRef<ValueAndLength> Operands) {
215   Contents.push_back({Opcode, Byte});
216   Contents.insert(Contents.end(), Operands.begin(), Operands.end());
217 }
218 
219 void dwarfgen::LineTable::addExtendedOpcode(uint64_t Length, uint8_t Opcode,
220                                             ArrayRef<ValueAndLength> Operands) {
221   Contents.push_back({0, Byte});
222   Contents.push_back({Length, ULEB});
223   Contents.push_back({Opcode, Byte});
224   Contents.insert(Contents.end(), Operands.begin(), Operands.end());
225 }
226 
227 void dwarfgen::LineTable::generate(MCContext &MC, AsmPrinter &Asm) const {
228   MC.setDwarfVersion(Version);
229 
230   MCSymbol *EndSymbol = nullptr;
231   if (!CustomPrologue.empty()) {
232     writeData(CustomPrologue, Asm);
233   } else if (!Prologue) {
234     EndSymbol = writeDefaultPrologue(Asm);
235   } else {
236     writePrologue(Asm);
237   }
238 
239   writeData(Contents, Asm);
240   if (EndSymbol != nullptr)
241     Asm.OutStreamer->emitLabel(EndSymbol);
242 }
243 
244 void dwarfgen::LineTable::writeData(ArrayRef<ValueAndLength> Data,
245                                     AsmPrinter &Asm) const {
246   for (auto Entry : Data) {
247     switch (Entry.Length) {
248     case Byte:
249     case Half:
250     case Long:
251     case Quad:
252       Asm.OutStreamer->emitIntValue(Entry.Value, Entry.Length);
253       continue;
254     case ULEB:
255       Asm.emitULEB128(Entry.Value);
256       continue;
257     case SLEB:
258       Asm.emitSLEB128(Entry.Value);
259       continue;
260     }
261     llvm_unreachable("unsupported ValueAndLength Length value");
262   }
263 }
264 
265 size_t dwarfgen::LineTable::getContentsSize() const {
266   size_t Size = 0;
267   for (auto Entry : Contents) {
268     switch (Entry.Length) {
269     case ULEB:
270       Size += getULEB128Size(Entry.Value);
271       break;
272     case SLEB:
273       Size += getSLEB128Size(Entry.Value);
274       break;
275     default:
276       Size += Entry.Length;
277       break;
278     }
279   }
280   return Size;
281 }
282 
283 MCSymbol *dwarfgen::LineTable::writeDefaultPrologue(AsmPrinter &Asm) const {
284   MCSymbol *UnitStart = Asm.createTempSymbol("line_unit_start");
285   MCSymbol *UnitEnd = Asm.createTempSymbol("line_unit_end");
286   if (Format == DwarfFormat::DWARF64) {
287     Asm.emitInt32((int)dwarf::DW_LENGTH_DWARF64);
288     Asm.emitLabelDifference(UnitEnd, UnitStart, 8);
289   } else {
290     Asm.emitLabelDifference(UnitEnd, UnitStart, 4);
291   }
292   Asm.OutStreamer->emitLabel(UnitStart);
293   Asm.emitInt16(Version);
294   if (Version == 5) {
295     Asm.emitInt8(AddrSize);
296     Asm.emitInt8(SegSize);
297   }
298 
299   MCSymbol *PrologueStart = Asm.createTempSymbol("line_prologue_start");
300   MCSymbol *PrologueEnd = Asm.createTempSymbol("line_prologue_end");
301   Asm.emitLabelDifference(PrologueEnd, PrologueStart,
302                           Format == DwarfFormat::DWARF64 ? 8 : 4);
303   Asm.OutStreamer->emitLabel(PrologueStart);
304 
305   DWARFDebugLine::Prologue DefaultPrologue = createBasicPrologue();
306   writeProloguePayload(DefaultPrologue, Asm);
307   Asm.OutStreamer->emitLabel(PrologueEnd);
308   return UnitEnd;
309 }
310 
311 void dwarfgen::LineTable::writePrologue(AsmPrinter &Asm) const {
312   if (Format == DwarfFormat::DWARF64) {
313     Asm.emitInt32((int)dwarf::DW_LENGTH_DWARF64);
314     Asm.emitInt64(Prologue->TotalLength);
315   } else {
316     Asm.emitInt32(Prologue->TotalLength);
317   }
318   Asm.emitInt16(Prologue->getVersion());
319   if (Version == 5) {
320     Asm.emitInt8(Prologue->getAddressSize());
321     Asm.emitInt8(Prologue->SegSelectorSize);
322   }
323   if (Format == DwarfFormat::DWARF64)
324     Asm.emitInt64(Prologue->PrologueLength);
325   else
326     Asm.emitInt32(Prologue->PrologueLength);
327 
328   writeProloguePayload(*Prologue, Asm);
329 }
330 
331 static void writeCString(StringRef Str, AsmPrinter &Asm) {
332   Asm.OutStreamer->emitBytes(Str);
333   Asm.emitInt8(0);
334 }
335 
336 static void writeV2IncludeAndFileTable(const DWARFDebugLine::Prologue &Prologue,
337                                        AsmPrinter &Asm) {
338   for (auto Include : Prologue.IncludeDirectories) {
339     assert(Include.getAsCString() && "expected a string form for include dir");
340     writeCString(*Include.getAsCString(), Asm);
341   }
342   Asm.emitInt8(0);
343 
344   for (auto File : Prologue.FileNames) {
345     assert(File.Name.getAsCString() && "expected a string form for file name");
346     writeCString(*File.Name.getAsCString(), Asm);
347     Asm.emitULEB128(File.DirIdx);
348     Asm.emitULEB128(File.ModTime);
349     Asm.emitULEB128(File.Length);
350   }
351   Asm.emitInt8(0);
352 }
353 
354 static void writeV5IncludeAndFileTable(const DWARFDebugLine::Prologue &Prologue,
355                                        AsmPrinter &Asm) {
356   Asm.emitInt8(1); // directory_entry_format_count.
357   // TODO: Add support for other content descriptions - we currently only
358   // support a single DW_LNCT_path/DW_FORM_string.
359   Asm.emitULEB128(DW_LNCT_path);
360   Asm.emitULEB128(DW_FORM_string);
361   Asm.emitULEB128(Prologue.IncludeDirectories.size());
362   for (auto Include : Prologue.IncludeDirectories) {
363     assert(Include.getAsCString() && "expected a string form for include dir");
364     writeCString(*Include.getAsCString(), Asm);
365   }
366 
367   Asm.emitInt8(2); // file_name_entry_format_count.
368   Asm.emitULEB128(DW_LNCT_path);
369   Asm.emitULEB128(DW_FORM_string);
370   Asm.emitULEB128(DW_LNCT_directory_index);
371   Asm.emitULEB128(DW_FORM_data1);
372   Asm.emitULEB128(Prologue.FileNames.size());
373   for (auto File : Prologue.FileNames) {
374     assert(File.Name.getAsCString() && "expected a string form for file name");
375     writeCString(*File.Name.getAsCString(), Asm);
376     Asm.emitInt8(File.DirIdx);
377   }
378 }
379 
380 void dwarfgen::LineTable::writeProloguePayload(
381     const DWARFDebugLine::Prologue &Prologue, AsmPrinter &Asm) const {
382   Asm.emitInt8(Prologue.MinInstLength);
383   if (Version >= 4)
384     Asm.emitInt8(Prologue.MaxOpsPerInst);
385   Asm.emitInt8(Prologue.DefaultIsStmt);
386   Asm.emitInt8(Prologue.LineBase);
387   Asm.emitInt8(Prologue.LineRange);
388   Asm.emitInt8(Prologue.OpcodeBase);
389   for (auto Length : Prologue.StandardOpcodeLengths) {
390     Asm.emitInt8(Length);
391   }
392 
393   if (Version < 5)
394     writeV2IncludeAndFileTable(Prologue, Asm);
395   else
396     writeV5IncludeAndFileTable(Prologue, Asm);
397 }
398 
399 //===----------------------------------------------------------------------===//
400 /// dwarfgen::Generator implementation.
401 //===----------------------------------------------------------------------===//
402 
403 dwarfgen::Generator::Generator()
404     : MAB(nullptr), MCE(nullptr), MS(nullptr), TLOF(nullptr),
405       StringPool(nullptr), Abbreviations(Allocator),
406       StringOffsetsStartSym(nullptr), Version(0) {}
407 dwarfgen::Generator::~Generator() = default;
408 
409 llvm::Expected<std::unique_ptr<dwarfgen::Generator>>
410 dwarfgen::Generator::create(Triple TheTriple, uint16_t DwarfVersion) {
411   std::unique_ptr<dwarfgen::Generator> GenUP(new dwarfgen::Generator());
412   llvm::Error error = GenUP->init(TheTriple, DwarfVersion);
413   if (error)
414     return Expected<std::unique_ptr<dwarfgen::Generator>>(std::move(error));
415   return Expected<std::unique_ptr<dwarfgen::Generator>>(std::move(GenUP));
416 }
417 
418 llvm::Error dwarfgen::Generator::init(Triple TheTriple, uint16_t V) {
419   Version = V;
420   std::string ErrorStr;
421   std::string TripleName;
422 
423   // Get the target.
424   const Target *TheTarget =
425       TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
426   if (!TheTarget)
427     return make_error<StringError>(ErrorStr, inconvertibleErrorCode());
428 
429   TripleName = TheTriple.getTriple();
430 
431   // Create all the MC Objects.
432   MRI.reset(TheTarget->createMCRegInfo(TripleName));
433   if (!MRI)
434     return make_error<StringError>(Twine("no register info for target ") +
435                                        TripleName,
436                                    inconvertibleErrorCode());
437 
438   MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
439   MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
440   if (!MAI)
441     return make_error<StringError>("no asm info for target " + TripleName,
442                                    inconvertibleErrorCode());
443 
444   MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
445   if (!MSTI)
446     return make_error<StringError>("no subtarget info for target " + TripleName,
447                                    inconvertibleErrorCode());
448 
449   MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
450   if (!MAB)
451     return make_error<StringError>("no asm backend for target " + TripleName,
452                                    inconvertibleErrorCode());
453 
454   MII.reset(TheTarget->createMCInstrInfo());
455   if (!MII)
456     return make_error<StringError>("no instr info info for target " +
457                                        TripleName,
458                                    inconvertibleErrorCode());
459 
460   TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
461                                           None));
462   if (!TM)
463     return make_error<StringError>("no target machine for target " + TripleName,
464                                    inconvertibleErrorCode());
465 
466   TLOF = TM->getObjFileLowering();
467   MC.reset(new MCContext(MAI.get(), MRI.get(), TLOF));
468   TLOF->Initialize(*MC, *TM);
469 
470   MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC);
471   if (!MCE)
472     return make_error<StringError>("no code emitter for target " + TripleName,
473                                    inconvertibleErrorCode());
474 
475   Stream = std::make_unique<raw_svector_ostream>(FileBytes);
476 
477   MS = TheTarget->createMCObjectStreamer(
478       TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
479       MAB->createObjectWriter(*Stream), std::unique_ptr<MCCodeEmitter>(MCE),
480       *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
481       /*DWARFMustBeAtTheEnd*/ false);
482   if (!MS)
483     return make_error<StringError>("no object streamer for target " +
484                                        TripleName,
485                                    inconvertibleErrorCode());
486 
487 
488   // Finally create the AsmPrinter we'll use to emit the DIEs.
489   Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
490   if (!Asm)
491     return make_error<StringError>("no asm printer for target " + TripleName,
492                                    inconvertibleErrorCode());
493 
494   // Set the DWARF version correctly on all classes that we use.
495   MC->setDwarfVersion(Version);
496   Asm->setDwarfVersion(Version);
497 
498   StringPool = std::make_unique<DwarfStringPool>(Allocator, *Asm, StringRef());
499   StringOffsetsStartSym = Asm->createTempSymbol("str_offsets_base");
500 
501   return Error::success();
502 }
503 
504 StringRef dwarfgen::Generator::generate() {
505   // Offset from the first CU in the debug info section is 0 initially.
506   unsigned SecOffset = 0;
507 
508   // Iterate over each compile unit and set the size and offsets for each
509   // DIE within each compile unit. All offsets are CU relative.
510   for (auto &CU : CompileUnits) {
511     // Set the absolute .debug_info offset for this compile unit.
512     CU->setOffset(SecOffset);
513     // The DIEs contain compile unit relative offsets.
514     unsigned CUOffset = 11;
515     CUOffset = CU->getUnitDIE().computeSizeAndOffsets(CUOffset);
516     // Update our absolute .debug_info offset.
517     SecOffset += CUOffset;
518     CU->setLength(CUOffset - 4);
519   }
520   Abbreviations.Emit(Asm.get(), TLOF->getDwarfAbbrevSection());
521 
522   StringPool->emitStringOffsetsTableHeader(*Asm, TLOF->getDwarfStrOffSection(),
523                                            StringOffsetsStartSym);
524   StringPool->emit(*Asm, TLOF->getDwarfStrSection(),
525                    TLOF->getDwarfStrOffSection());
526 
527   MS->SwitchSection(TLOF->getDwarfInfoSection());
528   for (auto &CU : CompileUnits) {
529     uint16_t Version = CU->getVersion();
530     auto Length = CU->getLength();
531     MC->setDwarfVersion(Version);
532     assert(Length != -1U);
533     Asm->emitInt32(Length);
534     Asm->emitInt16(Version);
535     if (Version <= 4) {
536       Asm->emitInt32(0);
537       Asm->emitInt8(CU->getAddressSize());
538     } else {
539       Asm->emitInt8(dwarf::DW_UT_compile);
540       Asm->emitInt8(CU->getAddressSize());
541       Asm->emitInt32(0);
542     }
543     Asm->emitDwarfDIE(*CU->getUnitDIE().Die);
544   }
545 
546   MS->SwitchSection(TLOF->getDwarfLineSection());
547   for (auto &LT : LineTables)
548     LT->generate(*MC, *Asm);
549 
550   MS->Finish();
551   if (FileBytes.empty())
552     return StringRef();
553   return StringRef(FileBytes.data(), FileBytes.size());
554 }
555 
556 bool dwarfgen::Generator::saveFile(StringRef Path) {
557   if (FileBytes.empty())
558     return false;
559   std::error_code EC;
560   raw_fd_ostream Strm(Path, EC, sys::fs::OF_None);
561   if (EC)
562     return false;
563   Strm.write(FileBytes.data(), FileBytes.size());
564   Strm.close();
565   return true;
566 }
567 
568 dwarfgen::CompileUnit &dwarfgen::Generator::addCompileUnit() {
569   CompileUnits.push_back(
570       std::make_unique<CompileUnit>(*this, Version, Asm->getPointerSize()));
571   return *CompileUnits.back();
572 }
573 
574 dwarfgen::LineTable &dwarfgen::Generator::addLineTable(DwarfFormat Format) {
575   LineTables.push_back(
576       std::make_unique<LineTable>(Version, Format, Asm->getPointerSize()));
577   return *LineTables.back();
578 }
579