blob: d95cf501face8e430dd8df77cbc634323bed86a5 [file] [log] [blame]
//===-- ManualDWARFIndex.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_MANUALDWARFINDEX_H
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
#include "llvm/ADT/DenseSet.h"
class DWARFDebugInfo;
class SymbolFileDWARFDwo;
namespace lldb_private {
class ManualDWARFIndex : public DWARFIndex {
public:
ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf,
llvm::DenseSet<dw_offset_t> units_to_avoid = {})
: DWARFIndex(module), m_dwarf(&dwarf),
m_units_to_avoid(std::move(units_to_avoid)) {}
void Preload() override { Index(); }
void
GetGlobalVariables(ConstString basename,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void
GetGlobalVariables(const RegularExpression &regex,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void
GetGlobalVariables(DWARFUnit &unit,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetObjCMethods(ConstString class_name,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetCompleteObjCClass(
ConstString class_name, bool must_be_implementation,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetTypes(ConstString name,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetTypes(const DWARFDeclContext &context,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetNamespaces(ConstString name,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetFunctions(const Module::LookupInfo &lookup_info,
SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetFunctions(const RegularExpression &regex,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void Dump(Stream &s) override;
// Make IndexSet public so we can unit test the encoding and decoding logic.
struct IndexSet {
NameToDIE function_basenames;
NameToDIE function_fullnames;
NameToDIE function_methods;
NameToDIE function_selectors;
NameToDIE objc_class_selectors;
NameToDIE globals;
NameToDIE types;
NameToDIE namespaces;
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
void Encode(DataEncoder &encoder) const;
bool operator==(const IndexSet &rhs) const {
return function_basenames == rhs.function_basenames &&
function_fullnames == rhs.function_fullnames &&
function_methods == rhs.function_methods &&
function_selectors == rhs.function_selectors &&
objc_class_selectors == rhs.objc_class_selectors &&
globals == rhs.globals && types == rhs.types &&
namespaces == rhs.namespaces;
}
};
private:
void Index();
/// Decode a serialized version of this object from data.
///
/// \param data
/// The decoder object that references the serialized data.
///
/// \param offset_ptr
/// A pointer that contains the offset from which the data will be decoded
/// from that gets updated as data gets decoded.
///
/// \param strtab
/// All strings in cache files are put into string tables for efficiency
/// and cache file size reduction. Strings are stored as uint32_t string
/// table offsets in the cache data.
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
bool &signature_mismatch);
/// Encode this object into a data encoder object.
///
/// This allows this object to be serialized to disk.
///
/// \param encoder
/// A data encoder object that serialized bytes will be encoded into.
///
/// \param strtab
/// All strings in cache files are put into string tables for efficiency
/// and cache file size reduction. Strings are stored as uint32_t string
/// table offsets in the cache data.
///
/// \return
/// True if the symbol table's object file can generate a valid signature
/// and all data for the symbol table was encoded, false otherwise.
bool Encode(DataEncoder &encoder) const;
/// Get the cache key string for this symbol table.
///
/// The cache key must start with the module's cache key and is followed
/// by information that indicates this key is for caching the symbol table
/// contents and should also include the has of the object file. A module can
/// be represented by an ObjectFile object for the main executable, but can
/// also have a symbol file that is from the same or a different object file.
/// This means we might have two symbol tables cached in the index cache, one
/// for the main executable and one for the symbol file.
///
/// \return
/// The unique cache key used to save and retrieve data from the index
/// cache.
std::string GetCacheKey();
/// Save the symbol table data out into a cache.
///
/// The symbol table will only be saved to a cache file if caching is enabled.
///
/// We cache the contents of the symbol table since symbol tables in LLDB take
/// some time to initialize. This is due to the many sources for data that are
/// used to create a symbol table:
/// - standard symbol table
/// - dynamic symbol table (ELF)
/// - compressed debug info sections
/// - unwind information
/// - function pointers found in runtimes for global constructor/destructors
/// - other sources.
/// All of the above sources are combined and one symbol table results after
/// all sources have been considered.
void SaveToCache();
/// Load the symbol table from the index cache.
///
/// Quickly load the finalized symbol table from the index cache. This saves
/// time when the debugger starts up. The index cache file for the symbol
/// table has the modification time set to the same time as the main module.
/// If the cache file exists and the modification times match, we will load
/// the symbol table from the serlized cache file.
///
/// \return
/// True if the symbol table was successfully loaded from the index cache,
/// false if the symbol table wasn't cached or was out of date.
bool LoadFromCache();
void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set);
static void IndexUnitImpl(DWARFUnit &unit,
const lldb::LanguageType cu_language,
IndexSet &set);
/// The DWARF file which we are indexing.
SymbolFileDWARF *m_dwarf;
/// Which dwarf units should we skip while building the index.
llvm::DenseSet<dw_offset_t> m_units_to_avoid;
IndexSet m_set;
bool m_indexed = false;
};
} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H