10b57cec5SDimitry Andric //===-- GDBRemoteCommunicationClient.h --------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "GDBRemoteClientBase.h"
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include <chrono>
150b57cec5SDimitry Andric #include <map>
160b57cec5SDimitry Andric #include <mutex>
17bdd1243dSDimitry Andric #include <optional>
180b57cec5SDimitry Andric #include <string>
190b57cec5SDimitry Andric #include <vector>
200b57cec5SDimitry Andric 
219dba64beSDimitry Andric #include "lldb/Host/File.h"
225f757f3fSDimitry Andric #include "lldb/Utility/AddressableBits.h"
230b57cec5SDimitry Andric #include "lldb/Utility/ArchSpec.h"
249dba64beSDimitry Andric #include "lldb/Utility/GDBRemote.h"
255ffd83dbSDimitry Andric #include "lldb/Utility/ProcessInfo.h"
260b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h"
27fe6060f1SDimitry Andric #include "lldb/Utility/TraceGDBRemotePackets.h"
28bdd1243dSDimitry Andric #include "lldb/Utility/UUID.h"
290b57cec5SDimitry Andric #if defined(_WIN32)
300b57cec5SDimitry Andric #include "lldb/Host/windows/PosixApi.h"
310b57cec5SDimitry Andric #endif
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric #include "llvm/Support/VersionTuple.h"
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric namespace lldb_private {
360b57cec5SDimitry Andric namespace process_gdb_remote {
370b57cec5SDimitry Andric 
385ffd83dbSDimitry Andric /// The offsets used by the target when relocating the executable. Decoded from
395ffd83dbSDimitry Andric /// qOffsets packet response.
405ffd83dbSDimitry Andric struct QOffsets {
415ffd83dbSDimitry Andric   /// If true, the offsets field describes segments. Otherwise, it describes
425ffd83dbSDimitry Andric   /// sections.
435ffd83dbSDimitry Andric   bool segments;
445ffd83dbSDimitry Andric 
455ffd83dbSDimitry Andric   /// The individual offsets. Section offsets have two or three members.
465ffd83dbSDimitry Andric   /// Segment offsets have either one of two.
475ffd83dbSDimitry Andric   std::vector<uint64_t> offsets;
485ffd83dbSDimitry Andric };
495ffd83dbSDimitry Andric inline bool operator==(const QOffsets &a, const QOffsets &b) {
505ffd83dbSDimitry Andric   return a.segments == b.segments && a.offsets == b.offsets;
515ffd83dbSDimitry Andric }
525ffd83dbSDimitry Andric llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets);
535ffd83dbSDimitry Andric 
54fe6060f1SDimitry Andric // A trivial struct used to return a pair of PID and TID.
55fe6060f1SDimitry Andric struct PidTid {
56fe6060f1SDimitry Andric   uint64_t pid;
57fe6060f1SDimitry Andric   uint64_t tid;
58fe6060f1SDimitry Andric };
59fe6060f1SDimitry Andric 
600b57cec5SDimitry Andric class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
610b57cec5SDimitry Andric public:
620b57cec5SDimitry Andric   GDBRemoteCommunicationClient();
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   ~GDBRemoteCommunicationClient() override;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   // After connecting, send the handshake to the server to make sure
670b57cec5SDimitry Andric   // we are communicating with it.
680b57cec5SDimitry Andric   bool HandshakeWithServer(Status *error_ptr);
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   bool GetThreadSuffixSupported();
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   // This packet is usually sent first and the boolean return value
730b57cec5SDimitry Andric   // indicates if the packet was send and any response was received
740b57cec5SDimitry Andric   // even in the response is UNIMPLEMENTED. If the packet failed to
750b57cec5SDimitry Andric   // get a response, then false is returned. This quickly tells us
760b57cec5SDimitry Andric   // if we were able to connect and communicate with the remote GDB
770b57cec5SDimitry Andric   // server
780b57cec5SDimitry Andric   bool QueryNoAckModeSupported();
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   void GetListThreadsInStopReplySupported();
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   lldb::pid_t GetCurrentProcessID(bool allow_lazy = true);
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid,
850b57cec5SDimitry Andric                        uint16_t &port, std::string &socket_name);
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   size_t QueryGDBServer(
880b57cec5SDimitry Andric       std::vector<std::pair<uint16_t, std::string>> &connection_urls);
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   bool KillSpawnedProcess(lldb::pid_t pid);
910b57cec5SDimitry Andric 
92bdd1243dSDimitry Andric   /// Launch the process using the provided arguments.
930b57cec5SDimitry Andric   ///
94bdd1243dSDimitry Andric   /// \param[in] args
95bdd1243dSDimitry Andric   ///     A list of program arguments. The first entry is the program being run.
96bdd1243dSDimitry Andric   llvm::Error LaunchProcess(const Args &args);
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
990b57cec5SDimitry Andric   /// environment that will get used when launching an application
1000b57cec5SDimitry Andric   /// in conjunction with the 'A' packet. This function can be called
1010b57cec5SDimitry Andric   /// multiple times in a row in order to pass on the desired
1020b57cec5SDimitry Andric   /// environment that the inferior should be launched with.
1030b57cec5SDimitry Andric   ///
1040b57cec5SDimitry Andric   /// \param[in] name_equal_value
1050b57cec5SDimitry Andric   ///     A NULL terminated C string that contains a single environment
1060b57cec5SDimitry Andric   ///     in the format "NAME=VALUE".
1070b57cec5SDimitry Andric   ///
1080b57cec5SDimitry Andric   /// \return
1090b57cec5SDimitry Andric   ///     Zero if the response was "OK", a positive value if the
1100b57cec5SDimitry Andric   ///     the response was "Exx" where xx are two hex digits, or
1110b57cec5SDimitry Andric   ///     -1 if the call is unsupported or any other unexpected
1120b57cec5SDimitry Andric   ///     response was received.
1130b57cec5SDimitry Andric   int SendEnvironmentPacket(char const *name_equal_value);
1140b57cec5SDimitry Andric   int SendEnvironment(const Environment &env);
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   int SendLaunchArchPacket(const char *arch);
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   int SendLaunchEventDataPacket(const char *data,
1190b57cec5SDimitry Andric                                 bool *was_supported = nullptr);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   /// Sends a GDB remote protocol 'I' packet that delivers stdin
1220b57cec5SDimitry Andric   /// data to the remote process.
1230b57cec5SDimitry Andric   ///
1240b57cec5SDimitry Andric   /// \param[in] data
1250b57cec5SDimitry Andric   ///     A pointer to stdin data.
1260b57cec5SDimitry Andric   ///
1270b57cec5SDimitry Andric   /// \param[in] data_len
1280b57cec5SDimitry Andric   ///     The number of bytes available at \a data.
1290b57cec5SDimitry Andric   ///
1300b57cec5SDimitry Andric   /// \return
1310b57cec5SDimitry Andric   ///     Zero if the attach was successful, or an error indicating
1320b57cec5SDimitry Andric   ///     an error code.
1330b57cec5SDimitry Andric   int SendStdinNotification(const char *data, size_t data_len);
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   /// Sets the path to use for stdin/out/err for a process
1360b57cec5SDimitry Andric   /// that will be launched with the 'A' packet.
1370b57cec5SDimitry Andric   ///
138480093f4SDimitry Andric   /// \param[in] file_spec
1390b57cec5SDimitry Andric   ///     The path to use for stdin/out/err
1400b57cec5SDimitry Andric   ///
1410b57cec5SDimitry Andric   /// \return
1420b57cec5SDimitry Andric   ///     Zero if the for success, or an error code for failure.
1430b57cec5SDimitry Andric   int SetSTDIN(const FileSpec &file_spec);
1440b57cec5SDimitry Andric   int SetSTDOUT(const FileSpec &file_spec);
1450b57cec5SDimitry Andric   int SetSTDERR(const FileSpec &file_spec);
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   /// Sets the disable ASLR flag to \a enable for a process that will
1480b57cec5SDimitry Andric   /// be launched with the 'A' packet.
1490b57cec5SDimitry Andric   ///
1500b57cec5SDimitry Andric   /// \param[in] enable
1510b57cec5SDimitry Andric   ///     A boolean value indicating whether to disable ASLR or not.
1520b57cec5SDimitry Andric   ///
1530b57cec5SDimitry Andric   /// \return
1540b57cec5SDimitry Andric   ///     Zero if the for success, or an error code for failure.
1550b57cec5SDimitry Andric   int SetDisableASLR(bool enable);
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   /// Sets the DetachOnError flag to \a enable for the process controlled by the
1580b57cec5SDimitry Andric   /// stub.
1590b57cec5SDimitry Andric   ///
1600b57cec5SDimitry Andric   /// \param[in] enable
1610b57cec5SDimitry Andric   ///     A boolean value indicating whether to detach on error or not.
1620b57cec5SDimitry Andric   ///
1630b57cec5SDimitry Andric   /// \return
1640b57cec5SDimitry Andric   ///     Zero if the for success, or an error code for failure.
1650b57cec5SDimitry Andric   int SetDetachOnError(bool enable);
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   /// Sets the working directory to \a path for a process that will
1680b57cec5SDimitry Andric   /// be launched with the 'A' packet for non platform based
1690b57cec5SDimitry Andric   /// connections. If this packet is sent to a GDB server that
1700b57cec5SDimitry Andric   /// implements the platform, it will change the current working
1710b57cec5SDimitry Andric   /// directory for the platform process.
1720b57cec5SDimitry Andric   ///
1730b57cec5SDimitry Andric   /// \param[in] working_dir
1740b57cec5SDimitry Andric   ///     The path to a directory to use when launching our process
1750b57cec5SDimitry Andric   ///
1760b57cec5SDimitry Andric   /// \return
1770b57cec5SDimitry Andric   ///     Zero if the for success, or an error code for failure.
1780b57cec5SDimitry Andric   int SetWorkingDir(const FileSpec &working_dir);
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   /// Gets the current working directory of a remote platform GDB
1810b57cec5SDimitry Andric   /// server.
1820b57cec5SDimitry Andric   ///
1830b57cec5SDimitry Andric   /// \param[out] working_dir
1840b57cec5SDimitry Andric   ///     The current working directory on the remote platform.
1850b57cec5SDimitry Andric   ///
1860b57cec5SDimitry Andric   /// \return
1870b57cec5SDimitry Andric   ///     Boolean for success
1880b57cec5SDimitry Andric   bool GetWorkingDir(FileSpec &working_dir);
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   lldb::addr_t AllocateMemory(size_t size, uint32_t permissions);
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   bool DeallocateMemory(lldb::addr_t addr);
1930b57cec5SDimitry Andric 
194349cc55cSDimitry Andric   Status Detach(bool keep_stopped, lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   Status GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info);
1970b57cec5SDimitry Andric 
19806c3fb27SDimitry Andric   std::optional<uint32_t> GetWatchpointSlotCount();
1990b57cec5SDimitry Andric 
20006c3fb27SDimitry Andric   std::optional<bool> GetWatchpointReportedAfter();
2010b57cec5SDimitry Andric 
202*0fca6ea1SDimitry Andric   WatchpointHardwareFeature GetSupportedWatchpointTypes();
203*0fca6ea1SDimitry Andric 
2040b57cec5SDimitry Andric   const ArchSpec &GetHostArchitecture();
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   std::chrono::seconds GetHostDefaultPacketTimeout();
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   const ArchSpec &GetProcessArchitecture();
2090b57cec5SDimitry Andric 
2100eae32dcSDimitry Andric   bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value,
2110eae32dcSDimitry Andric                                   bool &value_is_offset);
2120eae32dcSDimitry Andric 
213bdd1243dSDimitry Andric   std::vector<lldb::addr_t> GetProcessStandaloneBinaries();
214bdd1243dSDimitry Andric 
2150b57cec5SDimitry Andric   void GetRemoteQSupported();
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   bool GetVContSupported(char flavor);
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   bool GetpPacketSupported(lldb::tid_t tid);
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   bool GetxPacketSupported();
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   bool GetVAttachOrWaitSupported();
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   bool GetSyncThreadStateSupported();
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   void ResetDiscoverableSettings(bool did_exec);
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   bool GetHostInfo(bool force = false);
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric   bool GetDefaultThreadId(lldb::tid_t &tid);
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   llvm::VersionTuple GetOSVersion();
2340b57cec5SDimitry Andric 
2359dba64beSDimitry Andric   llvm::VersionTuple GetMacCatalystVersion();
2369dba64beSDimitry Andric 
237bdd1243dSDimitry Andric   std::optional<std::string> GetOSBuildString();
2380b57cec5SDimitry Andric 
239bdd1243dSDimitry Andric   std::optional<std::string> GetOSKernelDescription();
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric   ArchSpec GetSystemArchitecture();
2420b57cec5SDimitry Andric 
2435f757f3fSDimitry Andric   lldb_private::AddressableBits GetAddressableBits();
244fe6060f1SDimitry Andric 
2450b57cec5SDimitry Andric   bool GetHostname(std::string &s);
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   lldb::addr_t GetShlibInfoAddr();
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric   bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info);
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info,
2520b57cec5SDimitry Andric                          ProcessInstanceInfoList &process_infos);
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   bool GetUserName(uint32_t uid, std::string &name);
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   bool GetGroupName(uint32_t gid, std::string &name);
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   bool HasFullVContSupport() { return GetVContSupported('A'); }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   bool HasAnyVContSupport() { return GetVContSupported('a'); }
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   bool GetStopReply(StringExtractorGDBRemote &response);
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response);
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   bool SupportsGDBStoppointPacket(GDBStoppointType type) {
2670b57cec5SDimitry Andric     switch (type) {
2680b57cec5SDimitry Andric     case eBreakpointSoftware:
2690b57cec5SDimitry Andric       return m_supports_z0;
2700b57cec5SDimitry Andric     case eBreakpointHardware:
2710b57cec5SDimitry Andric       return m_supports_z1;
2720b57cec5SDimitry Andric     case eWatchpointWrite:
2730b57cec5SDimitry Andric       return m_supports_z2;
2740b57cec5SDimitry Andric     case eWatchpointRead:
2750b57cec5SDimitry Andric       return m_supports_z3;
2760b57cec5SDimitry Andric     case eWatchpointReadWrite:
2770b57cec5SDimitry Andric       return m_supports_z4;
2780b57cec5SDimitry Andric     default:
2790b57cec5SDimitry Andric       return false;
2800b57cec5SDimitry Andric     }
2810b57cec5SDimitry Andric   }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   uint8_t SendGDBStoppointTypePacket(
2840b57cec5SDimitry Andric       GDBStoppointType type, // Type of breakpoint or watchpoint
2850b57cec5SDimitry Andric       bool insert,           // Insert or remove?
2860b57cec5SDimitry Andric       lldb::addr_t addr,     // Address of breakpoint or watchpoint
287fe6060f1SDimitry Andric       uint32_t length,       // Byte Size of breakpoint or watchpoint
288fe6060f1SDimitry Andric       std::chrono::seconds interrupt_timeout); // Time to wait for an interrupt
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send,
2910b57cec5SDimitry Andric                        uint32_t max_recv, uint64_t recv_amount, bool json,
2920b57cec5SDimitry Andric                        Stream &strm);
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   // This packet is for testing the speed of the interface only. Both
2950b57cec5SDimitry Andric   // the client and server need to support it, but this allows us to
2960b57cec5SDimitry Andric   // measure the packet speed without any other work being done on the
2970b57cec5SDimitry Andric   // other end and avoids any of that work affecting the packet send
2980b57cec5SDimitry Andric   // and response times.
2990b57cec5SDimitry Andric   bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);
3000b57cec5SDimitry Andric 
301bdd1243dSDimitry Andric   std::optional<PidTid> SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid,
302bdd1243dSDimitry Andric                                                    char op);
3030b57cec5SDimitry Andric 
304fe6060f1SDimitry Andric   bool SetCurrentThread(uint64_t tid,
305fe6060f1SDimitry Andric                         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
306fe6060f1SDimitry Andric 
307fe6060f1SDimitry Andric   bool SetCurrentThreadForRun(uint64_t tid,
308fe6060f1SDimitry Andric                               lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   bool GetQXferAuxvReadSupported();
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric   void EnableErrorStringInPacket();
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   bool GetQXferLibrariesReadSupported();
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   bool GetQXferLibrariesSVR4ReadSupported();
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric   uint64_t GetRemoteMaxPacketSize();
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   bool GetEchoSupported();
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   bool GetQPassSignalsSupported();
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric   bool GetAugmentedLibrariesSVR4ReadSupported();
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   bool GetQXferFeaturesReadSupported();
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   bool GetQXferMemoryMapReadSupported();
3290b57cec5SDimitry Andric 
33004eeddc0SDimitry Andric   bool GetQXferSigInfoReadSupported();
33104eeddc0SDimitry Andric 
332bdd1243dSDimitry Andric   bool GetMultiprocessSupported();
333bdd1243dSDimitry Andric 
3340b57cec5SDimitry Andric   LazyBool SupportsAllocDeallocMemory() // const
3350b57cec5SDimitry Andric   {
3360b57cec5SDimitry Andric     // Uncomment this to have lldb pretend the debug server doesn't respond to
3370b57cec5SDimitry Andric     // alloc/dealloc memory packets.
3380b57cec5SDimitry Andric     // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
3390b57cec5SDimitry Andric     return m_supports_alloc_dealloc_memory;
3400b57cec5SDimitry Andric   }
3410b57cec5SDimitry Andric 
342fe6060f1SDimitry Andric   std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
343fe6060f1SDimitry Andric   GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable);
344fe6060f1SDimitry Andric 
3450b57cec5SDimitry Andric   size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
3460b57cec5SDimitry Andric                              bool &sequence_mutex_unavailable);
3470b57cec5SDimitry Andric 
3489dba64beSDimitry Andric   lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
3490b57cec5SDimitry Andric                            mode_t mode, Status &error);
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   bool CloseFile(lldb::user_id_t fd, Status &error);
3520b57cec5SDimitry Andric 
353bdd1243dSDimitry Andric   std::optional<GDBRemoteFStatData> FStat(lldb::user_id_t fd);
354349cc55cSDimitry Andric 
355349cc55cSDimitry Andric   // NB: this is just a convenience wrapper over open() + fstat().  It does not
356349cc55cSDimitry Andric   // work if the file cannot be opened.
357bdd1243dSDimitry Andric   std::optional<GDBRemoteFStatData> Stat(const FileSpec &file_spec);
358349cc55cSDimitry Andric 
3590b57cec5SDimitry Andric   lldb::user_id_t GetFileSize(const FileSpec &file_spec);
3600b57cec5SDimitry Andric 
361e8d8bef9SDimitry Andric   void AutoCompleteDiskFileOrDirectory(CompletionRequest &request,
362e8d8bef9SDimitry Andric                                        bool only_dir);
363e8d8bef9SDimitry Andric 
3640b57cec5SDimitry Andric   Status GetFilePermissions(const FileSpec &file_spec,
3650b57cec5SDimitry Andric                             uint32_t &file_permissions);
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   Status SetFilePermissions(const FileSpec &file_spec,
3680b57cec5SDimitry Andric                             uint32_t file_permissions);
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
3710b57cec5SDimitry Andric                     uint64_t dst_len, Status &error);
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
3740b57cec5SDimitry Andric                      uint64_t src_len, Status &error);
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   Status CreateSymlink(const FileSpec &src, const FileSpec &dst);
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric   Status Unlink(const FileSpec &file_spec);
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   Status MakeDirectory(const FileSpec &file_spec, uint32_t mode);
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric   bool GetFileExists(const FileSpec &file_spec);
3830b57cec5SDimitry Andric 
3840b57cec5SDimitry Andric   Status RunShellCommand(
385e8d8bef9SDimitry Andric       llvm::StringRef command,
3860b57cec5SDimitry Andric       const FileSpec &working_dir, // Pass empty FileSpec to use the current
3870b57cec5SDimitry Andric                                    // working directory
3880b57cec5SDimitry Andric       int *status_ptr, // Pass nullptr if you don't want the process exit status
3890b57cec5SDimitry Andric       int *signo_ptr,  // Pass nullptr if you don't want the signal that caused
3900b57cec5SDimitry Andric                        // the process to exit
3910b57cec5SDimitry Andric       std::string
3920b57cec5SDimitry Andric           *command_output, // Pass nullptr if you don't want the command output
3930b57cec5SDimitry Andric       const Timeout<std::micro> &timeout);
3940b57cec5SDimitry Andric 
395*0fca6ea1SDimitry Andric   llvm::ErrorOr<llvm::MD5::MD5Result> CalculateMD5(const FileSpec &file_spec);
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   lldb::DataBufferSP ReadRegister(
3980b57cec5SDimitry Andric       lldb::tid_t tid,
3990b57cec5SDimitry Andric       uint32_t
4000b57cec5SDimitry Andric           reg_num); // Must be the eRegisterKindProcessPlugin register number
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid);
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   bool
4050b57cec5SDimitry Andric   WriteRegister(lldb::tid_t tid,
4060b57cec5SDimitry Andric                 uint32_t reg_num, // eRegisterKindProcessPlugin register number
4070b57cec5SDimitry Andric                 llvm::ArrayRef<uint8_t> data);
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id);
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric   bool SyncThreadState(lldb::tid_t tid);
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   const char *GetGDBServerProgramName();
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   uint32_t GetGDBServerProgramVersion();
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   bool AvoidGPackets(ProcessGDBRemote *process);
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   StructuredData::ObjectSP GetThreadsInfo();
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   bool GetThreadExtendedInfoSupported();
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   bool GetLoadedDynamicLibrariesInfosSupported();
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   bool GetSharedCacheInfoSupported();
4300b57cec5SDimitry Andric 
431bdd1243dSDimitry Andric   bool GetDynamicLoaderProcessStateSupported();
432bdd1243dSDimitry Andric 
433fe6060f1SDimitry Andric   bool GetMemoryTaggingSupported();
434fe6060f1SDimitry Andric 
435349cc55cSDimitry Andric   bool UsesNativeSignals();
436349cc55cSDimitry Andric 
437fe6060f1SDimitry Andric   lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len,
438fe6060f1SDimitry Andric                                     int32_t type);
439fe6060f1SDimitry Andric 
440fe6060f1SDimitry Andric   Status WriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
441fe6060f1SDimitry Andric                          const std::vector<uint8_t> &tags);
442fe6060f1SDimitry Andric 
4435ffd83dbSDimitry Andric   /// Use qOffsets to query the offset used when relocating the target
4445ffd83dbSDimitry Andric   /// executable. If successful, the returned structure will contain at least
4455ffd83dbSDimitry Andric   /// one value in the offsets field.
446bdd1243dSDimitry Andric   std::optional<QOffsets> GetQOffsets();
4475ffd83dbSDimitry Andric 
4480b57cec5SDimitry Andric   bool GetModuleInfo(const FileSpec &module_file_spec,
4490b57cec5SDimitry Andric                      const ArchSpec &arch_spec, ModuleSpec &module_spec);
4500b57cec5SDimitry Andric 
451bdd1243dSDimitry Andric   std::optional<std::vector<ModuleSpec>>
4520b57cec5SDimitry Andric   GetModulesInfo(llvm::ArrayRef<FileSpec> module_file_specs,
4530b57cec5SDimitry Andric                  const llvm::Triple &triple);
4540b57cec5SDimitry Andric 
455349cc55cSDimitry Andric   llvm::Expected<std::string> ReadExtFeature(llvm::StringRef object,
456349cc55cSDimitry Andric                                              llvm::StringRef annex);
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric   void ServeSymbolLookups(lldb_private::Process *process);
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   // Sends QPassSignals packet to the server with given signals to ignore.
4610b57cec5SDimitry Andric   Status SendSignalsToIgnore(llvm::ArrayRef<int32_t> signals);
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   /// Return the feature set supported by the gdb-remote server.
4640b57cec5SDimitry Andric   ///
4650b57cec5SDimitry Andric   /// This method returns the remote side's response to the qSupported
4660b57cec5SDimitry Andric   /// packet.  The response is the complete string payload returned
4670b57cec5SDimitry Andric   /// to the client.
4680b57cec5SDimitry Andric   ///
4690b57cec5SDimitry Andric   /// \return
4700b57cec5SDimitry Andric   ///     The string returned by the server to the qSupported query.
4710b57cec5SDimitry Andric   const std::string &GetServerSupportedFeatures() const {
4720b57cec5SDimitry Andric     return m_qSupported_response;
4730b57cec5SDimitry Andric   }
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric   /// Return the array of async JSON packet types supported by the remote.
4760b57cec5SDimitry Andric   ///
4770b57cec5SDimitry Andric   /// This method returns the remote side's array of supported JSON
4780b57cec5SDimitry Andric   /// packet types as a list of type names.  Each of the results are
4790b57cec5SDimitry Andric   /// expected to have an Enable{type_name} command to enable and configure
4800b57cec5SDimitry Andric   /// the related feature.  Each type_name for an enabled feature will
4810b57cec5SDimitry Andric   /// possibly send async-style packets that contain a payload of a
4820b57cec5SDimitry Andric   /// binhex-encoded JSON dictionary.  The dictionary will have a
4830b57cec5SDimitry Andric   /// string field named 'type', that contains the type_name of the
4840b57cec5SDimitry Andric   /// supported packet type.
4850b57cec5SDimitry Andric   ///
4860b57cec5SDimitry Andric   /// There is a Plugin category called structured-data plugins.
4870b57cec5SDimitry Andric   /// A plugin indicates whether it knows how to handle a type_name.
4880b57cec5SDimitry Andric   /// If so, it can be used to process the async JSON packet.
4890b57cec5SDimitry Andric   ///
4900b57cec5SDimitry Andric   /// \return
4910b57cec5SDimitry Andric   ///     The string returned by the server to the qSupported query.
4920b57cec5SDimitry Andric   lldb_private::StructuredData::Array *GetSupportedStructuredDataPlugins();
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   /// Configure a StructuredData feature on the remote end.
4950b57cec5SDimitry Andric   ///
4960b57cec5SDimitry Andric   /// \see \b Process::ConfigureStructuredData(...) for details.
4970b57cec5SDimitry Andric   Status
49806c3fb27SDimitry Andric   ConfigureRemoteStructuredData(llvm::StringRef type_name,
4990b57cec5SDimitry Andric                                 const StructuredData::ObjectSP &config_sp);
5000b57cec5SDimitry Andric 
501fe6060f1SDimitry Andric   llvm::Expected<TraceSupportedResponse>
502fe6060f1SDimitry Andric   SendTraceSupported(std::chrono::seconds interrupt_timeout);
5030b57cec5SDimitry Andric 
504fe6060f1SDimitry Andric   llvm::Error SendTraceStart(const llvm::json::Value &request,
505fe6060f1SDimitry Andric                              std::chrono::seconds interrupt_timeout);
5060b57cec5SDimitry Andric 
507fe6060f1SDimitry Andric   llvm::Error SendTraceStop(const TraceStopRequest &request,
508fe6060f1SDimitry Andric                             std::chrono::seconds interrupt_timeout);
5090b57cec5SDimitry Andric 
510fe6060f1SDimitry Andric   llvm::Expected<std::string>
511fe6060f1SDimitry Andric   SendTraceGetState(llvm::StringRef type,
512fe6060f1SDimitry Andric                     std::chrono::seconds interrupt_timeout);
5130b57cec5SDimitry Andric 
514fe6060f1SDimitry Andric   llvm::Expected<std::vector<uint8_t>>
515fe6060f1SDimitry Andric   SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request,
516fe6060f1SDimitry Andric                          std::chrono::seconds interrupt_timeout);
517e8d8bef9SDimitry Andric 
518349cc55cSDimitry Andric   bool GetSaveCoreSupported() const;
519349cc55cSDimitry Andric 
520972a253aSDimitry Andric   llvm::Expected<int> KillProcess(lldb::pid_t pid);
521972a253aSDimitry Andric 
5220b57cec5SDimitry Andric protected:
523fe6060f1SDimitry Andric   LazyBool m_supports_not_sending_acks = eLazyBoolCalculate;
524fe6060f1SDimitry Andric   LazyBool m_supports_thread_suffix = eLazyBoolCalculate;
525fe6060f1SDimitry Andric   LazyBool m_supports_threads_in_stop_reply = eLazyBoolCalculate;
526fe6060f1SDimitry Andric   LazyBool m_supports_vCont_all = eLazyBoolCalculate;
527fe6060f1SDimitry Andric   LazyBool m_supports_vCont_any = eLazyBoolCalculate;
528fe6060f1SDimitry Andric   LazyBool m_supports_vCont_c = eLazyBoolCalculate;
529fe6060f1SDimitry Andric   LazyBool m_supports_vCont_C = eLazyBoolCalculate;
530fe6060f1SDimitry Andric   LazyBool m_supports_vCont_s = eLazyBoolCalculate;
531fe6060f1SDimitry Andric   LazyBool m_supports_vCont_S = eLazyBoolCalculate;
532fe6060f1SDimitry Andric   LazyBool m_qHostInfo_is_valid = eLazyBoolCalculate;
533fe6060f1SDimitry Andric   LazyBool m_curr_pid_is_valid = eLazyBoolCalculate;
534fe6060f1SDimitry Andric   LazyBool m_qProcessInfo_is_valid = eLazyBoolCalculate;
535fe6060f1SDimitry Andric   LazyBool m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
536fe6060f1SDimitry Andric   LazyBool m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
537fe6060f1SDimitry Andric   LazyBool m_supports_memory_region_info = eLazyBoolCalculate;
538fe6060f1SDimitry Andric   LazyBool m_supports_watchpoint_support_info = eLazyBoolCalculate;
539fe6060f1SDimitry Andric   LazyBool m_supports_detach_stay_stopped = eLazyBoolCalculate;
540fe6060f1SDimitry Andric   LazyBool m_watchpoints_trigger_after_instruction = eLazyBoolCalculate;
541fe6060f1SDimitry Andric   LazyBool m_attach_or_wait_reply = eLazyBoolCalculate;
542fe6060f1SDimitry Andric   LazyBool m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
543fe6060f1SDimitry Andric   LazyBool m_supports_p = eLazyBoolCalculate;
544fe6060f1SDimitry Andric   LazyBool m_supports_x = eLazyBoolCalculate;
545fe6060f1SDimitry Andric   LazyBool m_avoid_g_packets = eLazyBoolCalculate;
546fe6060f1SDimitry Andric   LazyBool m_supports_QSaveRegisterState = eLazyBoolCalculate;
547fe6060f1SDimitry Andric   LazyBool m_supports_qXfer_auxv_read = eLazyBoolCalculate;
548fe6060f1SDimitry Andric   LazyBool m_supports_qXfer_libraries_read = eLazyBoolCalculate;
549fe6060f1SDimitry Andric   LazyBool m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
550fe6060f1SDimitry Andric   LazyBool m_supports_qXfer_features_read = eLazyBoolCalculate;
551fe6060f1SDimitry Andric   LazyBool m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
55204eeddc0SDimitry Andric   LazyBool m_supports_qXfer_siginfo_read = eLazyBoolCalculate;
553fe6060f1SDimitry Andric   LazyBool m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
554fe6060f1SDimitry Andric   LazyBool m_supports_jThreadExtendedInfo = eLazyBoolCalculate;
555fe6060f1SDimitry Andric   LazyBool m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolCalculate;
556fe6060f1SDimitry Andric   LazyBool m_supports_jGetSharedCacheInfo = eLazyBoolCalculate;
557bdd1243dSDimitry Andric   LazyBool m_supports_jGetDyldProcessState = eLazyBoolCalculate;
558fe6060f1SDimitry Andric   LazyBool m_supports_QPassSignals = eLazyBoolCalculate;
559fe6060f1SDimitry Andric   LazyBool m_supports_error_string_reply = eLazyBoolCalculate;
560fe6060f1SDimitry Andric   LazyBool m_supports_multiprocess = eLazyBoolCalculate;
561fe6060f1SDimitry Andric   LazyBool m_supports_memory_tagging = eLazyBoolCalculate;
562349cc55cSDimitry Andric   LazyBool m_supports_qSaveCore = eLazyBoolCalculate;
563349cc55cSDimitry Andric   LazyBool m_uses_native_signals = eLazyBoolCalculate;
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric   bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
5660b57cec5SDimitry Andric       m_supports_qUserName : 1, m_supports_qGroupName : 1,
5670b57cec5SDimitry Andric       m_supports_qThreadStopInfo : 1, m_supports_z0 : 1, m_supports_z1 : 1,
5680b57cec5SDimitry Andric       m_supports_z2 : 1, m_supports_z3 : 1, m_supports_z4 : 1,
5690b57cec5SDimitry Andric       m_supports_QEnvironment : 1, m_supports_QEnvironmentHexEncoded : 1,
5700b57cec5SDimitry Andric       m_supports_qSymbol : 1, m_qSymbol_requests_done : 1,
5710b57cec5SDimitry Andric       m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1,
572349cc55cSDimitry Andric       m_supports_jModulesInfo : 1, m_supports_vFileSize : 1,
573349cc55cSDimitry Andric       m_supports_vFileMode : 1, m_supports_vFileExists : 1,
574349cc55cSDimitry Andric       m_supports_vRun : 1;
5750b57cec5SDimitry Andric 
576fe6060f1SDimitry Andric   /// Current gdb remote protocol process identifier for all other operations
577fe6060f1SDimitry Andric   lldb::pid_t m_curr_pid = LLDB_INVALID_PROCESS_ID;
578fe6060f1SDimitry Andric   /// Current gdb remote protocol process identifier for continue, step, etc
579fe6060f1SDimitry Andric   lldb::pid_t m_curr_pid_run = LLDB_INVALID_PROCESS_ID;
580fe6060f1SDimitry Andric   /// Current gdb remote protocol thread identifier for all other operations
581fe6060f1SDimitry Andric   lldb::tid_t m_curr_tid = LLDB_INVALID_THREAD_ID;
582fe6060f1SDimitry Andric   /// Current gdb remote protocol thread identifier for continue, step, etc
583fe6060f1SDimitry Andric   lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID;
5840b57cec5SDimitry Andric 
585fe6060f1SDimitry Andric   uint32_t m_num_supported_hardware_watchpoints = 0;
586*0fca6ea1SDimitry Andric   WatchpointHardwareFeature m_watchpoint_types =
587*0fca6ea1SDimitry Andric       eWatchpointHardwareFeatureUnknown;
5885f757f3fSDimitry Andric   uint32_t m_low_mem_addressing_bits = 0;
5895f757f3fSDimitry Andric   uint32_t m_high_mem_addressing_bits = 0;
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric   ArchSpec m_host_arch;
59206c3fb27SDimitry Andric   std::string m_host_distribution_id;
5930b57cec5SDimitry Andric   ArchSpec m_process_arch;
5940eae32dcSDimitry Andric   UUID m_process_standalone_uuid;
5950eae32dcSDimitry Andric   lldb::addr_t m_process_standalone_value = LLDB_INVALID_ADDRESS;
5960eae32dcSDimitry Andric   bool m_process_standalone_value_is_offset = false;
597bdd1243dSDimitry Andric   std::vector<lldb::addr_t> m_binary_addresses;
5980b57cec5SDimitry Andric   llvm::VersionTuple m_os_version;
5999dba64beSDimitry Andric   llvm::VersionTuple m_maccatalyst_version;
6000b57cec5SDimitry Andric   std::string m_os_build;
6010b57cec5SDimitry Andric   std::string m_os_kernel;
6020b57cec5SDimitry Andric   std::string m_hostname;
6030b57cec5SDimitry Andric   std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if
6040b57cec5SDimitry Andric                                  // qGDBServerVersion is not supported
605fe6060f1SDimitry Andric   uint32_t m_gdb_server_version =
606fe6060f1SDimitry Andric       UINT32_MAX; // from reply to qGDBServerVersion, zero if
6070b57cec5SDimitry Andric                   // qGDBServerVersion is not supported
6080b57cec5SDimitry Andric   std::chrono::seconds m_default_packet_timeout;
609fe6060f1SDimitry Andric   int m_target_vm_page_size = 0; // target system VM page size; 0 unspecified
610fe6060f1SDimitry Andric   uint64_t m_max_packet_size = 0;    // as returned by qSupported
6110b57cec5SDimitry Andric   std::string m_qSupported_response; // the complete response to qSupported
6120b57cec5SDimitry Andric 
613fe6060f1SDimitry Andric   bool m_supported_async_json_packets_is_valid = false;
6140b57cec5SDimitry Andric   lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   std::vector<MemoryRegionInfo> m_qXfer_memory_map;
617fe6060f1SDimitry Andric   bool m_qXfer_memory_map_loaded = false;
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric   bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric   bool GetGDBServerVersion();
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   // Given the list of compression types that the remote debug stub can support,
6240b57cec5SDimitry Andric   // possibly enable compression if we find an encoding we can handle.
625fe6060f1SDimitry Andric   void MaybeEnableCompression(
626fe6060f1SDimitry Andric       llvm::ArrayRef<llvm::StringRef> supported_compressions);
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
6290b57cec5SDimitry Andric                                  ProcessInstanceInfo &process_info);
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric   void OnRunPacketSent(bool first) override;
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric   PacketResult SendThreadSpecificPacketAndWaitForResponse(
6340b57cec5SDimitry Andric       lldb::tid_t tid, StreamString &&payload,
635fe6060f1SDimitry Andric       StringExtractorGDBRemote &response);
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   Status SendGetTraceDataPacket(StreamGDBRemote &packet, lldb::user_id_t uid,
6380b57cec5SDimitry Andric                                 lldb::tid_t thread_id,
6390b57cec5SDimitry Andric                                 llvm::MutableArrayRef<uint8_t> &buffer,
6400b57cec5SDimitry Andric                                 size_t offset);
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   Status LoadQXferMemoryMap();
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr,
6450b57cec5SDimitry Andric                                      MemoryRegionInfo &region);
6460b57cec5SDimitry Andric 
647480093f4SDimitry Andric   LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr);
648480093f4SDimitry Andric 
6490b57cec5SDimitry Andric private:
6505ffd83dbSDimitry Andric   GDBRemoteCommunicationClient(const GDBRemoteCommunicationClient &) = delete;
6515ffd83dbSDimitry Andric   const GDBRemoteCommunicationClient &
6525ffd83dbSDimitry Andric   operator=(const GDBRemoteCommunicationClient &) = delete;
6530b57cec5SDimitry Andric };
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric } // namespace process_gdb_remote
6560b57cec5SDimitry Andric } // namespace lldb_private
6570b57cec5SDimitry Andric 
6585ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
659