//===-- Module.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_MODULE_H
#define LLDB_CORE_MODULE_H

#include "lldb/Core/Address.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/PathMappingList.h"
#include "lldb/Target/Statistics.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/UUID.h"
#include "lldb/Utility/XcodeSDK.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"

#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Chrono.h"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <vector>

namespace lldb_private {
class CompilerDeclContext;
class Function;
class Log;
class ObjectFile;
class RegularExpression;
class SectionList;
class Stream;
class Symbol;
class SymbolContext;
class SymbolContextList;
class SymbolFile;
class Symtab;
class Target;
class TypeList;
class TypeMap;
class VariableList;

/// Options used by Module::FindFunctions. This cannot be a nested class
/// because it must be forward-declared in ModuleList.h.
struct ModuleFunctionSearchOptions {
  /// Include the symbol table.
  bool include_symbols = false;
  /// Include inlined functions.
  bool include_inlines = false;
};

/// \class Module Module.h "lldb/Core/Module.h"
/// A class that describes an executable image and its associated
///        object and symbol files.
///
/// The module is designed to be able to select a single slice of an
/// executable image as it would appear on disk and during program execution.
///
/// Modules control when and if information is parsed according to which
/// accessors are called. For example the object file (ObjectFile)
/// representation will only be parsed if the object file is requested using
/// the Module::GetObjectFile() is called. The debug symbols will only be
/// parsed if the symbol file (SymbolFile) is requested using the
/// Module::GetSymbolFile() method.
///
/// The module will parse more detailed information as more queries are made.
class Module : public std::enable_shared_from_this<Module>,
               public SymbolContextScope {
public:
  // Static functions that can track the lifetime of module objects. This is
  // handy because we might have Module objects that are in shared pointers
  // that aren't in the global module list (from ModuleList). If this is the
  // case we need to know about it. The modules in the global list maintained
  // by these functions can be viewed using the "target modules list" command
  // using the "--global" (-g for short).
  static size_t GetNumberAllocatedModules();

  static Module *GetAllocatedModuleAtIndex(size_t idx);

  static std::recursive_mutex &GetAllocationModuleCollectionMutex();

  /// Construct with file specification and architecture.
  ///
  /// Clients that wish to share modules with other targets should use
  /// ModuleList::GetSharedModule().
  ///
  /// \param[in] file_spec
  ///     The file specification for the on disk representation of
  ///     this executable image.
  ///
  /// \param[in] arch
  ///     The architecture to set as the current architecture in
  ///     this module.
  ///
  /// \param[in] object_name
  ///     The name of an object in a module used to extract a module
  ///     within a module (.a files and modules that contain multiple
  ///     architectures).
  ///
  /// \param[in] object_offset
  ///     The offset within an existing module used to extract a
  ///     module within a module (.a files and modules that contain
  ///     multiple architectures).
  Module(
      const FileSpec &file_spec, const ArchSpec &arch,
      const ConstString *object_name = nullptr,
      lldb::offset_t object_offset = 0,
      const llvm::sys::TimePoint<> &object_mod_time = llvm::sys::TimePoint<>());

  Module(const ModuleSpec &module_spec);

  template <typename ObjFilePlugin, typename... Args>
  static lldb::ModuleSP CreateModuleFromObjectFile(Args &&...args) {
    // Must create a module and place it into a shared pointer before we can
    // create an object file since it has a std::weak_ptr back to the module,
    // so we need to control the creation carefully in this static function
    lldb::ModuleSP module_sp(new Module());
    module_sp->m_objfile_sp =
        std::make_shared<ObjFilePlugin>(module_sp, std::forward<Args>(args)...);
    module_sp->m_did_load_objfile.store(true, std::memory_order_relaxed);

    // Once we get the object file, set module ArchSpec to the one we get from
    // the object file. If the object file does not have an architecture, we
    // consider the creation a failure.
    ArchSpec arch = module_sp->m_objfile_sp->GetArchitecture();
    if (!arch)
      return nullptr;
    module_sp->m_arch = arch;

    // Also copy the object file's FileSpec.
    module_sp->m_file = module_sp->m_objfile_sp->GetFileSpec();
    return module_sp;
  }

  /// Destructor.
  ~Module() override;

  bool MatchesModuleSpec(const ModuleSpec &module_ref);

  /// Set the load address for all sections in a module to be the file address
  /// plus \a slide.
  ///
  /// Many times a module will be loaded in a target with a constant offset
  /// applied to all top level sections. This function can set the load
  /// address for all top level sections to be the section file address +
  /// offset.
  ///
  /// \param[in] target
  ///     The target in which to apply the section load addresses.
  ///
  /// \param[in] value
  ///     if \a value_is_offset is true, then value is the offset to
  ///     apply to all file addresses for all top level sections in
  ///     the object file as each section load address is being set.
  ///     If \a value_is_offset is false, then "value" is the new
  ///     absolute base address for the image.
  ///
  /// \param[in] value_is_offset
  ///     If \b true, then \a value is an offset to apply to each
  ///     file address of each top level section.
  ///     If \b false, then \a value is the image base address that
  ///     will be used to rigidly slide all loadable sections.
  ///
  /// \param[out] changed
  ///     If any section load addresses were changed in \a target,
  ///     then \a changed will be set to \b true. Else \a changed
  ///     will be set to false. This allows this function to be
  ///     called multiple times on the same module for the same
  ///     target. If the module hasn't moved, then \a changed will
  ///     be false and no module updated notification will need to
  ///     be sent out.
  ///
  /// \return
  ///     /b True if any sections were successfully loaded in \a target,
  ///     /b false otherwise.
  bool SetLoadAddress(Target &target, lldb::addr_t value, bool value_is_offset,
                      bool &changed);

  /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
  ///
  /// \see SymbolContextScope
  void CalculateSymbolContext(SymbolContext *sc) override;

  lldb::ModuleSP CalculateSymbolContextModule() override;

  void
  GetDescription(llvm::raw_ostream &s,
                 lldb::DescriptionLevel level = lldb::eDescriptionLevelFull);

  /// Get the module path and object name.
  ///
  /// Modules can refer to object files. In this case the specification is
  /// simple and would return the path to the file:
  ///
  ///     "/usr/lib/foo.dylib"
  ///
  /// Modules can be .o files inside of a BSD archive (.a file). In this case,
  /// the object specification will look like:
  ///
  ///     "/usr/lib/foo.a(bar.o)"
  ///
  /// There are many places where logging wants to log this fully qualified
  /// specification, so we centralize this functionality here.
  ///
  /// \return
  ///     The object path + object name if there is one.
  std::string GetSpecificationDescription() const;

  /// Dump a description of this object to a Stream.
  ///
  /// Dump a description of the contents of this object to the supplied stream
  /// \a s. The dumped content will be only what has been loaded or parsed up
  /// to this point at which this function is called, so this is a good way to
  /// see what has been parsed in a module.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  void Dump(Stream *s);

  /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
  ///
  /// \see SymbolContextScope
  void DumpSymbolContext(Stream *s) override;

  /// Find a symbol in the object file's symbol table.
  ///
  /// \param[in] name
  ///     The name of the symbol that we are looking for.
  ///
  /// \param[in] symbol_type
  ///     If set to eSymbolTypeAny, find a symbol of any type that
  ///     has a name that matches \a name. If set to any other valid
  ///     SymbolType enumeration value, then search only for
  ///     symbols that match \a symbol_type.
  ///
  /// \return
  ///     Returns a valid symbol pointer if a symbol was found,
  ///     nullptr otherwise.
  const Symbol *FindFirstSymbolWithNameAndType(
      ConstString name, lldb::SymbolType symbol_type = lldb::eSymbolTypeAny);

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

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

  /// Find a function symbols in the object file's symbol table.
  ///
  /// \param[in] name
  ///     The name of the symbol that we are looking for.
  ///
  /// \param[in] name_type_mask
  ///     A mask that has one or more bitwise OR'ed values from the
  ///     lldb::FunctionNameType enumeration type that indicate what
  ///     kind of names we are looking for.
  ///
  /// \param[out] sc_list
  ///     A list to append any matching symbol contexts to.
  void FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
                           SymbolContextList &sc_list);

