//===-- GDBRemoteCommunicationClient.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_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H

#include "GDBRemoteClientBase.h"

#include <chrono>
#include <map>
#include <mutex>
#include <string>
#include <vector>

#include "lldb/Host/File.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/TraceGDBRemotePackets.h"
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
#endif

#include "llvm/ADT/Optional.h"
#include "llvm/Support/VersionTuple.h"

namespace lldb_private {
namespace process_gdb_remote {

/// The offsets used by the target when relocating the executable. Decoded from
/// qOffsets packet response.
struct QOffsets {
  /// If true, the offsets field describes segments. Otherwise, it describes
  /// sections.
  bool segments;

  /// The individual offsets. Section offsets have two or three members.
  /// Segment offsets have either one of two.
  std::vector<uint64_t> offsets;
};
inline bool operator==(const QOffsets &a, const QOffsets &b) {
  return a.segments == b.segments && a.offsets == b.offsets;
}
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets);

class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
public:
  GDBRemoteCommunicationClient();

  ~GDBRemoteCommunicationClient() override;

  // After connecting, send the handshake to the server to make sure
  // we are communicating with it.
  bool HandshakeWithServer(Status *error_ptr);

  // For packets which specify a range of output to be returned,
  // return all of the output via a series of request packets of the form
  // <prefix>0,<size>
  // <prefix><size>,<size>
  // <prefix><size>*2,<size>
  // <prefix><size>*3,<size>
  // ...
  // until a "$l..." packet is received, indicating the end.
  // (size is in hex; this format is used by a standard gdbserver to
  // return the given portion of the output specified by <prefix>;
  // for example, "qXfer:libraries-svr4:read::fff,1000" means
  // "return a chunk of the xml description file for shared
  // library load addresses, where the chunk starts at offset 0xfff
  // and continues for 0x1000 bytes").
  // Concatenate the resulting server response packets together and
  // return in response_string.  If any packet fails, the return value
  // indicates that failure and the returned string value is undefined.
  PacketResult
  SendPacketsAndConcatenateResponses(const char *send_payload_prefix,
                                     std::string &response_string);

  bool GetThreadSuffixSupported();

  // This packet is usually sent first and the boolean return value
  // indicates if the packet was send and any response was received
  // even in the response is UNIMPLEMENTED. If the packet failed to
  // get a response, then false is returned. This quickly tells us
  // if we were able to connect and communicate with the remote GDB
  // server
  bool QueryNoAckModeSupported();

  void GetListThreadsInStopReplySupported();

  lldb::pid_t GetCurrentProcessID(bool allow_lazy = true);

  bool GetLaunchSuccess(std::string &error_str);

  bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid,
                       uint16_t &port, std::string &socket_name);

  size_t QueryGDBServer(
      std::vector<std::pair<uint16_t, std::string>> &connection_urls);

  bool KillSpawnedProcess(lldb::pid_t pid);

  /// Sends a GDB remote protocol 'A' packet that delivers program
  /// arguments to the remote server.
  ///
  /// \param[in] launch_info
  ///     A NULL terminated array of const C strings to use as the
  ///     arguments.
  ///
  /// \return
  ///     Zero if the response was "OK", a positive value if the
  ///     the response was "Exx" where xx are two hex digits, or
  ///     -1 if the call is unsupported or any other unexpected
  ///     response was received.
  int SendArgumentsPacket(const ProcessLaunchInfo &launch_info);

  /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
  /// environment that will get used when launching an application
  /// in conjunction with the 'A' packet. This function can be called
  /// multiple times in a row in order to pass on the desired
  /// environment that the inferior should be launched with.
  ///
  /// \param[in] name_equal_value
  ///     A NULL terminated C string that contains a single environment
  ///     in the format "NAME=VALUE".
  ///
  /// \return
  ///     Zero if the response was "OK", a positive value if the
  ///     the response was "Exx" where xx are two hex digits, or
  ///     -1 if the call is unsupported or any other unexpected
  ///     response was received.
  int SendEnvironmentPacket(char const *name_equal_value);
  int SendEnvironment(const Environment &env);

  int SendLaunchArchPacket(const char *arch);

  int SendLaunchEventDataPacket(const char *data,
                                bool *was_supported = nullptr);

  /// Sends a "vAttach:PID" where PID is in hex.
  ///
  /// \param[in] pid
  ///     A process ID for the remote gdb server to attach to.
  ///
  /// \param[out] response
  ///     The response received from the gdb server. If the return
  ///     value is zero, \a response will contain a stop reply
  ///     packet.
  ///
  /// \return
  ///     Zero if the attach was successful, or an error indicating
  ///     an error code.
  int SendAttach(lldb::pid_t pid, StringExtractorGDBRemote &response);

  /// Sends a GDB remote protocol 'I' packet that delivers stdin
  /// data to the remote process.
  ///
  /// \param[in] data
  ///     A pointer to stdin data.
  ///
  /// \param[in] data_len
  ///     The number of bytes available at \a data.
  ///
  /// \return
  ///     Zero if the attach was successful, or an error indicating
  ///     an error code.
  int SendStdinNotification(const char *data, size_t data_len);

  /// Sets the path to use for stdin/out/err for a process
  /// that will be launched with the 'A' packet.
  ///
  /// \param[in] file_spec
  ///     The path to use for stdin/out/err
  ///
  /// \return
  ///     Zero if the for success, or an error code for failure.
  int SetSTDIN(const FileSpec &file_spec);
  int SetSTDOUT(const FileSpec &file_spec);
  int SetSTDERR(const FileSpec &file_spec);

  /// Sets the disable ASLR flag to \a enable for a process that will
  /// be launched with the 'A' packet.
  ///
  /// \param[in] enable
  ///     A boolean value indicating whether to disable ASLR or not.
  ///
  /// \return
  ///     Zero if the for success, or an error code for failure.
  int SetDisableASLR(bool enable);

  /// Sets the DetachOnError flag to \a enable for the process controlled by the
  /// stub.
  ///
  /// \param[in] enable
  ///     A boolean value indicating whether to detach on error or not.
  ///
  /// \return
  ///     Zero if the for success, or an error code for failure.
  int SetDetachOnError(bool enable);

  /// Sets the working directory to \a path for a process that will
  /// be launched with the 'A' packet for non platform based
  /// connections. If this packet is sent to a GDB server that
  /// implements the platform, it will change the current working
  /// directory for the platform process.
  ///
  /// \param[in] working_dir
  ///     The path to a directory to use when launching our process
  ///
  /// \return
  ///     Zero if the for success, or an error code for failure.
  int SetWorkingDir(const FileSpec &working_dir);

  /// Gets the current working directory of a remote platform GDB
  /// server.
  ///
  /// \param[out] working_dir
  ///     The current working directory on the remote platform.
  ///
  /// \return
  ///     Boolean for success
  bool GetWorkingDir(FileSpec &working_dir);

  lldb::addr_t AllocateMemory(size_t size, uint32_t permissions);

  bool DeallocateMemory(lldb::addr_t addr);

  Status Detach(bool keep_stopped);

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

  Status GetWatchpointSupportInfo(uint32_t &num);

  Status GetWatchpointSupportInfo(uint32_t &num, bool &after,
                                  const ArchSpec &arch);

  Status GetWatchpointsTriggerAfterInstruction(bool &after,
                                               const ArchSpec &arch);

  const ArchSpec &GetHostArchitecture();

  std::chrono::seconds GetHostDefaultPacketTimeout();

  const ArchSpec &GetProcessArchitecture();

  void GetRemoteQSupported();

  bool GetVContSupported(char flavor);

  bool GetpPacketSupported(lldb::tid_t tid);

  bool GetxPacketSupported();

  bool GetVAttachOrWaitSupported();

  bool GetSyncThreadStateSupported();

  void ResetDiscoverableSettings(bool did_exec);

  bool GetHostInfo(bool force = false);

  bool GetDefaultThreadId(lldb::tid_t &tid);

  llvm::VersionTuple GetOSVersion();

  llvm::VersionTuple GetMacCatalystVersion();

  bool GetOSBuildString(std::string &s);

  bool GetOSKernelDescription(std::string &s);

  ArchSpec GetSystemArchitecture();

  bool GetHostname(std::string &s);

  lldb::addr_t GetShlibInfoAddr();

  bool GetSupportsThreadSuffix();

  bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info);

  uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info,
                         ProcessInstanceInfoList &process_infos);

  bool GetUserName(uint32_t uid, std::string &name);

  bool GetGroupName(uint32_t gid, std::string &name);

  bool HasFullVContSupport() { return GetVContSupported('A'); }

  bool HasAnyVContSupport() { return GetVContSupported('a'); }

  bool GetStopReply(StringExtractorGDBRemote &response);

  bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response);

  bool SupportsGDBStoppointPacket(GDBStoppointType type) {
    switch (type) {
    case eBreakpointSoftware:
      return m_supports_z0;
    case eBreakpointHardware:
      return m_supports_z1;
    case eWatchpointWrite:
      return m_supports_z2;
    case eWatchpointRead:
      return m_supports_z3;
    case eWatchpointReadWrite:
      return m_supports_z4;
    default:
      return false;
    }
  }

  uint8_t SendGDBStoppointTypePacket(
      GDBStoppointType type, // Type of breakpoint or watchpoint
      bool insert,           // Insert or remove?
      lldb::addr_t addr,     // Address of breakpoint or watchpoint
      uint32_t length);      // Byte Size of breakpoint or watchpoint

  bool SetNonStopMode(const bool enable);

  void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send,
                       uint32_t max_recv, uint64_t recv_amount, bool json,
                       Stream &strm);

  // This packet is for testing the speed of the interface only. Both
  // the client and server need to support it, but this allows us to
  // measure the packet speed without any other work being done on the
  // other end and avoids any of that work affecting the packet send
  // and response times.
  bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);

  bool SetCurrentThread(uint64_t tid);

  bool SetCurrentThreadForRun(uint64_t tid);

  bool GetQXferAuxvReadSupported();

  void EnableErrorStringInPacket();

  bool GetQXferLibrariesReadSupported();

  bool GetQXferLibrariesSVR4ReadSupported();

  uint64_t GetRemoteMaxPacketSize();

  bool GetEchoSupported();

  bool GetQPassSignalsSupported();

  bool GetAugmentedLibrariesSVR4ReadSupported();

  bool GetQXferFeaturesReadSupported();

  bool GetQXferMemoryMapReadSupported();

  LazyBool SupportsAllocDeallocMemory() // const
  {
    // Uncomment this to have lldb pretend the debug server doesn't respond to
    // alloc/dealloc memory packets.
    // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
    return m_supports_alloc_dealloc_memory;
  }

  std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
  GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable);

  size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
                             bool &sequence_mutex_unavailable);

  lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
                           mode_t mode, Status &error);

  bool CloseFile(lldb::user_id_t fd, Status &error);

  lldb::user_id_t GetFileSize(const FileSpec &file_spec);

  void AutoCompleteDiskFileOrDirectory(CompletionRequest &request,
                                       bool only_dir);

  Status GetFilePermissions(const FileSpec &file_spec,
                            uint32_t &file_permissions);

  Status SetFilePermissions(const FileSpec &file_spec,
                            uint32_t file_permissions);

  uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
                    uint64_t dst_len, Status &error);

  uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
                     uint64_t src_len, Status &error);

  Status CreateSymlink(const FileSpec &src, const FileSpec &dst);

  Status Unlink(const FileSpec &file_spec);

  Status MakeDirectory(const FileSpec &file_spec, uint32_t mode);

  bool GetFileExists(const FileSpec &file_spec);

  Status RunShellCommand(
      llvm::StringRef command,
      const FileSpec &working_dir, // Pass empty FileSpec to use the current
                                   // working directory
      int *status_ptr, // Pass nullptr if you don't want the process exit status
      int *signo_ptr,  // Pass nullptr if you don't want the signal that caused
                       // the process to exit
      std::string
          *command_output, // Pass nullptr if you don't want the command output
      const Timeout<std::micro> &timeout);

  bool CalculateMD5(const FileSpec &file_spec, uint64_t &high, uint64_t &low);

  lldb::DataBufferSP ReadRegister(
      lldb::tid_t tid,
      uint32_t
          reg_num); // Must be the eRegisterKindProcessPlugin register number

  lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid);

  bool
  WriteRegister(lldb::tid_t tid,
                uint32_t reg_num, // eRegisterKindProcessPlugin register number
                llvm::ArrayRef<uint8_t> data);

  bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);

  bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);

  bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id);

  bool SyncThreadState(lldb::tid_t tid);

  const char *GetGDBServerProgramName();

  uint32_t GetGDBServerProgramVersion();

  bool AvoidGPackets(ProcessGDBRemote *process);

  StructuredData::ObjectSP GetThreadsInfo();

  bool GetThreadExtendedInfoSupported();

  bool GetLoadedDynamicLibrariesInfosSupported();

  bool GetSharedCacheInfoSupported();

  /// Use qOffsets to query the offset used when relocating the target
  /// executable. If successful, the returned structure will contain at least
  /// one value in the offsets field.
  llvm::Optional<QOffsets> GetQOffsets();

  bool GetModuleInfo(const FileSpec &module_file_spec,
                     const ArchSpec &arch_spec, ModuleSpec &module_spec);

  llvm::Optional<std::vector<ModuleSpec>>
  GetModulesInfo(llvm::ArrayRef<FileSpec> module_file_specs,
                 const llvm::Triple &triple);

  bool ReadExtFeature(const lldb_private::ConstString object,
                      const lldb_private::ConstString annex, std::string &out,
                      lldb_private::Status &err);

  void ServeSymbolLookups(lldb_private::Process *process);

  // Sends QPassSignals packet to the server with given signals to ignore.
  Status SendSignalsToIgnore(llvm::ArrayRef<int32_t> signals);

  /// Return the feature set supported by the gdb-remote server.
  ///
  /// This method returns the remote side's response to the qSupported
  /// packet.  The response is the complete string payload returned
  /// to the client.
  ///
  /// \return
  ///     The string returned by the server to the qSupported query.
  const std::string &GetServerSupportedFeatures() const {
    return m_qSupported_response;
  }

  /// Return the array of async JSON packet types supported by the remote.
  ///
  /// This method returns the remote side's array of supported JSON
  /// packet types as a list of type names.  Each of the results are
  /// expected to have an Enable{type_name} command to enable and configure
  /// the related feature.  Each type_name for an enabled feature will
  /// possibly send async-style packets that contain a payload of a
  /// binhex-encoded JSON dictionary.  The dictionary will have a
  /// string field named 'type', that contains the type_name of the
  /// supported packet type.
  ///
  /// There is a Plugin category called structured-data plugins.
  /// A plugin indicates whether it knows how to handle a type_name.
  /// If so, it can be used to process the async JSON packet.
  ///
  /// \return
  ///     The string returned by the server to the qSupported query.
  lldb_private::StructuredData::Array *GetSupportedStructuredDataPlugins();

  /// Configure a StructuredData feature on the remote end.
  ///
  /// \see \b Process::ConfigureStructuredData(...) for details.
  Status
  ConfigureRemoteStructuredData(ConstString type_name,
                                const StructuredData::ObjectSP &config_sp);

  llvm::Expected<TraceSupportedResponse> SendTraceSupported();

  llvm::Error SendTraceStart(const llvm::json::Value &request);

  llvm::Error SendTraceStop(const TraceStopRequest &request);

  llvm::Expected<std::string> SendTraceGetState(llvm::StringRef type);

  llvm::Expected<std::vector<uint8_t>>
  SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request);

