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

    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
