Home | History | Annotate | Line # | Download | only in ObjectYAML
      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/SetVector.h"
     19 #include "llvm/ADT/StringRef.h"
     20 #include "llvm/BinaryFormat/Dwarf.h"
     21 #include "llvm/ObjectYAML/YAML.h"
     22 #include "llvm/Support/YAMLTraits.h"
     23 #include <cstdint>
     24 #include <unordered_map>
     25 #include <vector>
     26 
     27 namespace llvm {
     28 namespace DWARFYAML {
     29 
     30 struct AttributeAbbrev {
     31   llvm::dwarf::Attribute Attribute;
     32   llvm::dwarf::Form Form;
     33   llvm::yaml::Hex64 Value; // Some DWARF5 attributes have values
     34 };
     35 
     36 struct Abbrev {
     37   Optional<yaml::Hex64> Code;
     38   llvm::dwarf::Tag Tag;
     39   llvm::dwarf::Constants Children;
     40   std::vector<AttributeAbbrev> Attributes;
     41 };
     42 
     43 struct AbbrevTable {
     44   Optional<uint64_t> ID;
     45   std::vector<Abbrev> Table;
     46 };
     47 
     48 struct ARangeDescriptor {
     49   llvm::yaml::Hex64 Address;
     50   yaml::Hex64 Length;
     51 };
     52 
     53 struct ARange {
     54   dwarf::DwarfFormat Format;
     55   Optional<yaml::Hex64> Length;
     56   uint16_t Version;
     57   yaml::Hex64 CuOffset;
     58   Optional<yaml::Hex8> AddrSize;
     59   yaml::Hex8 SegSize;
     60   std::vector<ARangeDescriptor> Descriptors;
     61 };
     62 
     63 /// Class that describes a range list entry, or a base address selection entry
     64 /// within a range list in the .debug_ranges section.
     65 struct RangeEntry {
     66   llvm::yaml::Hex64 LowOffset;
     67   llvm::yaml::Hex64 HighOffset;
     68 };
     69 
     70 /// Class that describes a single range list inside the .debug_ranges section.
     71 struct Ranges {
     72   Optional<llvm::yaml::Hex64> Offset;
     73   Optional<llvm::yaml::Hex8> AddrSize;
     74   std::vector<RangeEntry> Entries;
     75 };
     76 
     77 struct PubEntry {
     78   llvm::yaml::Hex32 DieOffset;
     79   llvm::yaml::Hex8 Descriptor;
     80   StringRef Name;
     81 };
     82 
     83 struct PubSection {
     84   dwarf::DwarfFormat Format;
     85   yaml::Hex64 Length;
     86   uint16_t Version;
     87   uint32_t UnitOffset;
     88   uint32_t UnitSize;
     89   std::vector<PubEntry> Entries;
     90 };
     91 
     92 struct FormValue {
     93   llvm::yaml::Hex64 Value;
     94   StringRef CStr;
     95   std::vector<llvm::yaml::Hex8> BlockData;
     96 };
     97 
     98 struct Entry {
     99   llvm::yaml::Hex32 AbbrCode;
    100   std::vector<FormValue> Values;
    101 };
    102 
    103 /// Class that contains helpful context information when mapping YAML into DWARF
    104 /// data structures.
    105 struct DWARFContext {
    106   bool IsGNUPubSec = false;
    107 };
    108 
    109 struct Unit {
    110   dwarf::DwarfFormat Format;
    111   Optional<yaml::Hex64> Length;
    112   uint16_t Version;
    113   Optional<uint8_t> AddrSize;
    114   llvm::dwarf::UnitType Type; // Added in DWARF 5
    115   Optional<uint64_t> AbbrevTableID;
    116   Optional<yaml::Hex64> AbbrOffset;
    117   std::vector<Entry> Entries;
    118 };
    119 
    120 struct File {
    121   StringRef Name;
    122   uint64_t DirIdx;
    123   uint64_t ModTime;
    124   uint64_t Length;
    125 };
    126 
    127 struct LineTableOpcode {
    128   dwarf::LineNumberOps Opcode;
    129   Optional<uint64_t> ExtLen;
    130   dwarf::LineNumberExtendedOps SubOpcode;
    131   uint64_t Data;
    132   int64_t SData;
    133   File FileEntry;
    134   std::vector<llvm::yaml::Hex8> UnknownOpcodeData;
    135   std::vector<llvm::yaml::Hex64> StandardOpcodeData;
    136 };
    137 
    138 struct LineTable {
    139   dwarf::DwarfFormat Format;
    140   Optional<uint64_t> Length;
    141   uint16_t Version;
    142   Optional<uint64_t> PrologueLength;
    143   uint8_t MinInstLength;
    144   uint8_t MaxOpsPerInst;
    145   uint8_t DefaultIsStmt;
    146   uint8_t LineBase;
    147   uint8_t LineRange;
    148   Optional<uint8_t> OpcodeBase;
    149   Optional<std::vector<uint8_t>> StandardOpcodeLengths;
    150   std::vector<StringRef> IncludeDirs;
    151   std::vector<File> Files;
    152   std::vector<LineTableOpcode> Opcodes;
    153 };
    154 
    155 struct SegAddrPair {
    156   yaml::Hex64 Segment;
    157   yaml::Hex64 Address;
    158 };
    159 
    160 struct AddrTableEntry {
    161   dwarf::DwarfFormat Format;
    162   Optional<yaml::Hex64> Length;
    163   yaml::Hex16 Version;
    164   Optional<yaml::Hex8> AddrSize;
    165   yaml::Hex8 SegSelectorSize;
    166   std::vector<SegAddrPair> SegAddrPairs;
    167 };
    168 
    169 struct StringOffsetsTable {
    170   dwarf::DwarfFormat Format;
    171   Optional<yaml::Hex64> Length;
    172   yaml::Hex16 Version;
    173   yaml::Hex16 Padding;
    174   std::vector<yaml::Hex64> Offsets;
    175 };
    176 
    177 struct DWARFOperation {
    178   dwarf::LocationAtom Operator;
    179   std::vector<yaml::Hex64> Values;
    180 };
    181 
    182 struct RnglistEntry {
    183   dwarf::RnglistEntries Operator;
    184   std::vector<yaml::Hex64> Values;
    185 };
    186 
    187 struct LoclistEntry {
    188   dwarf::LoclistEntries Operator;
    189   std::vector<yaml::Hex64> Values;
    190   Optional<yaml::Hex64> DescriptionsLength;
    191   std::vector<DWARFOperation> Descriptions;
    192 };
    193 
    194 template <typename EntryType> struct ListEntries {
    195   Optional<std::vector<EntryType>> Entries;
    196   Optional<yaml::BinaryRef> Content;
    197 };
    198 
    199 template <typename EntryType> struct ListTable {
    200   dwarf::DwarfFormat Format;
    201   Optional<yaml::Hex64> Length;
    202   yaml::Hex16 Version;
    203   Optional<yaml::Hex8> AddrSize;
    204   yaml::Hex8 SegSelectorSize;
    205   Optional<uint32_t> OffsetEntryCount;
    206   Optional<std::vector<yaml::Hex64>> Offsets;
    207   std::vector<ListEntries<EntryType>> Lists;
    208 };
    209 
    210 struct Data {
    211   bool IsLittleEndian;
    212   bool Is64BitAddrSize;
    213   std::vector<AbbrevTable> DebugAbbrev;
    214   Optional<std::vector<StringRef>> DebugStrings;
    215   Optional<std::vector<StringOffsetsTable>> DebugStrOffsets;
    216   Optional<std::vector<ARange>> DebugAranges;
    217   Optional<std::vector<Ranges>> DebugRanges;
    218   Optional<std::vector<AddrTableEntry>> DebugAddr;
    219   Optional<PubSection> PubNames;
    220   Optional<PubSection> PubTypes;
    221 
    222   Optional<PubSection> GNUPubNames;
    223   Optional<PubSection> GNUPubTypes;
    224 
    225   std::vector<Unit> CompileUnits;
    226 
    227   std::vector<LineTable> DebugLines;
    228   Optional<std::vector<ListTable<RnglistEntry>>> DebugRnglists;
    229   Optional<std::vector<ListTable<LoclistEntry>>> DebugLoclists;
    230 
    231   bool isEmpty() const;
    232 
    233   SetVector<StringRef> getNonEmptySectionNames() const;
    234 
    235   struct AbbrevTableInfo {
    236     uint64_t Index;
    237     uint64_t Offset;
    238   };
    239   Expected<AbbrevTableInfo> getAbbrevTableInfoByID(uint64_t ID) const;
    240   StringRef getAbbrevTableContentByIndex(uint64_t Index) const;
    241 
    242 private:
    243   mutable std::unordered_map<uint64_t, AbbrevTableInfo> AbbrevTableInfoMap;
    244   mutable std::unordered_map<uint64_t, std::string> AbbrevTableContents;
    245 };
    246 
    247 } // end namespace DWARFYAML
    248 } // end namespace llvm
    249 
    250 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
    251 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
    252 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AbbrevTable)
    253 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
    254 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
    255 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RangeEntry)
    256 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Ranges)
    257 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
    258 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
    259 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
    260 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
    261 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
    262 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
    263 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
    264 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::SegAddrPair)
    265 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AddrTableEntry)
    266 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::StringOffsetsTable)
    267 LLVM_YAML_IS_SEQUENCE_VECTOR(
    268     llvm::DWARFYAML::ListTable<DWARFYAML::RnglistEntry>)
    269 LLVM_YAML_IS_SEQUENCE_VECTOR(
    270     llvm::DWARFYAML::ListEntries<DWARFYAML::RnglistEntry>)
    271 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistEntry)
    272 LLVM_YAML_IS_SEQUENCE_VECTOR(
    273     llvm::DWARFYAML::ListTable<DWARFYAML::LoclistEntry>)
    274 LLVM_YAML_IS_SEQUENCE_VECTOR(
    275     llvm::DWARFYAML::ListEntries<DWARFYAML::LoclistEntry>)
    276 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LoclistEntry)
    277 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::DWARFOperation)
    278 
    279 namespace llvm {
    280 namespace yaml {
    281 
    282 template <> struct MappingTraits<DWARFYAML::Data> {
    283   static void mapping(IO &IO, DWARFYAML::Data &DWARF);
    284 };
    285 
    286 template <> struct MappingTraits<DWARFYAML::AbbrevTable> {
    287   static void mapping(IO &IO, DWARFYAML::AbbrevTable &AbbrevTable);
    288 };
    289 
    290 template <> struct MappingTraits<DWARFYAML::Abbrev> {
    291   static void mapping(IO &IO, DWARFYAML::Abbrev &Abbrev);
    292 };
    293 
    294 template <> struct MappingTraits<DWARFYAML::AttributeAbbrev> {
    295   static void mapping(IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev);
    296 };
    297 
    298 template <> struct MappingTraits<DWARFYAML::ARangeDescriptor> {
    299   static void mapping(IO &IO, DWARFYAML::ARangeDescriptor &Descriptor);
    300 };
    301 
    302 template <> struct MappingTraits<DWARFYAML::ARange> {
    303   static void mapping(IO &IO, DWARFYAML::ARange &ARange);
    304 };
    305 
    306 template <> struct MappingTraits<DWARFYAML::RangeEntry> {
    307   static void mapping(IO &IO, DWARFYAML::RangeEntry &Entry);
    308 };
    309 
    310 template <> struct MappingTraits<DWARFYAML::Ranges> {
    311   static void mapping(IO &IO, DWARFYAML::Ranges &Ranges);
    312 };
    313 
    314 template <> struct MappingTraits<DWARFYAML::PubEntry> {
    315   static void mapping(IO &IO, DWARFYAML::PubEntry &Entry);
    316 };
    317 
    318 template <> struct MappingTraits<DWARFYAML::PubSection> {
    319   static void mapping(IO &IO, DWARFYAML::PubSection &Section);
    320 };
    321 
    322 template <> struct MappingTraits<DWARFYAML::Unit> {
    323   static void mapping(IO &IO, DWARFYAML::Unit &Unit);
    324 };
    325 
    326 template <> struct MappingTraits<DWARFYAML::Entry> {
    327   static void mapping(IO &IO, DWARFYAML::Entry &Entry);
    328 };
    329 
    330 template <> struct MappingTraits<DWARFYAML::FormValue> {
    331   static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
    332 };
    333 
    334 template <> struct MappingTraits<DWARFYAML::File> {
    335   static void mapping(IO &IO, DWARFYAML::File &File);
    336 };
    337 
    338 template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
    339   static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
    340 };
    341 
    342 template <> struct MappingTraits<DWARFYAML::LineTable> {
    343   static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
    344 };
    345 
    346 template <> struct MappingTraits<DWARFYAML::SegAddrPair> {
    347   static void mapping(IO &IO, DWARFYAML::SegAddrPair &SegAddrPair);
    348 };
    349 
    350 template <> struct MappingTraits<DWARFYAML::DWARFOperation> {
    351   static void mapping(IO &IO, DWARFYAML::DWARFOperation &DWARFOperation);
    352 };
    353 
    354 template <typename EntryType>
    355 struct MappingTraits<DWARFYAML::ListTable<EntryType>> {
    356   static void mapping(IO &IO, DWARFYAML::ListTable<EntryType> &ListTable);
    357 };
    358 
    359 template <typename EntryType>
    360 struct MappingTraits<DWARFYAML::ListEntries<EntryType>> {
    361   static void mapping(IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries);
    362   static std::string validate(IO &IO,
    363                               DWARFYAML::ListEntries<EntryType> &ListEntries);
    364 };
    365 
    366 template <> struct MappingTraits<DWARFYAML::RnglistEntry> {
    367   static void mapping(IO &IO, DWARFYAML::RnglistEntry &RnglistEntry);
    368 };
    369 
    370 template <> struct MappingTraits<DWARFYAML::LoclistEntry> {
    371   static void mapping(IO &IO, DWARFYAML::LoclistEntry &LoclistEntry);
    372 };
    373 
    374 template <> struct MappingTraits<DWARFYAML::AddrTableEntry> {
    375   static void mapping(IO &IO, DWARFYAML::AddrTableEntry &AddrTable);
    376 };
    377 
    378 template <> struct MappingTraits<DWARFYAML::StringOffsetsTable> {
    379   static void mapping(IO &IO, DWARFYAML::StringOffsetsTable &StrOffsetsTable);
    380 };
    381 
    382 template <> struct ScalarEnumerationTraits<dwarf::DwarfFormat> {
    383   static void enumeration(IO &IO, dwarf::DwarfFormat &Format) {
    384     IO.enumCase(Format, "DWARF32", dwarf::DWARF32);
    385     IO.enumCase(Format, "DWARF64", dwarf::DWARF64);
    386   }
    387 };
    388 
    389 #define HANDLE_DW_TAG(unused, name, unused2, unused3, unused4)                 \
    390   io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
    391 
    392 template <> struct ScalarEnumerationTraits<dwarf::Tag> {
    393   static void enumeration(IO &io, dwarf::Tag &value) {
    394 #include "llvm/BinaryFormat/Dwarf.def"
    395     io.enumFallback<Hex16>(value);
    396   }
    397 };
    398 
    399 #define HANDLE_DW_LNS(unused, name)                                            \
    400   io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);
    401 
    402 template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
    403   static void enumeration(IO &io, dwarf::LineNumberOps &value) {
    404 #include "llvm/BinaryFormat/Dwarf.def"
    405     io.enumFallback<Hex8>(value);
    406   }
    407 };
    408 
    409 #define HANDLE_DW_LNE(unused, name)                                            \
    410   io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);
    411 
    412 template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
    413   static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
    414 #include "llvm/BinaryFormat/Dwarf.def"
    415     io.enumFallback<Hex16>(value);
    416   }
    417 };
    418 
    419 #define HANDLE_DW_AT(unused, name, unused2, unused3)                           \
    420   io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
    421 
    422 template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
    423   static void enumeration(IO &io, dwarf::Attribute &value) {
    424 #include "llvm/BinaryFormat/Dwarf.def"
    425     io.enumFallback<Hex16>(value);
    426   }
    427 };
    428 
    429 #define HANDLE_DW_FORM(unused, name, unused2, unused3)                         \
    430   io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
    431 
    432 template <> struct ScalarEnumerationTraits<dwarf::Form> {
    433   static void enumeration(IO &io, dwarf::Form &value) {
    434 #include "llvm/BinaryFormat/Dwarf.def"
    435     io.enumFallback<Hex16>(value);
    436   }
    437 };
    438 
    439 #define HANDLE_DW_UT(unused, name)                                             \
    440   io.enumCase(value, "DW_UT_" #name, dwarf::DW_UT_##name);
    441 
    442 template <> struct ScalarEnumerationTraits<dwarf::UnitType> {
    443   static void enumeration(IO &io, dwarf::UnitType &value) {
    444 #include "llvm/BinaryFormat/Dwarf.def"
    445     io.enumFallback<Hex8>(value);
    446   }
    447 };
    448 
    449 template <> struct ScalarEnumerationTraits<dwarf::Constants> {
    450   static void enumeration(IO &io, dwarf::Constants &value) {
    451     io.enumCase(value, "DW_CHILDREN_no", dwarf::DW_CHILDREN_no);
    452     io.enumCase(value, "DW_CHILDREN_yes", dwarf::DW_CHILDREN_yes);
    453     io.enumFallback<Hex16>(value);
    454   }
    455 };
    456 
    457 #define HANDLE_DW_RLE(unused, name)                                            \
    458   io.enumCase(value, "DW_RLE_" #name, dwarf::DW_RLE_##name);
    459 
    460 template <> struct ScalarEnumerationTraits<dwarf::RnglistEntries> {
    461   static void enumeration(IO &io, dwarf::RnglistEntries &value) {
    462 #include "llvm/BinaryFormat/Dwarf.def"
    463   }
    464 };
    465 
    466 #define HANDLE_DW_LLE(unused, name)                                            \
    467   io.enumCase(value, "DW_LLE_" #name, dwarf::DW_LLE_##name);
    468 
    469 template <> struct ScalarEnumerationTraits<dwarf::LoclistEntries> {
    470   static void enumeration(IO &io, dwarf::LoclistEntries &value) {
    471 #include "llvm/BinaryFormat/Dwarf.def"
    472   }
    473 };
    474 
    475 #define HANDLE_DW_OP(id, name, version, vendor)                                \
    476   io.enumCase(value, "DW_OP_" #name, dwarf::DW_OP_##name);
    477 
    478 template <> struct ScalarEnumerationTraits<dwarf::LocationAtom> {
    479   static void enumeration(IO &io, dwarf::LocationAtom &value) {
    480 #include "llvm/BinaryFormat/Dwarf.def"
    481     io.enumFallback<yaml::Hex8>(value);
    482   }
    483 };
    484 
    485 } // end namespace yaml
    486 } // end namespace llvm
    487 
    488 #endif // LLVM_OBJECTYAML_DWARFYAML_H
    489