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 <cstdint> 15 #include <memory> 16 17 namespace llvm { 18 19 class raw_ostream; 20 class DataExtractor; 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 inline const char *toString(DWARFSectionKind Kind) { 68 switch (Kind) { 69 case DW_SECT_EXT_unknown: 70 return "Unknown DW_SECT value 0"; 71 #define STRINGIZE(X) #X 72 #define HANDLE_DW_SECT(ID, NAME) \ 73 case DW_SECT_##NAME: \ 74 return "DW_SECT_" STRINGIZE(NAME); 75 #include "llvm/BinaryFormat/Dwarf.def" 76 case DW_SECT_EXT_TYPES: 77 return "DW_SECT_TYPES"; 78 case DW_SECT_EXT_LOC: 79 return "DW_SECT_LOC"; 80 case DW_SECT_EXT_MACINFO: 81 return "DW_SECT_MACINFO"; 82 } 83 llvm_unreachable("unknown DWARFSectionKind"); 84 } 85 86 /// Convert the internal value for a section kind to an on-disk value. 87 /// 88 /// The conversion depends on the version of the index section. 89 /// IndexVersion is expected to be either 2 for pre-standard GNU proposal 90 /// or 5 for DWARFv5 package file. 91 uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion); 92 93 /// Convert a value read from an index section to the internal representation. 94 /// 95 /// The conversion depends on the index section version, which is expected 96 /// to be either 2 for pre-standard GNU proposal or 5 for DWARFv5 package file. 97 DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion); 98 99 class DWARFUnitIndex { 100 struct Header { 101 uint32_t Version; 102 uint32_t NumColumns; 103 uint32_t NumUnits; 104 uint32_t NumBuckets = 0; 105 106 bool parse(DataExtractor IndexData, uint64_t *OffsetPtr); 107 void dump(raw_ostream &OS) const; 108 }; 109 110 public: 111 class Entry { 112 public: 113 struct SectionContribution { 114 uint32_t Offset; 115 uint32_t Length; 116 }; 117 118 private: 119 const DWARFUnitIndex *Index; 120 uint64_t Signature; 121 std::unique_ptr<SectionContribution[]> Contributions; 122 friend class DWARFUnitIndex; 123 124 public: 125 const SectionContribution *getContribution(DWARFSectionKind Sec) const; 126 const SectionContribution *getContribution() const; 127 128 const SectionContribution *getContributions() const { 129 return Contributions.get(); 130 } 131 132 uint64_t getSignature() const { return Signature; } 133 }; 134 135 private: 136 struct Header Header; 137 138 DWARFSectionKind InfoColumnKind; 139 int InfoColumn = -1; 140 std::unique_ptr<DWARFSectionKind[]> ColumnKinds; 141 // This is a parallel array of section identifiers as they read from the input 142 // file. The mapping from raw values to DWARFSectionKind is not revertable in 143 // case of unknown identifiers, so we keep them here. 144 std::unique_ptr<uint32_t[]> RawSectionIds; 145 std::unique_ptr<Entry[]> Rows; 146 mutable std::vector<Entry *> OffsetLookup; 147 148 static StringRef getColumnHeader(DWARFSectionKind DS); 149 150 bool parseImpl(DataExtractor IndexData); 151 152 public: 153 DWARFUnitIndex(DWARFSectionKind InfoColumnKind) 154 : InfoColumnKind(InfoColumnKind) {} 155 156 explicit operator bool() const { return Header.NumBuckets; } 157 158 bool parse(DataExtractor IndexData); 159 void dump(raw_ostream &OS) const; 160 161 uint32_t getVersion() const { return Header.Version; } 162 163 const Entry *getFromOffset(uint32_t Offset) const; 164 const Entry *getFromHash(uint64_t Offset) const; 165 166 ArrayRef<DWARFSectionKind> getColumnKinds() const { 167 return makeArrayRef(ColumnKinds.get(), Header.NumColumns); 168 } 169 170 ArrayRef<Entry> getRows() const { 171 return makeArrayRef(Rows.get(), Header.NumBuckets); 172 } 173 }; 174 175 } // end namespace llvm 176 177 #endif // LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H 178