//===-- IRExecutionUnit.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_EXPRESSION_IREXECUTIONUNIT_H
#define LLDB_EXPRESSION_IREXECUTIONUNIT_H

#include <atomic>
#include <memory>
#include <string>
#include <vector>

#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/Module.h"

#include "lldb/Expression/IRMemoryMap.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"

namespace llvm {

class Module;
class ExecutionEngine;
class ObjectCache;

} // namespace llvm

namespace lldb_private {

class Status;

/// \class IRExecutionUnit IRExecutionUnit.h
/// "lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT-
/// compiled code for a module.
///
/// This class encapsulates the compiled version of an expression, in IR form
/// (for interpretation purposes) and in raw machine code form (for execution
/// in the target).
///
/// This object wraps an IR module that comes from the expression parser, and
/// knows how to use the JIT to make it into executable code.  It can then be
/// used as input to the IR interpreter, or the address of the executable code
/// can be passed to a thread plan to run in the target.
///
/// This class creates a subclass of LLVM's SectionMemoryManager, because that
/// is how the JIT emits code.  Because LLDB needs to move JIT-compiled code
/// into the target process, the IRExecutionUnit knows how to copy the emitted
/// code into the target process.
class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>,
                        public IRMemoryMap,
                        public ObjectFileJITDelegate {
public:
  /// Constructor
  IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_up,
                  std::unique_ptr<llvm::Module> &module_up, ConstString &name,
                  const lldb::TargetSP &target_sp, const SymbolContext &sym_ctx,
                  std::vector<std::string> &cpu_features);

  /// Destructor
  ~IRExecutionUnit() override;

  ConstString GetFunctionName() { return m_name; }

  llvm::Module *GetModule() { return m_module; }

  llvm::Function *GetFunction() {
    return ((m_module != nullptr) ? m_module->getFunction(m_name.GetStringRef())
                                  : nullptr);
  }

