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 24 namespace llvm { 25 namespace DWARFYAML { 26 27 struct 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 47 struct AttributeAbbrev { 48 llvm::dwarf::Attribute Attribute; 49 llvm::dwarf::Form Form; 50 llvm::yaml::Hex64 Value; // Some DWARF5 attributes have values 51 }; 52 53 struct Abbrev { 54 llvm::yaml::Hex32 Code; 55 llvm::dwarf::Tag Tag; 56 llvm::dwarf::Constants Children; 57 std::vector<AttributeAbbrev> Attributes; 58 }; 59 60 struct ARangeDescriptor { 61 llvm::yaml::Hex64 Address; 62 uint64_t Length; 63 }; 64 65 struct 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 74 struct PubEntry { 75 llvm::yaml::Hex32 DieOffset; 76 llvm::yaml::Hex8 Descriptor; 77 StringRef Name; 78 }; 79 80 struct 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 89 struct FormValue { 90 llvm::yaml::Hex64 Value; 91 StringRef CStr; 92 std::vector<llvm::yaml::Hex8> BlockData; 93 }; 94 95 struct Entry { 96 llvm::yaml::Hex32 AbbrCode; 97 std::vector<FormValue> Values; 98 }; 99 100 struct 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 109 struct File { 110 StringRef Name; 111 uint64_t DirIdx; 112 uint64_t ModTime; 113 uint64_t Length; 114 }; 115 116 struct 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 127 struct 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 143 struct 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 164 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev) 165 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev) 166 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor) 167 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange) 168 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry) 169 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit) 170 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue) 171 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry) 172 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File) 173 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable) 174 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode) 175 176 namespace llvm { 177 namespace yaml { 178 179 template <> struct MappingTraits<DWARFYAML::Data> { 180 static void mapping(IO &IO, DWARFYAML::Data &DWARF); 181 }; 182 183 template <> struct MappingTraits<DWARFYAML::Abbrev> { 184 static void mapping(IO &IO, DWARFYAML::Abbrev &Abbrev); 185 }; 186 187 template <> struct MappingTraits<DWARFYAML::AttributeAbbrev> { 188 static void mapping(IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev); 189 }; 190 191 template <> struct MappingTraits<DWARFYAML::ARangeDescriptor> { 192 static void mapping(IO &IO, DWARFYAML::ARangeDescriptor &Descriptor); 193 }; 194 195 template <> struct MappingTraits<DWARFYAML::ARange> { 196 static void mapping(IO &IO, DWARFYAML::ARange &Range); 197 }; 198 199 template <> struct MappingTraits<DWARFYAML::PubEntry> { 200 static void mapping(IO &IO, DWARFYAML::PubEntry &Entry); 201 }; 202 203 template <> struct MappingTraits<DWARFYAML::PubSection> { 204 static void mapping(IO &IO, DWARFYAML::PubSection &Section); 205 }; 206 207 template <> struct MappingTraits<DWARFYAML::Unit> { 208 static void mapping(IO &IO, DWARFYAML::Unit &Unit); 209 }; 210 211 template <> struct MappingTraits<DWARFYAML::Entry> { 212 static void mapping(IO &IO, DWARFYAML::Entry &Entry); 213 }; 214 215 template <> struct MappingTraits<DWARFYAML::FormValue> { 216 static void mapping(IO &IO, DWARFYAML::FormValue &FormValue); 217 }; 218 219 template <> struct MappingTraits<DWARFYAML::File> { 220 static void mapping(IO &IO, DWARFYAML::File &File); 221 }; 222 223 template <> struct MappingTraits<DWARFYAML::LineTableOpcode> { 224 static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode); 225 }; 226 227 template <> struct MappingTraits<DWARFYAML::LineTable> { 228 static void mapping(IO &IO, DWARFYAML::LineTable &LineTable); 229 }; 230 231 template <> 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 238 template <> 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 248 template <> 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 258 template <> 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 268 template <> 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 278 template <> 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 288 template <> 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 295 template <> 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