  /// 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 function 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);

  /// Find functions by name.
  ///
  /// If the function is an inlined function, it will have a block,
  /// representing the inlined function, and the function will be the
  /// containing function.  If it is not inlined, then the block will be NULL.
  ///
  /// \param[in] name
  ///     The name of the compile unit we are looking for.
  ///
  /// \param[in] name_type_mask
  ///     A bit mask of bits that indicate what kind of names should
  ///     be used when doing the lookup. Bits include fully qualified
  ///     names, base names, C++ methods, or ObjC selectors.
  ///     See FunctionNameType for more details.
  ///
  /// \param[out] sc_list
  ///     A symbol context list that gets filled in with all of the
  ///     matches.
  void FindFunctions(ConstString name,
                     const CompilerDeclContext &parent_decl_ctx,
                     lldb::FunctionNameType name_type_mask,
                     const ModuleFunctionSearchOptions &options,
                     SymbolContextList &sc_list);

  /// Find functions by name.
  ///
  /// If the function is an inlined function, it will have a block,
  /// representing the inlined function, and the function will be the
  /// containing function.  If it is not inlined, then the block will be NULL.
  ///
  /// \param[in] regex
  ///     A regular expression to use when matching the name.
  ///
  /// \param[out] sc_list
  ///     A symbol context list that gets filled in with all of the
  ///     matches.
  void FindFunctions(const RegularExpression &regex,
                     const ModuleFunctionSearchOptions &options,
                     SymbolContextList &sc_list);

