//===-- NativeProcessProtocol.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_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
#define LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H

#include "NativeBreakpointList.h"
#include "NativeThreadProtocol.h"
#include "NativeWatchpointList.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/MainLoop.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/TraceGDBRemotePackets.h"
#include "lldb/Utility/UnimplementedError.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include <mutex>
#include <unordered_map>
#include <vector>

namespace lldb_private {
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();

class MemoryRegionInfo;
class ResumeActionList;

struct SVR4LibraryInfo {
  std::string name;
  lldb::addr_t link_map;
  lldb::addr_t base_addr;
  lldb::addr_t ld_addr;
  lldb::addr_t next;
};

// NativeProcessProtocol
class NativeProcessProtocol {
public:
  virtual ~NativeProcessProtocol() = default;

  virtual Status Resume(const ResumeActionList &resume_actions) = 0;

  virtual Status Halt() = 0;

  virtual Status Detach() = 0;

  /// Sends a process a UNIX signal \a signal.
  ///
  /// \return
  ///     Returns an error object.
  virtual Status Signal(int signo) = 0;

  /// Tells a process to interrupt all operations as if by a Ctrl-C.
  ///
  /// The default implementation will send a local host's equivalent of
  /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
  /// operation.
  ///
  /// \return
  ///     Returns an error object.
  virtual Status Interrupt();

  virtual Status Kill() = 0;

  // Tells a process not to stop the inferior on given signals and just
  // reinject them back.
  virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);

  // Memory and memory region functions

  virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
                                     MemoryRegionInfo &range_info);

  virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
                            size_t &bytes_read) = 0;

  Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
                               size_t &bytes_read);

  virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
                                std::vector<uint8_t> &tags);

  virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
                                 const std::vector<uint8_t> &tags);

  /// Reads a null terminated string from memory.
  ///
  /// Reads up to \p max_size bytes of memory until it finds a '\0'.
  /// If a '\0' is not found then it reads max_size-1 bytes as a string and a
  /// '\0' is added as the last character of the \p buffer.
  ///
  /// \param[in] addr
  ///     The address in memory to read from.
  ///
  /// \param[in] buffer
  ///     An allocated buffer with at least \p max_size size.
  ///
  /// \param[in] max_size
  ///     The maximum number of bytes to read from memory until it reads the
  ///     string.
  ///
  /// \param[out] total_bytes_read
  ///     The number of bytes read from memory into \p buffer.
  ///
  /// \return
  ///     Returns a StringRef backed up by the \p buffer passed in.
  llvm::Expected<llvm::StringRef>
  ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size,
                        size_t &total_bytes_read);

  virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
                             size_t &bytes_written) = 0;

  virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
                                                      uint32_t permissions) {
    return llvm::make_error<UnimplementedError>();
  }

  virtual llvm::Error DeallocateMemory(lldb::addr_t addr) {
    return llvm::make_error<UnimplementedError>();
  }

  virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;

  virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
  GetLoadedSVR4Libraries() {
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Not implemented");
  }

  virtual bool IsAlive() const;

  virtual size_t UpdateThreads() = 0;

  virtual const ArchSpec &GetArchitecture() const = 0;

  // Breakpoint functions
  virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
                               bool hardware) = 0;

  virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);

  // Hardware Breakpoint functions
  virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;

  virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);

  virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);

  // Watchpoint functions
  virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;

  virtual llvm::Optional<std::pair<uint32_t, uint32_t>>
  GetHardwareDebugSupportInfo() const;

  virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
                               uint32_t watch_flags, bool hardware);

  virtual Status RemoveWatchpoint(lldb::addr_t addr);

  // Accessors
  lldb::pid_t GetID() const { return m_pid; }

  lldb::StateType GetState() const;

  bool IsRunning() const {
    return m_state == lldb::eStateRunning || IsStepping();
  }

  bool IsStepping() const { return m_state == lldb::eStateStepping; }

  bool CanResume() const { return m_state == lldb::eStateStopped; }

  lldb::ByteOrder GetByteOrder() const {
    return GetArchitecture().GetByteOrder();
  }

  uint32_t GetAddressByteSize() const {
    return GetArchitecture().GetAddressByteSize();
  }

  virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
  GetAuxvData() const = 0;

  // Exit Status
  virtual llvm::Optional<WaitStatus> GetExitStatus();

  virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);

  // Access to threads
  NativeThreadProtocol *GetThreadAtIndex(uint32_t idx);

  NativeThreadProtocol *GetThreadByID(lldb::tid_t tid);

  void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }

  lldb::tid_t GetCurrentThreadID() { return m_current_thread_id; }

  NativeThreadProtocol *GetCurrentThread() {
    return GetThreadByID(m_current_thread_id);
  }

  // Access to inferior stdio
  virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }

  // Stop id interface

  uint32_t GetStopID() const;

  // Callbacks for low-level process state changes
  class NativeDelegate {
  public:
    virtual ~NativeDelegate() = default;

    virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;

    virtual void ProcessStateChanged(NativeProcessProtocol *process,
                                     lldb::StateType state) = 0;

    virtual void DidExec(NativeProcessProtocol *process) = 0;

    virtual void
    NewSubprocess(NativeProcessProtocol *parent_process,
                  std::unique_ptr<NativeProcessProtocol> child_process) = 0;
  };

  virtual Status GetLoadedModuleFileSpec(const char *module_path,
                                         FileSpec &file_spec) = 0;

  virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
                                    lldb::addr_t &load_addr) = 0;

  /// Extension flag constants, returned by Factory::GetSupportedExtensions()
  /// and passed to SetEnabledExtension()
  enum class Extension {
    multiprocess = (1u << 0),
    fork = (1u << 1),
    vfork = (1u << 2),
    pass_signals = (1u << 3),
    auxv = (1u << 4),
    libraries_svr4 = (1u << 5),
    memory_tagging = (1u << 6),

    LLVM_MARK_AS_BITMASK_ENUM(memory_tagging)
  };

  class Factory {
  public:
    virtual ~Factory();
    /// Launch a process for debugging.
    ///
    /// \param[in] launch_info
    ///     Information required to launch the process.
    ///
    /// \param[in] native_delegate
    ///     The delegate that will receive messages regarding the
    ///     inferior.  Must outlive the NativeProcessProtocol
    ///     instance.
    ///
    /// \param[in] mainloop
    ///     The mainloop instance with which the process can register
    ///     callbacks. Must outlive the NativeProcessProtocol
    ///     instance.
    ///
    /// \return
    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
    ///     an error object if it failed.
    virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
    Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
           MainLoop &mainloop) const = 0;

    /// Attach to an existing process.
    ///
    /// \param[in] pid
    ///     pid of the process locatable
    ///
    /// \param[in] native_delegate
    ///     The delegate that will receive messages regarding the
    ///     inferior.  Must outlive the NativeProcessProtocol
    ///     instance.
    ///
    /// \param[in] mainloop
    ///     The mainloop instance with which the process can register
    ///     callbacks. Must outlive the NativeProcessProtocol
    ///     instance.
    ///
    /// \return
    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
    ///     an error object if it failed.
    virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
    Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
           MainLoop &mainloop) const = 0;

    /// Get the bitmask of extensions supported by this process plugin.
    ///
    /// \return
    ///     A NativeProcessProtocol::Extension bitmask.
    virtual Extension GetSupportedExtensions() const { return {}; }
  };

  /// Start tracing a process or its threads.
  ///
  /// \param[in] json_params
  ///     JSON object with the information of what and how to trace.
  ///     In the case of gdb-remote, this object should conform to the
  ///     jLLDBTraceStart packet.
  ///
  ///     This object should have a string entry called "type", which is the
  ///     tracing technology name.
  ///
  /// \param[in] type
  ///     Tracing technology type, as described in the \a json_params.
  ///
  /// \return
  ///     \a llvm::Error::success if the operation was successful, or an
  ///     \a llvm::Error otherwise.
  virtual llvm::Error TraceStart(llvm::StringRef json_params,
                                 llvm::StringRef type) {
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Unsupported tracing type '%s'",
                                   type.data());
  }

  /// \copydoc Process::TraceStop(const TraceStopRequest &)
  virtual llvm::Error TraceStop(const TraceStopRequest &request) {
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Unsupported tracing type '%s'",
                                   request.type.data());
  }

  /// \copydoc Process::TraceGetState(llvm::StringRef type)
  virtual llvm::Expected<llvm::json::Value>
  TraceGetState(llvm::StringRef type) {
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Unsupported tracing type '%s'",
                                   type.data());
  }

  /// \copydoc Process::TraceGetBinaryData(const TraceGetBinaryDataRequest &)
  virtual llvm::Expected<std::vector<uint8_t>>
  TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {
    return llvm::createStringError(
        llvm::inconvertibleErrorCode(),
        "Unsupported data kind '%s' for the '%s' tracing technology",
        request.kind.c_str(), request.type.c_str());
  }

  /// \copydoc Process::TraceSupported()
  virtual llvm::Expected<TraceSupportedResponse> TraceSupported() {
    return llvm::make_error<UnimplementedError>();
  }

  /// Method called in order to propagate the bitmap of protocol
  /// extensions supported by the client.
  ///
  /// \param[in] flags
  ///     The bitmap of enabled extensions.
  virtual void SetEnabledExtensions(Extension flags) {
    m_enabled_extensions = flags;
  }