  void GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
                       lldb::addr_t &func_end);

  /// Accessors for IRForTarget and other clients that may want binary data
  /// placed on their behalf.  The binary data is owned by the IRExecutionUnit
  /// unless the client explicitly chooses to free it.

  lldb::addr_t WriteNow(const uint8_t *bytes, size_t size, Status &error);

  void FreeNow(lldb::addr_t allocation);

  /// ObjectFileJITDelegate overrides
  lldb::ByteOrder GetByteOrder() const override;

  uint32_t GetAddressByteSize() const override;

  void PopulateSymtab(lldb_private::ObjectFile *obj_file,
                      lldb_private::Symtab &symtab) override;

  void PopulateSectionList(lldb_private::ObjectFile *obj_file,
                           lldb_private::SectionList &section_list) override;

  ArchSpec GetArchitecture() override;

  lldb::ModuleSP GetJITModule();

  lldb::addr_t FindSymbol(ConstString name, bool &missing_weak);

  void GetStaticInitializers(std::vector<lldb::addr_t> &static_initializers);

  /// \class JittedFunction IRExecutionUnit.h
  /// "lldb/Expression/IRExecutionUnit.h"
  /// Encapsulates a single function that has been generated by the JIT.
  ///
  /// Functions that have been generated by the JIT are first resident in the
  /// local process, and then placed in the target process.  JittedFunction
  /// represents a function possibly resident in both.
  struct JittedEntity {
    ConstString m_name;        ///< The function's name
    lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
    lldb::addr_t
        m_remote_addr; ///< The address of the function in the target's memory

    /// Constructor
    ///
    /// Initializes class variabes.
    ///
    /// \param[in] name
    ///     The name of the function.
    ///
    /// \param[in] local_addr
    ///     The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
    ///     it is not present in LLDB's memory.
    ///
    /// \param[in] remote_addr
    ///     The address of the function in the target, or LLDB_INVALID_ADDRESS
    ///     if it is not present in the target's memory.
    JittedEntity(const char *name,
                 lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
                 lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
        : m_name(name), m_local_addr(local_addr), m_remote_addr(remote_addr) {}
  };

  struct JittedFunction : JittedEntity {
    bool m_external;
    JittedFunction(const char *name, bool external,
                   lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
                   lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
        : JittedEntity(name, local_addr, remote_addr), m_external(external) {}
  };

  struct JittedGlobalVariable : JittedEntity {
    JittedGlobalVariable(const char *name,
                         lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
                         lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
        : JittedEntity(name, local_addr, remote_addr) {}
  };

  const std::vector<JittedFunction> &GetJittedFunctions() {
    return m_jitted_functions;
  }

  const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables() {
    return m_jitted_global_variables;
  }

private:
  /// Look up the object in m_address_map that contains a given address, find
  /// where it was copied to, and return the remote address at the same offset
  /// into the copied entity
  ///
  /// \param[in] local_address
  ///     The address in the debugger.
  ///
  /// \return
  ///     The address in the target process.
  lldb::addr_t GetRemoteAddressForLocal(lldb::addr_t local_address);

  typedef std::pair<lldb::addr_t, uintptr_t> AddrRange;

  /// Look up the object in m_address_map that contains a given address, find
  /// where it was copied to, and return its address range in the target
  /// process
  ///
  /// \param[in] local_address
  ///     The address in the debugger.
  ///
  /// \return
  ///     The range of the containing object in the target process.
  AddrRange GetRemoteRangeForLocal(lldb::addr_t local_address);

  /// Commit all allocations to the process and record where they were stored.
  ///
  /// \param[in] process_sp
  ///     The process to allocate memory in.
  ///
  /// \return
  ///     True <=> all allocations were performed successfully.
  ///     This method will attempt to free allocated memory if the
  ///     operation fails.
  bool CommitAllocations(lldb::ProcessSP &process_sp);

  /// Report all committed allocations to the execution engine.
  ///
  /// \param[in] engine
  ///     The execution engine to notify.
  void ReportAllocations(llvm::ExecutionEngine &engine);

  /// Write the contents of all allocations to the process.
  ///
  /// \param[in] process_sp
  ///     The process containing the allocations.
  ///
  /// \return
  ///     True <=> all allocations were performed successfully.
  bool WriteData(lldb::ProcessSP &process_sp);

  Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp);

  void CollectCandidateCNames(std::vector<ConstString> &C_names,
                              ConstString name);

  void CollectCandidateCPlusPlusNames(std::vector<ConstString> &CPP_names,
                                      const std::vector<ConstString> &C_names,
                                      const SymbolContext &sc);

  lldb::addr_t FindInSymbols(const std::vector<ConstString> &names,
                             const lldb_private::SymbolContext &sc,
                             bool &symbol_was_missing_weak);

  lldb::addr_t FindInRuntimes(const std::vector<ConstString> &names,
                              const lldb_private::SymbolContext &sc);

  lldb::addr_t FindInUserDefinedSymbols(const std::vector<ConstString> &names,
                                        const lldb_private::SymbolContext &sc);

  void ReportSymbolLookupError(ConstString name);

  class MemoryManager : public llvm::SectionMemoryManager {
  public:
    MemoryManager(IRExecutionUnit &parent);

    ~MemoryManager() override;

    /// Allocate space for executable code, and add it to the m_spaceBlocks
    /// map
    ///
    /// \param[in] Size
    ///     The size of the area.
    ///
    /// \param[in] Alignment
    ///     The required alignment of the area.
    ///
    /// \param[in] SectionID
    ///     A unique identifier for the section.
    ///
    /// \return
    ///     Allocated space.
    uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
                                 unsigned SectionID,
                                 llvm::StringRef SectionName) override;

    /// Allocate space for data, and add it to the m_spaceBlocks map
    ///
    /// \param[in] Size
    ///     The size of the area.
    ///
    /// \param[in] Alignment
    ///     The required alignment of the area.
    ///
    /// \param[in] SectionID
    ///     A unique identifier for the section.
    ///
    /// \param[in] IsReadOnly
    ///     Flag indicating the section is read-only.
    ///
    /// \return
    ///     Allocated space.
    uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
                                 unsigned SectionID,
                                 llvm::StringRef SectionName,
                                 bool IsReadOnly) override;

    /// Called when object loading is complete and section page permissions
    /// can be applied. Currently unimplemented for LLDB.
    ///
    /// \param[out] ErrMsg
    ///     The error that prevented the page protection from succeeding.
    ///
    /// \return
    ///     True in case of failure, false in case of success.
    bool finalizeMemory(std::string *ErrMsg) override {
      // TODO: Ensure that the instruction cache is flushed because
      // relocations are updated by dy-load.  See:
      //   sys::Memory::InvalidateInstructionCache
      //   llvm::SectionMemoryManager
      return false;
    }

    // Ignore any EHFrame registration.
    void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
                          size_t Size) override {}
    void deregisterEHFrames() override {}

    uint64_t getSymbolAddress(const std::string &Name) override;

    // Find the address of the symbol Name.  If Name is a missing weak symbol
    // then missing_weak will be true.
    uint64_t GetSymbolAddressAndPresence(const std::string &Name,
                                         bool &missing_weak);

    llvm::JITSymbol findSymbol(const std::string &Name) override;

    void *getPointerToNamedFunction(const std::string &Name,
                                    bool AbortOnFailure = true) override;

  private:
    std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory
                                                           /// allocator to use
                                                           /// in actually
                                                           /// creating space.
                                                           /// All calls are
                                                           /// passed through to
                                                           /// it.
    IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
  };

  static const unsigned eSectionIDInvalid = (unsigned)-1;

  enum class AllocationKind { Stub, Code, Data, Global, Bytes };

  static lldb::SectionType
  GetSectionTypeFromSectionName(const llvm::StringRef &name,
                                AllocationKind alloc_kind);

  /// Encapsulates a single allocation request made by the JIT.
  ///
  /// Allocations made by the JIT are first queued up and then applied in bulk
  /// to the underlying process.
  struct AllocationRecord {
    std::string m_name;
    lldb::addr_t m_process_address;
    uintptr_t m_host_address;
    uint32_t m_permissions;
    lldb::SectionType m_sect_type;
    size_t m_size;
    unsigned m_alignment;
    unsigned m_section_id;

    AllocationRecord(uintptr_t host_address, uint32_t permissions,
                     lldb::SectionType sect_type, size_t size,
                     unsigned alignment, unsigned section_id, const char *name)
        : m_name(), m_process_address(LLDB_INVALID_ADDRESS),
          m_host_address(host_address), m_permissions(permissions),
          m_sect_type(sect_type), m_size(size), m_alignment(alignment),
          m_section_id(section_id) {
      if (name && name[0])
        m_name = name;
    }

    void dump(Log *log);
  };

  bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error,
                           AllocationRecord &record);

  typedef std::vector<AllocationRecord> RecordVector;
  RecordVector m_records;

  std::unique_ptr<llvm::LLVMContext> m_context_up;
  std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up;
  std::unique_ptr<llvm::ObjectCache> m_object_cache_up;
  std::unique_ptr<llvm::Module>
      m_module_up;        ///< Holder for the module until it's been handed off
  llvm::Module *m_module; ///< Owned by the execution engine
  std::vector<std::string> m_cpu_features;
  std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions
                                                  ///that have been JITted into
                                                  ///machine code
  std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of
                                                               ///all functions
                                                               ///that have been
                                                               ///JITted into
                                                               ///machine code
  const ConstString m_name;
  SymbolContext m_sym_ctx; ///< Used for symbol lookups
  std::vector<ConstString> m_failed_lookups;

  std::atomic<bool> m_did_jit;

  lldb::addr_t m_function_load_addr;
  lldb::addr_t m_function_end_load_addr;

  bool m_strip_underscore = true; ///< True for platforms where global symbols
                                  ///  have a _ prefix
  bool m_reported_allocations; ///< True after allocations have been reported.
                               ///It is possible that
  ///< sections will be allocated when this is true, in which case they weren't
  ///< depended on by any function.  (Top-level code defining a variable, but
  ///< defining no functions using that variable, would do this.)  If this
  ///< is true, any allocations need to be committed immediately -- no
  ///< opportunity for relocation.
};

} // namespace lldb_private

#endif // LLDB_EXPRESSION_IREXECUTIONUNIT_H