  /// 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);

  /// Find global and static variables by name.
  ///
  /// \param[in] name
  ///     The name of the global or static variable we are looking
  ///     for.
  ///
  /// \param[in] parent_decl_ctx
  ///     If valid, a decl context that results must exist within
  ///
  /// \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,
                           const CompilerDeclContext &parent_decl_ctx,
                           size_t max_matches, VariableList &variable_list);

  /// 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);

  /// Find types by name.
  ///
  /// Type lookups in modules go through the SymbolFile. The SymbolFile needs to
  /// be able to lookup types by basename and not the fully qualified typename.
  /// This allows the type accelerator tables to stay small, even with heavily
  /// templatized C++. The type search will then narrow down the search
  /// results. If "exact_match" is true, then the type search will only match
  /// exact type name matches. If "exact_match" is false, the type will match
  /// as long as the base typename matches and as long as any immediate
  /// containing namespaces/class scopes that are specified match. So to
  /// search for a type "d" in "b::c", the name "b::c::d" can be specified and
  /// it will match any class/namespace "b" which contains a class/namespace
  /// "c" which contains type "d". We do this to allow users to not always
  /// have to specify complete scoping on all expressions, but it also allows
  /// for exact matching when required.
  ///
  /// \param[in] type_name
  ///     The name of the type we are looking for that is a fully
  ///     or partially qualified type name.
  ///
  /// \param[in] exact_match
  ///     If \b true, \a type_name is fully qualified and must match
  ///     exactly. If \b false, \a type_name is a partially qualified
  ///     name where the leading namespaces or classes can be
  ///     omitted to make finding types that a user may type
  ///     easier.
  ///
  /// \param[out] types
  ///     A type list gets populated with any matches.
  ///
  void
  FindTypes(ConstString type_name, bool exact_match, size_t max_matches,
            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
            TypeList &types);

  /// Find types by name.
  ///
  /// This behaves like the other FindTypes method but allows to
  /// specify a DeclContext and a language for the type being searched
  /// for.
  ///
  /// \param searched_symbol_files
  ///     Prevents one file from being visited multiple times.
  void
  FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
            TypeMap &types);

  lldb::TypeSP FindFirstType(const SymbolContext &sc, ConstString type_name,
                             bool exact_match);

  /// Find types by name that are in a namespace. This function is used by the
  /// expression parser when searches need to happen in an exact namespace
  /// scope.
  ///
  /// \param[in] type_name
  ///     The name of a type within a namespace that should not include
  ///     any qualifying namespaces (just a type basename).
  ///
  /// \param[out] type_list
  ///     A type list gets populated with any matches.
  void FindTypesInNamespace(ConstString type_name,
                            const CompilerDeclContext &parent_decl_ctx,
                            size_t max_matches, TypeList &type_list);

  /// Get const accessor for the module architecture.
  ///
  /// \return
  ///     A const reference to the architecture object.
  const ArchSpec &GetArchitecture() const;

  /// Get const accessor for the module file specification.
  ///
  /// This function returns the file for the module on the host system that is
  /// running LLDB. This can differ from the path on the platform since we
  /// might be doing remote debugging.
  ///
  /// \return
  ///     A const reference to the file specification object.
  const FileSpec &GetFileSpec() const { return m_file; }

  /// Get accessor for the module platform file specification.
  ///
  /// Platform file refers to the path of the module as it is known on the
  /// remote system on which it is being debugged. For local debugging this is
  /// always the same as Module::GetFileSpec(). But remote debugging might
  /// mention a file "/usr/lib/liba.dylib" which might be locally downloaded
  /// and cached. In this case the platform file could be something like:
  /// "/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib" The
  /// file could also be cached in a local developer kit directory.
  ///
  /// \return
  ///     A const reference to the file specification object.
  const FileSpec &GetPlatformFileSpec() const {
    if (m_platform_file)
      return m_platform_file;
    return m_file;
  }

  void SetPlatformFileSpec(const FileSpec &file) { m_platform_file = file; }

  const FileSpec &GetRemoteInstallFileSpec() const {
    return m_remote_install_file;
  }

  void SetRemoteInstallFileSpec(const FileSpec &file) {
    m_remote_install_file = file;
  }

  const FileSpec &GetSymbolFileFileSpec() const { return m_symfile_spec; }

  void PreloadSymbols();

  void SetSymbolFileFileSpec(const FileSpec &file);

  const llvm::sys::TimePoint<> &GetModificationTime() const {
    return m_mod_time;
  }

  const llvm::sys::TimePoint<> &GetObjectModificationTime() const {
    return m_object_mod_time;
  }

  /// This callback will be called by SymbolFile implementations when
  /// parsing a compile unit that contains SDK information.
  /// \param sysroot will be added to the path remapping dictionary.
  void RegisterXcodeSDK(llvm::StringRef sdk, llvm::StringRef sysroot);

  /// Tells whether this module is capable of being the main executable for a
  /// process.
  ///
  /// \return
  ///     \b true if it is, \b false otherwise.
  bool IsExecutable();

  /// Tells whether this module has been loaded in the target passed in. This
  /// call doesn't distinguish between whether the module is loaded by the
  /// dynamic loader, or by a "target module add" type call.
  ///
  /// \param[in] target
  ///    The target to check whether this is loaded in.
  ///
  /// \return
  ///     \b true if it is, \b false otherwise.
  bool IsLoadedInTarget(Target *target);

  bool LoadScriptingResourceInTarget(Target *target, Status &error,
                                     Stream *feedback_stream = nullptr);

  /// Get the number of compile units for this module.
  ///
  /// \return
  ///     The number of compile units that the symbol vendor plug-in
  ///     finds.
  size_t GetNumCompileUnits();

  lldb::CompUnitSP GetCompileUnitAtIndex(size_t idx);

  ConstString GetObjectName() const;

  uint64_t GetObjectOffset() const { return m_object_offset; }

  /// Get the object file representation for the current architecture.
  ///
  /// If the object file has not been located or parsed yet, this function
  /// will find the best ObjectFile plug-in that can parse Module::m_file.
  ///
  /// \return
  ///     If Module::m_file does not exist, or no plug-in was found
  ///     that can parse the file, or the object file doesn't contain
  ///     the current architecture in Module::m_arch, nullptr will be
  ///     returned, else a valid object file interface will be
  ///     returned. The returned pointer is owned by this object and
  ///     remains valid as long as the object is around.
  virtual ObjectFile *GetObjectFile();

  /// Get the unified section list for the module. This is the section list
  /// created by the module's object file and any debug info and symbol files
  /// created by the symbol vendor.
  ///
  /// If the symbol vendor has not been loaded yet, this function will return
  /// the section list for the object file.
  ///
  /// \return
  ///     Unified module section list.
  virtual SectionList *GetSectionList();

  /// Notify the module that the file addresses for the Sections have been
  /// updated.
  ///
  /// If the Section file addresses for a module are updated, this method
  /// should be called.  Any parts of the module, object file, or symbol file
  /// that has cached those file addresses must invalidate or update its
  /// cache.
  virtual void SectionFileAddressesChanged();

  /// Returns a reference to the UnwindTable for this Module
  ///
  /// The UnwindTable contains FuncUnwinders objects for any function in this
  /// Module.  If a FuncUnwinders object hasn't been created yet (i.e. the
  /// function has yet to be unwound in a stack walk), it will be created when
  /// requested.  Specifically, we do not create FuncUnwinders objects for
  /// functions until they are needed.
  ///
  /// \return
  ///     Returns the unwind table for this module. If this object has no
  ///     associated object file, an empty UnwindTable is returned.
  UnwindTable &GetUnwindTable();

  llvm::VersionTuple GetVersion();

  /// Load an object file from memory.
  ///
  /// If available, the size of the object file in memory may be passed to
  /// avoid additional round trips to process memory. If the size is not
  /// provided, a default value is used. This value should be large enough to
  /// enable the ObjectFile plugins to read the header of the object file
  /// without going back to the process.
  ///
  /// \return
  ///     The object file loaded from memory or nullptr, if the operation
  ///     failed (see the `error` for more information in that case).
  ObjectFile *GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
                                  lldb::addr_t header_addr, Status &error,
                                  size_t size_to_read = 512);

  /// Get the module's symbol file
  ///
  /// If the symbol file has already been loaded, this function returns it. All
  /// arguments are ignored. If the symbol file has not been located yet, and
  /// the can_create argument is false, the function returns nullptr. If
  /// can_create is true, this function will find the best SymbolFile plug-in
  /// that can use the current object file. feedback_strm, if not null, is used
  /// to report the details of the search process.
  virtual SymbolFile *GetSymbolFile(bool can_create = true,
                                    Stream *feedback_strm = nullptr);

  Symtab *GetSymtab();

  /// Get a reference to the UUID value contained in this object.
  ///
  /// If the executable image file doesn't not have a UUID value built into
  /// the file format, an MD5 checksum of the entire file, or slice of the
  /// file for the current architecture should be used.
  ///
  /// \return
  ///     A const pointer to the internal copy of the UUID value in
  ///     this module if this module has a valid UUID value, NULL
  ///     otherwise.
  const lldb_private::UUID &GetUUID();

  /// A debugging function that will cause everything in a module to
  /// be parsed.
  ///
  /// All compile units will be parsed, along with all globals and static
  /// variables and all functions for those compile units. All types, scopes,
  /// local variables, static variables, global variables, and line tables
  /// will be parsed. This can be used prior to dumping a module to see a
  /// complete list of the resulting debug information that gets parsed, or as
  /// a debug function to ensure that the module can consume all of the debug
  /// data the symbol vendor provides.
  void ParseAllDebugSymbols();

  bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr);

  /// Resolve the symbol context for the given address.
  ///
  /// Tries to resolve the matching symbol context based on a lookup from the
  /// current symbol vendor.  If the lazy lookup fails, an attempt is made to
  /// parse the eh_frame section to handle stripped symbols.  If this fails,
  /// an attempt is made to resolve the symbol to the previous address to
  /// handle the case of a function with a tail call.
  ///
  /// Use properties of the modified SymbolContext to inspect any resolved
  /// target, module, compilation unit, symbol, function, function block or
  /// line entry.  Use the return value to determine which of these properties
  /// have been modified.
  ///
  /// \param[in] so_addr
  ///     A load address to resolve.
  ///
  /// \param[in] resolve_scope
  ///     The scope that should be resolved (see SymbolContext::Scope).
  ///     A combination of flags from the enumeration SymbolContextItem
  ///     requesting a resolution depth.  Note that the flags that are
  ///     actually resolved may be a superset of the requested flags.
  ///     For instance, eSymbolContextSymbol requires resolution of
  ///     eSymbolContextModule, and eSymbolContextFunction requires
  ///     eSymbolContextSymbol.
  ///
  /// \param[out] sc
  ///     The SymbolContext that is modified based on symbol resolution.
  ///
  /// \param[in] resolve_tail_call_address
  ///     Determines if so_addr should resolve to a symbol in the case
  ///     of a function whose last instruction is a call.  In this case,
  ///     the PC can be one past the address range of the function.
  ///
  /// \return
  ///     The scope that has been resolved (see SymbolContext::Scope).
  ///
  /// \see SymbolContext::Scope
  uint32_t ResolveSymbolContextForAddress(
      const Address &so_addr, lldb::SymbolContextItem resolve_scope,
      SymbolContext &sc, bool resolve_tail_call_address = false);

  /// Resolve items in the symbol context for a given file and line.
  ///
  /// Tries to resolve \a file_path and \a line to a list of matching symbol
  /// contexts.
  ///
  /// The line table entries contains addresses that can be used to further
  /// resolve the values in each match: the function, block, symbol. Care
  /// should be taken to minimize the amount of information that is requested
  /// to only what is needed -- typically the module, compile unit, line table
  /// and line table entry are sufficient.
  ///
  /// \param[in] file_path
  ///     A path to a source file to match. If \a file_path does not
  ///     specify a directory, then this query will match all files
  ///     whose base filename matches. If \a file_path does specify
  ///     a directory, the fullpath to the file must match.
  ///
  /// \param[in] line
  ///     The source line to match, or zero if just the compile unit
  ///     should be resolved.
  ///
  /// \param[in] check_inlines
  ///     Check for inline file and line number matches. This option
  ///     should be used sparingly as it will cause all line tables
  ///     for every compile unit to be parsed and searched for
  ///     matching inline file entries.
  ///
  /// \param[in] resolve_scope
  ///     The scope that should be resolved (see
  ///     SymbolContext::Scope).
  ///
  /// \param[out] sc_list
  ///     A symbol context list that gets matching symbols contexts
  ///     appended to.
  ///
  /// \return
  ///     The number of matches that were added to \a sc_list.
  ///
  /// \see SymbolContext::Scope
  uint32_t ResolveSymbolContextForFilePath(
      const char *file_path, uint32_t line, bool check_inlines,
      lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list);

  /// Resolve items in the symbol context for a given file and line.
  ///
  /// Tries to resolve \a file_spec and \a line to a list of matching symbol
  /// contexts.
  ///
  /// The line table entries contains addresses that can be used to further
  /// resolve the values in each match: the function, block, symbol. Care
  /// should be taken to minimize the amount of information that is requested
  /// to only what is needed -- typically the module, compile unit, line table
  /// and line table entry are sufficient.
  ///
  /// \param[in] file_spec
  ///     A file spec to a source file to match. If \a file_path does
  ///     not specify a directory, then this query will match all
  ///     files whose base filename matches. If \a file_path does
  ///     specify a directory, the fullpath to the file must match.
  ///
  /// \param[in] line
  ///     The source line to match, or zero if just the compile unit
  ///     should be resolved.
  ///
  /// \param[in] check_inlines
  ///     Check for inline file and line number matches. This option
  ///     should be used sparingly as it will cause all line tables
  ///     for every compile unit to be parsed and searched for
  ///     matching inline file entries.
  ///
  /// \param[in] resolve_scope
  ///     The scope that should be resolved (see
  ///     SymbolContext::Scope).
  ///
  /// \param[out] sc_list
  ///     A symbol context list that gets filled in with all of the
  ///     matches.
  ///
  /// \return
  ///     A integer that contains SymbolContext::Scope bits set for
  ///     each item that was successfully resolved.
  ///
  /// \see SymbolContext::Scope
  uint32_t ResolveSymbolContextsForFileSpec(
      const FileSpec &file_spec, uint32_t line, bool check_inlines,
      lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list);

  void SetFileSpecAndObjectName(const FileSpec &file, ConstString object_name);

  bool GetIsDynamicLinkEditor();

  llvm::Expected<TypeSystem &>
  GetTypeSystemForLanguage(lldb::LanguageType language);

  // Special error functions that can do printf style formatting that will
  // prepend the message with something appropriate for this module (like the
  // architecture, path and object name (if any)). This centralizes code so
  // that everyone doesn't need to format their error and log messages on their
  // own and keeps the output a bit more consistent.
  void LogMessage(Log *log, const char *format, ...)
      __attribute__((format(printf, 3, 4)));

  void LogMessageVerboseBacktrace(Log *log, const char *format, ...)
      __attribute__((format(printf, 3, 4)));

  void ReportWarning(const char *format, ...)
      __attribute__((format(printf, 2, 3)));

  void ReportError(const char *format, ...)
      __attribute__((format(printf, 2, 3)));

  // Only report an error once when the module is first detected to be modified
  // so we don't spam the console with many messages.
  void ReportErrorIfModifyDetected(const char *format, ...)
      __attribute__((format(printf, 2, 3)));

  void ReportWarningOptimization(llvm::Optional<lldb::user_id_t> debugger_id);

  void
  ReportWarningUnsupportedLanguage(lldb::LanguageType language,
                                   llvm::Optional<lldb::user_id_t> debugger_id);

  // Return true if the file backing this module has changed since the module
  // was originally created  since we saved the initial file modification time
  // when the module first gets created.
  bool FileHasChanged() const;

  // SymbolFile and ObjectFile member objects should lock the
  // module mutex to avoid deadlocks.
  std::recursive_mutex &GetMutex() const { return m_mutex; }

  PathMappingList &GetSourceMappingList() { return m_source_mappings; }

  const PathMappingList &GetSourceMappingList() const {
    return m_source_mappings;
  }

  /// Finds a source file given a file spec using the module source path
  /// remappings (if any).
  ///
  /// Tries to resolve \a orig_spec by checking the module source path
  /// remappings. It makes sure the file exists, so this call can be expensive
  /// if the remappings are on a network file system, so use this function
  /// sparingly (not in a tight debug info parsing loop).
  ///
  /// \param[in] orig_spec
  ///     The original source file path to try and remap.
  ///
  /// \param[out] new_spec
  ///     The newly remapped filespec that is guaranteed to exist.
  ///
  /// \return
  ///     /b true if \a orig_spec was successfully located and
  ///     \a new_spec is filled in with an existing file spec,
  ///     \b false otherwise.
  bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const;

  /// Remaps a source file given \a path into \a new_path.
  ///
  /// Remaps \a path if any source remappings match. This function does NOT
  /// stat the file system so it can be used in tight loops where debug info
  /// is being parsed.
  ///
  /// \param[in] path
  ///     The original source file path to try and remap.
  ///
  /// \return
  ///     The newly remapped filespec that is may or may not exist if
  ///     \a path was successfully located.
  llvm::Optional<std::string> RemapSourceFile(llvm::StringRef path) const;
  bool RemapSourceFile(const char *, std::string &) const = delete;

  /// Update the ArchSpec to a more specific variant.
  bool MergeArchitecture(const ArchSpec &arch_spec);

  /// Accessor for the symbol table parse time metric.
  ///
  /// The value is returned as a reference to allow it to be updated by the
  /// ElapsedTime RAII object.
  StatsDuration &GetSymtabParseTime() { return m_symtab_parse_time; }

  /// Accessor for the symbol table index time metric.
  ///
  /// The value is returned as a reference to allow it to be updated by the
  /// ElapsedTime RAII object.
  StatsDuration &GetSymtabIndexTime() { return m_symtab_index_time; }

  /// \class LookupInfo Module.h "lldb/Core/Module.h"
  /// A class that encapsulates name lookup information.
  ///
  /// Users can type a wide variety of partial names when setting breakpoints
  /// by name or when looking for functions by name. The SymbolFile object is
  /// only required to implement name lookup for function basenames and for
  /// fully mangled names. This means if the user types in a partial name, we
  /// must reduce this to a name lookup that will work with all SymbolFile
  /// objects. So we might reduce a name lookup to look for a basename, and then
  /// prune out any results that don't match.
  ///
  /// The "m_name" member variable represents the name as it was typed by the
  /// user. "m_lookup_name" will be the name we actually search for through
  /// the symbol or objects files. Lanaguage is included in case we need to
  /// filter results by language at a later date. The "m_name_type_mask"
  /// member variable tells us what kinds of names we are looking for and can
  /// help us prune out unwanted results.
  ///
  /// Function lookups are done in Module.cpp, ModuleList.cpp and in
  /// BreakpointResolverName.cpp and they all now use this class to do lookups
  /// correctly.
  class LookupInfo {
  public:
    LookupInfo() {}

    LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask,
               lldb::LanguageType language);

    ConstString GetName() const { return m_name; }

    void SetName(ConstString name) { m_name = name; }

    ConstString GetLookupName() const { return m_lookup_name; }

    void SetLookupName(ConstString name) { m_lookup_name = name; }

    lldb::FunctionNameType GetNameTypeMask() const { return m_name_type_mask; }

    void SetNameTypeMask(lldb::FunctionNameType mask) {
      m_name_type_mask = mask;
    }

    void Prune(SymbolContextList &sc_list, size_t start_idx) const;

  protected:
    /// What the user originally typed
    ConstString m_name;

    /// The actual name will lookup when calling in the object or symbol file
    ConstString m_lookup_name;

    /// Limit matches to only be for this language
    lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;

    /// One or more bits from lldb::FunctionNameType that indicate what kind of
    /// names we are looking for
    lldb::FunctionNameType m_name_type_mask = lldb::eFunctionNameTypeNone;

    ///< If \b true, then demangled names that match will need to contain
    ///< "m_name" in order to be considered a match
    bool m_match_name_after_lookup = false;
  };

  /// Get a unique hash for this module.
  ///
  /// The hash should be enough to identify the file on disk and the
  /// architecture of the file. If the module represents an object inside of a
  /// file, then the hash should include the object name and object offset to
  /// ensure a unique hash. Some examples:
  /// - just a regular object file (mach-o, elf, coff, etc) should create a hash
  /// - a universal mach-o file that contains to multiple architectures,
  ///   each architecture slice should have a unique hash even though they come
  ///   from the same file
  /// - a .o file inside of a BSD archive. Each .o file will have an object name
  ///   and object offset that should produce a unique hash. The object offset
  ///   is needed as BSD archive files can contain multiple .o files that have
  ///   the same name.
  uint32_t Hash();

  /// Get a unique cache key for the current module.
  ///
  /// The cache key must be unique for a file on disk and not change if the file
  /// is updated. This allows cache data to use this key as a prefix and as
  /// files are modified in disk, we will overwrite the cache files. If one file
  /// can contain multiple files, like a universal mach-o file or like a BSD
  /// archive, the cache key must contain enough information to differentiate
  /// these different files.
  std::string GetCacheKey();

  /// Get the global index file cache.
  ///
  /// LLDB can cache data for a module between runs. This cache directory can be
  /// used to stored data that previously was manually created each time you debug.
  /// Examples include debug information indexes, symbol tables, symbol table
  /// indexes, and more.
  ///
  /// \returns
  ///   If caching is enabled in the lldb settings, return a pointer to the data
  ///   file cache. If caching is not enabled, return NULL.
  static DataFileCache *GetIndexCache();
