fdeazeve updated this revision to Diff 535162.
fdeazeve added a comment.
rebase
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D153867/new/
https://reviews.llvm.org/D153867
Files:
lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
Index: llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
===================================================================
--- llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -314,6 +314,13 @@
/// Return the Atom description, which can be used to interpret the raw values
/// of the Accelerator Entries in this table.
ArrayRef<std::pair<HeaderData::AtomType, HeaderData::Form>> getAtomsDesc();
+
+ /// Returns true iff `AtomTy` is one of the atoms available in Entries of this
+ /// table.
+ bool containsAtomType(HeaderData::AtomType AtomTy) const {
+ return is_contained(make_first_range(HdrData.Atoms), AtomTy);
+ }
+
bool validateForms();
/// Return information related to the DWARF DIE we're looking for when
Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -135,19 +135,6 @@
bool FindByName(llvm::StringRef name,
llvm::function_ref<bool(DIERef ref)> callback);
- void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag,
- llvm::function_ref<bool(DIERef ref)> callback);
-
- void FindByNameAndTagAndQualifiedNameHash(
- llvm::StringRef name, const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- llvm::function_ref<bool(DIERef ref)> callback);
-
- void
- FindCompleteObjCClassByName(llvm::StringRef name,
- llvm::function_ref<bool(DIERef ref)> callback,
- bool must_be_implementation);
-
protected:
void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
@@ -164,25 +151,6 @@
llvm::function_ref<bool(DIERef ref)> callback);
protected:
- static void ExtractDIEArray(const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- llvm::function_ref<bool(DIERef ref)> callback);
-
- static void ExtractDIEArray(const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- llvm::function_ref<bool(DIERef ref)> callback);
-
- static void
- ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array,
- bool return_implementation_only_if_available,
- llvm::function_ref<bool(DIERef ref)> callback);
-
- 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);
};
Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -23,92 +23,6 @@
return true;
}
-void DWARFMappedHash::ExtractDIEArray(
- const DIEInfoArray &die_info_array, const dw_tag_t tag,
- llvm::function_ref<bool(DIERef ref)> callback) {
- if (tag == 0) {
- ExtractDIEArray(die_info_array, callback);
- return;
- }
-
- const size_t count = die_info_array.size();
- for (size_t i = 0; i < count; ++i) {
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches) {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches) {
- if (!callback(DIERef(die_info_array[i])))
- return;
- }
- }
-}
-
-void DWARFMappedHash::ExtractDIEArray(
- const DIEInfoArray &die_info_array, const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- llvm::function_ref<bool(DIERef ref)> callback) {
- if (tag == 0) {
- ExtractDIEArray(die_info_array, callback);
- return;
- }
-
- const size_t count = die_info_array.size();
- for (size_t i = 0; i < count; ++i) {
- if (qualified_name_hash != die_info_array[i].qualified_name_hash)
- continue;
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches) {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches) {
- if (!callback(DIERef(die_info_array[i])))
- return;
- }
- }
-}
-
-void DWARFMappedHash::ExtractClassOrStructDIEArray(
- const DIEInfoArray &die_info_array,
- bool return_implementation_only_if_available,
- llvm::function_ref<bool(DIERef ref)> callback) {
- const size_t count = die_info_array.size();
- for (size_t i = 0; i < count; ++i) {
- const dw_tag_t die_tag = die_info_array[i].tag;
- if (!(die_tag == 0 || die_tag == DW_TAG_class_type ||
- die_tag == DW_TAG_structure_type))
- continue;
- bool is_implementation =
- (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) != 0;
- if (is_implementation != return_implementation_only_if_available)
- continue;
- if (return_implementation_only_if_available) {
- // We found the one true definition for this class, so only return
- // that
- callback(DIERef(die_info_array[i]));
- return;
- }
- if (!callback(DIERef(die_info_array[i])))
- return;
- }
-}
-
-void DWARFMappedHash::ExtractTypesFromDIEArray(
- const DIEInfoArray &die_info_array, uint32_t type_flag_mask,
- uint32_t type_flag_value, llvm::function_ref<bool(DIERef ref)> callback) {
- const size_t count = die_info_array.size();
- for (size_t i = 0; i < count; ++i) {
- if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) {
- if (!callback(DIERef(die_info_array[i])))
- return;
- }
- }
-}
-
const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) {
switch (atom) {
case eAtomTypeNULL:
@@ -414,56 +328,6 @@
return DWARFMappedHash::ExtractDIEArray(die_info_array, callback);
}
-void DWARFMappedHash::MemoryTable::FindByNameAndTag(
- llvm::StringRef name, const dw_tag_t tag,
- llvm::function_ref<bool(DIERef ref)> callback) {
- DIEInfoArray die_info_array;
- FindByName(name, die_info_array);
- DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback);
-}
-
-void DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
- llvm::StringRef name, const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- llvm::function_ref<bool(DIERef ref)> callback) {
- DIEInfoArray die_info_array;
- FindByName(name, die_info_array);
- DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash,
- callback);
-}
-
-void DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
- llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback,
- bool must_be_implementation) {
- DIEInfoArray die_info_array;
- FindByName(name, die_info_array);
- if (must_be_implementation &&
- GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) {
- // If we have two atoms, then we have the DIE offset and the type flags
- // so we can find the objective C class efficiently.
- DWARFMappedHash::ExtractTypesFromDIEArray(
- die_info_array, UINT32_MAX, eTypeFlagClassIsImplementation, callback);
- return;
- }
- // We don't only want the one true definition, so try and see what we can
- // find, and only return class or struct DIEs. If we do have the full
- // implementation, then return it alone, else return all possible
- // matches.
- bool found_implementation = false;
- DWARFMappedHash::ExtractClassOrStructDIEArray(
- die_info_array, true /*return_implementation_only_if_available*/,
- [&](DIERef ref) {
- found_implementation = true;
- // Here the return value does not matter as we are called at most once.
- return callback(ref);
- });
- if (found_implementation)
- return;
- DWARFMappedHash::ExtractClassOrStructDIEArray(
- die_info_array, false /*return_implementation_only_if_available*/,
- callback);
-}
-
void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
DIEInfoArray &die_info_array) {
if (name.empty())
Index: lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
+++ lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
@@ -24,7 +24,7 @@
AppleDWARFIndex(Module &module,
std::unique_ptr<llvm::AppleAcceleratorTable> apple_names,
std::unique_ptr<llvm::AppleAcceleratorTable> apple_namespaces,
- std::unique_ptr<DWARFMappedHash::MemoryTable> apple_types,
+ std::unique_ptr<llvm::AppleAcceleratorTable> apple_types,
std::unique_ptr<DWARFMappedHash::MemoryTable> apple_objc)
: DWARFIndex(module), m_apple_names_up(std::move(apple_names)),
m_apple_namespaces_up(std::move(apple_namespaces)),
@@ -65,7 +65,7 @@
private:
std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_names_up;
std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_namespaces_up;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_up;
+ std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_types_up;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_up;
/// Search for entries whose name is `name` in `table`, calling `callback` for
Index: lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -32,10 +32,8 @@
std::make_unique<llvm::AppleAcceleratorTable>(
apple_namespaces.GetAsLLVMDWARF(), llvm_debug_str);
- auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
- apple_types, debug_str, ".apple_types");
- if (!apple_types_table_up->IsValid())
- apple_types_table_up.reset();
+ auto apple_types_table_up = std::make_unique<llvm::AppleAcceleratorTable>(
+ apple_types.GetAsLLVMDWARF(), llvm_debug_str);
auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_objc, debug_str, ".apple_objc");
@@ -51,6 +49,7 @@
extract_and_check(apple_names_table_up);
extract_and_check(apple_namespaces_table_up);
+ extract_and_check(apple_types_table_up);
if (apple_names_table_up || apple_namespaces_table_up ||
apple_types_table_up || apple_objc_table_up)
@@ -62,16 +61,69 @@
return nullptr;
}
+/// Returns true if `tag` is a class_type of structure_type tag.
+static bool IsClassOrStruct(dw_tag_t tag) {
+ return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;
+}
+
+/// Returns true if `entry` has an extractable DW_ATOM_qual_name_hash and it
+/// matches `expected_hash`.
+static bool
+EntryHasMatchingQualhash(const llvm::AppleAcceleratorTable::Entry &entry,
+ uint32_t expected_hash) {
+ std::optional<llvm::DWARFFormValue> form_value =
+ entry.lookup(dwarf::DW_ATOM_qual_name_hash);
+ if (!form_value)
+ return false;
+ std::optional<uint64_t> hash = form_value->getAsUnsignedConstant();
+ return hash && (*hash == expected_hash);
+}
+
+/// Returns true if `entry` has an extractable DW_ATOM_die_tag and it matches
+/// `expected_tag`. We also consider it a match if the tags are different but
+/// in the set of {TAG_class_type, TAG_struct_type}.
+static bool EntryHasMatchingTag(const llvm::AppleAcceleratorTable::Entry &entry,
+ dw_tag_t expected_tag) {
+ std::optional<llvm::DWARFFormValue> form_value =
+ entry.lookup(dwarf::DW_ATOM_die_tag);
+ if (!form_value)
+ return false;
+ std::optional<uint64_t> maybe_tag = form_value->getAsUnsignedConstant();
+ if (!maybe_tag)
+ return false;
+ auto tag = static_cast<dw_tag_t>(*maybe_tag);
+ return tag == expected_tag ||
+ (IsClassOrStruct(tag) && IsClassOrStruct(expected_tag));
+}
+
+/// Returns true if `entry` has an extractable DW_ATOM_type_flags and the flag
+/// "DW_FLAG_type_implementation" is set.
+static bool
+HasImplementationFlag(const llvm::AppleAcceleratorTable::Entry &entry) {
+ std::optional<llvm::DWARFFormValue> form_value =
+ entry.lookup(dwarf::DW_ATOM_type_flags);
+ if (!form_value)
+ return false;
+ std::optional<uint64_t> Flags = form_value->getAsUnsignedConstant();
+ return Flags &&
+ (*Flags & llvm::dwarf::AcceleratorTable::DW_FLAG_type_implementation);
+}
+
void AppleDWARFIndex::SearchFor(const llvm::AppleAcceleratorTable &table,
llvm::StringRef name,
llvm::function_ref<bool(DWARFDIE die)> callback,
std::optional<dw_tag_t> search_for_tag,
std::optional<uint32_t> search_for_qualhash) {
- assert(!search_for_tag && !search_for_qualhash && "not yet implemented");
auto converted_cb = DIERefCallback(callback, name);
- for (const auto &entry : table.equal_range(name))
+ for (const auto &entry : table.equal_range(name)) {
+ if (search_for_qualhash &&
+ !EntryHasMatchingQualhash(entry, *search_for_qualhash))
+ continue;
+ if (search_for_tag && !EntryHasMatchingTag(entry, *search_for_tag))
+ continue;
if (!converted_cb(entry))
break;
+ }
}
void AppleDWARFIndex::GetGlobalVariables(
@@ -130,18 +182,32 @@
llvm::function_ref<bool(DWARFDIE die)> callback) {
if (!m_apple_types_up)
return;
- m_apple_types_up->FindCompleteObjCClassByName(
- class_name.GetStringRef(),
- DIERefCallback(callback, class_name.GetStringRef()),
- must_be_implementation);
+
+ llvm::SmallVector<DIERef> decl_dies;
+ auto converted_cb = DIERefCallback(callback, class_name);
+
+ for (const auto &entry : m_apple_types_up->equal_range(class_name)) {
+ if (HasImplementationFlag(entry)) {
+ converted_cb(entry);
+ return;
+ }
+
+ decl_dies.emplace_back(std::nullopt, DIERef::Section::DebugInfo,
+ *entry.getDIESectionOffset());
+ }
+
+ if (must_be_implementation)
+ return;
+ for (DIERef ref : decl_dies)
+ if (!converted_cb(ref))
+ return;
}
void AppleDWARFIndex::GetTypes(
ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
if (!m_apple_types_up)
return;
- m_apple_types_up->FindByName(name.GetStringRef(),
- DIERefCallback(callback, name.GetStringRef()));
+ SearchFor(*m_apple_types_up, name, callback);
}
void AppleDWARFIndex::GetTypes(
@@ -151,51 +217,47 @@
return;
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
- const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
- DWARFMappedHash::eAtomTypeTag);
- const bool has_qualified_name_hash =
- m_apple_types_up->GetHeader().header_data.ContainsAtom(
- DWARFMappedHash::eAtomTypeQualNameHash);
-
- const ConstString type_name(context[0].name);
- const dw_tag_t tag = context[0].tag;
- if (has_tag && has_qualified_name_hash) {
- const char *qualified_name = context.GetQualifiedName();
- const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
+ const bool entries_have_tag =
+ m_apple_types_up->containsAtomType(DW_ATOM_die_tag);
+ const bool entries_have_qual_hash =
+ m_apple_types_up->containsAtomType(DW_ATOM_qual_name_hash);
+
+ llvm::StringRef expected_name = context[0].name;
+
+ if (entries_have_tag && entries_have_qual_hash) {
+ const dw_tag_t expected_tag = context[0].tag;
+ const uint32_t expected_qualname_hash =
+ llvm::djbHash(context.GetQualifiedName());
if (log)
m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
- m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
- type_name.GetStringRef(), tag, qualified_name_hash,
- DIERefCallback(callback, type_name.GetStringRef()));
+ SearchFor(*m_apple_types_up, expected_name, callback, expected_tag,
+ expected_qualname_hash);
return;
}
- if (has_tag) {
- // When searching for a scoped type (for example,
- // "std::vector<int>::const_iterator") searching for the innermost
- // name alone ("const_iterator") could yield many false
- // positives. By searching for the parent type ("vector<int>")
- // first we can avoid extracting type DIEs from object files that
- // would fail the filter anyway.
- if (!has_qualified_name_hash && (context.GetSize() > 1) &&
- (context[1].tag == DW_TAG_class_type ||
- context[1].tag == DW_TAG_structure_type)) {
- if (m_apple_types_up->FindByName(context[1].name,
- [&](DIERef ref) { return false; }))
- return;
- }
-
- if (log)
- m_module.LogMessage(log, "FindByNameAndTag()");
- m_apple_types_up->FindByNameAndTag(
- type_name.GetStringRef(), tag,
- DIERefCallback(callback, type_name.GetStringRef()));
+ // Historically, if there are no tags, we also ignore qual_hash (why?)
+ if (!entries_have_tag) {
+ SearchFor(*m_apple_names_up, expected_name, callback);
return;
}
- m_apple_types_up->FindByName(
- type_name.GetStringRef(),
- DIERefCallback(callback, type_name.GetStringRef()));
+ // We have a tag but no qual hash.
+
+ // When searching for a scoped type (for example,
+ // "std::vector<int>::const_iterator") searching for the innermost
+ // name alone ("const_iterator") could yield many false
+ // positives. By searching for the parent type ("vector<int>")
+ // first we can avoid extracting type DIEs from object files that
+ // would fail the filter anyway.
+ if ((context.GetSize() > 1) && IsClassOrStruct(context[1].tag))
+ if (m_apple_types_up->equal_range(context[1].name).empty())
+ return;
+
+ if (log)
+ m_module.LogMessage(log, "FindByNameAndTag()");
+ const dw_tag_t expected_tag = context[0].tag;
+ SearchFor(*m_apple_types_up, expected_name, callback, expected_tag);
+ return;
}
void AppleDWARFIndex::GetNamespaces(
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits