10#include "llvm/ADT/StringRef.h"
16 llvm::function_ref<
bool(
DIERef ref)> callback) {
17 const size_t count = die_info_array.size();
18 for (
size_t i = 0; i < count; ++i)
19 if (!callback(
DIERef(die_info_array[i])))
26 llvm::function_ref<
bool(
DIERef ref)> callback) {
32 const size_t count = die_info_array.size();
33 for (
size_t i = 0; i < count; ++i) {
34 const dw_tag_t die_tag = die_info_array[i].tag;
35 bool tag_matches = die_tag == 0 || tag == die_tag;
37 if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
38 tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
41 if (!callback(
DIERef(die_info_array[i])))
50 llvm::function_ref<
bool(
DIERef ref)> callback) {
56 const size_t count = die_info_array.size();
57 for (
size_t i = 0; i < count; ++i) {
58 if (qualified_name_hash != die_info_array[i].qualified_name_hash)
60 const dw_tag_t die_tag = die_info_array[i].tag;
61 bool tag_matches = die_tag == 0 || tag == die_tag;
63 if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
64 tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
67 if (!callback(
DIERef(die_info_array[i])))
75 bool return_implementation_only_if_available,
76 llvm::function_ref<
bool(
DIERef ref)> callback) {
77 const size_t count = die_info_array.size();
78 for (
size_t i = 0; i < count; ++i) {
79 const dw_tag_t die_tag = die_info_array[i].tag;
80 if (!(die_tag == 0 || die_tag == DW_TAG_class_type ||
81 die_tag == DW_TAG_structure_type))
83 bool is_implementation =
85 if (is_implementation != return_implementation_only_if_available)
87 if (return_implementation_only_if_available) {
90 callback(
DIERef(die_info_array[i]));
93 if (!callback(
DIERef(die_info_array[i])))
100 uint32_t type_flag_value, llvm::function_ref<
bool(
DIERef ref)> callback) {
101 const size_t count = die_info_array.size();
102 for (
size_t i = 0; i < count; ++i) {
103 if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) {
104 if (!callback(
DIERef(die_info_array[i])))
125 return "qualified-name-hash";
132 : die_offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
135 : die_base_offset(_die_base_offset), atoms() {
142 hash_data_has_fixed_byte_size =
true;
143 min_hash_data_byte_size = 0;
149 return (atom_mask & (1u << atom_type)) != 0;
158 atoms.push_back({type, form});
159 atom_mask |= 1u << type;
161 case DW_FORM_indirect:
162 case DW_FORM_exprloc:
163 case DW_FORM_flag_present:
164 case DW_FORM_ref_sig8:
165 llvm_unreachable(
"Unhandled atom form");
173 case DW_FORM_ref_udata:
174 case DW_FORM_GNU_addr_index:
175 case DW_FORM_GNU_str_index:
176 hash_data_has_fixed_byte_size =
false;
181 case DW_FORM_sec_offset:
182 min_hash_data_byte_size += 1;
186 hash_data_has_fixed_byte_size =
false;
190 min_hash_data_byte_size += 2;
194 hash_data_has_fixed_byte_size =
false;
199 case DW_FORM_ref_addr:
201 min_hash_data_byte_size += 4;
206 min_hash_data_byte_size += 8;
216 die_base_offset = data.
GetU32(&offset);
219 if (atom_count == 0x00060003u) {
221 while (data.
GetU32(&offset)) {
228 for (
uint32_t i = 0; i < atom_count; ++i) {
231 AppendAtom(type, form);
240 return sizeof(die_base_offset) +
sizeof(
uint32_t) +
241 atoms.size() *
sizeof(
Atom);
245 return min_hash_data_byte_size;
249 return hash_data_has_fixed_byte_size;
253 return header_data.GetByteSize();
260 offset = header_data.Read(data, offset);
268 const size_t num_atoms = header_data.atoms.size();
272 for (
size_t i = 0; i < num_atoms; ++i) {
278 switch (header_data.atoms[i].type) {
283 : form_value.
Reference(header_data.die_base_offset);
310 m_data(table_data), m_string_table(string_table), m_name(name) {}
315 return m_string_table.PeekCStr(key);
323 const uint32_t count = m_data.GetU32(&offset);
325 hash_data.resize(count);
326 for (
uint32_t i = 0; i < count; ++i) {
327 if (!m_header.Read(m_data, &offset, hash_data[i]))
339 pair.key = m_data.GetU32(hash_data_offset_ptr);
345 return eResultEndOfHashData;
349 const char *strp_cstr = m_string_table.PeekCStr(pair.key);
350 if (strp_cstr ==
nullptr) {
355 const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
356 const size_t min_total_hash_data_size =
357 count * m_header.header_data.GetMinimumHashDataByteSize();
358 if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
359 min_total_hash_data_size)) {
364 const bool match = name == strp_cstr;
366 if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
370 *hash_data_offset_ptr += min_total_hash_data_size;
375 for (
uint32_t i = 0; i < count; ++i) {
377 if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
380 pair.value.push_back(die_info);
391 return eResultKeyMatch;
396 return eResultKeyMismatch;
408 pair.key = m_data.GetU32(hash_data_offset_ptr);
412 return eResultEndOfHashData;
416 const char *strp_cstr = m_string_table.PeekCStr(pair.key);
417 if (strp_cstr ==
nullptr)
420 const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
421 const size_t min_total_hash_data_size =
422 count * m_header.header_data.GetMinimumHashDataByteSize();
423 if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
424 min_total_hash_data_size)) {
425 const bool match = regex.
Execute(llvm::StringRef(strp_cstr));
427 if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
431 *hash_data_offset_ptr += min_total_hash_data_size;
436 for (
uint32_t i = 0; i < count; ++i) {
438 if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
441 pair.value.push_back(die_info);
452 return eResultKeyMatch;
457 return eResultKeyMismatch;
468 const uint32_t hash_count = m_header.hashes_count;
470 for (
uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) {
475 AppendHashDataForRegularExpression(regex, &hash_data_offset, pair);
476 if (prev_hash_data_offset == hash_data_offset)
480 switch (hash_result) {
481 case eResultKeyMatch:
482 case eResultKeyMismatch:
486 case eResultEndOfHashData:
493 die_info_array.swap(pair.value);
499 const uint32_t hash_count = m_header.hashes_count;
500 for (
uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) {
503 while (!done && hash_data_offset !=
UINT32_MAX) {
504 KeyType key = m_data.GetU32(&hash_data_offset);
510 const uint32_t count = m_data.GetU32(&hash_data_offset);
511 for (
uint32_t i = 0; i < count; ++i) {
513 if (m_header.Read(m_data, &hash_data_offset, die_info)) {
516 if (die_offset_start <= die_info.
die_offset &&
518 die_info_array.push_back(die_info);
526 llvm::StringRef name, llvm::function_ref<
bool(
DIERef ref)> callback) {
531 FindByName(name, die_info_array);
536 llvm::StringRef name,
const dw_tag_t tag,
537 llvm::function_ref<
bool(
DIERef ref)> callback) {
539 FindByName(name, die_info_array);
544 llvm::StringRef name,
const dw_tag_t tag,
546 llvm::function_ref<
bool(
DIERef ref)> callback) {
548 FindByName(name, die_info_array);
554 llvm::StringRef name, llvm::function_ref<
bool(
DIERef ref)> callback,
555 bool must_be_implementation) {
557 FindByName(name, die_info_array);
558 if (must_be_implementation &&
570 bool found_implementation =
false;
572 die_info_array,
true ,
574 found_implementation =
true;
576 return callback(ref);
578 if (found_implementation)
581 die_info_array,
false ,
591 if (Find(name, kv_pair))
592 die_info_array.swap(kv_pair.value);
Identifies a DWARF debug info entry within a given Module.
A class for reading and using a saved hash table from a block of data in memory.
void FindCompleteObjCClassByName(llvm::StringRef name, llvm::function_ref< bool(DIERef ref)> callback, bool must_be_implementation)
Result AppendHashDataForRegularExpression(const lldb_private::RegularExpression ®ex, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const
Result GetHashDataForName(llvm::StringRef name, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const override
MemoryTable(lldb_private::DWARFDataExtractor &table_data, const lldb_private::DWARFDataExtractor &string_table, const char *name)
void FindByNameAndTagAndQualifiedNameHash(llvm::StringRef name, const dw_tag_t tag, const uint32_t qualified_name_hash, llvm::function_ref< bool(DIERef ref)> callback)
bool ReadHashData(uint32_t hash_data_offset, HashData &hash_data) const override
void AppendAllDIEsInRange(const uint32_t die_offset_start, const uint32_t die_offset_end, DIEInfoArray &die_info_array) const
void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, llvm::function_ref< bool(DIERef ref)> callback)
bool FindByName(llvm::StringRef name, llvm::function_ref< bool(DIERef ref)> callback)
const char * GetStringForKeyType(KeyType key) const override
void AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, DIEInfoArray &die_info_array) const
lldb::offset_t Read(const lldb_private::DataExtractor &data, lldb::offset_t offset)
size_t GetMinimumHashDataByteSize() const
bool HashDataHasFixedByteSize() const
Prologue(dw_offset_t _die_base_offset=0)
void AppendAtom(AtomType type, dw_form_t form)
size_t GetByteSize() const
bool ContainsAtom(AtomType atom_type) const
static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, uint32_t type_flag_mask, uint32_t type_flag_value, llvm::function_ref< bool(DIERef ref)> callback)
static const char * GetAtomTypeName(uint16_t atom)
static void ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, bool return_implementation_only_if_available, llvm::function_ref< bool(DIERef ref)> callback)
@ eTypeFlagClassIsImplementation
Always set for C++, only set for ObjC if this is the @implementation for class.
@ eAtomTypeQualNameHash
A 32 bit hash of the full qualified name (since all hash entries are basename only) For example a typ...
@ eAtomTypeCUOffset
DIE offset of the compiler unit header that contains the item in question.
@ eAtomTypeDIEOffset
DIE offset, check form for encoding.
@ eAtomTypeTag
DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2.
std::vector< DIEInfo > DIEInfoArray
static bool ExtractDIEArray(const DIEInfoArray &die_info_array, llvm::function_ref< bool(DIERef ref)> callback)
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
#define DW_INVALID_OFFSET
llvm::dwarf::Tag dw_tag_t
uint32_t type_flags
Any flags for this DIEInfo.
uint32_t qualified_name_hash
A 32 bit hash of the fully qualified name.