xref: /freebsd/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFEmitter.cpp (revision e3f4a63af63bea70bc86b6c790b14aa5ee99fcd0)
1 //===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===//
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 /// \file
10 /// The DWARF component of yaml2obj. Provided as library code for tests.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ObjectYAML/DWARFEmitter.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/BinaryFormat/Dwarf.h"
20 #include "llvm/ObjectYAML/DWARFYAML.h"
21 #include "llvm/Support/Errc.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/LEB128.h"
24 #include "llvm/Support/MathExtras.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/SwapByteOrder.h"
28 #include "llvm/Support/YAMLTraits.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/TargetParser/Host.h"
31 #include <cassert>
32 #include <cstddef>
33 #include <cstdint>
34 #include <memory>
35 #include <optional>
36 #include <string>
37 #include <vector>
38 
39 using namespace llvm;
40 
41 template <typename T>
42 static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) {
43   if (IsLittleEndian != sys::IsLittleEndianHost)
44     sys::swapByteOrder(Integer);
45   OS.write(reinterpret_cast<char *>(&Integer), sizeof(T));
46 }
47 
48 static Error writeVariableSizedInteger(uint64_t Integer, size_t Size,
49                                        raw_ostream &OS, bool IsLittleEndian) {
50   if (8 == Size)
51     writeInteger((uint64_t)Integer, OS, IsLittleEndian);
52   else if (4 == Size)
53     writeInteger((uint32_t)Integer, OS, IsLittleEndian);
54   else if (2 == Size)
55     writeInteger((uint16_t)Integer, OS, IsLittleEndian);
56   else if (1 == Size)
57     writeInteger((uint8_t)Integer, OS, IsLittleEndian);
58   else
59     return createStringError(errc::not_supported,
60                              "invalid integer write size: %zu", Size);
61 
62   return Error::success();
63 }
64 
65 static void ZeroFillBytes(raw_ostream &OS, size_t Size) {
66   std::vector<uint8_t> FillData(Size, 0);
67   OS.write(reinterpret_cast<char *>(FillData.data()), Size);
68 }
69 
70 static void writeInitialLength(const dwarf::DwarfFormat Format,
71                                const uint64_t Length, raw_ostream &OS,
72                                bool IsLittleEndian) {
73   bool IsDWARF64 = Format == dwarf::DWARF64;
74   if (IsDWARF64)
75     cantFail(writeVariableSizedInteger(dwarf::DW_LENGTH_DWARF64, 4, OS,
76                                        IsLittleEndian));
77   cantFail(
78       writeVariableSizedInteger(Length, IsDWARF64 ? 8 : 4, OS, IsLittleEndian));
79 }
80 
81 static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format,
82                              raw_ostream &OS, bool IsLittleEndian) {
83   cantFail(writeVariableSizedInteger(Offset, Format == dwarf::DWARF64 ? 8 : 4,
84                                      OS, IsLittleEndian));
85 }
86 
87 Error DWARFYAML::emitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) {
88   for (StringRef Str : *DI.DebugStrings) {
89     OS.write(Str.data(), Str.size());
90     OS.write('\0');
91   }
92 
93   return Error::success();
94 }
95 
96 StringRef DWARFYAML::Data::getAbbrevTableContentByIndex(uint64_t Index) const {
97   assert(Index < DebugAbbrev.size() &&
98          "Index should be less than the size of DebugAbbrev array");
99   auto [It, Inserted] = AbbrevTableContents.try_emplace(Index);
100   if (!Inserted)
101     return It->second;
102 
103   raw_string_ostream OS(It->second);
104 
105   uint64_t AbbrevCode = 0;
106   for (const DWARFYAML::Abbrev &AbbrevDecl : DebugAbbrev[Index].Table) {
107     AbbrevCode = AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
108     encodeULEB128(AbbrevCode, OS);
109     encodeULEB128(AbbrevDecl.Tag, OS);
110     OS.write(AbbrevDecl.Children);
111     for (const auto &Attr : AbbrevDecl.Attributes) {
112       encodeULEB128(Attr.Attribute, OS);
113       encodeULEB128(Attr.Form, OS);
114       if (Attr.Form == dwarf::DW_FORM_implicit_const)
115         encodeSLEB128(Attr.Value, OS);
116     }
117     encodeULEB128(0, OS);
118     encodeULEB128(0, OS);
119   }
120 
121   // The abbreviations for a given compilation unit end with an entry
122   // consisting of a 0 byte for the abbreviation code.
123   OS.write_zeros(1);
124 
125   return It->second;
126 }
127 
128 Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
129   for (uint64_t I = 0; I < DI.DebugAbbrev.size(); ++I) {
130     StringRef AbbrevTableContent = DI.getAbbrevTableContentByIndex(I);
131     OS.write(AbbrevTableContent.data(), AbbrevTableContent.size());
132   }
133 
134   return Error::success();
135 }
136 
137 Error DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
138   assert(DI.DebugAranges && "unexpected emitDebugAranges() call");
139   for (const auto &Range : *DI.DebugAranges) {
140     uint8_t AddrSize;
141     if (Range.AddrSize)
142       AddrSize = *Range.AddrSize;
143     else
144       AddrSize = DI.Is64BitAddrSize ? 8 : 4;
145 
146     uint64_t Length = 4; // sizeof(version) 2 + sizeof(address_size) 1 +
147                          // sizeof(segment_selector_size) 1
148     Length +=
149         Range.Format == dwarf::DWARF64 ? 8 : 4; // sizeof(debug_info_offset)
150 
151     const uint64_t HeaderLength =
152         Length + (Range.Format == dwarf::DWARF64
153                       ? 12
154                       : 4); // sizeof(unit_header) = 12 (DWARF64) or 4 (DWARF32)
155     const uint64_t PaddedHeaderLength = alignTo(HeaderLength, AddrSize * 2);
156 
157     if (Range.Length) {
158       Length = *Range.Length;
159     } else {
160       Length += PaddedHeaderLength - HeaderLength;
161       Length += AddrSize * 2 * (Range.Descriptors.size() + 1);
162     }
163 
164     writeInitialLength(Range.Format, Length, OS, DI.IsLittleEndian);
165     writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian);
166     writeDWARFOffset(Range.CuOffset, Range.Format, OS, DI.IsLittleEndian);
167     writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
168     writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian);
169     ZeroFillBytes(OS, PaddedHeaderLength - HeaderLength);
170 
171     for (const auto &Descriptor : Range.Descriptors) {
172       if (Error Err = writeVariableSizedInteger(Descriptor.Address, AddrSize,
173                                                 OS, DI.IsLittleEndian))
174         return createStringError(errc::not_supported,
175                                  "unable to write debug_aranges address: %s",
176                                  toString(std::move(Err)).c_str());
177       cantFail(writeVariableSizedInteger(Descriptor.Length, AddrSize, OS,
178                                          DI.IsLittleEndian));
179     }
180     ZeroFillBytes(OS, AddrSize * 2);
181   }
182 
183   return Error::success();
184 }
185 
186 Error DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
187   const size_t RangesOffset = OS.tell();
188   uint64_t EntryIndex = 0;
189   for (const auto &DebugRanges : *DI.DebugRanges) {
190     const size_t CurrOffset = OS.tell() - RangesOffset;
191     if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset)
192       return createStringError(errc::invalid_argument,
193                                "'Offset' for 'debug_ranges' with index " +
194                                    Twine(EntryIndex) +
195                                    " must be greater than or equal to the "
196                                    "number of bytes written already (0x" +
197                                    Twine::utohexstr(CurrOffset) + ")");
198     if (DebugRanges.Offset)
199       ZeroFillBytes(OS, *DebugRanges.Offset - CurrOffset);
200 
201     uint8_t AddrSize;
202     if (DebugRanges.AddrSize)
203       AddrSize = *DebugRanges.AddrSize;
204     else
205       AddrSize = DI.Is64BitAddrSize ? 8 : 4;
206     for (const auto &Entry : DebugRanges.Entries) {
207       if (Error Err = writeVariableSizedInteger(Entry.LowOffset, AddrSize, OS,
208                                                 DI.IsLittleEndian))
209         return createStringError(
210             errc::not_supported,
211             "unable to write debug_ranges address offset: %s",
212             toString(std::move(Err)).c_str());
213       cantFail(writeVariableSizedInteger(Entry.HighOffset, AddrSize, OS,
214                                          DI.IsLittleEndian));
215     }
216     ZeroFillBytes(OS, AddrSize * 2);
217     ++EntryIndex;
218   }
219 
220   return Error::success();
221 }
222 
223 static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect,
224                             bool IsLittleEndian, bool IsGNUPubSec = false) {
225   writeInitialLength(Sect.Format, Sect.Length, OS, IsLittleEndian);
226   writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
227   writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
228   writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
229   for (const auto &Entry : Sect.Entries) {
230     writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
231     if (IsGNUPubSec)
232       writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian);
233     OS.write(Entry.Name.data(), Entry.Name.size());
234     OS.write('\0');
235   }
236   return Error::success();
237 }
238 
239 Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, const Data &DI) {
240   assert(DI.PubNames && "unexpected emitDebugPubnames() call");
241   return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian);
242 }
243 
244 Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, const Data &DI) {
245   assert(DI.PubTypes && "unexpected emitDebugPubtypes() call");
246   return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian);
247 }
248 
249 Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, const Data &DI) {
250   assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call");
251   return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian,
252                         /*IsGNUStyle=*/true);
253 }
254 
255 Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI) {
256   assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call");
257   return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian,
258                         /*IsGNUStyle=*/true);
259 }
260 
261 static Expected<uint64_t> writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex,
262                                    uint64_t AbbrevTableID,
263                                    const dwarf::FormParams &Params,
264                                    const DWARFYAML::Entry &Entry,
265                                    raw_ostream &OS, bool IsLittleEndian) {
266   uint64_t EntryBegin = OS.tell();
267   encodeULEB128(Entry.AbbrCode, OS);
268   uint32_t AbbrCode = Entry.AbbrCode;
269   if (AbbrCode == 0 || Entry.Values.empty())
270     return OS.tell() - EntryBegin;
271 
272   Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
273       DI.getAbbrevTableInfoByID(AbbrevTableID);
274   if (!AbbrevTableInfoOrErr)
275     return createStringError(errc::invalid_argument,
276                              toString(AbbrevTableInfoOrErr.takeError()) +
277                                  " for compilation unit with index " +
278                                  utostr(CUIndex));
279 
280   ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
281       DI.DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);
282 
283   if (AbbrCode > AbbrevDecls.size())
284     return createStringError(
285         errc::invalid_argument,
286         "abbrev code must be less than or equal to the number of "
287         "entries in abbreviation table");
288   const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1];
289   auto FormVal = Entry.Values.begin();
290   auto AbbrForm = Abbrev.Attributes.begin();
291   for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
292        ++FormVal, ++AbbrForm) {
293     dwarf::Form Form = AbbrForm->Form;
294     bool Indirect;
295     do {
296       Indirect = false;
297       switch (Form) {
298       case dwarf::DW_FORM_addr:
299         // TODO: Test this error.
300         if (Error Err = writeVariableSizedInteger(
301                 FormVal->Value, Params.AddrSize, OS, IsLittleEndian))
302           return std::move(Err);
303         break;
304       case dwarf::DW_FORM_ref_addr:
305         // TODO: Test this error.
306         if (Error Err = writeVariableSizedInteger(FormVal->Value,
307                                                   Params.getRefAddrByteSize(),
308                                                   OS, IsLittleEndian))
309           return std::move(Err);
310         break;
311       case dwarf::DW_FORM_exprloc:
312       case dwarf::DW_FORM_block:
313         encodeULEB128(FormVal->BlockData.size(), OS);
314         OS.write((const char *)FormVal->BlockData.data(),
315                  FormVal->BlockData.size());
316         break;
317       case dwarf::DW_FORM_block1: {
318         writeInteger((uint8_t)FormVal->BlockData.size(), OS, IsLittleEndian);
319         OS.write((const char *)FormVal->BlockData.data(),
320                  FormVal->BlockData.size());
321         break;
322       }
323       case dwarf::DW_FORM_block2: {
324         writeInteger((uint16_t)FormVal->BlockData.size(), OS, IsLittleEndian);
325         OS.write((const char *)FormVal->BlockData.data(),
326                  FormVal->BlockData.size());
327         break;
328       }
329       case dwarf::DW_FORM_block4: {
330         writeInteger((uint32_t)FormVal->BlockData.size(), OS, IsLittleEndian);
331         OS.write((const char *)FormVal->BlockData.data(),
332                  FormVal->BlockData.size());
333         break;
334       }
335       case dwarf::DW_FORM_strx:
336       case dwarf::DW_FORM_addrx:
337       case dwarf::DW_FORM_rnglistx:
338       case dwarf::DW_FORM_loclistx:
339       case dwarf::DW_FORM_udata:
340       case dwarf::DW_FORM_ref_udata:
341       case dwarf::DW_FORM_GNU_addr_index:
342       case dwarf::DW_FORM_GNU_str_index:
343         encodeULEB128(FormVal->Value, OS);
344         break;
345       case dwarf::DW_FORM_data1:
346       case dwarf::DW_FORM_ref1:
347       case dwarf::DW_FORM_flag:
348       case dwarf::DW_FORM_strx1:
349       case dwarf::DW_FORM_addrx1:
350         writeInteger((uint8_t)FormVal->Value, OS, IsLittleEndian);
351         break;
352       case dwarf::DW_FORM_data2:
353       case dwarf::DW_FORM_ref2:
354       case dwarf::DW_FORM_strx2:
355       case dwarf::DW_FORM_addrx2:
356         writeInteger((uint16_t)FormVal->Value, OS, IsLittleEndian);
357         break;
358       case dwarf::DW_FORM_data4:
359       case dwarf::DW_FORM_ref4:
360       case dwarf::DW_FORM_ref_sup4:
361       case dwarf::DW_FORM_strx4:
362       case dwarf::DW_FORM_addrx4:
363         writeInteger((uint32_t)FormVal->Value, OS, IsLittleEndian);
364         break;
365       case dwarf::DW_FORM_data8:
366       case dwarf::DW_FORM_ref8:
367       case dwarf::DW_FORM_ref_sup8:
368       case dwarf::DW_FORM_ref_sig8:
369         writeInteger((uint64_t)FormVal->Value, OS, IsLittleEndian);
370         break;
371       case dwarf::DW_FORM_sdata:
372         encodeSLEB128(FormVal->Value, OS);
373         break;
374       case dwarf::DW_FORM_string:
375         OS.write(FormVal->CStr.data(), FormVal->CStr.size());
376         OS.write('\0');
377         break;
378       case dwarf::DW_FORM_indirect:
379         encodeULEB128(FormVal->Value, OS);
380         Indirect = true;
381         Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
382         ++FormVal;
383         break;
384       case dwarf::DW_FORM_strp:
385       case dwarf::DW_FORM_sec_offset:
386       case dwarf::DW_FORM_GNU_ref_alt:
387       case dwarf::DW_FORM_GNU_strp_alt:
388       case dwarf::DW_FORM_line_strp:
389       case dwarf::DW_FORM_strp_sup:
390         cantFail(writeVariableSizedInteger(FormVal->Value,
391                                            Params.getDwarfOffsetByteSize(), OS,
392                                            IsLittleEndian));
393         break;
394       default:
395         break;
396       }
397     } while (Indirect);
398   }
399 
400   return OS.tell() - EntryBegin;
401 }
402 
403 Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
404   for (uint64_t I = 0; I < DI.Units.size(); ++I) {
405     const DWARFYAML::Unit &Unit = DI.Units[I];
406     uint8_t AddrSize;
407     if (Unit.AddrSize)
408       AddrSize = *Unit.AddrSize;
409     else
410       AddrSize = DI.Is64BitAddrSize ? 8 : 4;
411     dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format};
412     uint64_t Length = 3; // sizeof(version) + sizeof(address_size)
413     Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset)
414     if (Unit.Version >= 5) {
415       ++Length; // sizeof(unit_type)
416       switch (Unit.Type) {
417       case dwarf::DW_UT_compile:
418       case dwarf::DW_UT_partial:
419       default:
420         break;
421       case dwarf::DW_UT_type:
422       case dwarf::DW_UT_split_type:
423         // sizeof(type_signature) + sizeof(type_offset)
424         Length += 8 + Params.getDwarfOffsetByteSize();
425         break;
426       case dwarf::DW_UT_skeleton:
427       case dwarf::DW_UT_split_compile:
428         Length += 8; // sizeof(dwo_id)
429       }
430     }
431 
432     // Since the length of the current compilation unit is undetermined yet, we
433     // firstly write the content of the compilation unit to a buffer to
434     // calculate it and then serialize the buffer content to the actual output
435     // stream.
436     std::string EntryBuffer;
437     raw_string_ostream EntryBufferOS(EntryBuffer);
438 
439     uint64_t AbbrevTableID = Unit.AbbrevTableID.value_or(I);
440     for (const DWARFYAML::Entry &Entry : Unit.Entries) {
441       if (Expected<uint64_t> EntryLength =
442               writeDIE(DI, I, AbbrevTableID, Params, Entry, EntryBufferOS,
443                        DI.IsLittleEndian))
444         Length += *EntryLength;
445       else
446         return EntryLength.takeError();
447     }
448 
449     // If the length is specified in the YAML description, we use it instead of
450     // the actual length.
451     if (Unit.Length)
452       Length = *Unit.Length;
453 
454     writeInitialLength(Unit.Format, Length, OS, DI.IsLittleEndian);
455     writeInteger((uint16_t)Unit.Version, OS, DI.IsLittleEndian);
456 
457     uint64_t AbbrevTableOffset = 0;
458     if (Unit.AbbrOffset) {
459       AbbrevTableOffset = *Unit.AbbrOffset;
460     } else {
461       if (Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
462               DI.getAbbrevTableInfoByID(AbbrevTableID)) {
463         AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
464       } else {
465         // The current compilation unit may not have DIEs and it will not be
466         // able to find the associated abbrev table. We consume the error and
467         // assign 0 to the debug_abbrev_offset in such circumstances.
468         consumeError(AbbrevTableInfoOrErr.takeError());
469       }
470     }
471 
472     if (Unit.Version >= 5) {
473       writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian);
474       writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
475       writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
476       switch (Unit.Type) {
477       case dwarf::DW_UT_compile:
478       case dwarf::DW_UT_partial:
479       default:
480         break;
481       case dwarf::DW_UT_type:
482       case dwarf::DW_UT_split_type:
483         writeInteger(Unit.TypeSignatureOrDwoID, OS, DI.IsLittleEndian);
484         writeDWARFOffset(Unit.TypeOffset, Unit.Format, OS, DI.IsLittleEndian);
485         break;
486       case dwarf::DW_UT_skeleton:
487       case dwarf::DW_UT_split_compile:
488         writeInteger(Unit.TypeSignatureOrDwoID, OS, DI.IsLittleEndian);
489         break;
490       }
491     } else {
492       writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
493       writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
494     }
495 
496     OS.write(EntryBuffer.data(), EntryBuffer.size());
497   }
498 
499   return Error::success();
500 }
501 
502 static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
503   OS.write(File.Name.data(), File.Name.size());
504   OS.write('\0');
505   encodeULEB128(File.DirIdx, OS);
506   encodeULEB128(File.ModTime, OS);
507   encodeULEB128(File.Length, OS);
508 }
509 
510 static void writeExtendedOpcode(const DWARFYAML::LineTableOpcode &Op,
511                                 uint8_t AddrSize, bool IsLittleEndian,
512                                 raw_ostream &OS) {
513   // The first byte of extended opcodes is a zero byte. The next bytes are an
514   // ULEB128 integer giving the number of bytes in the instruction itself (does
515   // not include the first zero byte or the size). We serialize the instruction
516   // itself into the OpBuffer and then write the size of the buffer and the
517   // buffer to the real output stream.
518   std::string OpBuffer;
519   raw_string_ostream OpBufferOS(OpBuffer);
520   writeInteger((uint8_t)Op.SubOpcode, OpBufferOS, IsLittleEndian);
521   switch (Op.SubOpcode) {
522   case dwarf::DW_LNE_set_address:
523     cantFail(writeVariableSizedInteger(Op.Data, AddrSize, OpBufferOS,
524                                        IsLittleEndian));
525     break;
526   case dwarf::DW_LNE_define_file:
527     emitFileEntry(OpBufferOS, Op.FileEntry);
528     break;
529   case dwarf::DW_LNE_set_discriminator:
530     encodeULEB128(Op.Data, OpBufferOS);
531     break;
532   case dwarf::DW_LNE_end_sequence:
533     break;
534   default:
535     for (auto OpByte : Op.UnknownOpcodeData)
536       writeInteger((uint8_t)OpByte, OpBufferOS, IsLittleEndian);
537   }
538   uint64_t ExtLen = Op.ExtLen.value_or(OpBuffer.size());
539   encodeULEB128(ExtLen, OS);
540   OS.write(OpBuffer.data(), OpBuffer.size());
541 }
542 
543 static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op,
544                                  uint8_t OpcodeBase, uint8_t AddrSize,
545                                  raw_ostream &OS, bool IsLittleEndian) {
546   writeInteger((uint8_t)Op.Opcode, OS, IsLittleEndian);
547   if (Op.Opcode == 0) {
548     writeExtendedOpcode(Op, AddrSize, IsLittleEndian, OS);
549   } else if (Op.Opcode < OpcodeBase) {
550     switch (Op.Opcode) {
551     case dwarf::DW_LNS_copy:
552     case dwarf::DW_LNS_negate_stmt:
553     case dwarf::DW_LNS_set_basic_block:
554     case dwarf::DW_LNS_const_add_pc:
555     case dwarf::DW_LNS_set_prologue_end:
556     case dwarf::DW_LNS_set_epilogue_begin:
557       break;
558 
559     case dwarf::DW_LNS_advance_pc:
560     case dwarf::DW_LNS_set_file:
561     case dwarf::DW_LNS_set_column:
562     case dwarf::DW_LNS_set_isa:
563       encodeULEB128(Op.Data, OS);
564       break;
565 
566     case dwarf::DW_LNS_advance_line:
567       encodeSLEB128(Op.SData, OS);
568       break;
569 
570     case dwarf::DW_LNS_fixed_advance_pc:
571       writeInteger((uint16_t)Op.Data, OS, IsLittleEndian);
572       break;
573 
574     default:
575       for (auto OpData : Op.StandardOpcodeData) {
576         encodeULEB128(OpData, OS);
577       }
578     }
579   }
580 }
581 
582 static std::vector<uint8_t>
583 getStandardOpcodeLengths(uint16_t Version, std::optional<uint8_t> OpcodeBase) {
584   // If the opcode_base field isn't specified, we returns the
585   // standard_opcode_lengths array according to the version by default.
586   std::vector<uint8_t> StandardOpcodeLengths{0, 1, 1, 1, 1, 0,
587                                              0, 0, 1, 0, 0, 1};
588   if (Version == 2) {
589     // DWARF v2 uses the same first 9 standard opcodes as v3-5.
590     StandardOpcodeLengths.resize(9);
591   } else if (OpcodeBase) {
592     StandardOpcodeLengths.resize(*OpcodeBase > 0 ? *OpcodeBase - 1 : 0, 0);
593   }
594   return StandardOpcodeLengths;
595 }
596 
597 Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
598   for (const DWARFYAML::LineTable &LineTable : DI.DebugLines) {
599     // Buffer holds the bytes following the header_length (or prologue_length in
600     // DWARFv2) field to the end of the line number program itself.
601     std::string Buffer;
602     raw_string_ostream BufferOS(Buffer);
603 
604     writeInteger(LineTable.MinInstLength, BufferOS, DI.IsLittleEndian);
605     // TODO: Add support for emitting DWARFv5 line table.
606     if (LineTable.Version >= 4)
607       writeInteger(LineTable.MaxOpsPerInst, BufferOS, DI.IsLittleEndian);
608     writeInteger(LineTable.DefaultIsStmt, BufferOS, DI.IsLittleEndian);
609     writeInteger(LineTable.LineBase, BufferOS, DI.IsLittleEndian);
610     writeInteger(LineTable.LineRange, BufferOS, DI.IsLittleEndian);
611 
612     std::vector<uint8_t> StandardOpcodeLengths =
613         LineTable.StandardOpcodeLengths.value_or(
614             getStandardOpcodeLengths(LineTable.Version, LineTable.OpcodeBase));
615     uint8_t OpcodeBase = LineTable.OpcodeBase
616                              ? *LineTable.OpcodeBase
617                              : StandardOpcodeLengths.size() + 1;
618     writeInteger(OpcodeBase, BufferOS, DI.IsLittleEndian);
619     for (uint8_t OpcodeLength : StandardOpcodeLengths)
620       writeInteger(OpcodeLength, BufferOS, DI.IsLittleEndian);
621 
622     for (StringRef IncludeDir : LineTable.IncludeDirs) {
623       BufferOS.write(IncludeDir.data(), IncludeDir.size());
624       BufferOS.write('\0');
625     }
626     BufferOS.write('\0');
627 
628     for (const DWARFYAML::File &File : LineTable.Files)
629       emitFileEntry(BufferOS, File);
630     BufferOS.write('\0');
631 
632     uint64_t HeaderLength =
633         LineTable.PrologueLength ? *LineTable.PrologueLength : Buffer.size();
634 
635     for (const DWARFYAML::LineTableOpcode &Op : LineTable.Opcodes)
636       writeLineTableOpcode(Op, OpcodeBase, DI.Is64BitAddrSize ? 8 : 4, BufferOS,
637                            DI.IsLittleEndian);
638 
639     uint64_t Length;
640     if (LineTable.Length) {
641       Length = *LineTable.Length;
642     } else {
643       Length = 2; // sizeof(version)
644       Length +=
645           (LineTable.Format == dwarf::DWARF64 ? 8 : 4); // sizeof(header_length)
646       Length += Buffer.size();
647     }
648 
649     writeInitialLength(LineTable.Format, Length, OS, DI.IsLittleEndian);
650     writeInteger(LineTable.Version, OS, DI.IsLittleEndian);
651     writeDWARFOffset(HeaderLength, LineTable.Format, OS, DI.IsLittleEndian);
652     OS.write(Buffer.data(), Buffer.size());
653   }
654 
655   return Error::success();
656 }
657 
658 Error DWARFYAML::emitDebugAddr(raw_ostream &OS, const Data &DI) {
659   for (const AddrTableEntry &TableEntry : *DI.DebugAddr) {
660     uint8_t AddrSize;
661     if (TableEntry.AddrSize)
662       AddrSize = *TableEntry.AddrSize;
663     else
664       AddrSize = DI.Is64BitAddrSize ? 8 : 4;
665 
666     uint64_t Length;
667     if (TableEntry.Length)
668       Length = (uint64_t)*TableEntry.Length;
669     else
670       // 2 (version) + 1 (address_size) + 1 (segment_selector_size) = 4
671       Length = 4 + (AddrSize + TableEntry.SegSelectorSize) *
672                        TableEntry.SegAddrPairs.size();
673 
674     writeInitialLength(TableEntry.Format, Length, OS, DI.IsLittleEndian);
675     writeInteger((uint16_t)TableEntry.Version, OS, DI.IsLittleEndian);
676     writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
677     writeInteger((uint8_t)TableEntry.SegSelectorSize, OS, DI.IsLittleEndian);
678 
679     for (const SegAddrPair &Pair : TableEntry.SegAddrPairs) {
680       if (TableEntry.SegSelectorSize != yaml::Hex8{0})
681         if (Error Err = writeVariableSizedInteger(Pair.Segment,
682                                                   TableEntry.SegSelectorSize,
683                                                   OS, DI.IsLittleEndian))
684           return createStringError(errc::not_supported,
685                                    "unable to write debug_addr segment: %s",
686                                    toString(std::move(Err)).c_str());
687       if (AddrSize != 0)
688         if (Error Err = writeVariableSizedInteger(Pair.Address, AddrSize, OS,
689                                                   DI.IsLittleEndian))
690           return createStringError(errc::not_supported,
691                                    "unable to write debug_addr address: %s",
692                                    toString(std::move(Err)).c_str());
693     }
694   }
695 
696   return Error::success();
697 }
698 
699 Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, const Data &DI) {
700   assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call");
701   for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) {
702     uint64_t Length;
703     if (Table.Length)
704       Length = *Table.Length;
705     else
706       // sizeof(version) + sizeof(padding) = 4
707       Length =
708           4 + Table.Offsets.size() * (Table.Format == dwarf::DWARF64 ? 8 : 4);
709 
710     writeInitialLength(Table.Format, Length, OS, DI.IsLittleEndian);
711     writeInteger((uint16_t)Table.Version, OS, DI.IsLittleEndian);
712     writeInteger((uint16_t)Table.Padding, OS, DI.IsLittleEndian);
713 
714     for (uint64_t Offset : Table.Offsets)
715       writeDWARFOffset(Offset, Table.Format, OS, DI.IsLittleEndian);
716   }
717 
718   return Error::success();
719 }
720 
721 namespace {
722 /// Emits the header for a DebugNames section.
723 void emitDebugNamesHeader(raw_ostream &OS, bool IsLittleEndian,
724                           uint32_t NameCount, uint32_t AbbrevSize,
725                           uint32_t CombinedSizeOtherParts) {
726   // Use the same AugmentationString as AsmPrinter.
727   StringRef AugmentationString = "LLVM0700";
728   size_t TotalSize = CombinedSizeOtherParts + 5 * sizeof(uint32_t) +
729                      2 * sizeof(uint16_t) + sizeof(NameCount) +
730                      sizeof(AbbrevSize) + AugmentationString.size();
731   writeInteger(uint32_t(TotalSize), OS, IsLittleEndian); // Unit length
732 
733   // Everything below is included in total size.
734   writeInteger(uint16_t(5), OS, IsLittleEndian); // Version
735   writeInteger(uint16_t(0), OS, IsLittleEndian); // Padding
736   writeInteger(uint32_t(1), OS, IsLittleEndian); // Compilation Unit count
737   writeInteger(uint32_t(0), OS, IsLittleEndian); // Local Type Unit count
738   writeInteger(uint32_t(0), OS, IsLittleEndian); // Foreign Type Unit count
739   writeInteger(uint32_t(0), OS, IsLittleEndian); // Bucket count
740   writeInteger(NameCount, OS, IsLittleEndian);
741   writeInteger(AbbrevSize, OS, IsLittleEndian);
742   writeInteger(uint32_t(AugmentationString.size()), OS, IsLittleEndian);
743   OS.write(AugmentationString.data(), AugmentationString.size());
744 }
745 
746 /// Emits the abbreviations for a DebugNames section.
747 std::string
748 emitDebugNamesAbbrev(ArrayRef<DWARFYAML::DebugNameAbbreviation> Abbrevs) {
749   std::string Data;
750   raw_string_ostream OS(Data);
751   for (const DWARFYAML::DebugNameAbbreviation &Abbrev : Abbrevs) {
752     encodeULEB128(Abbrev.Code, OS);
753     encodeULEB128(Abbrev.Tag, OS);
754     for (auto [Idx, Form] : Abbrev.Indices) {
755       encodeULEB128(Idx, OS);
756       encodeULEB128(Form, OS);
757     }
758     encodeULEB128(0, OS);
759     encodeULEB128(0, OS);
760   }
761   encodeULEB128(0, OS);
762   return Data;
763 }
764 
765 /// Emits a simple CU offsets list for a DebugNames section containing a single
766 /// CU at offset 0.
767 std::string emitDebugNamesCUOffsets(bool IsLittleEndian) {
768   std::string Data;
769   raw_string_ostream OS(Data);
770   writeInteger(uint32_t(0), OS, IsLittleEndian);
771   return Data;
772 }
773 
774 /// Emits the "NameTable" for a DebugNames section; according to the spec, it
775 /// consists of two arrays: an array of string offsets, followed immediately by
776 /// an array of entry offsets. The string offsets are emitted in the order
777 /// provided in `Entries`.
778 std::string emitDebugNamesNameTable(
779     bool IsLittleEndian,
780     const DenseMap<uint32_t, std::vector<DWARFYAML::DebugNameEntry>> &Entries,
781     ArrayRef<uint32_t> EntryPoolOffsets) {
782   assert(Entries.size() == EntryPoolOffsets.size());
783 
784   std::string Data;
785   raw_string_ostream OS(Data);
786 
787   for (uint32_t Strp : make_first_range(Entries))
788     writeInteger(Strp, OS, IsLittleEndian);
789   for (uint32_t PoolOffset : EntryPoolOffsets)
790     writeInteger(PoolOffset, OS, IsLittleEndian);
791   return Data;
792 }
793 
794 /// Groups entries based on their name (strp) code and returns a map.
795 DenseMap<uint32_t, std::vector<DWARFYAML::DebugNameEntry>>
796 groupEntries(ArrayRef<DWARFYAML::DebugNameEntry> Entries) {
797   DenseMap<uint32_t, std::vector<DWARFYAML::DebugNameEntry>> StrpToEntries;
798   for (const DWARFYAML::DebugNameEntry &Entry : Entries)
799     StrpToEntries[Entry.NameStrp].push_back(Entry);
800   return StrpToEntries;
801 }
802 
803 /// Finds the abbreviation whose code is AbbrevCode and returns a list
804 /// containing the expected size of all non-zero-length forms.
805 Expected<SmallVector<uint8_t>>
806 getNonZeroDataSizesFor(uint32_t AbbrevCode,
807                        ArrayRef<DWARFYAML::DebugNameAbbreviation> Abbrevs) {
808   const auto *AbbrevIt = find_if(Abbrevs, [&](const auto &Abbrev) {
809     return Abbrev.Code.value == AbbrevCode;
810   });
811   if (AbbrevIt == Abbrevs.end())
812     return createStringError(inconvertibleErrorCode(),
813                              "did not find an Abbreviation for this code");
814 
815   SmallVector<uint8_t> DataSizes;
816   dwarf::FormParams Params{/*Version=*/5, /*AddrSize=*/4, dwarf::DWARF32};
817   for (auto [Idx, Form] : AbbrevIt->Indices) {
818     std::optional<uint8_t> FormSize = dwarf::getFixedFormByteSize(Form, Params);
819     if (!FormSize)
820       return createStringError(inconvertibleErrorCode(),
821                                "unsupported Form for YAML debug_names emitter");
822     if (FormSize == 0)
823       continue;
824     DataSizes.push_back(*FormSize);
825   }
826   return DataSizes;
827 }
828 
829 struct PoolOffsetsAndData {
830   std::string PoolData;
831   std::vector<uint32_t> PoolOffsets;
832 };
833 
834 /// Emits the entry pool and returns an array of offsets containing the start
835 /// offset for the entries of each unique name.
836 /// Verifies that the provided number of data values match those expected by
837 /// the abbreviation table.
838 Expected<PoolOffsetsAndData> emitDebugNamesEntryPool(
839     bool IsLittleEndian,
840     const DenseMap<uint32_t, std::vector<DWARFYAML::DebugNameEntry>>
841         &StrpToEntries,
842     ArrayRef<DWARFYAML::DebugNameAbbreviation> Abbrevs) {
843   PoolOffsetsAndData Result;
844   raw_string_ostream OS(Result.PoolData);
845 
846   for (ArrayRef<DWARFYAML::DebugNameEntry> EntriesWithSameName :
847        make_second_range(StrpToEntries)) {
848     Result.PoolOffsets.push_back(Result.PoolData.size());
849 
850     for (const DWARFYAML::DebugNameEntry &Entry : EntriesWithSameName) {
851       encodeULEB128(Entry.Code, OS);
852 
853       Expected<SmallVector<uint8_t>> DataSizes =
854           getNonZeroDataSizesFor(Entry.Code, Abbrevs);
855       if (!DataSizes)
856         return DataSizes.takeError();
857       if (DataSizes->size() != Entry.Values.size())
858         return createStringError(
859             inconvertibleErrorCode(),
860             "mismatch between provided and required number of values");
861 
862       for (auto [Value, ValueSize] : zip_equal(Entry.Values, *DataSizes))
863         if (Error E =
864                 writeVariableSizedInteger(Value, ValueSize, OS, IsLittleEndian))
865           return std::move(E);
866     }
867     encodeULEB128(0, OS);
868   }
869 
870   return Result;
871 }
872 } // namespace
873 
874 Error DWARFYAML::emitDebugNames(raw_ostream &OS, const Data &DI) {
875   assert(DI.DebugNames && "unexpected emitDebugNames() call");
876   const DebugNamesSection DebugNames = DI.DebugNames.value();
877 
878   DenseMap<uint32_t, std::vector<DebugNameEntry>> StrpToEntries =
879       groupEntries(DebugNames.Entries);
880 
881   // Emit all sub-sections into individual strings so that we may compute
882   // relative offsets and sizes.
883   Expected<PoolOffsetsAndData> PoolInfo = emitDebugNamesEntryPool(
884       DI.IsLittleEndian, StrpToEntries, DebugNames.Abbrevs);
885   if (!PoolInfo)
886     return PoolInfo.takeError();
887   std::string NamesTableData = emitDebugNamesNameTable(
888       DI.IsLittleEndian, StrpToEntries, PoolInfo->PoolOffsets);
889 
890   std::string AbbrevData = emitDebugNamesAbbrev(DebugNames.Abbrevs);
891   std::string CUOffsetsData = emitDebugNamesCUOffsets(DI.IsLittleEndian);
892 
893   size_t TotalSize = PoolInfo->PoolData.size() + NamesTableData.size() +
894                      AbbrevData.size() + CUOffsetsData.size();
895 
896   // Start real emission by combining all individual strings.
897   emitDebugNamesHeader(OS, DI.IsLittleEndian, StrpToEntries.size(),
898                        AbbrevData.size(), TotalSize);
899   OS.write(CUOffsetsData.data(), CUOffsetsData.size());
900   // No local TUs, no foreign TUs, no hash lookups table.
901   OS.write(NamesTableData.data(), NamesTableData.size());
902   OS.write(AbbrevData.data(), AbbrevData.size());
903   OS.write(PoolInfo->PoolData.data(), PoolInfo->PoolData.size());
904 
905   return Error::success();
906 }
907 
908 static Error checkOperandCount(StringRef EncodingString,
909                                ArrayRef<yaml::Hex64> Values,
910                                uint64_t ExpectedOperands) {
911   if (Values.size() != ExpectedOperands)
912     return createStringError(
913         errc::invalid_argument,
914         "invalid number (%zu) of operands for the operator: %s, %" PRIu64
915         " expected",
916         Values.size(), EncodingString.str().c_str(), ExpectedOperands);
917 
918   return Error::success();
919 }
920 
921 static Error writeListEntryAddress(StringRef EncodingName, raw_ostream &OS,
922                                    uint64_t Addr, uint8_t AddrSize,
923                                    bool IsLittleEndian) {
924   if (Error Err = writeVariableSizedInteger(Addr, AddrSize, OS, IsLittleEndian))
925     return createStringError(errc::invalid_argument,
926                              "unable to write address for the operator %s: %s",
927                              EncodingName.str().c_str(),
928                              toString(std::move(Err)).c_str());
929 
930   return Error::success();
931 }
932 
933 static Expected<uint64_t>
934 writeDWARFExpression(raw_ostream &OS,
935                      const DWARFYAML::DWARFOperation &Operation,
936                      uint8_t AddrSize, bool IsLittleEndian) {
937   auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
938     return checkOperandCount(dwarf::OperationEncodingString(Operation.Operator),
939                              Operation.Values, ExpectedOperands);
940   };
941 
942   uint64_t ExpressionBegin = OS.tell();
943   writeInteger((uint8_t)Operation.Operator, OS, IsLittleEndian);
944   switch (Operation.Operator) {
945   case dwarf::DW_OP_consts:
946     if (Error Err = CheckOperands(1))
947       return std::move(Err);
948     encodeSLEB128(Operation.Values[0], OS);
949     break;
950   case dwarf::DW_OP_stack_value:
951     if (Error Err = CheckOperands(0))
952       return std::move(Err);
953     break;
954   default:
955     StringRef EncodingStr = dwarf::OperationEncodingString(Operation.Operator);
956     return createStringError(errc::not_supported,
957                              "DWARF expression: " +
958                                  (EncodingStr.empty()
959                                       ? "0x" + utohexstr(Operation.Operator)
960                                       : EncodingStr) +
961                                  " is not supported");
962   }
963   return OS.tell() - ExpressionBegin;
964 }
965 
966 static Expected<uint64_t> writeListEntry(raw_ostream &OS,
967                                          const DWARFYAML::RnglistEntry &Entry,
968                                          uint8_t AddrSize,
969                                          bool IsLittleEndian) {
970   uint64_t BeginOffset = OS.tell();
971   writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
972 
973   StringRef EncodingName = dwarf::RangeListEncodingString(Entry.Operator);
974 
975   auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
976     return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
977   };
978 
979   auto WriteAddress = [&](uint64_t Addr) -> Error {
980     return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
981                                  IsLittleEndian);
982   };
983 
984   switch (Entry.Operator) {
985   case dwarf::DW_RLE_end_of_list:
986     if (Error Err = CheckOperands(0))
987       return std::move(Err);
988     break;
989   case dwarf::DW_RLE_base_addressx:
990     if (Error Err = CheckOperands(1))
991       return std::move(Err);
992     encodeULEB128(Entry.Values[0], OS);
993     break;
994   case dwarf::DW_RLE_startx_endx:
995   case dwarf::DW_RLE_startx_length:
996   case dwarf::DW_RLE_offset_pair:
997     if (Error Err = CheckOperands(2))
998       return std::move(Err);
999     encodeULEB128(Entry.Values[0], OS);
1000     encodeULEB128(Entry.Values[1], OS);
1001     break;
1002   case dwarf::DW_RLE_base_address:
1003     if (Error Err = CheckOperands(1))
1004       return std::move(Err);
1005     if (Error Err = WriteAddress(Entry.Values[0]))
1006       return std::move(Err);
1007     break;
1008   case dwarf::DW_RLE_start_end:
1009     if (Error Err = CheckOperands(2))
1010       return std::move(Err);
1011     if (Error Err = WriteAddress(Entry.Values[0]))
1012       return std::move(Err);
1013     cantFail(WriteAddress(Entry.Values[1]));
1014     break;
1015   case dwarf::DW_RLE_start_length:
1016     if (Error Err = CheckOperands(2))
1017       return std::move(Err);
1018     if (Error Err = WriteAddress(Entry.Values[0]))
1019       return std::move(Err);
1020     encodeULEB128(Entry.Values[1], OS);
1021     break;
1022   }
1023 
1024   return OS.tell() - BeginOffset;
1025 }
1026 
1027 static Expected<uint64_t> writeListEntry(raw_ostream &OS,
1028                                          const DWARFYAML::LoclistEntry &Entry,
1029                                          uint8_t AddrSize,
1030                                          bool IsLittleEndian) {
1031   uint64_t BeginOffset = OS.tell();
1032   writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
1033 
1034   StringRef EncodingName = dwarf::LocListEncodingString(Entry.Operator);
1035 
1036   auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
1037     return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
1038   };
1039 
1040   auto WriteAddress = [&](uint64_t Addr) -> Error {
1041     return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
1042                                  IsLittleEndian);
1043   };
1044 
1045   auto WriteDWARFOperations = [&]() -> Error {
1046     std::string OpBuffer;
1047     raw_string_ostream OpBufferOS(OpBuffer);
1048     uint64_t DescriptionsLength = 0;
1049 
1050     for (const DWARFYAML::DWARFOperation &Op : Entry.Descriptions) {
1051       if (Expected<uint64_t> OpSize =
1052               writeDWARFExpression(OpBufferOS, Op, AddrSize, IsLittleEndian))
1053         DescriptionsLength += *OpSize;
1054       else
1055         return OpSize.takeError();
1056     }
1057 
1058     if (Entry.DescriptionsLength)
1059       DescriptionsLength = *Entry.DescriptionsLength;
1060     else
1061       DescriptionsLength = OpBuffer.size();
1062 
1063     encodeULEB128(DescriptionsLength, OS);
1064     OS.write(OpBuffer.data(), OpBuffer.size());
1065 
1066     return Error::success();
1067   };
1068 
1069   switch (Entry.Operator) {
1070   case dwarf::DW_LLE_end_of_list:
1071     if (Error Err = CheckOperands(0))
1072       return std::move(Err);
1073     break;
1074   case dwarf::DW_LLE_base_addressx:
1075     if (Error Err = CheckOperands(1))
1076       return std::move(Err);
1077     encodeULEB128(Entry.Values[0], OS);
1078     break;
1079   case dwarf::DW_LLE_startx_endx:
1080   case dwarf::DW_LLE_startx_length:
1081   case dwarf::DW_LLE_offset_pair:
1082     if (Error Err = CheckOperands(2))
1083       return std::move(Err);
1084     encodeULEB128(Entry.Values[0], OS);
1085     encodeULEB128(Entry.Values[1], OS);
1086     if (Error Err = WriteDWARFOperations())
1087       return std::move(Err);
1088     break;
1089   case dwarf::DW_LLE_default_location:
1090     if (Error Err = CheckOperands(0))
1091       return std::move(Err);
1092     if (Error Err = WriteDWARFOperations())
1093       return std::move(Err);
1094     break;
1095   case dwarf::DW_LLE_base_address:
1096     if (Error Err = CheckOperands(1))
1097       return std::move(Err);
1098     if (Error Err = WriteAddress(Entry.Values[0]))
1099       return std::move(Err);
1100     break;
1101   case dwarf::DW_LLE_start_end:
1102     if (Error Err = CheckOperands(2))
1103       return std::move(Err);
1104     if (Error Err = WriteAddress(Entry.Values[0]))
1105       return std::move(Err);
1106     cantFail(WriteAddress(Entry.Values[1]));
1107     if (Error Err = WriteDWARFOperations())
1108       return std::move(Err);
1109     break;
1110   case dwarf::DW_LLE_start_length:
1111     if (Error Err = CheckOperands(2))
1112       return std::move(Err);
1113     if (Error Err = WriteAddress(Entry.Values[0]))
1114       return std::move(Err);
1115     encodeULEB128(Entry.Values[1], OS);
1116     if (Error Err = WriteDWARFOperations())
1117       return std::move(Err);
1118     break;
1119   }
1120 
1121   return OS.tell() - BeginOffset;
1122 }
1123 
1124 template <typename EntryType>
1125 static Error writeDWARFLists(raw_ostream &OS,
1126                              ArrayRef<DWARFYAML::ListTable<EntryType>> Tables,
1127                              bool IsLittleEndian, bool Is64BitAddrSize) {
1128   for (const DWARFYAML::ListTable<EntryType> &Table : Tables) {
1129     // sizeof(version) + sizeof(address_size) + sizeof(segment_selector_size) +
1130     // sizeof(offset_entry_count) = 8
1131     uint64_t Length = 8;
1132 
1133     uint8_t AddrSize;
1134     if (Table.AddrSize)
1135       AddrSize = *Table.AddrSize;
1136     else
1137       AddrSize = Is64BitAddrSize ? 8 : 4;
1138 
1139     // Since the length of the current range/location lists entry is
1140     // undetermined yet, we firstly write the content of the range/location
1141     // lists to a buffer to calculate the length and then serialize the buffer
1142     // content to the actual output stream.
1143     std::string ListBuffer;
1144     raw_string_ostream ListBufferOS(ListBuffer);
1145 
1146     // Offsets holds offsets for each range/location list. The i-th element is
1147     // the offset from the beginning of the first range/location list to the
1148     // location of the i-th range list.
1149     std::vector<uint64_t> Offsets;
1150 
1151     for (const DWARFYAML::ListEntries<EntryType> &List : Table.Lists) {
1152       Offsets.push_back(ListBufferOS.tell());
1153       if (List.Content) {
1154         List.Content->writeAsBinary(ListBufferOS, UINT64_MAX);
1155         Length += List.Content->binary_size();
1156       } else if (List.Entries) {
1157         for (const EntryType &Entry : *List.Entries) {
1158           Expected<uint64_t> EntrySize =
1159               writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
1160           if (!EntrySize)
1161             return EntrySize.takeError();
1162           Length += *EntrySize;
1163         }
1164       }
1165     }
1166 
1167     // If the offset_entry_count field isn't specified, yaml2obj will infer it
1168     // from the 'Offsets' field in the YAML description. If the 'Offsets' field
1169     // isn't specified either, yaml2obj will infer it from the auto-generated
1170     // offsets.
1171     uint32_t OffsetEntryCount;
1172     if (Table.OffsetEntryCount)
1173       OffsetEntryCount = *Table.OffsetEntryCount;
1174     else
1175       OffsetEntryCount = Table.Offsets ? Table.Offsets->size() : Offsets.size();
1176     uint64_t OffsetsSize =
1177         OffsetEntryCount * (Table.Format == dwarf::DWARF64 ? 8 : 4);
1178     Length += OffsetsSize;
1179 
1180     // If the length is specified in the YAML description, we use it instead of
1181     // the actual length.
1182     if (Table.Length)
1183       Length = *Table.Length;
1184 
1185     writeInitialLength(Table.Format, Length, OS, IsLittleEndian);
1186     writeInteger((uint16_t)Table.Version, OS, IsLittleEndian);
1187     writeInteger((uint8_t)AddrSize, OS, IsLittleEndian);
1188     writeInteger((uint8_t)Table.SegSelectorSize, OS, IsLittleEndian);
1189     writeInteger((uint32_t)OffsetEntryCount, OS, IsLittleEndian);
1190 
1191     auto EmitOffsets = [&](ArrayRef<uint64_t> Offsets, uint64_t OffsetsSize) {
1192       for (uint64_t Offset : Offsets)
1193         writeDWARFOffset(OffsetsSize + Offset, Table.Format, OS,
1194                          IsLittleEndian);
1195     };
1196 
1197     if (Table.Offsets)
1198       EmitOffsets(ArrayRef<uint64_t>((const uint64_t *)Table.Offsets->data(),
1199                                      Table.Offsets->size()),
1200                   0);
1201     else if (OffsetEntryCount != 0)
1202       EmitOffsets(Offsets, OffsetsSize);
1203 
1204     OS.write(ListBuffer.data(), ListBuffer.size());
1205   }
1206 
1207   return Error::success();
1208 }
1209 
1210 Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
1211   assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call");
1212   return writeDWARFLists<DWARFYAML::RnglistEntry>(
1213       OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize);
1214 }
1215 
1216 Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, const Data &DI) {
1217   assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call");
1218   return writeDWARFLists<DWARFYAML::LoclistEntry>(
1219       OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize);
1220 }
1221 
1222 std::function<Error(raw_ostream &, const DWARFYAML::Data &)>
1223 DWARFYAML::getDWARFEmitterByName(StringRef SecName) {
1224   auto EmitFunc =
1225       StringSwitch<
1226           std::function<Error(raw_ostream &, const DWARFYAML::Data &)>>(SecName)
1227           .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev)
1228           .Case("debug_addr", DWARFYAML::emitDebugAddr)
1229           .Case("debug_aranges", DWARFYAML::emitDebugAranges)
1230           .Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames)
1231           .Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes)
1232           .Case("debug_info", DWARFYAML::emitDebugInfo)
1233           .Case("debug_line", DWARFYAML::emitDebugLine)
1234           .Case("debug_loclists", DWARFYAML::emitDebugLoclists)
1235           .Case("debug_pubnames", DWARFYAML::emitDebugPubnames)
1236           .Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes)
1237           .Case("debug_ranges", DWARFYAML::emitDebugRanges)
1238           .Case("debug_rnglists", DWARFYAML::emitDebugRnglists)
1239           .Case("debug_str", DWARFYAML::emitDebugStr)
1240           .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets)
1241           .Case("debug_names", DWARFYAML::emitDebugNames)
1242           .Default([&](raw_ostream &, const DWARFYAML::Data &) {
1243             return createStringError(errc::not_supported,
1244                                      SecName + " is not supported");
1245           });
1246 
1247   return EmitFunc;
1248 }
1249 
1250 static Error
1251 emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec,
1252                      StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) {
1253   std::string Data;
1254   raw_string_ostream DebugInfoStream(Data);
1255 
1256   auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec);
1257 
1258   if (Error Err = EmitFunc(DebugInfoStream, DI))
1259     return Err;
1260   DebugInfoStream.flush();
1261   if (!Data.empty())
1262     OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data);
1263 
1264   return Error::success();
1265 }
1266 
1267 Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
1268 DWARFYAML::emitDebugSections(StringRef YAMLString, bool IsLittleEndian,
1269                              bool Is64BitAddrSize) {
1270   auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) {
1271     *static_cast<SMDiagnostic *>(DiagContext) = Diag;
1272   };
1273 
1274   SMDiagnostic GeneratedDiag;
1275   yaml::Input YIn(YAMLString, /*Ctxt=*/nullptr, CollectDiagnostic,
1276                   &GeneratedDiag);
1277 
1278   DWARFYAML::Data DI;
1279   DI.IsLittleEndian = IsLittleEndian;
1280   DI.Is64BitAddrSize = Is64BitAddrSize;
1281 
1282   YIn >> DI;
1283   if (YIn.error())
1284     return createStringError(YIn.error(), GeneratedDiag.getMessage());
1285 
1286   StringMap<std::unique_ptr<MemoryBuffer>> DebugSections;
1287   Error Err = Error::success();
1288 
1289   for (StringRef SecName : DI.getNonEmptySectionNames())
1290     Err = joinErrors(std::move(Err),
1291                      emitDebugSectionImpl(DI, SecName, DebugSections));
1292 
1293   if (Err)
1294     return std::move(Err);
1295   return std::move(DebugSections);
1296 }
1297