Home | History | Annotate | Line # | Download | only in DWARF
      1 //===- DWARFUnitIndex.h -----------------------------------------*- 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 #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
     10 #define LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
     11 
     12 #include "llvm/ADT/ArrayRef.h"
     13 #include "llvm/ADT/StringRef.h"
     14 #include "llvm/Support/DataExtractor.h"
     15 #include <cstdint>
     16 #include <memory>
     17 
     18 namespace llvm {
     19 
     20 class raw_ostream;
     21 
     22 /// The enum of section identifiers to be used in internal interfaces.
     23 ///
     24 /// Pre-standard implementation of package files defined a number of section
     25 /// identifiers with values that clash definitions in the DWARFv5 standard.
     26 /// See https://gcc.gnu.org/wiki/DebugFissionDWP and Section 7.3.5.3 in DWARFv5.
     27 ///
     28 /// The following identifiers are the same in the proposal and in DWARFv5:
     29 /// - DW_SECT_INFO         = 1 (.debug_info.dwo)
     30 /// - DW_SECT_ABBREV       = 3 (.debug_abbrev.dwo)
     31 /// - DW_SECT_LINE         = 4 (.debug_line.dwo)
     32 /// - DW_SECT_STR_OFFSETS  = 6 (.debug_str_offsets.dwo)
     33 ///
     34 /// The following identifiers are defined only in DWARFv5:
     35 /// - DW_SECT_LOCLISTS     = 5 (.debug_loclists.dwo)
     36 /// - DW_SECT_RNGLISTS     = 8 (.debug_rnglists.dwo)
     37 ///
     38 /// The following identifiers are defined only in the GNU proposal:
     39 /// - DW_SECT_TYPES        = 2 (.debug_types.dwo)
     40 /// - DW_SECT_LOC          = 5 (.debug_loc.dwo)
     41 /// - DW_SECT_MACINFO      = 7 (.debug_macinfo.dwo)
     42 ///
     43 /// DW_SECT_MACRO for the .debug_macro.dwo section is defined in both standards,
     44 /// but with different values, 8 in GNU and 7 in DWARFv5.
     45 ///
     46 /// This enum defines constants to represent the identifiers of both sets.
     47 /// For DWARFv5 ones, the values are the same as defined in the standard.
     48 /// For pre-standard ones that correspond to sections being deprecated in
     49 /// DWARFv5, the values are chosen arbitrary and a tag "_EXT_" is added to
     50 /// the names.
     51 ///
     52 /// The enum is for internal use only. The user should not expect the values
     53 /// to correspond to any input/output constants. Special conversion functions,
     54 /// serializeSectionKind() and deserializeSectionKind(), should be used for
     55 /// the translation.
     56 enum DWARFSectionKind {
     57   /// Denotes a value read from an index section that does not correspond
     58   /// to any of the supported standards.
     59   DW_SECT_EXT_unknown = 0,
     60 #define HANDLE_DW_SECT(ID, NAME) DW_SECT_##NAME = ID,
     61 #include "llvm/BinaryFormat/Dwarf.def"
     62   DW_SECT_EXT_TYPES = 2,
     63   DW_SECT_EXT_LOC = 9,
     64   DW_SECT_EXT_MACINFO = 10,
     65 };
     66 
     67 /// Convert the internal value for a section kind to an on-disk value.
     68 ///
     69 /// The conversion depends on the version of the index section.
     70 /// IndexVersion is expected to be either 2 for pre-standard GNU proposal
     71 /// or 5 for DWARFv5 package file.
     72 uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion);
     73 
     74 /// Convert a value read from an index section to the internal representation.
     75 ///
     76 /// The conversion depends on the index section version, which is expected
     77 /// to be either 2 for pre-standard GNU proposal or 5 for DWARFv5 package file.
     78 DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion);
     79 
     80 class DWARFUnitIndex {
     81   struct Header {
     82     uint32_t Version;
     83     uint32_t NumColumns;
     84     uint32_t NumUnits;
     85     uint32_t NumBuckets = 0;
     86 
     87     bool parse(DataExtractor IndexData, uint64_t *OffsetPtr);
     88     void dump(raw_ostream &OS) const;
     89   };
     90 
     91 public:
     92   class Entry {
     93   public:
     94     struct SectionContribution {
     95       uint32_t Offset;
     96       uint32_t Length;
     97     };
     98 
     99   private:
    100     const DWARFUnitIndex *Index;
    101     uint64_t Signature;
    102     std::unique_ptr<SectionContribution[]> Contributions;
    103     friend class DWARFUnitIndex;
    104 
    105   public:
    106     const SectionContribution *getContribution(DWARFSectionKind Sec) const;
    107     const SectionContribution *getContribution() const;
    108 
    109     const SectionContribution *getContributions() const {
    110       return Contributions.get();
    111     }
    112 
    113     uint64_t getSignature() const { return Signature; }
    114   };
    115 
    116 private:
    117   struct Header Header;
    118 
    119   DWARFSectionKind InfoColumnKind;
    120   int InfoColumn = -1;
    121   std::unique_ptr<DWARFSectionKind[]> ColumnKinds;
    122   // This is a parallel array of section identifiers as they read from the input
    123   // file. The mapping from raw values to DWARFSectionKind is not revertable in
    124   // case of unknown identifiers, so we keep them here.
    125   std::unique_ptr<uint32_t[]> RawSectionIds;
    126   std::unique_ptr<Entry[]> Rows;
    127   mutable std::vector<Entry *> OffsetLookup;
    128 
    129   static StringRef getColumnHeader(DWARFSectionKind DS);
    130 
    131   bool parseImpl(DataExtractor IndexData);
    132 
    133 public:
    134   DWARFUnitIndex(DWARFSectionKind InfoColumnKind)
    135       : InfoColumnKind(InfoColumnKind) {}
    136 
    137   explicit operator bool() const { return Header.NumBuckets; }
    138 
    139   bool parse(DataExtractor IndexData);
    140   void dump(raw_ostream &OS) const;
    141 
    142   uint32_t getVersion() const { return Header.Version; }
    143 
    144   const Entry *getFromOffset(uint32_t Offset) const;
    145   const Entry *getFromHash(uint64_t Offset) const;
    146 
    147   ArrayRef<DWARFSectionKind> getColumnKinds() const {
    148     return makeArrayRef(ColumnKinds.get(), Header.NumColumns);
    149   }
    150 
    151   ArrayRef<Entry> getRows() const {
    152     return makeArrayRef(Rows.get(), Header.NumBuckets);
    153   }
    154 };
    155 
    156 } // end namespace llvm
    157 
    158 #endif // LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
    159