DWARFUnitIndex.h 6.8 KB

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