| //===-- ModuleList.h --------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef liblldb_ModuleList_h_ |
| #define liblldb_ModuleList_h_ |
| |
| #include "lldb/Core/Address.h" // for Address |
| #include "lldb/Core/ModuleSpec.h" // for ModuleSpec |
| #include "lldb/Core/UserSettingsController.h" |
| #include "lldb/Utility/FileSpec.h" // for FileSpec |
| #include "lldb/Utility/Iterable.h" |
| #include "lldb/Utility/Status.h" // for Status |
| #include "lldb/lldb-enumerations.h" |
| #include "lldb/lldb-forward.h" |
| #include "lldb/lldb-types.h" |
| |
| #include "llvm/ADT/DenseSet.h" |
| |
| #include <functional> |
| #include <list> |
| #include <mutex> |
| #include <vector> |
| |
| #include <stddef.h> // for size_t |
| #include <stdint.h> // for uint32_t |
| |
| namespace lldb_private { |
| class ConstString; |
| } |
| namespace lldb_private { |
| class FileSpecList; |
| } |
| namespace lldb_private { |
| class Function; |
| } |
| namespace lldb_private { |
| class Log; |
| } |
| namespace lldb_private { |
| class Module; |
| } |
| namespace lldb_private { |
| class RegularExpression; |
| } |
| namespace lldb_private { |
| class Stream; |
| } |
| namespace lldb_private { |
| class SymbolContext; |
| } |
| namespace lldb_private { |
| class SymbolContextList; |
| } |
| namespace lldb_private { |
| class SymbolFile; |
| } |
| namespace lldb_private { |
| class Target; |
| } |
| namespace lldb_private { |
| class TypeList; |
| } |
| namespace lldb_private { |
| class UUID; |
| } |
| namespace lldb_private { |
| class VariableList; |
| } |
| |
| namespace lldb_private { |
| |
| class ModuleListProperties : public Properties { |
| public: |
| ModuleListProperties(); |
| |
| FileSpec GetClangModulesCachePath() const; |
| bool SetClangModulesCachePath(llvm::StringRef path); |
| bool GetEnableExternalLookup() const; |
| }; |
| |
| //---------------------------------------------------------------------- |
| /// @class ModuleList ModuleList.h "lldb/Core/ModuleList.h" |
| /// A collection class for Module objects. |
| /// |
| /// Modules in the module collection class are stored as reference counted |
| /// shared pointers to Module objects. |
| //---------------------------------------------------------------------- |
| class ModuleList { |
| public: |
| class Notifier { |
| public: |
| virtual ~Notifier() = default; |
| |
| virtual void ModuleAdded(const ModuleList &module_list, |
| const lldb::ModuleSP &module_sp) = 0; |
| virtual void ModuleRemoved(const ModuleList &module_list, |
| const lldb::ModuleSP &module_sp) = 0; |
| virtual void ModuleUpdated(const ModuleList &module_list, |
| const lldb::ModuleSP &old_module_sp, |
| const lldb::ModuleSP &new_module_sp) = 0; |
| virtual void WillClearList(const ModuleList &module_list) = 0; |
| }; |
| |
| //------------------------------------------------------------------ |
| /// Default constructor. |
| /// |
| /// Creates an empty list of Module objects. |
| //------------------------------------------------------------------ |
| ModuleList(); |
| |
| //------------------------------------------------------------------ |
| /// Copy Constructor. |
| /// |
| /// Creates a new module list object with a copy of the modules from \a rhs. |
| /// |
| /// @param[in] rhs |
| /// Another module list object. |
| //------------------------------------------------------------------ |
| ModuleList(const ModuleList &rhs); |
| |
| ModuleList(ModuleList::Notifier *notifier); |
| |
| //------------------------------------------------------------------ |
| /// Destructor. |
| //------------------------------------------------------------------ |
| ~ModuleList(); |
| |
| //------------------------------------------------------------------ |
| /// Assignment operator. |
| /// |
| /// Copies the module list from \a rhs into this list. |
| /// |
| /// @param[in] rhs |
| /// Another module list object. |
| /// |
| /// @return |
| /// A const reference to this object. |
| //------------------------------------------------------------------ |
| const ModuleList &operator=(const ModuleList &rhs); |
| |
| //------------------------------------------------------------------ |
| /// Append a module to the module list. |
| /// |
| /// Appends the module to the collection. |
| /// |
| /// @param[in] module_sp |
| /// A shared pointer to a module to add to this collection. |
| //------------------------------------------------------------------ |
| void Append(const lldb::ModuleSP &module_sp); |
| |
| //------------------------------------------------------------------ |
| /// Append a module to the module list and remove any equivalent modules. |
| /// Equivalent modules are ones whose file, platform file and architecture |
| /// matches. |
| /// |
| /// Replaces the module to the collection. |
| /// |
| /// @param[in] module_sp |
| /// A shared pointer to a module to replace in this collection. |
| //------------------------------------------------------------------ |
| void ReplaceEquivalent(const lldb::ModuleSP &module_sp); |
| |
| bool AppendIfNeeded(const lldb::ModuleSP &module_sp); |
| |
| void Append(const ModuleList &module_list); |
| |
| bool AppendIfNeeded(const ModuleList &module_list); |
| |
| bool ReplaceModule(const lldb::ModuleSP &old_module_sp, |
| const lldb::ModuleSP &new_module_sp); |
| |
| //------------------------------------------------------------------ |
| /// Clear the object's state. |
| /// |
| /// Clears the list of modules and releases a reference to each module |
| /// object and if the reference count goes to zero, the module will be |
| /// deleted. |
| //------------------------------------------------------------------ |
| void Clear(); |
| |
| //------------------------------------------------------------------ |
| /// Clear the object's state. |
| /// |
| /// Clears the list of modules and releases a reference to each module |
| /// object and if the reference count goes to zero, the module will be |
| /// deleted. Also release all memory that might be held by any collection |
| /// classes (like std::vector) |
| //------------------------------------------------------------------ |
| void Destroy(); |
| |
| //------------------------------------------------------------------ |
| /// Dump the description of each module contained in this list. |
| /// |
| /// Dump the description of each module contained in this list to the |
| /// supplied stream \a s. |
| /// |
| /// @param[in] s |
| /// The stream to which to dump the object description. |
| /// |
| /// @see Module::Dump(Stream *) const |
| //------------------------------------------------------------------ |
| void Dump(Stream *s) const; |
| |
| void LogUUIDAndPaths(Log *log, const char *prefix_cstr); |
| |
| std::recursive_mutex &GetMutex() const { return m_modules_mutex; } |
| |
| size_t GetIndexForModule(const Module *module) const; |
| |
| //------------------------------------------------------------------ |
| /// Get the module shared pointer for the module at index \a idx. |
| /// |
| /// @param[in] idx |
| /// An index into this module collection. |
| /// |
| /// @return |
| /// A shared pointer to a Module which can contain NULL if |
| /// \a idx is out of range. |
| /// |
| /// @see ModuleList::GetSize() |
| //------------------------------------------------------------------ |
| lldb::ModuleSP GetModuleAtIndex(size_t idx) const; |
| |
| //------------------------------------------------------------------ |
| /// Get the module shared pointer for the module at index \a idx without |
| /// acquiring the ModuleList mutex. This MUST already have been acquired |
| /// with ModuleList::GetMutex and locked for this call to be safe. |
| /// |
| /// @param[in] idx |
| /// An index into this module collection. |
| /// |
| /// @return |
| /// A shared pointer to a Module which can contain NULL if |
| /// \a idx is out of range. |
| /// |
| /// @see ModuleList::GetSize() |
| //------------------------------------------------------------------ |
| lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const; |
| |
| //------------------------------------------------------------------ |
| /// Get the module pointer for the module at index \a idx. |
| /// |
| /// @param[in] idx |
| /// An index into this module collection. |
| /// |
| /// @return |
| /// A pointer to a Module which can by nullptr if \a idx is out |
| /// of range. |
| /// |
| /// @see ModuleList::GetSize() |
| //------------------------------------------------------------------ |
| Module *GetModulePointerAtIndex(size_t idx) const; |
| |
| //------------------------------------------------------------------ |
| /// Get the module pointer for the module at index \a idx without acquiring |
| /// the ModuleList mutex. This MUST already have been acquired with |
| /// ModuleList::GetMutex and locked for this call to be safe. |
| /// |
| /// @param[in] idx |
| /// An index into this module collection. |
| /// |
| /// @return |
| /// A pointer to a Module which can by nullptr if \a idx is out |
| /// of range. |
| /// |
| /// @see ModuleList::GetSize() |
| //------------------------------------------------------------------ |
| Module *GetModulePointerAtIndexUnlocked(size_t idx) const; |
| |
| //------------------------------------------------------------------ |
| /// Find compile units by partial or full path. |
| /// |
| /// Finds all compile units that match \a path in all of the modules and |
| /// returns the results in \a sc_list. |
| /// |
| /// @param[in] path |
| /// The name of the compile unit we are looking for. |
| /// |
| /// @param[in] append |
| /// If \b true, then append any compile units that were found |
| /// to \a sc_list. If \b false, then the \a sc_list is cleared |
| /// and the contents of \a sc_list are replaced. |
| /// |
| /// @param[out] sc_list |
| /// A symbol context list that gets filled in with all of the |
| /// matches. |
| /// |
| /// @return |
| /// The number of matches added to \a sc_list. |
| //------------------------------------------------------------------ |
| size_t FindCompileUnits(const FileSpec &path, bool append, |
| SymbolContextList &sc_list) const; |
| |
| //------------------------------------------------------------------ |
| /// @see Module::FindFunctions () |
| //------------------------------------------------------------------ |
| size_t FindFunctions(const ConstString &name, uint32_t name_type_mask, |
| bool include_symbols, bool include_inlines, bool append, |
| SymbolContextList &sc_list) const; |
| |
| //------------------------------------------------------------------ |
| /// @see Module::FindFunctionSymbols () |
| //------------------------------------------------------------------ |
| size_t FindFunctionSymbols(const ConstString &name, uint32_t name_type_mask, |
| SymbolContextList &sc_list); |
| |
| //------------------------------------------------------------------ |
| /// @see Module::FindFunctions () |
| //------------------------------------------------------------------ |
| size_t FindFunctions(const RegularExpression &name, bool include_symbols, |
| bool include_inlines, bool append, |
| SymbolContextList &sc_list); |
| |
| //------------------------------------------------------------------ |
| /// Find global and static variables by name. |
| /// |
| /// @param[in] name |
| /// The name of the global or static variable we are looking |
| /// for. |
| /// |
| /// @param[in] max_matches |
| /// Allow the number of matches to be limited to \a |
| /// max_matches. Specify UINT32_MAX to get all possible matches. |
| /// |
| /// @param[in] variable_list |
| /// A list of variables that gets the matches appended to. |
| /// |
| /// @return |
| /// The number of matches added to \a variable_list. |
| //------------------------------------------------------------------ |
| size_t FindGlobalVariables(const ConstString &name, size_t max_matches, |
| VariableList &variable_list) const; |
| |
| //------------------------------------------------------------------ |
| /// Find global and static variables by regular expression. |
| /// |
| /// @param[in] regex |
| /// A regular expression to use when matching the name. |
| /// |
| /// @param[in] max_matches |
| /// Allow the number of matches to be limited to \a |
| /// max_matches. Specify UINT32_MAX to get all possible matches. |
| /// |
| /// @param[in] variable_list |
| /// A list of variables that gets the matches appended to. |
| /// |
| /// @return |
| /// The number of matches added to \a variable_list. |
| //------------------------------------------------------------------ |
| size_t FindGlobalVariables(const RegularExpression ®ex, size_t max_matches, |
| VariableList &variable_list) const; |
| |
| //------------------------------------------------------------------ |
| /// Finds the first module whose file specification matches \a file_spec. |
| /// |
| /// @param[in] file_spec_ptr |
| /// A file specification object to match against the Module's |
| /// file specifications. If \a file_spec does not have |
| /// directory information, matches will occur by matching only |
| /// the basename of any modules in this list. If this value is |
| /// NULL, then file specifications won't be compared when |
| /// searching for matching modules. |
| /// |
| /// @param[in] arch_ptr |
| /// The architecture to search for if non-NULL. If this value |
| /// is NULL no architecture matching will be performed. |
| /// |
| /// @param[in] uuid_ptr |
| /// The uuid to search for if non-NULL. If this value is NULL |
| /// no uuid matching will be performed. |
| /// |
| /// @param[in] object_name |
| /// An optional object name that must match as well. This value |
| /// can be NULL. |
| /// |
| /// @param[out] matching_module_list |
| /// A module list that gets filled in with any modules that |
| /// match the search criteria. |
| /// |
| /// @return |
| /// The number of matching modules found by the search. |
| //------------------------------------------------------------------ |
| size_t FindModules(const ModuleSpec &module_spec, |
| ModuleList &matching_module_list) const; |
| |
| lldb::ModuleSP FindModule(const Module *module_ptr) const; |
| |
| //------------------------------------------------------------------ |
| // Find a module by UUID |
| // |
| // The UUID value for a module is extracted from the ObjectFile and is the |
| // MD5 checksum, or a smarter object file equivalent, so finding modules by |
| // UUID values is very efficient and accurate. |
| //------------------------------------------------------------------ |
| lldb::ModuleSP FindModule(const UUID &uuid) const; |
| |
| lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const; |
| |
| size_t FindSymbolsWithNameAndType(const ConstString &name, |
| lldb::SymbolType symbol_type, |
| SymbolContextList &sc_list, |
| bool append = false) const; |
| |
| size_t FindSymbolsMatchingRegExAndType(const RegularExpression ®ex, |
| lldb::SymbolType symbol_type, |
| SymbolContextList &sc_list, |
| bool append = false) const; |
| |
| //------------------------------------------------------------------ |
| /// Find types by name. |
| /// |
| /// @param[in] sc |
| /// A symbol context that scopes where to extract a type list |
| /// from. |
| /// |
| /// @param[in] name |
| /// The name of the type we are looking for. |
| /// |
| /// @param[in] append |
| /// If \b true, any matches will be appended to \a |
| /// variable_list, else matches replace the contents of |
| /// \a variable_list. |
| /// |
| /// @param[in] max_matches |
| /// Allow the number of matches to be limited to \a |
| /// max_matches. Specify UINT32_MAX to get all possible matches. |
| /// |
| /// @param[in] encoding |
| /// Limit the search to specific types, or get all types if |
| /// set to Type::invalid. |
| /// |
| /// @param[in] udt_name |
| /// If the encoding is a user defined type, specify the name |
| /// of the user defined type ("struct", "union", "class", etc). |
| /// |
| /// @param[out] type_list |
| /// A type list gets populated with any matches. |
| /// |
| /// @return |
| /// The number of matches added to \a type_list. |
| //------------------------------------------------------------------ |
| size_t FindTypes(const SymbolContext &sc, const ConstString &name, |
| bool name_is_fully_qualified, size_t max_matches, |
| llvm::DenseSet<SymbolFile *> &searched_symbol_files, |
| TypeList &types) const; |
| |
| bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const; |
| |
| //------------------------------------------------------------------ |
| /// Find addresses by file/line |
| /// |
| /// @param[in] target_sp |
| /// The target the addresses are desired for. |
| /// |
| /// @param[in] file |
| /// Source file to locate. |
| /// |
| /// @param[in] line |
| /// Source line to locate. |
| /// |
| /// @param[in] function |
| /// Optional filter function. Addresses within this function will be |
| /// added to the 'local' list. All others will be added to the 'extern' |
| /// list. |
| /// |
| /// @param[out] output_local |
| /// All matching addresses within 'function' |
| /// |
| /// @param[out] output_extern |
| /// All matching addresses not within 'function' |
| void FindAddressesForLine(const lldb::TargetSP target_sp, |
| const FileSpec &file, uint32_t line, |
| Function *function, |
| std::vector<Address> &output_local, |
| std::vector<Address> &output_extern); |
| |
| bool Remove(const lldb::ModuleSP &module_sp); |
| |
| size_t Remove(ModuleList &module_list); |
| |
| bool RemoveIfOrphaned(const Module *module_ptr); |
| |
| size_t RemoveOrphans(bool mandatory); |
| |
| bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) const; |
| |
| //------------------------------------------------------------------ |
| /// @copydoc Module::ResolveSymbolContextForAddress (const Address |
| /// &,uint32_t,SymbolContext&) |
| //------------------------------------------------------------------ |
| uint32_t ResolveSymbolContextForAddress(const Address &so_addr, |
| uint32_t resolve_scope, |
| SymbolContext &sc) const; |
| |
| //------------------------------------------------------------------ |
| /// @copydoc Module::ResolveSymbolContextForFilePath (const char |
| /// *,uint32_t,bool,uint32_t,SymbolContextList&) |
| //------------------------------------------------------------------ |
| uint32_t ResolveSymbolContextForFilePath(const char *file_path, uint32_t line, |
| bool check_inlines, |
| uint32_t resolve_scope, |
| SymbolContextList &sc_list) const; |
| |
| //------------------------------------------------------------------ |
| /// @copydoc Module::ResolveSymbolContextsForFileSpec (const FileSpec |
| /// &,uint32_t,bool,uint32_t,SymbolContextList&) |
| //------------------------------------------------------------------ |
| uint32_t ResolveSymbolContextsForFileSpec(const FileSpec &file_spec, |
| uint32_t line, bool check_inlines, |
| uint32_t resolve_scope, |
| SymbolContextList &sc_list) const; |
| |
| //------------------------------------------------------------------ |
| /// Gets the size of the module list. |
| /// |
| /// @return |
| /// The number of modules in the module list. |
| //------------------------------------------------------------------ |
| size_t GetSize() const; |
| |
| bool LoadScriptingResourcesInTarget(Target *target, std::list<Status> &errors, |
| Stream *feedback_stream = nullptr, |
| bool continue_on_error = true); |
| |
| static ModuleListProperties &GetGlobalModuleListProperties(); |
| |
| static bool ModuleIsInCache(const Module *module_ptr); |
| |
| static Status GetSharedModule(const ModuleSpec &module_spec, |
| lldb::ModuleSP &module_sp, |
| const FileSpecList *module_search_paths_ptr, |
| lldb::ModuleSP *old_module_sp_ptr, |
| bool *did_create_ptr, |
| bool always_create = false); |
| |
| static bool RemoveSharedModule(lldb::ModuleSP &module_sp); |
| |
| static size_t FindSharedModules(const ModuleSpec &module_spec, |
| ModuleList &matching_module_list); |
| |
| static size_t RemoveOrphanSharedModules(bool mandatory); |
| |
| static bool RemoveSharedModuleIfOrphaned(const Module *module_ptr); |
| |
| void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const |
| &callback) const; |
| |
| protected: |
| //------------------------------------------------------------------ |
| // Class typedefs. |
| //------------------------------------------------------------------ |
| typedef std::vector<lldb::ModuleSP> |
| collection; ///< The module collection type. |
| |
| void AppendImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true); |
| |
| bool RemoveImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true); |
| |
| collection::iterator RemoveImpl(collection::iterator pos, |
| bool use_notifier = true); |
| |
| void ClearImpl(bool use_notifier = true); |
| |
| //------------------------------------------------------------------ |
| // Member variables. |
| //------------------------------------------------------------------ |
| collection m_modules; ///< The collection of modules. |
| mutable std::recursive_mutex m_modules_mutex; |
| |
| Notifier *m_notifier; |
| |
| public: |
| typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter, |
| std::recursive_mutex> |
| ModuleIterable; |
| ModuleIterable Modules() { return ModuleIterable(m_modules, GetMutex()); } |
| |
| typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter> |
| ModuleIterableNoLocking; |
| ModuleIterableNoLocking ModulesNoLocking() { |
| return ModuleIterableNoLocking(m_modules); |
| } |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // liblldb_ModuleList_h_ |