1 //===-- PlatformRemoteGDBServer.h ----------------------------------------*- C++
2 //-*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
11 #define LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
12 
13 #include <optional>
14 #include <string>
15 
16 #include "Plugins/Process/Utility/GDBRemoteSignals.h"
17 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
18 #include "lldb/Target/Platform.h"
19 
20 namespace lldb_private {
21 namespace platform_gdb_server {
22 
23 class PlatformRemoteGDBServer : public Platform, private UserIDResolver {
24 public:
25   static void Initialize();
26 
27   static void Terminate();
28 
29   static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
30 
GetPluginNameStatic()31   static llvm::StringRef GetPluginNameStatic() { return "remote-gdb-server"; }
32 
33   static llvm::StringRef GetDescriptionStatic();
34 
35   PlatformRemoteGDBServer();
36 
37   ~PlatformRemoteGDBServer() override;
38 
39   // lldb_private::PluginInterface functions
GetPluginName()40   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
41 
42   // lldb_private::Platform functions
43   bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
44                      ModuleSpec &module_spec) override;
45 
46   llvm::StringRef GetDescription() override;
47 
48   Status GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid_ptr,
49                          FileSpec &local_file) override;
50 
51   bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
52 
53   uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
54                          ProcessInstanceInfoList &process_infos) override;
55 
56   Status LaunchProcess(ProcessLaunchInfo &launch_info) override;
57 
58   Status KillProcess(const lldb::pid_t pid) override;
59 
60   lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
61                                Debugger &debugger, Target &target,
62                                Status &error) override;
63 
64   lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
65                          Target *target, // Can be NULL, if NULL create a new
66                                          // target, else use existing one
67                          Status &error) override;
68 
69   std::vector<ArchSpec>
GetSupportedArchitectures(const ArchSpec & process_host_arch)70   GetSupportedArchitectures(const ArchSpec &process_host_arch) override {
71     return m_supported_architectures;
72   }
73 
74   size_t GetSoftwareBreakpointTrapOpcode(Target &target,
75                                          BreakpointSite *bp_site) override;
76 
77   bool GetRemoteOSVersion() override;
78 
79   std::optional<std::string> GetRemoteOSBuildString() override;
80 
81   std::optional<std::string> GetRemoteOSKernelDescription() override;
82 
83   // Remote Platform subclasses need to override this function
84   ArchSpec GetRemoteSystemArchitecture() override;
85 
86   FileSpec GetRemoteWorkingDirectory() override;
87 
88   bool SetRemoteWorkingDirectory(const FileSpec &working_dir) override;
89 
90   // Remote subclasses should override this and return a valid instance
91   // name if connected.
92   const char *GetHostname() override;
93 
GetUserIDResolver()94   UserIDResolver &GetUserIDResolver() override { return *this; }
95 
96   bool IsConnected() const override;
97 
98   Status ConnectRemote(Args &args) override;
99 
100   Status DisconnectRemote() override;
101 
102   Status MakeDirectory(const FileSpec &file_spec,
103                        uint32_t file_permissions) override;
104 
105   Status GetFilePermissions(const FileSpec &file_spec,
106                             uint32_t &file_permissions) override;
107 
108   Status SetFilePermissions(const FileSpec &file_spec,
109                             uint32_t file_permissions) override;
110 
111   lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
112                            uint32_t mode, Status &error) override;
113 
114   bool CloseFile(lldb::user_id_t fd, Status &error) override;
115 
116   uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *data_ptr,
117                     uint64_t len, Status &error) override;
118 
119   uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *data,
120                      uint64_t len, Status &error) override;
121 
122   lldb::user_id_t GetFileSize(const FileSpec &file_spec) override;
123 
124   void AutoCompleteDiskFileOrDirectory(CompletionRequest &request,
125                                        bool only_dir) override;
126 
127   Status PutFile(const FileSpec &source, const FileSpec &destination,
128                  uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override;
129 
130   Status CreateSymlink(const FileSpec &src, const FileSpec &dst) override;
131 
132   bool GetFileExists(const FileSpec &file_spec) override;
133 
134   Status Unlink(const FileSpec &path) override;
135 
136   Status RunShellCommand(
137       llvm::StringRef shell, llvm::StringRef command,
138       const FileSpec &working_dir, // Pass empty FileSpec to use the current
139                                    // working directory
140       int *status_ptr, // Pass NULL if you don't want the process exit status
141       int *signo_ptr,  // Pass NULL if you don't want the signal that caused the
142                        // process to exit
143       std::string
144           *command_output, // Pass NULL if you don't want the command output
145       const lldb_private::Timeout<std::micro> &timeout) override;
146 
147   void CalculateTrapHandlerSymbolNames() override;
148 
149   const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;
150 
151   size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
152                                    lldb_private::Status &error) override;
153 
154   virtual size_t
155   GetPendingGdbServerList(std::vector<std::string> &connection_urls);
156 
157 protected:
158   std::unique_ptr<process_gdb_remote::GDBRemoteCommunicationClient>
159       m_gdb_client_up;
160   std::string m_platform_description; // After we connect we can get a more
161                                       // complete description of what we are
162                                       // connected to
163   std::string m_platform_scheme;
164   std::string m_platform_hostname;
165 
166   lldb::UnixSignalsSP m_remote_signals_sp;
167 
168   // Launch the debug server on the remote host - caller connects to launched
169   // debug server using connect_url.
170   // Subclasses should override this method if they want to do extra actions
171   // before or
172   // after launching the debug server.
173   virtual bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url);
174 
175   virtual bool KillSpawnedProcess(lldb::pid_t pid);
176 
177   virtual std::string MakeUrl(const char *scheme, const char *hostname,
178                               uint16_t port, const char *path);
179 
180 private:
181   std::string MakeGdbServerUrl(const std::string &platform_scheme,
182                                const std::string &platform_hostname,
183                                uint16_t port, const char *socket_name);
184 
185   std::optional<std::string> DoGetUserName(UserIDResolver::id_t uid) override;
186   std::optional<std::string> DoGetGroupName(UserIDResolver::id_t uid) override;
187 
188   std::vector<ArchSpec> m_supported_architectures;
189 
190   PlatformRemoteGDBServer(const PlatformRemoteGDBServer &) = delete;
191   const PlatformRemoteGDBServer &
192   operator=(const PlatformRemoteGDBServer &) = delete;
193 };
194 
195 } // namespace platform_gdb_server
196 } // namespace lldb_private
197 
198 #endif // LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
199