Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:42

0001 //===- DWARFUnitIndex.h -----------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
0010 #define LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
0011 
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/ADT/StringRef.h"
0014 #include <cstdint>
0015 #include <memory>
0016 
0017 namespace llvm {
0018 
0019 class raw_ostream;
0020 class DataExtractor;
0021 
0022 /// The enum of section identifiers to be used in internal interfaces.
0023 ///
0024 /// Pre-standard implementation of package files defined a number of section
0025 /// identifiers with values that clash definitions in the DWARFv5 standard.
0026 /// See https://gcc.gnu.org/wiki/DebugFissionDWP and Section 7.3.5.3 in DWARFv5.
0027 ///
0028 /// The following identifiers are the same in the proposal and in DWARFv5:
0029 /// - DW_SECT_INFO         = 1 (.debug_info.dwo)
0030 /// - DW_SECT_ABBREV       = 3 (.debug_abbrev.dwo)
0031 /// - DW_SECT_LINE         = 4 (.debug_line.dwo)
0032 /// - DW_SECT_STR_OFFSETS  = 6 (.debug_str_offsets.dwo)
0033 ///
0034 /// The following identifiers are defined only in DWARFv5:
0035 /// - DW_SECT_LOCLISTS     = 5 (.debug_loclists.dwo)
0036 /// - DW_SECT_RNGLISTS     = 8 (.debug_rnglists.dwo)
0037 ///
0038 /// The following identifiers are defined only in the GNU proposal:
0039 /// - DW_SECT_TYPES        = 2 (.debug_types.dwo)
0040 /// - DW_SECT_LOC          = 5 (.debug_loc.dwo)
0041 /// - DW_SECT_MACINFO      = 7 (.debug_macinfo.dwo)
0042 ///
0043 /// DW_SECT_MACRO for the .debug_macro.dwo section is defined in both standards,
0044 /// but with different values, 8 in GNU and 7 in DWARFv5.
0045 ///
0046 /// This enum defines constants to represent the identifiers of both sets.
0047 /// For DWARFv5 ones, the values are the same as defined in the standard.
0048 /// For pre-standard ones that correspond to sections being deprecated in
0049 /// DWARFv5, the values are chosen arbitrary and a tag "_EXT_" is added to
0050 /// the names.
0051 ///
0052 /// The enum is for internal use only. The user should not expect the values
0053 /// to correspond to any input/output constants. Special conversion functions,
0054 /// serializeSectionKind() and deserializeSectionKind(), should be used for
0055 /// the translation.
0056 enum DWARFSectionKind {
0057   /// Denotes a value read from an index section that does not correspond
0058   /// to any of the supported standards.
0059   DW_SECT_EXT_unknown = 0,
0060 #define HANDLE_DW_SECT(ID, NAME) DW_SECT_##NAME = ID,
0061 #include "llvm/BinaryFormat/Dwarf.def"
0062   DW_SECT_EXT_TYPES = 2,
0063   DW_SECT_EXT_LOC = 9,
0064   DW_SECT_EXT_MACINFO = 10,
0065 };
0066 
0067 inline const char *toString(DWARFSectionKind Kind) {
0068   switch (Kind) {
0069   case DW_SECT_EXT_unknown:
0070     return "Unknown DW_SECT value 0";
0071 #define STRINGIZE(X) #X
0072 #define HANDLE_DW_SECT(ID, NAME)                                               \
0073   case DW_SECT_##NAME:                                                         \
0074     return "DW_SECT_" STRINGIZE(NAME);
0075 #include "llvm/BinaryFormat/Dwarf.def"
0076   case DW_SECT_EXT_TYPES:
0077     return "DW_SECT_TYPES";
0078   case DW_SECT_EXT_LOC:
0079     return "DW_SECT_LOC";
0080   case DW_SECT_EXT_MACINFO:
0081     return "DW_SECT_MACINFO";
0082   }
0083   llvm_unreachable("unknown DWARFSectionKind");
0084 }
0085 
0086 /// Convert the internal value for a section kind to an on-disk value.
0087 ///
0088 /// The conversion depends on the version of the index section.
0089 /// IndexVersion is expected to be either 2 for pre-standard GNU proposal
0090 /// or 5 for DWARFv5 package file.
0091 uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion);
0092 
0093 /// Convert a value read from an index section to the internal representation.
0094 ///
0095 /// The conversion depends on the index section version, which is expected
0096 /// to be either 2 for pre-standard GNU proposal or 5 for DWARFv5 package file.
0097 DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion);
0098 
0099 class DWARFUnitIndex {
0100   struct Header {
0101     uint32_t Version;
0102     uint32_t NumColumns;
0103     uint32_t NumUnits;
0104     uint32_t NumBuckets = 0;
0105 
0106     bool parse(DataExtractor IndexData, uint64_t *OffsetPtr);
0107     void dump(raw_ostream &OS) const;
0108   };
0109 
0110 public:
0111   class Entry {
0112   public:
0113     class SectionContribution {
0114     private:
0115       uint64_t Offset;
0116       uint64_t Length;
0117 
0118     public:
0119       SectionContribution() : Offset(0), Length(0) {}
0120       SectionContribution(uint64_t Offset, uint64_t Length)
0121           : Offset(Offset), Length(Length) {}
0122 
0123       void setOffset(uint64_t Value) { Offset = Value; }
0124       void setLength(uint64_t Value) { Length = Value; }
0125       uint64_t getOffset() const { return Offset; }
0126       uint64_t getLength() const { return Length; }
0127       uint32_t getOffset32() const { return (uint32_t)Offset; }
0128       uint32_t getLength32() const { return (uint32_t)Length; }
0129     };
0130 
0131   private:
0132     const DWARFUnitIndex *Index;
0133     uint64_t Signature;
0134     std::unique_ptr<SectionContribution[]> Contributions;
0135     friend class DWARFUnitIndex;
0136 
0137   public:
0138     const SectionContribution *getContribution(DWARFSectionKind Sec) const;
0139     const SectionContribution *getContribution() const;
0140     SectionContribution &getContribution();
0141 
0142     const SectionContribution *getContributions() const {
0143       return Contributions.get();
0144     }
0145 
0146     uint64_t getSignature() const { return Signature; }
0147     bool isValid() { return Index; }
0148   };
0149 
0150 private:
0151   struct Header Header;
0152 
0153   DWARFSectionKind InfoColumnKind;
0154   int InfoColumn = -1;
0155   std::unique_ptr<DWARFSectionKind[]> ColumnKinds;
0156   // This is a parallel array of section identifiers as they read from the input
0157   // file. The mapping from raw values to DWARFSectionKind is not revertable in
0158   // case of unknown identifiers, so we keep them here.
0159   std::unique_ptr<uint32_t[]> RawSectionIds;
0160   std::unique_ptr<Entry[]> Rows;
0161   mutable std::vector<Entry *> OffsetLookup;
0162 
0163   static StringRef getColumnHeader(DWARFSectionKind DS);
0164 
0165   bool parseImpl(DataExtractor IndexData);
0166 
0167 public:
0168   DWARFUnitIndex(DWARFSectionKind InfoColumnKind)
0169       : InfoColumnKind(InfoColumnKind) {}
0170 
0171   explicit operator bool() const { return Header.NumBuckets; }
0172 
0173   bool parse(DataExtractor IndexData);
0174   void dump(raw_ostream &OS) const;
0175 
0176   uint32_t getVersion() const { return Header.Version; }
0177 
0178   const Entry *getFromOffset(uint64_t Offset) const;
0179   const Entry *getFromHash(uint64_t Offset) const;
0180 
0181   ArrayRef<DWARFSectionKind> getColumnKinds() const {
0182     return ArrayRef(ColumnKinds.get(), Header.NumColumns);
0183   }
0184 
0185   ArrayRef<Entry> getRows() const {
0186     return ArrayRef(Rows.get(), Header.NumBuckets);
0187   }
0188 
0189   MutableArrayRef<Entry> getMutableRows() {
0190     return MutableArrayRef(Rows.get(), Header.NumBuckets);
0191   }
0192 };
0193 
0194 } // end namespace llvm
0195 
0196 #endif // LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H