1//===- DWARFYAML.h - DWARF YAMLIO implementation ----------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file declares classes for handling the YAML representation
12/// of DWARF Debug Info.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_OBJECTYAML_DWARFYAML_H
17#define LLVM_OBJECTYAML_DWARFYAML_H
18
19#include "llvm/BinaryFormat/Dwarf.h"
20#include "llvm/ObjectYAML/YAML.h"
21
22namespace llvm {
23namespace DWARFYAML {
24
25struct InitialLength {
26  uint32_t TotalLength;
27  uint64_t TotalLength64;
28
29  bool isDWARF64() const { return TotalLength == UINT32_MAX; }
30
31  uint64_t getLength() const {
32    return isDWARF64() ? TotalLength64 : TotalLength;
33  }
34
35  void setLength(uint64_t Len) {
36    if (Len >= (uint64_t)UINT32_MAX) {
37      TotalLength64 = Len;
38      TotalLength = UINT32_MAX;
39    } else {
40      TotalLength = Len;
41    }
42  }
43};
44
45struct AttributeAbbrev {
46  llvm::dwarf::Attribute Attribute;
47  llvm::dwarf::Form Form;
48  llvm::yaml::Hex64 Value; // Some DWARF5 attributes have values
49};
50
51struct Abbrev {
52  llvm::yaml::Hex32 Code;
53  llvm::dwarf::Tag Tag;
54  llvm::dwarf::Constants Children;
55  std::vector<AttributeAbbrev> Attributes;
56};
57
58struct ARangeDescriptor {
59  llvm::yaml::Hex64 Address;
60  uint64_t Length;
61};
62
63struct ARange {
64  InitialLength Length;
65  uint16_t Version;
66  uint32_t CuOffset;
67  uint8_t AddrSize;
68  uint8_t SegSize;
69  std::vector<ARangeDescriptor> Descriptors;
70};
71
72struct PubEntry {
73  llvm::yaml::Hex32 DieOffset;
74  llvm::yaml::Hex8 Descriptor;
75  StringRef Name;
76};
77
78struct PubSection {
79  PubSection() : IsGNUStyle(false) {}
80
81  InitialLength Length;
82  uint16_t Version;
83  uint32_t UnitOffset;
84  uint32_t UnitSize;
85  bool IsGNUStyle;
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} // namespace llvm::DWARFYAML
162} // namespace llvm
163
164LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint8_t)
165LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
166LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
167LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
168LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
169LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
170LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
171LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
172LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
173LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
174LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
175LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
176LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
177LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
178LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
179
180namespace llvm {
181namespace yaml {
182
183template <> struct MappingTraits<DWARFYAML::Data> {
184  static void mapping(IO &IO, DWARFYAML::Data &DWARF);
185};
186
187template <> struct MappingTraits<DWARFYAML::Abbrev> {
188  static void mapping(IO &IO, DWARFYAML::Abbrev &Abbrev);
189};
190
191template <> struct MappingTraits<DWARFYAML::AttributeAbbrev> {
192  static void mapping(IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev);
193};
194
195template <> struct MappingTraits<DWARFYAML::ARangeDescriptor> {
196  static void mapping(IO &IO, DWARFYAML::ARangeDescriptor &Descriptor);
197};
198
199template <> struct MappingTraits<DWARFYAML::ARange> {
200  static void mapping(IO &IO, DWARFYAML::ARange &Range);
201};
202
203template <> struct MappingTraits<DWARFYAML::PubEntry> {
204  static void mapping(IO &IO, DWARFYAML::PubEntry &Entry);
205};
206
207template <> struct MappingTraits<DWARFYAML::PubSection> {
208  static void mapping(IO &IO, DWARFYAML::PubSection &Section);
209};
210
211template <> struct MappingTraits<DWARFYAML::Unit> {
212  static void mapping(IO &IO, DWARFYAML::Unit &Unit);
213};
214
215template <> struct MappingTraits<DWARFYAML::Entry> {
216  static void mapping(IO &IO, DWARFYAML::Entry &Entry);
217};
218
219template <> struct MappingTraits<DWARFYAML::FormValue> {
220  static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
221};
222
223template <> struct MappingTraits<DWARFYAML::File> {
224  static void mapping(IO &IO, DWARFYAML::File &File);
225};
226
227template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
228  static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
229};
230
231template <> struct MappingTraits<DWARFYAML::LineTable> {
232  static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
233};
234
235template <> struct MappingTraits<DWARFYAML::InitialLength> {
236  static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
237};
238
239#define HANDLE_DW_TAG(unused, name, unused2, unused3)                          \
240  io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
241
242template <> struct ScalarEnumerationTraits<dwarf::Tag> {
243  static void enumeration(IO &io, dwarf::Tag &value) {
244#include "llvm/BinaryFormat/Dwarf.def"
245    io.enumFallback<Hex16>(value);
246  }
247};
248
249#define HANDLE_DW_LNS(unused, name)                                            \
250  io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);
251
252template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
253  static void enumeration(IO &io, dwarf::LineNumberOps &value) {
254#include "llvm/BinaryFormat/Dwarf.def"
255    io.enumFallback<Hex8>(value);
256  }
257};
258
259#define HANDLE_DW_LNE(unused, name)                                            \
260  io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);
261
262template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
263  static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
264#include "llvm/BinaryFormat/Dwarf.def"
265    io.enumFallback<Hex16>(value);
266  }
267};
268
269#define HANDLE_DW_AT(unused, name, unused2, unused3)                           \
270  io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
271
272template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
273  static void enumeration(IO &io, dwarf::Attribute &value) {
274#include "llvm/BinaryFormat/Dwarf.def"
275    io.enumFallback<Hex16>(value);
276  }
277};
278
279#define HANDLE_DW_FORM(unused, name, unused2, unused3)                         \
280  io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
281
282template <> struct ScalarEnumerationTraits<dwarf::Form> {
283  static void enumeration(IO &io, dwarf::Form &value) {
284#include "llvm/BinaryFormat/Dwarf.def"
285    io.enumFallback<Hex16>(value);
286  }
287};
288
289#define HANDLE_DW_UT(unused, name)                                             \
290  io.enumCase(value, "DW_UT_" #name, dwarf::DW_UT_##name);
291
292template <> struct ScalarEnumerationTraits<dwarf::UnitType> {
293  static void enumeration(IO &io, dwarf::UnitType &value) {
294#include "llvm/BinaryFormat/Dwarf.def"
295    io.enumFallback<Hex8>(value);
296  }
297};
298
299template <> struct ScalarEnumerationTraits<dwarf::Constants> {
300  static void enumeration(IO &io, dwarf::Constants &value) {
301    io.enumCase(value, "DW_CHILDREN_no", dwarf::DW_CHILDREN_no);
302    io.enumCase(value, "DW_CHILDREN_yes", dwarf::DW_CHILDREN_yes);
303    io.enumFallback<Hex16>(value);
304  }
305};
306
307} // namespace llvm::yaml
308} // namespace llvm
309
310#endif
311