protected:
  // Member Variables
  mutable std::recursive_mutex m_mutex; ///< A mutex to keep this object happy
                                        /// in multi-threaded environments.

  /// The modification time for this module when it was created.
  llvm::sys::TimePoint<> m_mod_time;

  ArchSpec m_arch; ///< The architecture for this module.
  UUID m_uuid; ///< Each module is assumed to have a unique identifier to help
               /// match it up to debug symbols.
  FileSpec m_file; ///< The file representation on disk for this module (if
                   /// there is one).
  FileSpec m_platform_file; ///< The path to the module on the platform on which
                            /// it is being debugged
  FileSpec m_remote_install_file; ///< If set when debugging on remote
                                  /// platforms, this module will be installed
                                  /// at this location
  FileSpec m_symfile_spec;   ///< If this path is valid, then this is the file
                             /// that _will_ be used as the symbol file for this
                             /// module
  ConstString m_object_name; ///< The name an object within this module that is
                             /// selected, or empty of the module is represented
                             /// by \a m_file.
  uint64_t m_object_offset = 0;
  llvm::sys::TimePoint<> m_object_mod_time;

  /// DataBuffer containing the module image, if it was provided at
  /// construction time. Otherwise the data will be retrieved by mapping
  /// one of the FileSpec members above.
  lldb::DataBufferSP m_data_sp;

  lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file
                                   /// parser for this module as it may or may
                                   /// not be shared with the SymbolFile
  llvm::Optional<UnwindTable> m_unwind_table; ///< Table of FuncUnwinders
                                              /// objects created for this
                                              /// Module's functions
  lldb::SymbolVendorUP
      m_symfile_up; ///< A pointer to the symbol vendor for this module.
  std::vector<lldb::SymbolVendorUP>
      m_old_symfiles; ///< If anyone calls Module::SetSymbolFileFileSpec() and
                      /// changes the symbol file,
  ///< we need to keep all old symbol files around in case anyone has type
  /// references to them
  TypeSystemMap m_type_system_map; ///< A map of any type systems associated
                                   /// with this module
  /// Module specific source remappings for when you have debug info for a
  /// module that doesn't match where the sources currently are.
  PathMappingList m_source_mappings =
      ModuleList::GetGlobalModuleListProperties().GetSymlinkMappings();

  lldb::SectionListUP m_sections_up; ///< Unified section list for module that
                                     /// is used by the ObjectFile and and
                                     /// ObjectFile instances for the debug info

  std::atomic<bool> m_did_load_objfile{false};
  std::atomic<bool> m_did_load_symfile{false};
  std::atomic<bool> m_did_set_uuid{false};
  mutable bool m_file_has_changed : 1,
      m_first_file_changed_log : 1; /// See if the module was modified after it
                                    /// was initially opened.
  /// We store a symbol table parse time duration here because we might have
  /// an object file and a symbol file which both have symbol tables. The parse
  /// time for the symbol tables can be aggregated here.
  StatsDuration m_symtab_parse_time;
  /// We store a symbol named index time duration here because we might have
  /// an object file and a symbol file which both have symbol tables. The parse
  /// time for the symbol tables can be aggregated here.
  StatsDuration m_symtab_index_time;

  std::once_flag m_optimization_warning;
  std::once_flag m_language_warning;

  /// Resolve a file or load virtual address.
  ///
  /// Tries to resolve \a vm_addr as a file address (if \a
  /// vm_addr_is_file_addr is true) or as a load address if \a
  /// vm_addr_is_file_addr is false) in the symbol vendor. \a resolve_scope
  /// indicates what clients wish to resolve and can be used to limit the
  /// scope of what is parsed.
  ///
  /// \param[in] vm_addr
  ///     The load virtual address to resolve.
  ///
  /// \param[in] vm_addr_is_file_addr
  ///     If \b true, \a vm_addr is a file address, else \a vm_addr
  ///     if a load address.
  ///
  /// \param[in] resolve_scope
  ///     The scope that should be resolved (see
  ///     SymbolContext::Scope).
  ///
  /// \param[out] so_addr
  ///     The section offset based address that got resolved if
  ///     any bits are returned.
  ///
  /// \param[out] sc
  //      The symbol context that has objects filled in. Each bit
  ///     in the \a resolve_scope pertains to a member in the \a sc.
  ///
  /// \return
  ///     A integer that contains SymbolContext::Scope bits set for
  ///     each item that was successfully resolved.
  ///
  /// \see SymbolContext::Scope
  uint32_t ResolveSymbolContextForAddress(lldb::addr_t vm_addr,
                                          bool vm_addr_is_file_addr,
                                          lldb::SymbolContextItem resolve_scope,
                                          Address &so_addr, SymbolContext &sc);

  void SymbolIndicesToSymbolContextList(Symtab *symtab,
                                        std::vector<uint32_t> &symbol_indexes,
                                        SymbolContextList &sc_list);

  bool SetArchitecture(const ArchSpec &new_arch);

  void SetUUID(const lldb_private::UUID &uuid);

  SectionList *GetUnifiedSectionList();

  friend class ModuleList;
  friend class ObjectFile;
  friend class SymbolFile;

private:
  Module(); // Only used internally by CreateJITModule ()

  void FindTypes_Impl(
      ConstString name, const CompilerDeclContext &parent_decl_ctx,
      size_t max_matches,
      llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
      TypeMap &types);

  Module(const Module &) = delete;
  const Module &operator=(const Module &) = delete;
};

} // namespace lldb_private

#endif // LLDB_CORE_MODULE_H
