//===-- 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/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/XcodeSDK.h"
#include "lldb/Utility/UUID.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;

/// \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, bool symbols_ok,
                     bool inlines_ok, 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, bool symbols_ok,
                     bool inlines_ok, 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)));

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

  /// \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() : m_name(), m_lookup_name() {}

    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;
  };

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.

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