//===-- ModuleList.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_CORE_MODULELIST_H
#define LLDB_CORE_MODULELIST_H

#include "lldb/Core/Address.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Iterable.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"

#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/RWMutex.h"

#include <functional>
#include <list>
#include <mutex>
#include <vector>

#include <cstddef>
#include <cstdint>

namespace lldb_private {
class ConstString;
class FileSpecList;
class Function;
class Log;
class Module;
class RegularExpression;
class Stream;
class SymbolContext;
class SymbolContextList;
class SymbolFile;
class Target;
class TypeList;
class UUID;
class VariableList;
struct ModuleFunctionSearchOptions;

class ModuleListProperties : public Properties {
  mutable llvm::sys::RWMutex m_symlink_paths_mutex;
  PathMappingList m_symlink_paths;

  void UpdateSymlinkMappings();

public:
  ModuleListProperties();

  FileSpec GetClangModulesCachePath() const;
  bool SetClangModulesCachePath(const FileSpec &path);
  bool GetEnableExternalLookup() const;
  bool SetEnableExternalLookup(bool new_value);

  PathMappingList GetSymlinkMappings() 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 NotifyModuleAdded(const ModuleList &module_list,
                                   const lldb::ModuleSP &module_sp) = 0;
    virtual void NotifyModuleRemoved(const ModuleList &module_list,
                                     const lldb::ModuleSP &module_sp) = 0;
    virtual void NotifyModuleUpdated(const ModuleList &module_list,
                                     const lldb::ModuleSP &old_module_sp,
                                     const lldb::ModuleSP &new_module_sp) = 0;
    virtual void NotifyWillClearList(const ModuleList &module_list) = 0;

    virtual void NotifyModulesRemoved(lldb_private::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.
  ///
  /// \param[in] module_sp
  ///     A shared pointer to a module to add to this collection.
  ///
  /// \param[in] notify
  ///     If true, and a notifier function is set, the notifier function
  ///     will be called.  Defaults to true.
  ///
  ///     When this ModuleList is the Target's ModuleList, the notifier
  ///     function is Target::ModulesDidLoad -- the call to
  ///     ModulesDidLoad may be deferred when adding multiple Modules
  ///     to the Target, but it must be called at the end,
  ///     before resuming execution.
  void Append(const lldb::ModuleSP &module_sp, bool notify = true);

  /// 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.
  ///
  /// \param[in] old_modules
  ///     Optional pointer to a vector which, if provided, will have shared
  ///     pointers to the replaced module(s) appended to it.
  void ReplaceEquivalent(
      const lldb::ModuleSP &module_sp,
      llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules = nullptr);

  /// Append a module to the module list, if it is not already there.
  ///
  /// \param[in] notify
  ///     If true, and a notifier function is set, the notifier function
  ///     will be called.  Defaults to true.
  ///
  ///     When this ModuleList is the Target's ModuleList, the notifier
  ///     function is Target::ModulesDidLoad -- the call to
  ///     ModulesDidLoad may be deferred when adding multiple Modules
  ///     to the Target, but it must be called at the end,
  ///     before resuming execution.
  bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify = true);

  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;

  /// 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[out] sc_list
  ///     A symbol context list that gets filled in with all of the
  ///     matches.
  void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const;

  /// \see Module::FindFunctions ()
  void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask,
                     const ModuleFunctionSearchOptions &options,
                     SymbolContextList &sc_list) const;

  /// \see Module::FindFunctionSymbols ()
  void FindFunctionSymbols(ConstString name,
                           lldb::FunctionNameType name_type_mask,
                           SymbolContextList &sc_list);

  /// \see Module::FindFunctions ()
  void FindFunctions(const RegularExpression &name,
                     const ModuleFunctionSearchOptions &options,
                     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.
  void FindGlobalVariables(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.
  void FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
                           VariableList &variable_list) const;

  /// Finds the first module whose file specification matches \a file_spec.
  ///
  /// \param[in] module_spec
  ///     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[out] matching_module_list
  ///     A module list that gets filled in with any modules that
  ///     match the search criteria.
  void 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;

  void FindSymbolsWithNameAndType(ConstString name,
                                  lldb::SymbolType symbol_type,
                                  SymbolContextList &sc_list) const;

  void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
                                       lldb::SymbolType symbol_type,
                                       SymbolContextList &sc_list) const;

  /// Find types by name.
  ///
  /// \param[in] search_first
  ///     If non-null, this module will be searched before any other
  ///     modules.
  ///
  /// \param[in] name
  ///     The name of the type 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[out] types
  ///     A type list gets populated with any matches.
  ///
  void FindTypes(Module *search_first, 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);

  /// Remove a module from the module list.
  ///
  /// \param[in] module_sp
  ///     A shared pointer to a module to remove from this collection.
  ///
  /// \param[in] notify
  ///     If true, and a notifier function is set, the notifier function
  ///     will be called.  Defaults to true.
  ///
  ///     When this ModuleList is the Target's ModuleList, the notifier
  ///     function is Target::ModulesDidUnload -- the call to
  ///     ModulesDidUnload may be deferred when removing multiple Modules
  ///     from the Target, but it must be called at the end,
  ///     before resuming execution.
  bool Remove(const lldb::ModuleSP &module_sp, bool notify = true);

  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,
                                          lldb::SymbolContextItem 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,
      lldb::SymbolContextItem 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,
      lldb::SymbolContextItem 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 IsEmpty() const { return !GetSize(); }

  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,
                  llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
                  bool *did_create_ptr, bool always_create = false);

  static bool RemoveSharedModule(lldb::ModuleSP &module_sp);

  static void 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 = nullptr;

public:
  typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter,
                                 std::recursive_mutex>
      ModuleIterable;
  ModuleIterable Modules() const {
    return ModuleIterable(m_modules, GetMutex());
  }

  typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter>
      ModuleIterableNoLocking;
  ModuleIterableNoLocking ModulesNoLocking() const {
    return ModuleIterableNoLocking(m_modules);
  }
};

} // namespace lldb_private

#endif // LLDB_CORE_MODULELIST_H