protected:
  struct SoftwareBreakpoint {
    uint32_t ref_count;
    llvm::SmallVector<uint8_t, 4> saved_opcodes;
    llvm::ArrayRef<uint8_t> breakpoint_opcodes;
  };

  std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
  lldb::pid_t m_pid;

  std::vector<std::unique_ptr<NativeThreadProtocol>> m_threads;
  lldb::tid_t m_current_thread_id = LLDB_INVALID_THREAD_ID;
  mutable std::recursive_mutex m_threads_mutex;

  lldb::StateType m_state = lldb::eStateInvalid;
  mutable std::recursive_mutex m_state_mutex;

  llvm::Optional<WaitStatus> m_exit_status;

  NativeDelegate &m_delegate;
  NativeWatchpointList m_watchpoint_list;
  HardwareBreakpointMap m_hw_breakpoints_map;
  int m_terminal_fd;
  uint32_t m_stop_id = 0;

  // Set of signal numbers that LLDB directly injects back to inferior without
  // stopping it.
  llvm::DenseSet<int> m_signals_to_ignore;

  // Extensions enabled per the last SetEnabledExtensions() call.
  Extension m_enabled_extensions;

  // lldb_private::Host calls should be used to launch a process for debugging,
  // and then the process should be attached to. When attaching to a process
  // lldb_private::Host calls should be used to locate the process to attach
  // to, and then this function should be called.
  NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
                        NativeDelegate &delegate);

  void SetID(lldb::pid_t pid) { m_pid = pid; }

  // interface for state handling
  void SetState(lldb::StateType state, bool notify_delegates = true);

  // Derived classes need not implement this.  It can be used as a hook to
  // clear internal caches that should be invalidated when stop ids change.
  //
  // Note this function is called with the state mutex obtained by the caller.
  virtual void DoStopIDBumped(uint32_t newBumpId);

  // interface for software breakpoints

  Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
  Status RemoveSoftwareBreakpoint(lldb::addr_t addr);

  virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
  GetSoftwareBreakpointTrapOpcode(size_t size_hint);

  /// Return the offset of the PC relative to the software breakpoint that was hit. If an
  /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset
  /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the
  /// PC, this offset will be the size of the breakpoint opcode.
  virtual size_t GetSoftwareBreakpointPCOffset();

  // Adjust the thread's PC after hitting a software breakpoint. On
  // architectures where the PC points after the breakpoint instruction, this
  // resets it to point to the breakpoint itself.
  void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread);

  /// Notify the delegate that an exec occurred.
  ///
  /// Provide a mechanism for a delegate to clear out any exec-
  /// sensitive data.
  void NotifyDidExec();

  NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);

private:
  void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
  llvm::Expected<SoftwareBreakpoint>
  EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
};
} // namespace lldb_private

#endif // LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
