DWARFYAML.h revision 360784
1//===- DWARFYAML.h - DWARF YAMLIO implementation ----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file declares classes for handling the YAML representation
11/// of DWARF Debug Info.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OBJECTYAML_DWARFYAML_H
16#define LLVM_OBJECTYAML_DWARFYAML_H
17
18#include "llvm/ADT/StringRef.h"
19#include "llvm/BinaryFormat/Dwarf.h"
20#include "llvm/Support/YAMLTraits.h"
21#include <cstdint>
22#include <vector>
23
24namespace llvm {
25namespace DWARFYAML {
26
27struct InitialLength {
28  uint32_t TotalLength;
29  uint64_t TotalLength64;
30
31  bool isDWARF64() const { return TotalLength == UINT32_MAX; }
32
33  uint64_t getLength() const {
34    return isDWARF64() ? TotalLength64 : TotalLength;
35  }
36
37  void setLength(uint64_t Len) {
38    if (Len >= (uint64_t)UINT32_MAX) {
39      TotalLength64 = Len;
40      TotalLength = UINT32_MAX;
41    } else {
42      TotalLength = Len;
43    }
44  }
45};
46
47struct AttributeAbbrev {
48  llvm::dwarf::Attribute Attribute;
49  llvm::dwarf::Form Form;
50  llvm::yaml::Hex64 Value; // Some DWARF5 attributes have values
51};
52
53struct Abbrev {
54  llvm::yaml::Hex32 Code;
55  llvm::dwarf::Tag Tag;
56  llvm::dwarf::Constants Children;
57  std::vector<AttributeAbbrev> Attributes;
58};
59
60struct ARangeDescriptor {
61  llvm::yaml::Hex64 Address;
62  uint64_t Length;
63};
64
65struct ARange {
66  InitialLength Length;
67  uint16_t Version;
68  uint32_t CuOffset;
69  uint8_t AddrSize;
70  uint8_t SegSize;
71  std::vector<ARangeDescriptor> Descriptors;
72};
73
74struct PubEntry {
75  llvm::yaml::Hex32 DieOffset;
76  llvm::yaml::Hex8 Descriptor;
77  StringRef Name;
78};
79
80struct PubSection {
81  InitialLength Length;
82  uint16_t Version;
83  uint32_t UnitOffset;
84  uint32_t UnitSize;
85  bool IsGNUStyle = false;
86  std::vector<PubEntry> Entries;
87};
88
89struct FormValue {
90  llvm::yaml::Hex64 Value;
91  StringRef CStr;
92  std::vector<llvm::yaml::Hex8> BlockData;
93};
94
95struct Entry {
96  llvm::yaml::Hex32 AbbrCode;
97  std::vector<FormValue> Values;
98};
99
100struct Unit {
101  InitialLength Length;
102  uint16_t Version;
103  llvm::dwarf::UnitType Type; // Added in DWARF 5
104  uint32_t AbbrOffset;
105  uint8_t AddrSize;
106  std::vector<Entry> Entries;
107};
108
109struct File {
110  StringRef Name;
111  uint64_t DirIdx;
112  uint64_t ModTime;
113  uint64_t Length;
114};
115
116struct LineTableOpcode {
117  dwarf::LineNumberOps Opcode;
118  uint64_t ExtLen;
119  dwarf::LineNumberExtendedOps SubOpcode;
120  uint64_t Data;
121  int64_t SData;
122  File FileEntry;
123  std::vector<llvm::yaml::Hex8> UnknownOpcodeData;
124  std::vector<llvm::yaml::Hex64> StandardOpcodeData;
125};
126
127struct LineTable {
128  InitialLength Length;
129  uint16_t Version;
130  uint64_t PrologueLength;
131  uint8_t MinInstLength;
132  uint8_t MaxOpsPerInst;
133  uint8_t DefaultIsStmt;
134  uint8_t LineBase;
135  uint8_t LineRange;
136  uint8_t OpcodeBase;
137  std::vector<uint8_t> StandardOpcodeLengths;
138  std::vector<StringRef> IncludeDirs;
139  std::vector<File> Files;
140  std::vector<LineTableOpcode> Opcodes;
141};
142
143struct Data {
144  bool IsLittleEndian;
145  std::vector<Abbrev> AbbrevDecls;
146  std::vector<StringRef> DebugStrings;
147  std::vector<ARange> ARanges;
148  PubSection PubNames;
149  PubSection PubTypes;
150
151  PubSection GNUPubNames;
152  PubSection GNUPubTypes;
153
154  std::vector<Unit> CompileUnits;
155
156  std::vector<LineTable> DebugLines;
157
158  bool isEmpty() const;
159};
160
161} // end namespace DWARFYAML
162} // end namespace llvm
163
164LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
165LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
166LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
167LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
168LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
169LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
170LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
171LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
172LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
173LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
174LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
175
176namespace llvm {
177namespace yaml {
178
179template <> struct MappingTraits<DWARFYAML::Data> {
180  static void mapping(IO &IO, DWARFYAML::Data &DWARF);
181};
182
183template <> struct MappingTraits<DWARFYAML::Abbrev> {
184  static void mapping(IO &IO, DWARFYAML::Abbrev &Abbrev);
185};
186
187template <> struct MappingTraits<DWARFYAML::AttributeAbbrev> {
188  static void mapping(IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev);
189};
190
191template <> struct MappingTraits<DWARFYAML::ARangeDescriptor> {
192  static void mapping(IO &IO, DWARFYAML::ARangeDescriptor &Descriptor);
193};
194
195template <> struct MappingTraits<DWARFYAML::ARange> {
196  static void mapping(IO &IO, DWARFYAML::ARange &Range);
197};
198
199template <> struct MappingTraits<DWARFYAML::PubEntry> {
200  static void mapping(IO &IO, DWARFYAML::PubEntry &Entry);
201};
202
203template <> struct MappingTraits<DWARFYAML::PubSection> {
204  static void mapping(IO &IO, DWARFYAML::PubSection &Section);
205};
206
207template <> struct MappingTraits<DWARFYAML::Unit> {
208  static void mapping(IO &IO, DWARFYAML::Unit &Unit);
209};
210
211template <> struct MappingTraits<DWARFYAML::Entry> {
212  static void mapping(IO &IO, DWARFYAML::Entry &Entry);
213};
214
215template <> struct MappingTraits<DWARFYAML::FormValue> {
216  static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
217};
218
219template <> struct MappingTraits<DWARFYAML::File> {
220  static void mapping(IO &IO, DWARFYAML::File &File);
221};
222
223template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
224  static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
225};
226
227template <> struct MappingTraits<DWARFYAML::LineTable> {
228  static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
229};
230
231template <> struct MappingTraits<DWARFYAML::InitialLength> {
232  static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
233};
234
235#define HANDLE_DW_TAG(unused, name, unused2, unused3, unused4)                 \
236  io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
237
238template <> struct ScalarEnumerationTraits<dwarf::Tag> {
239  static void enumeration(IO &io, dwarf::Tag &value) {
240#include "llvm/BinaryFormat/Dwarf.def"
241    io.enumFallback<Hex16>(value);
242  }
243};
244
245#define HANDLE_DW_LNS(unused, name)                                            \
246  io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);
247
248template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
249  static void enumeration(IO &io, dwarf::LineNumberOps &value) {
250#include "llvm/BinaryFormat/Dwarf.def"
251    io.enumFallback<Hex8>(value);
252  }
253};
254
255#define HANDLE_DW_LNE(unused, name)                                            \
256  io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);
257
258template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
259  static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
260#include "llvm/BinaryFormat/Dwarf.def"
261    io.enumFallback<Hex16>(value);
262  }
263};
264
265#define HANDLE_DW_AT(unused, name, unused2, unused3)                           \
266  io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
267
268template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
269  static void enumeration(IO &io, dwarf::Attribute &value) {
270#include "llvm/BinaryFormat/Dwarf.def"
271    io.enumFallback<Hex16>(value);
272  }
273};
274
275#define HANDLE_DW_FORM(unused, name, unused2, unused3)                         \
276  io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
277
278template <> struct ScalarEnumerationTraits<dwarf::Form> {
279  static void enumeration(IO &io, dwarf::Form &value) {
280#include "llvm/BinaryFormat/Dwarf.def"
281    io.enumFallback<Hex16>(value);
282  }
283};
284
285#define HANDLE_DW_UT(unused, name)                                             \
286  io.enumCase(value, "DW_UT_" #name, dwarf::DW_UT_##name);
287
288template <> struct ScalarEnumerationTraits<dwarf::UnitType> {
289  static void enumeration(IO &io, dwarf::UnitType &value) {
290#include "llvm/BinaryFormat/Dwarf.def"
291    io.enumFallback<Hex8>(value);
292  }
293};
294
295template <> struct ScalarEnumerationTraits<dwarf::Constants> {
296  static void enumeration(IO &io, dwarf::Constants &value) {
297    io.enumCase(value, "DW_CHILDREN_no", dwarf::DW_CHILDREN_no);
298    io.enumCase(value, "DW_CHILDREN_yes", dwarf::DW_CHILDREN_yes);
299    io.enumFallback<Hex16>(value);
300  }
301};
302
303} // end namespace yaml
304} // end namespace llvm
305
306#endif // LLVM_OBJECTYAML_DWARFYAML_H
307