[lldb] Use LLVM's implementation of AppleTables for apple_objc
authorFelipe de Azevedo Piovezan <fpiovezan@apple.com>
Mon, 26 Jun 2023 14:14:25 +0000 (10:14 -0400)
committerFelipe de Azevedo Piovezan <fpiovezan@apple.com>
Wed, 28 Jun 2023 14:05:36 +0000 (10:05 -0400)
This concludes the migration of accelerator tables from LLDB code to LLVM code.

Differential Revision: https://reviews.llvm.org/D153868

lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp [deleted file]
lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h [deleted file]

index 0cd8b3d..34fb98b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/Function.h"
+#include "llvm/Support/DJB.h"
 
 using namespace lldb_private;
 using namespace lldb;
@@ -35,10 +36,8 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
   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");
-  if (!apple_objc_table_up->IsValid())
-    apple_objc_table_up.reset();
+  auto apple_objc_table_up = std::make_unique<llvm::AppleAcceleratorTable>(
+      apple_objc.GetAsLLVMDWARF(), llvm_debug_str);
 
   auto extract_and_check = [](auto &TablePtr) {
     if (auto E = TablePtr->extract()) {
@@ -50,6 +49,7 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
   extract_and_check(apple_names_table_up);
   extract_and_check(apple_namespaces_table_up);
   extract_and_check(apple_types_table_up);
+  extract_and_check(apple_objc_table_up);
 
   if (apple_names_table_up || apple_namespaces_table_up ||
       apple_types_table_up || apple_objc_table_up)
@@ -172,9 +172,7 @@ void AppleDWARFIndex::GetObjCMethods(
     ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
   if (!m_apple_objc_up)
     return;
-  m_apple_objc_up->FindByName(
-      class_name.GetStringRef(),
-      DIERefCallback(callback, class_name.GetStringRef()));
+  SearchFor(*m_apple_objc_up, class_name, callback);
 }
 
 void AppleDWARFIndex::GetCompleteObjCClass(
index 5ff88cd..6b948e0 100644 (file)
@@ -10,7 +10,6 @@
 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H
 
 #include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
-#include "Plugins/SymbolFile/DWARF/HashedNameToDIE.h"
 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
 
 namespace lldb_private {
@@ -25,7 +24,7 @@ public:
                   std::unique_ptr<llvm::AppleAcceleratorTable> apple_names,
                   std::unique_ptr<llvm::AppleAcceleratorTable> apple_namespaces,
                   std::unique_ptr<llvm::AppleAcceleratorTable> apple_types,
-                  std::unique_ptr<DWARFMappedHash::MemoryTable> apple_objc)
+                  std::unique_ptr<llvm::AppleAcceleratorTable> apple_objc)
       : DWARFIndex(module), m_apple_names_up(std::move(apple_names)),
         m_apple_namespaces_up(std::move(apple_namespaces)),
         m_apple_types_up(std::move(apple_types)),
@@ -66,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<llvm::AppleAcceleratorTable> m_apple_types_up;
-  std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_up;
+  std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_objc_up;
 
   /// Search for entries whose name is `name` in `table`, calling `callback` for
   /// each match. If `search_for_tag` is provided, ignore entries whose tag is
index 5eb2df9..dad2060 100644 (file)
@@ -31,7 +31,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
   DWARFIndex.cpp
   DWARFTypeUnit.cpp
   DWARFUnit.cpp
-  HashedNameToDIE.cpp
   LogChannelDWARF.cpp
   ManualDWARFIndex.cpp
   NameToDIE.cpp
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
deleted file mode 100644 (file)
index 19d2432..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-//===-- HashedNameToDIE.cpp -----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "HashedNameToDIE.h"
-#include "llvm/ADT/StringRef.h"
-
-#include "lldb/Core/Mangled.h"
-
-using namespace lldb_private::dwarf;
-
-bool DWARFMappedHash::ExtractDIEArray(
-    const DIEInfoArray &die_info_array,
-    llvm::function_ref<bool(DIERef ref)> callback) {
-  const size_t count = die_info_array.size();
-  for (size_t i = 0; i < count; ++i)
-    if (!callback(DIERef(die_info_array[i])))
-      return false;
-  return true;
-}
-
-const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) {
-  switch (atom) {
-  case eAtomTypeNULL:
-    return "NULL";
-  case eAtomTypeDIEOffset:
-    return "die-offset";
-  case eAtomTypeCUOffset:
-    return "cu-offset";
-  case eAtomTypeTag:
-    return "die-tag";
-  case eAtomTypeNameFlags:
-    return "name-flags";
-  case eAtomTypeTypeFlags:
-    return "type-flags";
-  case eAtomTypeQualNameHash:
-    return "qualified-name-hash";
-  }
-  return "<invalid>";
-}
-
-DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f,
-                                  uint32_t h)
-    : die_offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
-
-DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
-    : die_base_offset(_die_base_offset), atoms() {
-  // Define an array of DIE offsets by first defining an array, and then define
-  // the atom type for the array, in this case we have an array of DIE offsets.
-  AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
-}
-
-void DWARFMappedHash::Prologue::ClearAtoms() {
-  hash_data_has_fixed_byte_size = true;
-  min_hash_data_byte_size = 0;
-  atom_mask = 0;
-  atoms.clear();
-}
-
-bool DWARFMappedHash::Prologue::ContainsAtom(AtomType atom_type) const {
-  return (atom_mask & (1u << atom_type)) != 0;
-}
-
-void DWARFMappedHash::Prologue::Clear() {
-  die_base_offset = 0;
-  ClearAtoms();
-}
-
-void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) {
-  atoms.push_back({type, form});
-  atom_mask |= 1u << type;
-  switch (form) {
-  default:
-  case DW_FORM_indirect:
-  case DW_FORM_exprloc:
-  case DW_FORM_flag_present:
-  case DW_FORM_ref_sig8:
-    llvm_unreachable("Unhandled atom form");
-
-  case DW_FORM_addrx:
-  case DW_FORM_string:
-  case DW_FORM_block:
-  case DW_FORM_block1:
-  case DW_FORM_sdata:
-  case DW_FORM_udata:
-  case DW_FORM_ref_udata:
-  case DW_FORM_GNU_addr_index:
-  case DW_FORM_GNU_str_index:
-    hash_data_has_fixed_byte_size = false;
-    [[fallthrough]];
-  case DW_FORM_flag:
-  case DW_FORM_data1:
-  case DW_FORM_ref1:
-  case DW_FORM_sec_offset:
-    min_hash_data_byte_size += 1;
-    break;
-
-  case DW_FORM_block2:
-    hash_data_has_fixed_byte_size = false;
-    [[fallthrough]];
-  case DW_FORM_data2:
-  case DW_FORM_ref2:
-    min_hash_data_byte_size += 2;
-    break;
-
-  case DW_FORM_block4:
-    hash_data_has_fixed_byte_size = false;
-    [[fallthrough]];
-  case DW_FORM_data4:
-  case DW_FORM_ref4:
-  case DW_FORM_addr:
-  case DW_FORM_ref_addr:
-  case DW_FORM_strp:
-    min_hash_data_byte_size += 4;
-    break;
-
-  case DW_FORM_data8:
-  case DW_FORM_ref8:
-    min_hash_data_byte_size += 8;
-    break;
-  }
-}
-
-lldb::offset_t
-DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
-                                lldb::offset_t offset) {
-  ClearAtoms();
-
-  die_base_offset = data.GetU32(&offset);
-
-  const uint32_t atom_count = data.GetU32(&offset);
-  if (atom_count == 0x00060003u) {
-    // Old format, deal with contents of old pre-release format.
-    while (data.GetU32(&offset)) {
-      /* do nothing */;
-    }
-
-    // Hardcode to the only known value for now.
-    AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
-  } else {
-    for (uint32_t i = 0; i < atom_count; ++i) {
-      AtomType type = (AtomType)data.GetU16(&offset);
-      auto form = static_cast<dw_form_t>(data.GetU16(&offset));
-      AppendAtom(type, form);
-    }
-  }
-  return offset;
-}
-
-size_t DWARFMappedHash::Prologue::GetByteSize() const {
-  // Add an extra count to the atoms size for the zero termination Atom that
-  // gets written to disk.
-  return sizeof(die_base_offset) + sizeof(uint32_t) +
-         atoms.size() * sizeof(Atom);
-}
-
-size_t DWARFMappedHash::Prologue::GetMinimumHashDataByteSize() const {
-  return min_hash_data_byte_size;
-}
-
-bool DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const {
-  return hash_data_has_fixed_byte_size;
-}
-
-size_t DWARFMappedHash::Header::GetByteSize(const HeaderData &header_data) {
-  return header_data.GetByteSize();
-}
-
-lldb::offset_t DWARFMappedHash::Header::Read(lldb_private::DataExtractor &data,
-                                             lldb::offset_t offset) {
-  offset = MappedHash::Header<Prologue>::Read(data, offset);
-  if (offset != UINT32_MAX) {
-    offset = header_data.Read(data, offset);
-  }
-  return offset;
-}
-
-bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
-                                   lldb::offset_t *offset_ptr,
-                                   DIEInfo &hash_data) const {
-  const size_t num_atoms = header_data.atoms.size();
-  if (num_atoms == 0)
-    return false;
-
-  for (size_t i = 0; i < num_atoms; ++i) {
-    DWARFFormValue form_value(nullptr, header_data.atoms[i].form);
-
-    if (!form_value.ExtractValue(data, offset_ptr))
-      return false;
-
-    switch (header_data.atoms[i].type) {
-    case eAtomTypeDIEOffset: // DIE offset, check form for encoding
-      hash_data.die_offset =
-          DWARFFormValue::IsDataForm(form_value.Form())
-              ? form_value.Unsigned()
-              : form_value.Reference(header_data.die_base_offset);
-      break;
-
-    case eAtomTypeTag: // DW_TAG value for the DIE
-      hash_data.tag = (dw_tag_t)form_value.Unsigned();
-      break;
-
-    case eAtomTypeTypeFlags: // Flags from enum TypeFlags
-      hash_data.type_flags = (uint32_t)form_value.Unsigned();
-      break;
-
-    case eAtomTypeQualNameHash: // Flags from enum TypeFlags
-      hash_data.qualified_name_hash = form_value.Unsigned();
-      break;
-
-    default:
-      // We can always skip atoms we don't know about.
-      break;
-    }
-  }
-  return hash_data.die_offset != DW_INVALID_OFFSET;
-}
-
-DWARFMappedHash::MemoryTable::MemoryTable(
-    lldb_private::DWARFDataExtractor &table_data,
-    const lldb_private::DWARFDataExtractor &string_table, const char *name)
-    : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(table_data),
-      m_data(table_data), m_string_table(string_table), m_name(name) {}
-
-const char *
-DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const {
-  // The key in the DWARF table is the .debug_str offset for the string
-  return m_string_table.PeekCStr(key);
-}
-
-bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset,
-                                                HashData &hash_data) const {
-  lldb::offset_t offset = hash_data_offset;
-  // Skip string table offset that contains offset of hash name in .debug_str.
-  offset += 4;
-  const uint32_t count = m_data.GetU32(&offset);
-  if (count > 0) {
-    hash_data.resize(count);
-    for (uint32_t i = 0; i < count; ++i) {
-      if (!m_header.Read(m_data, &offset, hash_data[i]))
-        return false;
-    }
-  } else
-    hash_data.clear();
-  return true;
-}
-
-DWARFMappedHash::MemoryTable::Result
-DWARFMappedHash::MemoryTable::GetHashDataForName(
-    llvm::StringRef name, lldb::offset_t *hash_data_offset_ptr,
-    Pair &pair) const {
-  pair.key = m_data.GetU32(hash_data_offset_ptr);
-  pair.value.clear();
-
-  // If the key is zero, this terminates our chain of HashData objects for this
-  // hash value.
-  if (pair.key == 0)
-    return eResultEndOfHashData;
-
-  // There definitely should be a string for this string offset, if there
-  // isn't, there is something wrong, return and error.
-  const char *strp_cstr = m_string_table.PeekCStr(pair.key);
-  if (strp_cstr == nullptr) {
-    *hash_data_offset_ptr = UINT32_MAX;
-    return eResultError;
-  }
-
-  const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
-  const size_t min_total_hash_data_size =
-      count * m_header.header_data.GetMinimumHashDataByteSize();
-  if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
-                                                   min_total_hash_data_size)) {
-    // We have at least one HashData entry, and we have enough data to parse at
-    // least "count" HashData entries.
-
-    // First make sure the entire C string matches...
-    const bool match = name == strp_cstr;
-
-    if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
-      // If the string doesn't match and we have fixed size data, we can just
-      // add the total byte size of all HashData objects to the hash data
-      // offset and be done...
-      *hash_data_offset_ptr += min_total_hash_data_size;
-    } else {
-      // If the string does match, or we don't have fixed size data then we
-      // need to read the hash data as a stream. If the string matches we also
-      // append all HashData objects to the value array.
-      for (uint32_t i = 0; i < count; ++i) {
-        DIEInfo die_info;
-        if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
-          // Only happened if the HashData of the string matched...
-          if (match)
-            pair.value.push_back(die_info);
-        } else {
-          // Something went wrong while reading the data.
-          *hash_data_offset_ptr = UINT32_MAX;
-          return eResultError;
-        }
-      }
-    }
-    // Return the correct response depending on if the string matched or not...
-    if (match) {
-      // The key (cstring) matches and we have lookup results!
-      return eResultKeyMatch;
-    } else {
-      // The key doesn't match, this function will get called again for the
-      // next key/value or the key terminator which in our case is a zero
-      // .debug_str offset.
-      return eResultKeyMismatch;
-    }
-  } else {
-    *hash_data_offset_ptr = UINT32_MAX;
-    return eResultError;
-  }
-}
-
-bool DWARFMappedHash::MemoryTable::FindByName(
-    llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback) {
-  if (name.empty())
-    return true;
-
-  DIEInfoArray die_info_array;
-  FindByName(name, die_info_array);
-  return DWARFMappedHash::ExtractDIEArray(die_info_array, callback);
-}
-
-void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
-                                              DIEInfoArray &die_info_array) {
-  if (name.empty())
-    return;
-
-  Pair kv_pair;
-  if (Find(name, kv_pair))
-    die_info_array.swap(kv_pair.value);
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
deleted file mode 100644 (file)
index eb6d4c8..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-//===-- HashedNameToDIE.h ---------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H
-#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H
-
-#include <vector>
-
-#include "lldb/Core/MappedHash.h"
-#include "lldb/Core/dwarf.h"
-#include "lldb/Utility/RegularExpression.h"
-#include "lldb/lldb-defines.h"
-
-#include "DWARFDefines.h"
-#include "DWARFFormValue.h"
-#include "NameToDIE.h"
-
-class DWARFMappedHash {
-public:
-  enum AtomType : uint16_t {
-    eAtomTypeNULL = 0u,
-    /// DIE offset, check form for encoding.
-    eAtomTypeDIEOffset = 1u,
-    /// DIE offset of the compiler unit header that contains the item in
-    /// question.
-    eAtomTypeCUOffset = 2u,
-    /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed
-    /// 255) or DW_FORM_data2.
-    eAtomTypeTag = 3u,
-    // Flags from enum NameFlags.
-    eAtomTypeNameFlags = 4u,
-    // Flags from enum TypeFlags.
-    eAtomTypeTypeFlags = 5u,
-    /// A 32 bit hash of the full qualified name (since all hash entries are
-    /// basename only) For example a type like "std::vector<int>::iterator"
-    /// would have a name of "iterator" and a 32 bit hash for
-    /// "std::vector<int>::iterator" to allow us to not have to pull in debug
-    /// info for a type when we know the fully qualified name.
-    eAtomTypeQualNameHash = 6u
-  };
-
-  /// Bit definitions for the eAtomTypeTypeFlags flags.
-  enum TypeFlags {
-    /// Always set for C++, only set for ObjC if this is the
-    /// @implementation for class.
-    eTypeFlagClassIsImplementation = (1u << 1)
-  };
-
-  struct DIEInfo {
-    dw_offset_t die_offset = DW_INVALID_OFFSET;
-    dw_tag_t tag = llvm::dwarf::DW_TAG_null;
-
-    /// Any flags for this DIEInfo.
-    uint32_t type_flags = 0;
-
-    /// A 32 bit hash of the fully qualified name.
-    uint32_t qualified_name_hash = 0;
-
-    DIEInfo() = default;
-    DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
-
-    explicit operator DIERef() const {
-      return DIERef(std::nullopt, DIERef::Section::DebugInfo, die_offset);
-    }
-  };
-
-  struct Atom {
-    AtomType type;
-    dw_form_t form;
-  };
-
-  typedef std::vector<DIEInfo> DIEInfoArray;
-  typedef std::vector<Atom> AtomArray;
-
-  class Prologue {
-  public:
-    Prologue(dw_offset_t _die_base_offset = 0);
-
-    void ClearAtoms();
-
-    bool ContainsAtom(AtomType atom_type) const;
-
-    void Clear();
-
-    void AppendAtom(AtomType type, dw_form_t form);
-
-    lldb::offset_t Read(const lldb_private::DataExtractor &data,
-                        lldb::offset_t offset);
-
-    size_t GetByteSize() const;
-
-    size_t GetMinimumHashDataByteSize() const;
-
-    bool HashDataHasFixedByteSize() const;
-
-    /// DIE offset base so die offsets in hash_data can be CU relative.
-    dw_offset_t die_base_offset;
-    AtomArray atoms;
-    uint32_t atom_mask = 0;
-    size_t min_hash_data_byte_size = 0;
-    bool hash_data_has_fixed_byte_size = true;
-  };
-
-  class Header : public MappedHash::Header<Prologue> {
-  public:
-    size_t GetByteSize(const HeaderData &header_data) override;
-
-    lldb::offset_t Read(lldb_private::DataExtractor &data,
-                        lldb::offset_t offset) override;
-
-    bool Read(const lldb_private::DWARFDataExtractor &data,
-              lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
-  };
-
-  /// A class for reading and using a saved hash table from a block of data in
-  /// memory.
-  class MemoryTable
-      : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header,
-                                       DIEInfoArray> {
-  public:
-    MemoryTable(lldb_private::DWARFDataExtractor &table_data,
-                const lldb_private::DWARFDataExtractor &string_table,
-                const char *name);
-
-    const char *GetStringForKeyType(KeyType key) const override;
-
-    bool ReadHashData(uint32_t hash_data_offset,
-                      HashData &hash_data) const override;
-
-    bool FindByName(llvm::StringRef name,
-                    llvm::function_ref<bool(DIERef ref)> callback);
-
-  protected:
-    void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
-
-    Result GetHashDataForName(llvm::StringRef name,
-                              lldb::offset_t *hash_data_offset_ptr,
-                              Pair &pair) const override;
-
-    lldb_private::DWARFDataExtractor m_data;
-    lldb_private::DWARFDataExtractor m_string_table;
-    std::string m_name;
-  };
-
-  static bool ExtractDIEArray(const DIEInfoArray &die_info_array,
-                              llvm::function_ref<bool(DIERef ref)> callback);
-
-protected:
-  static const char *GetAtomTypeName(uint16_t atom);
-};
-
-#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H