protected:
  LazyBool m_supports_not_sending_acks;
  LazyBool m_supports_thread_suffix;
  LazyBool m_supports_threads_in_stop_reply;
  LazyBool m_supports_vCont_all;
  LazyBool m_supports_vCont_any;
  LazyBool m_supports_vCont_c;
  LazyBool m_supports_vCont_C;
  LazyBool m_supports_vCont_s;
  LazyBool m_supports_vCont_S;
  LazyBool m_qHostInfo_is_valid;
  LazyBool m_curr_pid_is_valid;
  LazyBool m_qProcessInfo_is_valid;
  LazyBool m_qGDBServerVersion_is_valid;
  LazyBool m_supports_alloc_dealloc_memory;
  LazyBool m_supports_memory_region_info;
  LazyBool m_supports_watchpoint_support_info;
  LazyBool m_supports_detach_stay_stopped;
  LazyBool m_watchpoints_trigger_after_instruction;
  LazyBool m_attach_or_wait_reply;
  LazyBool m_prepare_for_reg_writing_reply;
  LazyBool m_supports_p;
  LazyBool m_supports_x;
  LazyBool m_avoid_g_packets;
  LazyBool m_supports_QSaveRegisterState;
  LazyBool m_supports_qXfer_auxv_read;
  LazyBool m_supports_qXfer_libraries_read;
  LazyBool m_supports_qXfer_libraries_svr4_read;
  LazyBool m_supports_qXfer_features_read;
  LazyBool m_supports_qXfer_memory_map_read;
  LazyBool m_supports_augmented_libraries_svr4_read;
  LazyBool m_supports_jThreadExtendedInfo;
  LazyBool m_supports_jLoadedDynamicLibrariesInfos;
  LazyBool m_supports_jGetSharedCacheInfo;
  LazyBool m_supports_QPassSignals;
  LazyBool m_supports_error_string_reply;
  LazyBool m_supports_multiprocess;

  bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
      m_supports_qUserName : 1, m_supports_qGroupName : 1,
      m_supports_qThreadStopInfo : 1, m_supports_z0 : 1, m_supports_z1 : 1,
      m_supports_z2 : 1, m_supports_z3 : 1, m_supports_z4 : 1,
      m_supports_QEnvironment : 1, m_supports_QEnvironmentHexEncoded : 1,
      m_supports_qSymbol : 1, m_qSymbol_requests_done : 1,
      m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1,
      m_supports_jModulesInfo : 1;

  lldb::pid_t m_curr_pid;
  lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all
                          // other operations
  lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for
                              // continue, step, etc

  uint32_t m_num_supported_hardware_watchpoints;

  ArchSpec m_host_arch;
  ArchSpec m_process_arch;
  llvm::VersionTuple m_os_version;
  llvm::VersionTuple m_maccatalyst_version;
  std::string m_os_build;
  std::string m_os_kernel;
  std::string m_hostname;
  std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if
                                 // qGDBServerVersion is not supported
  uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if
                                 // qGDBServerVersion is not supported
  std::chrono::seconds m_default_packet_timeout;
  uint64_t m_max_packet_size;        // as returned by qSupported
  std::string m_qSupported_response; // the complete response to qSupported

  bool m_supported_async_json_packets_is_valid;
  lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;

  std::vector<MemoryRegionInfo> m_qXfer_memory_map;
  bool m_qXfer_memory_map_loaded;

  bool GetCurrentProcessInfo(bool allow_lazy_pid = true);

  bool GetGDBServerVersion();

  // Given the list of compression types that the remote debug stub can support,
  // possibly enable compression if we find an encoding we can handle.
  void MaybeEnableCompression(
      llvm::ArrayRef<llvm::StringRef> supported_compressions);

  bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
                                 ProcessInstanceInfo &process_info);

  void OnRunPacketSent(bool first) override;

  PacketResult SendThreadSpecificPacketAndWaitForResponse(
      lldb::tid_t tid, StreamString &&payload,
      StringExtractorGDBRemote &response, bool send_async);

  Status SendGetTraceDataPacket(StreamGDBRemote &packet, lldb::user_id_t uid,
                                lldb::tid_t thread_id,
                                llvm::MutableArrayRef<uint8_t> &buffer,
                                size_t offset);

  Status LoadQXferMemoryMap();

  Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr,
                                     MemoryRegionInfo &region);

  LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr);

private:
  GDBRemoteCommunicationClient(const GDBRemoteCommunicationClient &) = delete;
  const GDBRemoteCommunicationClient &
  operator=(const GDBRemoteCommunicationClient &) = delete;
};

} // namespace process_gdb_remote
} // namespace lldb_private

#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
