1311116Sdim//===- DWARFYAML.h - DWARF YAMLIO implementation ----------------*- C++ -*-===//
2311116Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6311116Sdim//
7311116Sdim//===----------------------------------------------------------------------===//
8311116Sdim///
9311116Sdim/// \file
10341825Sdim/// This file declares classes for handling the YAML representation
11311116Sdim/// of DWARF Debug Info.
12311116Sdim///
13311116Sdim//===----------------------------------------------------------------------===//
14311116Sdim
15311116Sdim#ifndef LLVM_OBJECTYAML_DWARFYAML_H
16311116Sdim#define LLVM_OBJECTYAML_DWARFYAML_H
17311116Sdim
18321369Sdim#include "llvm/ADT/StringRef.h"
19321369Sdim#include "llvm/BinaryFormat/Dwarf.h"
20321369Sdim#include "llvm/Support/YAMLTraits.h"
21321369Sdim#include <cstdint>
22321369Sdim#include <vector>
23311116Sdim
24311116Sdimnamespace llvm {
25311116Sdimnamespace DWARFYAML {
26311116Sdim
27321369Sdimstruct InitialLength {
28321369Sdim  uint32_t TotalLength;
29321369Sdim  uint64_t TotalLength64;
30321369Sdim
31321369Sdim  bool isDWARF64() const { return TotalLength == UINT32_MAX; }
32321369Sdim
33321369Sdim  uint64_t getLength() const {
34321369Sdim    return isDWARF64() ? TotalLength64 : TotalLength;
35321369Sdim  }
36321369Sdim
37321369Sdim  void setLength(uint64_t Len) {
38321369Sdim    if (Len >= (uint64_t)UINT32_MAX) {
39321369Sdim      TotalLength64 = Len;
40321369Sdim      TotalLength = UINT32_MAX;
41321369Sdim    } else {
42321369Sdim      TotalLength = Len;
43321369Sdim    }
44321369Sdim  }
45321369Sdim};
46321369Sdim
47311116Sdimstruct AttributeAbbrev {
48311116Sdim  llvm::dwarf::Attribute Attribute;
49311116Sdim  llvm::dwarf::Form Form;
50321369Sdim  llvm::yaml::Hex64 Value; // Some DWARF5 attributes have values
51311116Sdim};
52311116Sdim
53311116Sdimstruct Abbrev {
54311116Sdim  llvm::yaml::Hex32 Code;
55311116Sdim  llvm::dwarf::Tag Tag;
56311116Sdim  llvm::dwarf::Constants Children;
57311116Sdim  std::vector<AttributeAbbrev> Attributes;
58311116Sdim};
59311116Sdim
60311116Sdimstruct ARangeDescriptor {
61311116Sdim  llvm::yaml::Hex64 Address;
62311116Sdim  uint64_t Length;
63311116Sdim};
64311116Sdim
65311116Sdimstruct ARange {
66321369Sdim  InitialLength Length;
67311116Sdim  uint16_t Version;
68311116Sdim  uint32_t CuOffset;
69311116Sdim  uint8_t AddrSize;
70311116Sdim  uint8_t SegSize;
71311116Sdim  std::vector<ARangeDescriptor> Descriptors;
72311116Sdim};
73311116Sdim
74311116Sdimstruct PubEntry {
75311116Sdim  llvm::yaml::Hex32 DieOffset;
76311116Sdim  llvm::yaml::Hex8 Descriptor;
77311116Sdim  StringRef Name;
78311116Sdim};
79311116Sdim
80311116Sdimstruct PubSection {
81321369Sdim  InitialLength Length;
82311116Sdim  uint16_t Version;
83311116Sdim  uint32_t UnitOffset;
84311116Sdim  uint32_t UnitSize;
85321369Sdim  bool IsGNUStyle = false;
86311116Sdim  std::vector<PubEntry> Entries;
87311116Sdim};
88311116Sdim
89311116Sdimstruct FormValue {
90311116Sdim  llvm::yaml::Hex64 Value;
91311116Sdim  StringRef CStr;
92311116Sdim  std::vector<llvm::yaml::Hex8> BlockData;
93311116Sdim};
94311116Sdim
95311116Sdimstruct Entry {
96311116Sdim  llvm::yaml::Hex32 AbbrCode;
97311116Sdim  std::vector<FormValue> Values;
98311116Sdim};
99311116Sdim
100311116Sdimstruct Unit {
101321369Sdim  InitialLength Length;
102311116Sdim  uint16_t Version;
103321369Sdim  llvm::dwarf::UnitType Type; // Added in DWARF 5
104311116Sdim  uint32_t AbbrOffset;
105311116Sdim  uint8_t AddrSize;
106311116Sdim  std::vector<Entry> Entries;
107311116Sdim};
108311116Sdim
109312197Sdimstruct File {
110312197Sdim  StringRef Name;
111312197Sdim  uint64_t DirIdx;
112312197Sdim  uint64_t ModTime;
113312197Sdim  uint64_t Length;
114312197Sdim};
115312197Sdim
116312197Sdimstruct LineTableOpcode {
117312197Sdim  dwarf::LineNumberOps Opcode;
118312197Sdim  uint64_t ExtLen;
119312197Sdim  dwarf::LineNumberExtendedOps SubOpcode;
120312197Sdim  uint64_t Data;
121312197Sdim  int64_t SData;
122312197Sdim  File FileEntry;
123312197Sdim  std::vector<llvm::yaml::Hex8> UnknownOpcodeData;
124312197Sdim  std::vector<llvm::yaml::Hex64> StandardOpcodeData;
125312197Sdim};
126312197Sdim
127312197Sdimstruct LineTable {
128321369Sdim  InitialLength Length;
129312197Sdim  uint16_t Version;
130312197Sdim  uint64_t PrologueLength;
131312197Sdim  uint8_t MinInstLength;
132312197Sdim  uint8_t MaxOpsPerInst;
133312197Sdim  uint8_t DefaultIsStmt;
134312197Sdim  uint8_t LineBase;
135312197Sdim  uint8_t LineRange;
136312197Sdim  uint8_t OpcodeBase;
137312197Sdim  std::vector<uint8_t> StandardOpcodeLengths;
138312197Sdim  std::vector<StringRef> IncludeDirs;
139312197Sdim  std::vector<File> Files;
140312197Sdim  std::vector<LineTableOpcode> Opcodes;
141312197Sdim};
142312197Sdim
143311116Sdimstruct Data {
144311116Sdim  bool IsLittleEndian;
145311116Sdim  std::vector<Abbrev> AbbrevDecls;
146311116Sdim  std::vector<StringRef> DebugStrings;
147311116Sdim  std::vector<ARange> ARanges;
148311116Sdim  PubSection PubNames;
149311116Sdim  PubSection PubTypes;
150311116Sdim
151311116Sdim  PubSection GNUPubNames;
152311116Sdim  PubSection GNUPubTypes;
153321369Sdim
154311116Sdim  std::vector<Unit> CompileUnits;
155311116Sdim
156312197Sdim  std::vector<LineTable> DebugLines;
157312197Sdim
158311116Sdim  bool isEmpty() const;
159311116Sdim};
160311116Sdim
161321369Sdim} // end namespace DWARFYAML
162321369Sdim} // end namespace llvm
163311116Sdim
164311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
165311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
166311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
167311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
168311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
169311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
170311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
171311116SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
172312197SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
173312197SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
174312197SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
175311116Sdim
176311116Sdimnamespace llvm {
177311116Sdimnamespace yaml {
178311116Sdim
179311116Sdimtemplate <> struct MappingTraits<DWARFYAML::Data> {
180311116Sdim  static void mapping(IO &IO, DWARFYAML::Data &DWARF);
181311116Sdim};
182311116Sdim
183311116Sdimtemplate <> struct MappingTraits<DWARFYAML::Abbrev> {
184311116Sdim  static void mapping(IO &IO, DWARFYAML::Abbrev &Abbrev);
185311116Sdim};
186311116Sdim
187311116Sdimtemplate <> struct MappingTraits<DWARFYAML::AttributeAbbrev> {
188311116Sdim  static void mapping(IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev);
189311116Sdim};
190311116Sdim
191311116Sdimtemplate <> struct MappingTraits<DWARFYAML::ARangeDescriptor> {
192311116Sdim  static void mapping(IO &IO, DWARFYAML::ARangeDescriptor &Descriptor);
193311116Sdim};
194311116Sdim
195311116Sdimtemplate <> struct MappingTraits<DWARFYAML::ARange> {
196311116Sdim  static void mapping(IO &IO, DWARFYAML::ARange &Range);
197311116Sdim};
198311116Sdim
199311116Sdimtemplate <> struct MappingTraits<DWARFYAML::PubEntry> {
200311116Sdim  static void mapping(IO &IO, DWARFYAML::PubEntry &Entry);
201311116Sdim};
202311116Sdim
203311116Sdimtemplate <> struct MappingTraits<DWARFYAML::PubSection> {
204311116Sdim  static void mapping(IO &IO, DWARFYAML::PubSection &Section);
205311116Sdim};
206311116Sdim
207311116Sdimtemplate <> struct MappingTraits<DWARFYAML::Unit> {
208311116Sdim  static void mapping(IO &IO, DWARFYAML::Unit &Unit);
209311116Sdim};
210311116Sdim
211311116Sdimtemplate <> struct MappingTraits<DWARFYAML::Entry> {
212311116Sdim  static void mapping(IO &IO, DWARFYAML::Entry &Entry);
213311116Sdim};
214311116Sdim
215311116Sdimtemplate <> struct MappingTraits<DWARFYAML::FormValue> {
216311116Sdim  static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
217311116Sdim};
218311116Sdim
219312197Sdimtemplate <> struct MappingTraits<DWARFYAML::File> {
220312197Sdim  static void mapping(IO &IO, DWARFYAML::File &File);
221312197Sdim};
222321369Sdim
223312197Sdimtemplate <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
224312197Sdim  static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
225312197Sdim};
226312197Sdim
227312197Sdimtemplate <> struct MappingTraits<DWARFYAML::LineTable> {
228312197Sdim  static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
229312197Sdim};
230312197Sdim
231321369Sdimtemplate <> struct MappingTraits<DWARFYAML::InitialLength> {
232321369Sdim  static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
233321369Sdim};
234321369Sdim
235360784Sdim#define HANDLE_DW_TAG(unused, name, unused2, unused3, unused4)                 \
236311116Sdim  io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
237311116Sdim
238311116Sdimtemplate <> struct ScalarEnumerationTraits<dwarf::Tag> {
239311116Sdim  static void enumeration(IO &io, dwarf::Tag &value) {
240321369Sdim#include "llvm/BinaryFormat/Dwarf.def"
241311116Sdim    io.enumFallback<Hex16>(value);
242311116Sdim  }
243311116Sdim};
244311116Sdim
245312197Sdim#define HANDLE_DW_LNS(unused, name)                                            \
246312197Sdim  io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);
247312197Sdim
248312197Sdimtemplate <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
249312197Sdim  static void enumeration(IO &io, dwarf::LineNumberOps &value) {
250321369Sdim#include "llvm/BinaryFormat/Dwarf.def"
251312197Sdim    io.enumFallback<Hex8>(value);
252312197Sdim  }
253312197Sdim};
254312197Sdim
255312197Sdim#define HANDLE_DW_LNE(unused, name)                                            \
256312197Sdim  io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);
257312197Sdim
258312197Sdimtemplate <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
259312197Sdim  static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
260321369Sdim#include "llvm/BinaryFormat/Dwarf.def"
261312197Sdim    io.enumFallback<Hex16>(value);
262312197Sdim  }
263312197Sdim};
264312197Sdim
265321369Sdim#define HANDLE_DW_AT(unused, name, unused2, unused3)                           \
266311116Sdim  io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
267311116Sdim
268311116Sdimtemplate <> struct ScalarEnumerationTraits<dwarf::Attribute> {
269311116Sdim  static void enumeration(IO &io, dwarf::Attribute &value) {
270321369Sdim#include "llvm/BinaryFormat/Dwarf.def"
271311116Sdim    io.enumFallback<Hex16>(value);
272311116Sdim  }
273311116Sdim};
274311116Sdim
275321369Sdim#define HANDLE_DW_FORM(unused, name, unused2, unused3)                         \
276311116Sdim  io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
277311116Sdim
278311116Sdimtemplate <> struct ScalarEnumerationTraits<dwarf::Form> {
279311116Sdim  static void enumeration(IO &io, dwarf::Form &value) {
280321369Sdim#include "llvm/BinaryFormat/Dwarf.def"
281311116Sdim    io.enumFallback<Hex16>(value);
282311116Sdim  }
283311116Sdim};
284311116Sdim
285321369Sdim#define HANDLE_DW_UT(unused, name)                                             \
286321369Sdim  io.enumCase(value, "DW_UT_" #name, dwarf::DW_UT_##name);
287321369Sdim
288321369Sdimtemplate <> struct ScalarEnumerationTraits<dwarf::UnitType> {
289321369Sdim  static void enumeration(IO &io, dwarf::UnitType &value) {
290321369Sdim#include "llvm/BinaryFormat/Dwarf.def"
291321369Sdim    io.enumFallback<Hex8>(value);
292321369Sdim  }
293321369Sdim};
294321369Sdim
295311116Sdimtemplate <> struct ScalarEnumerationTraits<dwarf::Constants> {
296311116Sdim  static void enumeration(IO &io, dwarf::Constants &value) {
297311116Sdim    io.enumCase(value, "DW_CHILDREN_no", dwarf::DW_CHILDREN_no);
298311116Sdim    io.enumCase(value, "DW_CHILDREN_yes", dwarf::DW_CHILDREN_yes);
299311116Sdim    io.enumFallback<Hex16>(value);
300311116Sdim  }
301311116Sdim};
302311116Sdim
303321369Sdim} // end namespace yaml
304321369Sdim} // end namespace llvm
305311116Sdim
306321369Sdim#endif // LLVM_OBJECTYAML_DWARFYAML_H
307