//===-- 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 &module_sp, 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
