LLVM 18.0.0git
DWARFEmitter.cpp
Go to the documentation of this file.
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
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/Errc.h"
22#include "llvm/Support/Error.h"
23#include "llvm/Support/LEB128.h"
31#include <algorithm>
32#include <cassert>
33#include <cstddef>
34#include <cstdint>
35#include <memory>
36#include <optional>
37#include <string>
38#include <vector>
39
40using namespace llvm;
41
42template <typename T>
43static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) {
44 if (IsLittleEndian != sys::IsLittleEndianHost)
46 OS.write(reinterpret_cast<char *>(&Integer), sizeof(T));
47}
48
50 raw_ostream &OS, bool IsLittleEndian) {
51 if (8 == Size)
52 writeInteger((uint64_t)Integer, OS, IsLittleEndian);
53 else if (4 == Size)
54 writeInteger((uint32_t)Integer, OS, IsLittleEndian);
55 else if (2 == Size)
56 writeInteger((uint16_t)Integer, OS, IsLittleEndian);
57 else if (1 == Size)
58 writeInteger((uint8_t)Integer, OS, IsLittleEndian);
59 else
60 return createStringError(errc::not_supported,
61 "invalid integer write size: %zu", Size);
62
63 return Error::success();
64}
65
66static void ZeroFillBytes(raw_ostream &OS, size_t Size) {
67 std::vector<uint8_t> FillData(Size, 0);
68 OS.write(reinterpret_cast<char *>(FillData.data()), Size);
69}
70
71static void writeInitialLength(const dwarf::DwarfFormat Format,
73 bool IsLittleEndian) {
74 bool IsDWARF64 = Format == dwarf::DWARF64;
75 if (IsDWARF64)
77 IsLittleEndian));
79 writeVariableSizedInteger(Length, IsDWARF64 ? 8 : 4, OS, IsLittleEndian));
80}
81
83 raw_ostream &OS, bool IsLittleEndian) {
85 OS, IsLittleEndian));
86}
87
89 for (StringRef Str : *DI.DebugStrings) {
90 OS.write(Str.data(), Str.size());
91 OS.write('\0');
92 }
93
94 return Error::success();
95}
96
98 assert(Index < DebugAbbrev.size() &&
99 "Index should be less than the size of DebugAbbrev array");
100 auto It = AbbrevTableContents.find(Index);
101 if (It != AbbrevTableContents.cend())
102 return It->second;
103
104 std::string AbbrevTableBuffer;
105 raw_string_ostream OS(AbbrevTableBuffer);
106
107 uint64_t AbbrevCode = 0;
108 for (const DWARFYAML::Abbrev &AbbrevDecl : DebugAbbrev[Index].Table) {
109 AbbrevCode = AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
110 encodeULEB128(AbbrevCode, OS);
111 encodeULEB128(AbbrevDecl.Tag, OS);
112 OS.write(AbbrevDecl.Children);
113 for (const auto &Attr : AbbrevDecl.Attributes) {
114 encodeULEB128(Attr.Attribute, OS);
115 encodeULEB128(Attr.Form, OS);
116 if (Attr.Form == dwarf::DW_FORM_implicit_const)
117 encodeSLEB128(Attr.Value, OS);
118 }
119 encodeULEB128(0, OS);
120 encodeULEB128(0, OS);
121 }
122
123 // The abbreviations for a given compilation unit end with an entry
124 // consisting of a 0 byte for the abbreviation code.
125 OS.write_zeros(1);
126
127 AbbrevTableContents.insert({Index, AbbrevTableBuffer});
128
129 return AbbrevTableContents[Index];
130}
131
133 for (uint64_t I = 0; I < DI.DebugAbbrev.size(); ++I) {
134 StringRef AbbrevTableContent = DI.getAbbrevTableContentByIndex(I);
135 OS.write(AbbrevTableContent.data(), AbbrevTableContent.size());
136 }
137
138 return Error::success();
139}
140
142 assert(DI.DebugAranges && "unexpected emitDebugAranges() call");
143 for (const auto &Range : *DI.DebugAranges) {
144 uint8_t AddrSize;
145 if (Range.AddrSize)
146 AddrSize = *Range.AddrSize;
147 else
148 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
149
150 uint64_t Length = 4; // sizeof(version) 2 + sizeof(address_size) 1 +
151 // sizeof(segment_selector_size) 1
152 Length +=
153 Range.Format == dwarf::DWARF64 ? 8 : 4; // sizeof(debug_info_offset)
154
155 const uint64_t HeaderLength =
156 Length + (Range.Format == dwarf::DWARF64
157 ? 12
158 : 4); // sizeof(unit_header) = 12 (DWARF64) or 4 (DWARF32)
159 const uint64_t PaddedHeaderLength = alignTo(HeaderLength, AddrSize * 2);
160
161 if (Range.Length) {
162 Length = *Range.Length;
163 } else {
164 Length += PaddedHeaderLength - HeaderLength;
165 Length += AddrSize * 2 * (Range.Descriptors.size() + 1);
166 }
167
168 writeInitialLength(Range.Format, Length, OS, DI.IsLittleEndian);
169 writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian);
170 writeDWARFOffset(Range.CuOffset, Range.Format, OS, DI.IsLittleEndian);
171 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
172 writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian);
173 ZeroFillBytes(OS, PaddedHeaderLength - HeaderLength);
174
175 for (const auto &Descriptor : Range.Descriptors) {
176 if (Error Err = writeVariableSizedInteger(Descriptor.Address, AddrSize,
177 OS, DI.IsLittleEndian))
179 "unable to write debug_aranges address: %s",
180 toString(std::move(Err)).c_str());
181 cantFail(writeVariableSizedInteger(Descriptor.Length, AddrSize, OS,
182 DI.IsLittleEndian));
183 }
184 ZeroFillBytes(OS, AddrSize * 2);
185 }
186
187 return Error::success();
188}
189
191 const size_t RangesOffset = OS.tell();
192 uint64_t EntryIndex = 0;
193 for (const auto &DebugRanges : *DI.DebugRanges) {
194 const size_t CurrOffset = OS.tell() - RangesOffset;
195 if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset)
197 "'Offset' for 'debug_ranges' with index " +
198 Twine(EntryIndex) +
199 " must be greater than or equal to the "
200 "number of bytes written already (0x" +
201 Twine::utohexstr(CurrOffset) + ")");
202 if (DebugRanges.Offset)
203 ZeroFillBytes(OS, *DebugRanges.Offset - CurrOffset);
204
205 uint8_t AddrSize;
206 if (DebugRanges.AddrSize)
207 AddrSize = *DebugRanges.AddrSize;
208 else
209 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
210 for (const auto &Entry : DebugRanges.Entries) {
211 if (Error Err = writeVariableSizedInteger(Entry.LowOffset, AddrSize, OS,
212 DI.IsLittleEndian))
213 return createStringError(
215 "unable to write debug_ranges address offset: %s",
216 toString(std::move(Err)).c_str());
217 cantFail(writeVariableSizedInteger(Entry.HighOffset, AddrSize, OS,
218 DI.IsLittleEndian));
219 }
220 ZeroFillBytes(OS, AddrSize * 2);
221 ++EntryIndex;
222 }
223
224 return Error::success();
225}
226
228 bool IsLittleEndian, bool IsGNUPubSec = false) {
229 writeInitialLength(Sect.Format, Sect.Length, OS, IsLittleEndian);
230 writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
231 writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
232 writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
233 for (const auto &Entry : Sect.Entries) {
234 writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
235 if (IsGNUPubSec)
236 writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian);
237 OS.write(Entry.Name.data(), Entry.Name.size());
238 OS.write('\0');
239 }
240 return Error::success();
241}
242
244 assert(DI.PubNames && "unexpected emitDebugPubnames() call");
245 return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian);
246}
247
249 assert(DI.PubTypes && "unexpected emitDebugPubtypes() call");
250 return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian);
251}
252
254 assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call");
256 /*IsGNUStyle=*/true);
257}
258
260 assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call");
262 /*IsGNUStyle=*/true);
263}
264
266 uint64_t AbbrevTableID,
267 const dwarf::FormParams &Params,
268 const DWARFYAML::Entry &Entry,
269 raw_ostream &OS, bool IsLittleEndian) {
270 uint64_t EntryBegin = OS.tell();
271 encodeULEB128(Entry.AbbrCode, OS);
272 uint32_t AbbrCode = Entry.AbbrCode;
273 if (AbbrCode == 0 || Entry.Values.empty())
274 return OS.tell() - EntryBegin;
275
276 Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
277 DI.getAbbrevTableInfoByID(AbbrevTableID);
278 if (!AbbrevTableInfoOrErr)
280 toString(AbbrevTableInfoOrErr.takeError()) +
281 " for compilation unit with index " +
282 utostr(CUIndex));
283
284 ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
285 DI.DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);
286
287 if (AbbrCode > AbbrevDecls.size())
288 return createStringError(
290 "abbrev code must be less than or equal to the number of "
291 "entries in abbreviation table");
292 const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1];
293 auto FormVal = Entry.Values.begin();
294 auto AbbrForm = Abbrev.Attributes.begin();
295 for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
296 ++FormVal, ++AbbrForm) {
297 dwarf::Form Form = AbbrForm->Form;
298 bool Indirect;
299 do {
300 Indirect = false;
301 switch (Form) {
302 case dwarf::DW_FORM_addr:
303 // TODO: Test this error.
305 FormVal->Value, Params.AddrSize, OS, IsLittleEndian))
306 return std::move(Err);
307 break;
308 case dwarf::DW_FORM_ref_addr:
309 // TODO: Test this error.
310 if (Error Err = writeVariableSizedInteger(FormVal->Value,
311 Params.getRefAddrByteSize(),
312 OS, IsLittleEndian))
313 return std::move(Err);
314 break;
315 case dwarf::DW_FORM_exprloc:
316 case dwarf::DW_FORM_block:
317 encodeULEB128(FormVal->BlockData.size(), OS);
318 OS.write((const char *)FormVal->BlockData.data(),
319 FormVal->BlockData.size());
320 break;
321 case dwarf::DW_FORM_block1: {
322 writeInteger((uint8_t)FormVal->BlockData.size(), OS, IsLittleEndian);
323 OS.write((const char *)FormVal->BlockData.data(),
324 FormVal->BlockData.size());
325 break;
326 }
327 case dwarf::DW_FORM_block2: {
328 writeInteger((uint16_t)FormVal->BlockData.size(), OS, IsLittleEndian);
329 OS.write((const char *)FormVal->BlockData.data(),
330 FormVal->BlockData.size());
331 break;
332 }
333 case dwarf::DW_FORM_block4: {
334 writeInteger((uint32_t)FormVal->BlockData.size(), OS, IsLittleEndian);
335 OS.write((const char *)FormVal->BlockData.data(),
336 FormVal->BlockData.size());
337 break;
338 }
339 case dwarf::DW_FORM_strx:
340 case dwarf::DW_FORM_addrx:
341 case dwarf::DW_FORM_rnglistx:
342 case dwarf::DW_FORM_loclistx:
343 case dwarf::DW_FORM_udata:
344 case dwarf::DW_FORM_ref_udata:
345 case dwarf::DW_FORM_GNU_addr_index:
346 case dwarf::DW_FORM_GNU_str_index:
347 encodeULEB128(FormVal->Value, OS);
348 break;
349 case dwarf::DW_FORM_data1:
350 case dwarf::DW_FORM_ref1:
351 case dwarf::DW_FORM_flag:
352 case dwarf::DW_FORM_strx1:
353 case dwarf::DW_FORM_addrx1:
354 writeInteger((uint8_t)FormVal->Value, OS, IsLittleEndian);
355 break;
356 case dwarf::DW_FORM_data2:
357 case dwarf::DW_FORM_ref2:
358 case dwarf::DW_FORM_strx2:
359 case dwarf::DW_FORM_addrx2:
360 writeInteger((uint16_t)FormVal->Value, OS, IsLittleEndian);
361 break;
362 case dwarf::DW_FORM_data4:
363 case dwarf::DW_FORM_ref4:
364 case dwarf::DW_FORM_ref_sup4:
365 case dwarf::DW_FORM_strx4:
366 case dwarf::DW_FORM_addrx4:
367 writeInteger((uint32_t)FormVal->Value, OS, IsLittleEndian);
368 break;
369 case dwarf::DW_FORM_data8:
370 case dwarf::DW_FORM_ref8:
371 case dwarf::DW_FORM_ref_sup8:
372 case dwarf::DW_FORM_ref_sig8:
373 writeInteger((uint64_t)FormVal->Value, OS, IsLittleEndian);
374 break;
375 case dwarf::DW_FORM_sdata:
376 encodeSLEB128(FormVal->Value, OS);
377 break;
378 case dwarf::DW_FORM_string:
379 OS.write(FormVal->CStr.data(), FormVal->CStr.size());
380 OS.write('\0');
381 break;
382 case dwarf::DW_FORM_indirect:
383 encodeULEB128(FormVal->Value, OS);
384 Indirect = true;
385 Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
386 ++FormVal;
387 break;
388 case dwarf::DW_FORM_strp:
389 case dwarf::DW_FORM_sec_offset:
390 case dwarf::DW_FORM_GNU_ref_alt:
391 case dwarf::DW_FORM_GNU_strp_alt:
392 case dwarf::DW_FORM_line_strp:
393 case dwarf::DW_FORM_strp_sup:
394 cantFail(writeVariableSizedInteger(FormVal->Value,
395 Params.getDwarfOffsetByteSize(), OS,
396 IsLittleEndian));
397 break;
398 default:
399 break;
400 }
401 } while (Indirect);
402 }
403
404 return OS.tell() - EntryBegin;
405}
406
408 for (uint64_t I = 0; I < DI.CompileUnits.size(); ++I) {
409 const DWARFYAML::Unit &Unit = DI.CompileUnits[I];
410 uint8_t AddrSize;
411 if (Unit.AddrSize)
412 AddrSize = *Unit.AddrSize;
413 else
414 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
415 dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format};
416 uint64_t Length = 3; // sizeof(version) + sizeof(address_size)
417 Length += Unit.Version >= 5 ? 1 : 0; // sizeof(unit_type)
418 Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset)
419
420 // Since the length of the current compilation unit is undetermined yet, we
421 // firstly write the content of the compilation unit to a buffer to
422 // calculate it and then serialize the buffer content to the actual output
423 // stream.
424 std::string EntryBuffer;
425 raw_string_ostream EntryBufferOS(EntryBuffer);
426
427 uint64_t AbbrevTableID = Unit.AbbrevTableID.value_or(I);
428 for (const DWARFYAML::Entry &Entry : Unit.Entries) {
429 if (Expected<uint64_t> EntryLength =
430 writeDIE(DI, I, AbbrevTableID, Params, Entry, EntryBufferOS,
431 DI.IsLittleEndian))
432 Length += *EntryLength;
433 else
434 return EntryLength.takeError();
435 }
436
437 // If the length is specified in the YAML description, we use it instead of
438 // the actual length.
439 if (Unit.Length)
440 Length = *Unit.Length;
441
444
445 uint64_t AbbrevTableOffset = 0;
446 if (Unit.AbbrOffset) {
447 AbbrevTableOffset = *Unit.AbbrOffset;
448 } else {
449 if (Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
450 DI.getAbbrevTableInfoByID(AbbrevTableID)) {
451 AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
452 } else {
453 // The current compilation unit may not have DIEs and it will not be
454 // able to find the associated abbrev table. We consume the error and
455 // assign 0 to the debug_abbrev_offset in such circumstances.
456 consumeError(AbbrevTableInfoOrErr.takeError());
457 }
458 }
459
460 if (Unit.Version >= 5) {
461 writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian);
462 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
463 writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
464 } else {
465 writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
466 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
467 }
468
469 OS.write(EntryBuffer.data(), EntryBuffer.size());
470 }
471
472 return Error::success();
473}
474
475static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
476 OS.write(File.Name.data(), File.Name.size());
477 OS.write('\0');
478 encodeULEB128(File.DirIdx, OS);
479 encodeULEB128(File.ModTime, OS);
480 encodeULEB128(File.Length, OS);
481}
482
484 uint8_t AddrSize, bool IsLittleEndian,
485 raw_ostream &OS) {
486 // The first byte of extended opcodes is a zero byte. The next bytes are an
487 // ULEB128 integer giving the number of bytes in the instruction itself (does
488 // not include the first zero byte or the size). We serialize the instruction
489 // itself into the OpBuffer and then write the size of the buffer and the
490 // buffer to the real output stream.
491 std::string OpBuffer;
492 raw_string_ostream OpBufferOS(OpBuffer);
493 writeInteger((uint8_t)Op.SubOpcode, OpBufferOS, IsLittleEndian);
494 switch (Op.SubOpcode) {
495 case dwarf::DW_LNE_set_address:
496 cantFail(writeVariableSizedInteger(Op.Data, AddrSize, OpBufferOS,
497 IsLittleEndian));
498 break;
499 case dwarf::DW_LNE_define_file:
500 emitFileEntry(OpBufferOS, Op.FileEntry);
501 break;
502 case dwarf::DW_LNE_set_discriminator:
503 encodeULEB128(Op.Data, OpBufferOS);
504 break;
505 case dwarf::DW_LNE_end_sequence:
506 break;
507 default:
508 for (auto OpByte : Op.UnknownOpcodeData)
509 writeInteger((uint8_t)OpByte, OpBufferOS, IsLittleEndian);
510 }
511 uint64_t ExtLen = Op.ExtLen.value_or(OpBuffer.size());
512 encodeULEB128(ExtLen, OS);
513 OS.write(OpBuffer.data(), OpBuffer.size());
514}
515
517 uint8_t OpcodeBase, uint8_t AddrSize,
518 raw_ostream &OS, bool IsLittleEndian) {
519 writeInteger((uint8_t)Op.Opcode, OS, IsLittleEndian);
520 if (Op.Opcode == 0) {
521 writeExtendedOpcode(Op, AddrSize, IsLittleEndian, OS);
522 } else if (Op.Opcode < OpcodeBase) {
523 switch (Op.Opcode) {
524 case dwarf::DW_LNS_copy:
525 case dwarf::DW_LNS_negate_stmt:
526 case dwarf::DW_LNS_set_basic_block:
527 case dwarf::DW_LNS_const_add_pc:
528 case dwarf::DW_LNS_set_prologue_end:
529 case dwarf::DW_LNS_set_epilogue_begin:
530 break;
531
532 case dwarf::DW_LNS_advance_pc:
533 case dwarf::DW_LNS_set_file:
534 case dwarf::DW_LNS_set_column:
535 case dwarf::DW_LNS_set_isa:
536 encodeULEB128(Op.Data, OS);
537 break;
538
539 case dwarf::DW_LNS_advance_line:
540 encodeSLEB128(Op.SData, OS);
541 break;
542
543 case dwarf::DW_LNS_fixed_advance_pc:
544 writeInteger((uint16_t)Op.Data, OS, IsLittleEndian);
545 break;
546
547 default:
548 for (auto OpData : Op.StandardOpcodeData) {
549 encodeULEB128(OpData, OS);
550 }
551 }
552 }
553}
554
555static std::vector<uint8_t>
556getStandardOpcodeLengths(uint16_t Version, std::optional<uint8_t> OpcodeBase) {
557 // If the opcode_base field isn't specified, we returns the
558 // standard_opcode_lengths array according to the version by default.
559 std::vector<uint8_t> StandardOpcodeLengths{0, 1, 1, 1, 1, 0,
560 0, 0, 1, 0, 0, 1};
561 if (Version == 2) {
562 // DWARF v2 uses the same first 9 standard opcodes as v3-5.
563 StandardOpcodeLengths.resize(9);
564 } else if (OpcodeBase) {
565 StandardOpcodeLengths.resize(*OpcodeBase > 0 ? *OpcodeBase - 1 : 0, 0);
566 }
567 return StandardOpcodeLengths;
568}
569
571 for (const DWARFYAML::LineTable &LineTable : DI.DebugLines) {
572 // Buffer holds the bytes following the header_length (or prologue_length in
573 // DWARFv2) field to the end of the line number program itself.
574 std::string Buffer;
575 raw_string_ostream BufferOS(Buffer);
576
578 // TODO: Add support for emitting DWARFv5 line table.
579 if (LineTable.Version >= 4)
584
585 std::vector<uint8_t> StandardOpcodeLengths =
588 uint8_t OpcodeBase = LineTable.OpcodeBase
590 : StandardOpcodeLengths.size() + 1;
591 writeInteger(OpcodeBase, BufferOS, DI.IsLittleEndian);
592 for (uint8_t OpcodeLength : StandardOpcodeLengths)
593 writeInteger(OpcodeLength, BufferOS, DI.IsLittleEndian);
594
595 for (StringRef IncludeDir : LineTable.IncludeDirs) {
596 BufferOS.write(IncludeDir.data(), IncludeDir.size());
597 BufferOS.write('\0');
598 }
599 BufferOS.write('\0');
600
601 for (const DWARFYAML::File &File : LineTable.Files)
602 emitFileEntry(BufferOS, File);
603 BufferOS.write('\0');
604
605 uint64_t HeaderLength =
607
609 writeLineTableOpcode(Op, OpcodeBase, DI.Is64BitAddrSize ? 8 : 4, BufferOS,
610 DI.IsLittleEndian);
611
613 if (LineTable.Length) {
615 } else {
616 Length = 2; // sizeof(version)
617 Length +=
618 (LineTable.Format == dwarf::DWARF64 ? 8 : 4); // sizeof(header_length)
619 Length += Buffer.size();
620 }
621
625 OS.write(Buffer.data(), Buffer.size());
626 }
627
628 return Error::success();
629}
630
632 for (const AddrTableEntry &TableEntry : *DI.DebugAddr) {
633 uint8_t AddrSize;
634 if (TableEntry.AddrSize)
635 AddrSize = *TableEntry.AddrSize;
636 else
637 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
638
640 if (TableEntry.Length)
641 Length = (uint64_t)*TableEntry.Length;
642 else
643 // 2 (version) + 1 (address_size) + 1 (segment_selector_size) = 4
644 Length = 4 + (AddrSize + TableEntry.SegSelectorSize) *
645 TableEntry.SegAddrPairs.size();
646
649 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
650 writeInteger((uint8_t)TableEntry.SegSelectorSize, OS, DI.IsLittleEndian);
651
652 for (const SegAddrPair &Pair : TableEntry.SegAddrPairs) {
653 if (TableEntry.SegSelectorSize != yaml::Hex8{0})
655 TableEntry.SegSelectorSize,
656 OS, DI.IsLittleEndian))
658 "unable to write debug_addr segment: %s",
659 toString(std::move(Err)).c_str());
660 if (AddrSize != 0)
661 if (Error Err = writeVariableSizedInteger(Pair.Address, AddrSize, OS,
662 DI.IsLittleEndian))
664 "unable to write debug_addr address: %s",
665 toString(std::move(Err)).c_str());
666 }
667 }
668
669 return Error::success();
670}
671
673 assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call");
674 for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) {
676 if (Table.Length)
677 Length = *Table.Length;
678 else
679 // sizeof(version) + sizeof(padding) = 4
680 Length =
681 4 + Table.Offsets.size() * (Table.Format == dwarf::DWARF64 ? 8 : 4);
682
686
687 for (uint64_t Offset : Table.Offsets)
689 }
690
691 return Error::success();
692}
693
694static Error checkOperandCount(StringRef EncodingString,
696 uint64_t ExpectedOperands) {
697 if (Values.size() != ExpectedOperands)
698 return createStringError(
700 "invalid number (%zu) of operands for the operator: %s, %" PRIu64
701 " expected",
702 Values.size(), EncodingString.str().c_str(), ExpectedOperands);
703
704 return Error::success();
705}
706
708 uint64_t Addr, uint8_t AddrSize,
709 bool IsLittleEndian) {
710 if (Error Err = writeVariableSizedInteger(Addr, AddrSize, OS, IsLittleEndian))
712 "unable to write address for the operator %s: %s",
713 EncodingName.str().c_str(),
714 toString(std::move(Err)).c_str());
715
716 return Error::success();
717}
718
722 uint8_t AddrSize, bool IsLittleEndian) {
723 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
725 Operation.Values, ExpectedOperands);
726 };
727
728 uint64_t ExpressionBegin = OS.tell();
729 writeInteger((uint8_t)Operation.Operator, OS, IsLittleEndian);
730 switch (Operation.Operator) {
731 case dwarf::DW_OP_consts:
732 if (Error Err = CheckOperands(1))
733 return std::move(Err);
734 encodeSLEB128(Operation.Values[0], OS);
735 break;
736 case dwarf::DW_OP_stack_value:
737 if (Error Err = CheckOperands(0))
738 return std::move(Err);
739 break;
740 default:
741 StringRef EncodingStr = dwarf::OperationEncodingString(Operation.Operator);
743 "DWARF expression: " +
744 (EncodingStr.empty()
745 ? "0x" + utohexstr(Operation.Operator)
746 : EncodingStr) +
747 " is not supported");
748 }
749 return OS.tell() - ExpressionBegin;
750}
751
753 const DWARFYAML::RnglistEntry &Entry,
754 uint8_t AddrSize,
755 bool IsLittleEndian) {
756 uint64_t BeginOffset = OS.tell();
757 writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
758
759 StringRef EncodingName = dwarf::RangeListEncodingString(Entry.Operator);
760
761 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
762 return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
763 };
764
765 auto WriteAddress = [&](uint64_t Addr) -> Error {
766 return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
767 IsLittleEndian);
768 };
769
770 switch (Entry.Operator) {
771 case dwarf::DW_RLE_end_of_list:
772 if (Error Err = CheckOperands(0))
773 return std::move(Err);
774 break;
775 case dwarf::DW_RLE_base_addressx:
776 if (Error Err = CheckOperands(1))
777 return std::move(Err);
778 encodeULEB128(Entry.Values[0], OS);
779 break;
780 case dwarf::DW_RLE_startx_endx:
781 case dwarf::DW_RLE_startx_length:
782 case dwarf::DW_RLE_offset_pair:
783 if (Error Err = CheckOperands(2))
784 return std::move(Err);
785 encodeULEB128(Entry.Values[0], OS);
786 encodeULEB128(Entry.Values[1], OS);
787 break;
788 case dwarf::DW_RLE_base_address:
789 if (Error Err = CheckOperands(1))
790 return std::move(Err);
791 if (Error Err = WriteAddress(Entry.Values[0]))
792 return std::move(Err);
793 break;
794 case dwarf::DW_RLE_start_end:
795 if (Error Err = CheckOperands(2))
796 return std::move(Err);
797 if (Error Err = WriteAddress(Entry.Values[0]))
798 return std::move(Err);
799 cantFail(WriteAddress(Entry.Values[1]));
800 break;
801 case dwarf::DW_RLE_start_length:
802 if (Error Err = CheckOperands(2))
803 return std::move(Err);
804 if (Error Err = WriteAddress(Entry.Values[0]))
805 return std::move(Err);
806 encodeULEB128(Entry.Values[1], OS);
807 break;
808 }
809
810 return OS.tell() - BeginOffset;
811}
812
814 const DWARFYAML::LoclistEntry &Entry,
815 uint8_t AddrSize,
816 bool IsLittleEndian) {
817 uint64_t BeginOffset = OS.tell();
818 writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
819
820 StringRef EncodingName = dwarf::LocListEncodingString(Entry.Operator);
821
822 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
823 return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
824 };
825
826 auto WriteAddress = [&](uint64_t Addr) -> Error {
827 return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
828 IsLittleEndian);
829 };
830
831 auto WriteDWARFOperations = [&]() -> Error {
832 std::string OpBuffer;
833 raw_string_ostream OpBufferOS(OpBuffer);
834 uint64_t DescriptionsLength = 0;
835
836 for (const DWARFYAML::DWARFOperation &Op : Entry.Descriptions) {
837 if (Expected<uint64_t> OpSize =
838 writeDWARFExpression(OpBufferOS, Op, AddrSize, IsLittleEndian))
839 DescriptionsLength += *OpSize;
840 else
841 return OpSize.takeError();
842 }
843
844 if (Entry.DescriptionsLength)
845 DescriptionsLength = *Entry.DescriptionsLength;
846 else
847 DescriptionsLength = OpBuffer.size();
848
849 encodeULEB128(DescriptionsLength, OS);
850 OS.write(OpBuffer.data(), OpBuffer.size());
851
852 return Error::success();
853 };
854
855 switch (Entry.Operator) {
856 case dwarf::DW_LLE_end_of_list:
857 if (Error Err = CheckOperands(0))
858 return std::move(Err);
859 break;
860 case dwarf::DW_LLE_base_addressx:
861 if (Error Err = CheckOperands(1))
862 return std::move(Err);
863 encodeULEB128(Entry.Values[0], OS);
864 break;
865 case dwarf::DW_LLE_startx_endx:
866 case dwarf::DW_LLE_startx_length:
867 case dwarf::DW_LLE_offset_pair:
868 if (Error Err = CheckOperands(2))
869 return std::move(Err);
870 encodeULEB128(Entry.Values[0], OS);
871 encodeULEB128(Entry.Values[1], OS);
872 if (Error Err = WriteDWARFOperations())
873 return std::move(Err);
874 break;
875 case dwarf::DW_LLE_default_location:
876 if (Error Err = CheckOperands(0))
877 return std::move(Err);
878 if (Error Err = WriteDWARFOperations())
879 return std::move(Err);
880 break;
881 case dwarf::DW_LLE_base_address:
882 if (Error Err = CheckOperands(1))
883 return std::move(Err);
884 if (Error Err = WriteAddress(Entry.Values[0]))
885 return std::move(Err);
886 break;
887 case dwarf::DW_LLE_start_end:
888 if (Error Err = CheckOperands(2))
889 return std::move(Err);
890 if (Error Err = WriteAddress(Entry.Values[0]))
891 return std::move(Err);
892 cantFail(WriteAddress(Entry.Values[1]));
893 if (Error Err = WriteDWARFOperations())
894 return std::move(Err);
895 break;
896 case dwarf::DW_LLE_start_length:
897 if (Error Err = CheckOperands(2))
898 return std::move(Err);
899 if (Error Err = WriteAddress(Entry.Values[0]))
900 return std::move(Err);
901 encodeULEB128(Entry.Values[1], OS);
902 if (Error Err = WriteDWARFOperations())
903 return std::move(Err);
904 break;
905 }
906
907 return OS.tell() - BeginOffset;
908}
909
910template <typename EntryType>
913 bool IsLittleEndian, bool Is64BitAddrSize) {
914 for (const DWARFYAML::ListTable<EntryType> &Table : Tables) {
915 // sizeof(version) + sizeof(address_size) + sizeof(segment_selector_size) +
916 // sizeof(offset_entry_count) = 8
917 uint64_t Length = 8;
918
919 uint8_t AddrSize;
920 if (Table.AddrSize)
921 AddrSize = *Table.AddrSize;
922 else
923 AddrSize = Is64BitAddrSize ? 8 : 4;
924
925 // Since the length of the current range/location lists entry is
926 // undetermined yet, we firstly write the content of the range/location
927 // lists to a buffer to calculate the length and then serialize the buffer
928 // content to the actual output stream.
929 std::string ListBuffer;
930 raw_string_ostream ListBufferOS(ListBuffer);
931
932 // Offsets holds offsets for each range/location list. The i-th element is
933 // the offset from the beginning of the first range/location list to the
934 // location of the i-th range list.
935 std::vector<uint64_t> Offsets;
936
937 for (const DWARFYAML::ListEntries<EntryType> &List : Table.Lists) {
938 Offsets.push_back(ListBufferOS.tell());
939 if (List.Content) {
940 List.Content->writeAsBinary(ListBufferOS, UINT64_MAX);
941 Length += List.Content->binary_size();
942 } else if (List.Entries) {
943 for (const EntryType &Entry : *List.Entries) {
944 Expected<uint64_t> EntrySize =
945 writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
946 if (!EntrySize)
947 return EntrySize.takeError();
948 Length += *EntrySize;
949 }
950 }
951 }
952
953 // If the offset_entry_count field isn't specified, yaml2obj will infer it
954 // from the 'Offsets' field in the YAML description. If the 'Offsets' field
955 // isn't specified either, yaml2obj will infer it from the auto-generated
956 // offsets.
957 uint32_t OffsetEntryCount;
958 if (Table.OffsetEntryCount)
959 OffsetEntryCount = *Table.OffsetEntryCount;
960 else
961 OffsetEntryCount = Table.Offsets ? Table.Offsets->size() : Offsets.size();
962 uint64_t OffsetsSize =
963 OffsetEntryCount * (Table.Format == dwarf::DWARF64 ? 8 : 4);
964 Length += OffsetsSize;
965
966 // If the length is specified in the YAML description, we use it instead of
967 // the actual length.
968 if (Table.Length)
969 Length = *Table.Length;
970
971 writeInitialLength(Table.Format, Length, OS, IsLittleEndian);
972 writeInteger((uint16_t)Table.Version, OS, IsLittleEndian);
973 writeInteger((uint8_t)AddrSize, OS, IsLittleEndian);
974 writeInteger((uint8_t)Table.SegSelectorSize, OS, IsLittleEndian);
975 writeInteger((uint32_t)OffsetEntryCount, OS, IsLittleEndian);
976
977 auto EmitOffsets = [&](ArrayRef<uint64_t> Offsets, uint64_t OffsetsSize) {
978 for (uint64_t Offset : Offsets)
979 writeDWARFOffset(OffsetsSize + Offset, Table.Format, OS,
980 IsLittleEndian);
981 };
982
983 if (Table.Offsets)
984 EmitOffsets(ArrayRef<uint64_t>((const uint64_t *)Table.Offsets->data(),
985 Table.Offsets->size()),
986 0);
987 else if (OffsetEntryCount != 0)
988 EmitOffsets(Offsets, OffsetsSize);
989
990 OS.write(ListBuffer.data(), ListBuffer.size());
991 }
992
993 return Error::success();
994}
995
997 assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call");
998 return writeDWARFLists<DWARFYAML::RnglistEntry>(
1000}
1001
1003 assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call");
1004 return writeDWARFLists<DWARFYAML::LoclistEntry>(
1006}
1007
1008std::function<Error(raw_ostream &, const DWARFYAML::Data &)>
1010 auto EmitFunc =
1012 std::function<Error(raw_ostream &, const DWARFYAML::Data &)>>(SecName)
1013 .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev)
1014 .Case("debug_addr", DWARFYAML::emitDebugAddr)
1015 .Case("debug_aranges", DWARFYAML::emitDebugAranges)
1016 .Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames)
1017 .Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes)
1018 .Case("debug_info", DWARFYAML::emitDebugInfo)
1019 .Case("debug_line", DWARFYAML::emitDebugLine)
1020 .Case("debug_loclists", DWARFYAML::emitDebugLoclists)
1021 .Case("debug_pubnames", DWARFYAML::emitDebugPubnames)
1022 .Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes)
1023 .Case("debug_ranges", DWARFYAML::emitDebugRanges)
1024 .Case("debug_rnglists", DWARFYAML::emitDebugRnglists)
1025 .Case("debug_str", DWARFYAML::emitDebugStr)
1026 .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets)
1027 .Default([&](raw_ostream &, const DWARFYAML::Data &) {
1029 SecName + " is not supported");
1030 });
1031
1032 return EmitFunc;
1033}
1034
1035static Error
1037 StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) {
1038 std::string Data;
1039 raw_string_ostream DebugInfoStream(Data);
1040
1041 auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec);
1042
1043 if (Error Err = EmitFunc(DebugInfoStream, DI))
1044 return Err;
1045 DebugInfoStream.flush();
1046 if (!Data.empty())
1047 OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data);
1048
1049 return Error::success();
1050}
1051
1053DWARFYAML::emitDebugSections(StringRef YAMLString, bool IsLittleEndian,
1054 bool Is64BitAddrSize) {
1055 auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) {
1056 *static_cast<SMDiagnostic *>(DiagContext) = Diag;
1057 };
1058
1059 SMDiagnostic GeneratedDiag;
1060 yaml::Input YIn(YAMLString, /*Ctxt=*/nullptr, CollectDiagnostic,
1061 &GeneratedDiag);
1062
1063 DWARFYAML::Data DI;
1064 DI.IsLittleEndian = IsLittleEndian;
1065 DI.Is64BitAddrSize = Is64BitAddrSize;
1066
1067 YIn >> DI;
1068 if (YIn.error())
1069 return createStringError(YIn.error(), GeneratedDiag.getMessage());
1070
1072 Error Err = Error::success();
1073
1074 for (StringRef SecName : DI.getNonEmptySectionNames())
1075 Err = joinErrors(std::move(Err),
1076 emitDebugSectionImpl(DI, SecName, DebugSections));
1077
1078 if (Err)
1079 return std::move(Err);
1080 return std::move(DebugSections);
1081}
This file defines the StringMap class.
static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format, raw_ostream &OS, bool IsLittleEndian)
static Error emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec, StringMap< std::unique_ptr< MemoryBuffer > > &OutputBuffers)
static void ZeroFillBytes(raw_ostream &OS, size_t Size)
static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File)
static Error writeDWARFLists(raw_ostream &OS, ArrayRef< DWARFYAML::ListTable< EntryType > > Tables, bool IsLittleEndian, bool Is64BitAddrSize)
static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t OpcodeBase, uint8_t AddrSize, raw_ostream &OS, bool IsLittleEndian)
static Error writeVariableSizedInteger(uint64_t Integer, size_t Size, raw_ostream &OS, bool IsLittleEndian)
static Expected< uint64_t > writeListEntry(raw_ostream &OS, const DWARFYAML::RnglistEntry &Entry, uint8_t AddrSize, bool IsLittleEndian)
static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian)
static void writeExtendedOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t AddrSize, bool IsLittleEndian, raw_ostream &OS)
static Error checkOperandCount(StringRef EncodingString, ArrayRef< yaml::Hex64 > Values, uint64_t ExpectedOperands)
static Expected< uint64_t > writeDWARFExpression(raw_ostream &OS, const DWARFYAML::DWARFOperation &Operation, uint8_t AddrSize, bool IsLittleEndian)
static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect, bool IsLittleEndian, bool IsGNUPubSec=false)
static Expected< uint64_t > writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex, uint64_t AbbrevTableID, const dwarf::FormParams &Params, const DWARFYAML::Entry &Entry, raw_ostream &OS, bool IsLittleEndian)
static void writeInitialLength(const dwarf::DwarfFormat Format, const uint64_t Length, raw_ostream &OS, bool IsLittleEndian)
static std::vector< uint8_t > getStandardOpcodeLengths(uint16_t Version, std::optional< uint8_t > OpcodeBase)
static Error writeListEntryAddress(StringRef EncodingName, raw_ostream &OS, uint64_t Addr, uint8_t AddrSize, bool IsLittleEndian)
Common declarations for yaml2obj.
This file declares classes for handling the YAML representation of DWARF Debug Info.
This file contains constants used for implementing Dwarf debug support.
uint64_t Addr
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
PowerPC Reduce CR logical Operation
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
This class represents an Operation in the Expression.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
Error takeError()
Take ownership of the stored error.
Definition: Error.h:601
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
StringRef getMessage() const
Definition: SourceMgr.h:311
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:112
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:416
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:134
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
StringRef RangeListEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:549
StringRef LocListEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:560
StringRef OperationEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:138
#define UINT64_MAX
Definition: DataTypes.h:77
Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI)
Error emitDebugInfo(raw_ostream &OS, const Data &DI)
Error emitDebugRanges(raw_ostream &OS, const Data &DI)
Error emitDebugAranges(raw_ostream &OS, const Data &DI)
Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI)
Error emitDebugAbbrev(raw_ostream &OS, const Data &DI)
Error emitDebugRnglists(raw_ostream &OS, const Data &DI)
Error emitDebugLoclists(raw_ostream &OS, const Data &DI)
std::function< Error(raw_ostream &, const Data &)> getDWARFEmitterByName(StringRef SecName)
Expected< StringMap< std::unique_ptr< MemoryBuffer > > > emitDebugSections(StringRef YAMLString, bool IsLittleEndian=sys::IsLittleEndianHost, bool Is64BitAddrSize=true)
Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI)
Error emitDebugStr(raw_ostream &OS, const Data &DI)
Error emitDebugPubnames(raw_ostream &OS, const Data &DI)
Error emitDebugAddr(raw_ostream &OS, const Data &DI)
Error emitDebugPubtypes(raw_ostream &OS, const Data &DI)
Error emitDebugLine(raw_ostream &OS, const Data &DI)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:91
@ DWARF64
Definition: Dwarf.h:91
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition: Dwarf.h:55
static const bool IsLittleEndianHost
Definition: SwapByteOrder.h:57
void swapByteOrder(T &Value)
Definition: SwapByteOrder.h:90
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
@ Length
Definition: DWP.cpp:440
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1244
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:431
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:749
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition: LEB128.h:23
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1041
std::vector< AttributeAbbrev > Attributes
Definition: DWARFYAML.h:41
std::optional< yaml::Hex64 > Length
Definition: DWARFYAML.h:163
std::optional< yaml::Hex8 > AddrSize
Definition: DWARFYAML.h:165
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:162
std::vector< SegAddrPair > SegAddrPairs
Definition: DWARFYAML.h:167
std::vector< LineTable > DebugLines
Definition: DWARFYAML.h:228
std::optional< std::vector< AddrTableEntry > > DebugAddr
Definition: DWARFYAML.h:219
std::optional< std::vector< Ranges > > DebugRanges
Definition: DWARFYAML.h:218
std::optional< std::vector< ListTable< LoclistEntry > > > DebugLoclists
Definition: DWARFYAML.h:230
std::vector< AbbrevTable > DebugAbbrev
Definition: DWARFYAML.h:214
Expected< AbbrevTableInfo > getAbbrevTableInfoByID(uint64_t ID) const
Definition: DWARFYAML.cpp:59
std::optional< PubSection > GNUPubNames
Definition: DWARFYAML.h:223
std::optional< std::vector< ARange > > DebugAranges
Definition: DWARFYAML.h:217
StringRef getAbbrevTableContentByIndex(uint64_t Index) const
std::vector< Unit > CompileUnits
Definition: DWARFYAML.h:226
std::optional< PubSection > GNUPubTypes
Definition: DWARFYAML.h:224
SetVector< StringRef > getNonEmptySectionNames() const
Definition: DWARFYAML.cpp:25
std::optional< std::vector< StringOffsetsTable > > DebugStrOffsets
Definition: DWARFYAML.h:216
std::optional< std::vector< StringRef > > DebugStrings
Definition: DWARFYAML.h:215
std::optional< std::vector< ListTable< RnglistEntry > > > DebugRnglists
Definition: DWARFYAML.h:229
std::optional< PubSection > PubNames
Definition: DWARFYAML.h:220
std::optional< PubSection > PubTypes
Definition: DWARFYAML.h:221
std::optional< uint64_t > Length
Definition: DWARFYAML.h:141
std::optional< uint8_t > OpcodeBase
Definition: DWARFYAML.h:149
std::vector< LineTableOpcode > Opcodes
Definition: DWARFYAML.h:153
std::optional< uint64_t > PrologueLength
Definition: DWARFYAML.h:143
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:140
std::vector< File > Files
Definition: DWARFYAML.h:152
std::vector< StringRef > IncludeDirs
Definition: DWARFYAML.h:151
std::optional< std::vector< uint8_t > > StandardOpcodeLengths
Definition: DWARFYAML.h:150
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:85
std::vector< PubEntry > Entries
Definition: DWARFYAML.h:90
std::optional< yaml::Hex64 > Length
Definition: DWARFYAML.h:172
std::vector< yaml::Hex64 > Offsets
Definition: DWARFYAML.h:175
std::optional< uint64_t > AbbrevTableID
Definition: DWARFYAML.h:116
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:111
std::optional< yaml::Hex64 > Length
Definition: DWARFYAML.h:112
std::optional< uint8_t > AddrSize
Definition: DWARFYAML.h:114
llvm::dwarf::UnitType Type
Definition: DWARFYAML.h:115
std::vector< Entry > Entries
Definition: DWARFYAML.h:118
std::optional< yaml::Hex64 > AbbrOffset
Definition: DWARFYAML.h:117
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:743
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:761
uint8_t getRefAddrByteSize() const
The definition of the size of form DW_FORM_ref_addr depends on the version.
Definition: Dwarf.h:754