DWARFUnitIndex.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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 "llvm/Support/DataExtractor.h"
  18. #include <cstdint>
  19. #include <memory>
  20. namespace llvm {
  21. class raw_ostream;
  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. /// Convert the internal value for a section kind to an on-disk value.
  67. ///
  68. /// The conversion depends on the version of the index section.
  69. /// IndexVersion is expected to be either 2 for pre-standard GNU proposal
  70. /// or 5 for DWARFv5 package file.
  71. uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion);
  72. /// Convert a value read from an index section to the internal representation.
  73. ///
  74. /// The conversion depends on the index section version, which is expected
  75. /// to be either 2 for pre-standard GNU proposal or 5 for DWARFv5 package file.
  76. DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion);
  77. class DWARFUnitIndex {
  78. struct Header {
  79. uint32_t Version;
  80. uint32_t NumColumns;
  81. uint32_t NumUnits;
  82. uint32_t NumBuckets = 0;
  83. bool parse(DataExtractor IndexData, uint64_t *OffsetPtr);
  84. void dump(raw_ostream &OS) const;
  85. };
  86. public:
  87. class Entry {
  88. public:
  89. struct SectionContribution {
  90. uint32_t Offset;
  91. uint32_t Length;
  92. };
  93. private:
  94. const DWARFUnitIndex *Index;
  95. uint64_t Signature;
  96. std::unique_ptr<SectionContribution[]> Contributions;
  97. friend class DWARFUnitIndex;
  98. public:
  99. const SectionContribution *getContribution(DWARFSectionKind Sec) const;
  100. const SectionContribution *getContribution() const;
  101. const SectionContribution *getContributions() const {
  102. return Contributions.get();
  103. }
  104. uint64_t getSignature() const { return Signature; }
  105. };
  106. private:
  107. struct Header Header;
  108. DWARFSectionKind InfoColumnKind;
  109. int InfoColumn = -1;
  110. std::unique_ptr<DWARFSectionKind[]> ColumnKinds;
  111. // This is a parallel array of section identifiers as they read from the input
  112. // file. The mapping from raw values to DWARFSectionKind is not revertable in
  113. // case of unknown identifiers, so we keep them here.
  114. std::unique_ptr<uint32_t[]> RawSectionIds;
  115. std::unique_ptr<Entry[]> Rows;
  116. mutable std::vector<Entry *> OffsetLookup;
  117. static StringRef getColumnHeader(DWARFSectionKind DS);
  118. bool parseImpl(DataExtractor IndexData);
  119. public:
  120. DWARFUnitIndex(DWARFSectionKind InfoColumnKind)
  121. : InfoColumnKind(InfoColumnKind) {}
  122. explicit operator bool() const { return Header.NumBuckets; }
  123. bool parse(DataExtractor IndexData);
  124. void dump(raw_ostream &OS) const;
  125. uint32_t getVersion() const { return Header.Version; }
  126. const Entry *getFromOffset(uint32_t Offset) const;
  127. const Entry *getFromHash(uint64_t Offset) const;
  128. ArrayRef<DWARFSectionKind> getColumnKinds() const {
  129. return makeArrayRef(ColumnKinds.get(), Header.NumColumns);
  130. }
  131. ArrayRef<Entry> getRows() const {
  132. return makeArrayRef(Rows.get(), Header.NumBuckets);
  133. }
  134. };
  135. } // end namespace llvm
  136. #endif // LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
  137. #ifdef __GNUC__
  138. #pragma GCC diagnostic pop
  139. #endif