HashedNameToDIE.h revision 360784
1//===-- HashedNameToDIE.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 SymbolFileDWARF_HashedNameToDIE_h_
10#define SymbolFileDWARF_HashedNameToDIE_h_
11
12#include <vector>
13
14#include "lldb/Core/MappedHash.h"
15#include "lldb/Core/dwarf.h"
16#include "lldb/Utility/RegularExpression.h"
17#include "lldb/lldb-defines.h"
18
19#include "DWARFDefines.h"
20#include "DWARFFormValue.h"
21#include "NameToDIE.h"
22
23class DWARFMappedHash {
24public:
25  enum AtomType : uint16_t {
26    eAtomTypeNULL = 0u,
27    /// DIE offset, check form for encoding.
28    eAtomTypeDIEOffset = 1u,
29    /// DIE offset of the compiler unit header that contains the item in
30    /// question.
31    eAtomTypeCUOffset = 2u,
32    /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed
33    /// 255) or DW_FORM_data2.
34    eAtomTypeTag = 3u,
35    // Flags from enum NameFlags.
36    eAtomTypeNameFlags = 4u,
37    // Flags from enum TypeFlags.
38    eAtomTypeTypeFlags = 5u,
39    /// A 32 bit hash of the full qualified name (since all hash entries are
40    /// basename only) For example a type like "std::vector<int>::iterator"
41    /// would have a name of "iterator" and a 32 bit hash for
42    /// "std::vector<int>::iterator" to allow us to not have to pull in debug
43    /// info for a type when we know the fully qualified name.
44    eAtomTypeQualNameHash = 6u
45  };
46
47  /// Bit definitions for the eAtomTypeTypeFlags flags.
48  enum TypeFlags {
49    /// Always set for C++, only set for ObjC if this is the
50    /// @implementation for class.
51    eTypeFlagClassIsImplementation = (1u << 1)
52  };
53
54  struct DIEInfo {
55    dw_offset_t die_offset = DW_INVALID_OFFSET;
56    dw_tag_t tag = llvm::dwarf::DW_TAG_null;
57
58    /// Any flags for this DIEInfo.
59    uint32_t type_flags = 0;
60
61    /// A 32 bit hash of the fully qualified name.
62    uint32_t qualified_name_hash = 0;
63
64    DIEInfo() = default;
65    DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
66
67    explicit operator DIERef() const {
68      return DIERef(llvm::None, DIERef::Section::DebugInfo, die_offset);
69    }
70  };
71
72  struct Atom {
73    AtomType type;
74    dw_form_t form;
75  };
76
77  typedef std::vector<DIEInfo> DIEInfoArray;
78  typedef std::vector<Atom> AtomArray;
79
80  class Prologue {
81  public:
82    Prologue(dw_offset_t _die_base_offset = 0);
83
84    void ClearAtoms();
85
86    bool ContainsAtom(AtomType atom_type) const;
87
88    void Clear();
89
90    void AppendAtom(AtomType type, dw_form_t form);
91
92    lldb::offset_t Read(const lldb_private::DataExtractor &data,
93                        lldb::offset_t offset);
94
95    size_t GetByteSize() const;
96
97    size_t GetMinimumHashDataByteSize() const;
98
99    bool HashDataHasFixedByteSize() const;
100
101    /// DIE offset base so die offsets in hash_data can be CU relative.
102    dw_offset_t die_base_offset;
103    AtomArray atoms;
104    uint32_t atom_mask;
105    size_t min_hash_data_byte_size;
106    bool hash_data_has_fixed_byte_size;
107  };
108
109  class Header : public MappedHash::Header<Prologue> {
110  public:
111    size_t GetByteSize(const HeaderData &header_data) override;
112
113    lldb::offset_t Read(lldb_private::DataExtractor &data,
114                        lldb::offset_t offset) override;
115
116    bool Read(const lldb_private::DWARFDataExtractor &data,
117              lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
118  };
119
120  /// A class for reading and using a saved hash table from a block of data in
121  /// memory.
122  class MemoryTable
123      : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header,
124                                       DIEInfoArray> {
125  public:
126    MemoryTable(lldb_private::DWARFDataExtractor &table_data,
127                const lldb_private::DWARFDataExtractor &string_table,
128                const char *name);
129
130    const char *GetStringForKeyType(KeyType key) const override;
131
132    bool ReadHashData(uint32_t hash_data_offset,
133                      HashData &hash_data) const override;
134
135    size_t
136    AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression &regex,
137                                   DIEInfoArray &die_info_array) const;
138
139    size_t AppendAllDIEsInRange(const uint32_t die_offset_start,
140                                const uint32_t die_offset_end,
141                                DIEInfoArray &die_info_array) const;
142
143    size_t FindByName(llvm::StringRef name, DIEArray &die_offsets);
144
145    size_t FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag,
146                            DIEArray &die_offsets);
147
148    size_t FindByNameAndTagAndQualifiedNameHash(
149        llvm::StringRef name, const dw_tag_t tag,
150        const uint32_t qualified_name_hash, DIEArray &die_offsets);
151
152    size_t FindCompleteObjCClassByName(llvm::StringRef name,
153                                       DIEArray &die_offsets,
154                                       bool must_be_implementation);
155
156  protected:
157    Result AppendHashDataForRegularExpression(
158        const lldb_private::RegularExpression &regex,
159        lldb::offset_t *hash_data_offset_ptr, Pair &pair) const;
160
161    size_t FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
162
163    Result GetHashDataForName(llvm::StringRef name,
164                              lldb::offset_t *hash_data_offset_ptr,
165                              Pair &pair) const override;
166
167    lldb_private::DWARFDataExtractor m_data;
168    lldb_private::DWARFDataExtractor m_string_table;
169    std::string m_name;
170  };
171
172  static void ExtractDIEArray(const DIEInfoArray &die_info_array,
173                              DIEArray &die_offsets);
174
175protected:
176  static void ExtractDIEArray(const DIEInfoArray &die_info_array,
177                              const dw_tag_t tag, DIEArray &die_offsets);
178
179  static void ExtractDIEArray(const DIEInfoArray &die_info_array,
180                              const dw_tag_t tag,
181                              const uint32_t qualified_name_hash,
182                              DIEArray &die_offsets);
183
184  static void
185  ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array,
186                               bool return_implementation_only_if_available,
187                               DIEArray &die_offsets);
188
189  static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array,
190                                       uint32_t type_flag_mask,
191                                       uint32_t type_flag_value,
192                                       DIEArray &die_offsets);
193
194  static const char *GetAtomTypeName(uint16_t atom);
195};
196
197#endif // SymbolFileDWARF_HashedNameToDIE_h_
198