GDBRemoteCommunicationServer.h revision 263367
1//===-- GDBRemoteCommunicationServer.h --------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_GDBRemoteCommunicationServer_h_
11#define liblldb_GDBRemoteCommunicationServer_h_
12
13// C Includes
14// C++ Includes
15#include <vector>
16#include <set>
17// Other libraries and framework includes
18// Project includes
19#include "lldb/Host/Mutex.h"
20#include "lldb/Target/Process.h"
21#include "GDBRemoteCommunication.h"
22
23class ProcessGDBRemote;
24class StringExtractorGDBRemote;
25
26class GDBRemoteCommunicationServer : public GDBRemoteCommunication
27{
28public:
29    typedef std::map<uint16_t, lldb::pid_t> PortMap;
30
31    enum
32    {
33        eBroadcastBitRunPacketSent = kLoUserBroadcastBit
34    };
35    //------------------------------------------------------------------
36    // Constructors and Destructors
37    //------------------------------------------------------------------
38    GDBRemoteCommunicationServer(bool is_platform);
39
40    virtual
41    ~GDBRemoteCommunicationServer();
42
43    bool
44    GetPacketAndSendResponse (uint32_t timeout_usec,
45                              lldb_private::Error &error,
46                              bool &interrupt,
47                              bool &quit);
48
49    virtual bool
50    GetThreadSuffixSupported ()
51    {
52        return true;
53    }
54
55    // After connecting, do a little handshake with the client to make sure
56    // we are at least communicating
57    bool
58    HandshakeWithClient (lldb_private::Error *error_ptr);
59
60    // Set both ports to zero to let the platform automatically bind to
61    // a port chosen by the OS.
62    void
63    SetPortMap (PortMap &&port_map)
64    {
65        m_port_map = port_map;
66    }
67
68    //----------------------------------------------------------------------
69    // If we are using a port map where we can only use certain ports,
70    // get the next available port.
71    //
72    // If we are using a port map and we are out of ports, return UINT16_MAX
73    //
74    // If we aren't using a port map, return 0 to indicate we should bind to
75    // port 0 and then figure out which port we used.
76    //----------------------------------------------------------------------
77    uint16_t
78    GetNextAvailablePort ()
79    {
80        if (m_port_map.empty())
81            return 0; // Bind to port zero and get a port, we didn't have any limitations
82
83        for (auto &pair : m_port_map)
84        {
85            if (pair.second == LLDB_INVALID_PROCESS_ID)
86            {
87                pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
88                return pair.first;
89            }
90        }
91        return UINT16_MAX;
92    }
93
94    bool
95    AssociatePortWithProcess (uint16_t port, lldb::pid_t pid)
96    {
97        PortMap::iterator pos = m_port_map.find(port);
98        if (pos != m_port_map.end())
99        {
100            pos->second = pid;
101            return true;
102        }
103        return false;
104    }
105
106    bool
107    FreePort (uint16_t port)
108    {
109        PortMap::iterator pos = m_port_map.find(port);
110        if (pos != m_port_map.end())
111        {
112            pos->second = LLDB_INVALID_PROCESS_ID;
113            return true;
114        }
115        return false;
116    }
117
118    bool
119    FreePortForProcess (lldb::pid_t pid)
120    {
121        if (!m_port_map.empty())
122        {
123            for (auto &pair : m_port_map)
124            {
125                if (pair.second == pid)
126                {
127                    pair.second = LLDB_INVALID_PROCESS_ID;
128                    return true;
129                }
130            }
131        }
132        return false;
133    }
134
135    void
136    SetPortOffset (uint16_t port_offset)
137    {
138        m_port_offset = port_offset;
139    }
140
141protected:
142    lldb::thread_t m_async_thread;
143    lldb_private::ProcessLaunchInfo m_process_launch_info;
144    lldb_private::Error m_process_launch_error;
145    std::set<lldb::pid_t> m_spawned_pids;
146    lldb_private::Mutex m_spawned_pids_mutex;
147    lldb_private::ProcessInstanceInfoList m_proc_infos;
148    uint32_t m_proc_infos_index;
149    PortMap m_port_map;
150    uint16_t m_port_offset;
151
152
153    size_t
154    SendUnimplementedResponse (const char *packet);
155
156    size_t
157    SendErrorResponse (uint8_t error);
158
159    size_t
160    SendOKResponse ();
161
162    bool
163    Handle_A (StringExtractorGDBRemote &packet);
164
165    bool
166    Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
167
168    bool
169    Handle_qHostInfo (StringExtractorGDBRemote &packet);
170
171    bool
172    Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
173
174    bool
175    Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
176
177    bool
178    Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
179
180    bool
181    Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
182
183    bool
184    Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
185
186    bool
187    Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
188
189    bool
190    Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
191
192    bool
193    Handle_qC (StringExtractorGDBRemote &packet);
194
195    bool
196    Handle_qUserName (StringExtractorGDBRemote &packet);
197
198    bool
199    Handle_qGroupName (StringExtractorGDBRemote &packet);
200
201    bool
202    Handle_qSpeedTest (StringExtractorGDBRemote &packet);
203
204    bool
205    Handle_QEnvironment  (StringExtractorGDBRemote &packet);
206
207    bool
208    Handle_QLaunchArch (StringExtractorGDBRemote &packet);
209
210    bool
211    Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
212
213    bool
214    Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
215
216    bool
217    Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
218
219    bool
220    Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
221
222    bool
223    Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
224
225    bool
226    Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
227
228    bool
229    Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
230
231    bool
232    Handle_vFile_Open (StringExtractorGDBRemote &packet);
233
234    bool
235    Handle_vFile_Close (StringExtractorGDBRemote &packet);
236
237    bool
238    Handle_vFile_pRead (StringExtractorGDBRemote &packet);
239
240    bool
241    Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
242
243    bool
244    Handle_vFile_Size (StringExtractorGDBRemote &packet);
245
246    bool
247    Handle_vFile_Mode (StringExtractorGDBRemote &packet);
248
249    bool
250    Handle_vFile_Exists (StringExtractorGDBRemote &packet);
251
252    bool
253    Handle_vFile_symlink (StringExtractorGDBRemote &packet);
254
255    bool
256    Handle_vFile_unlink (StringExtractorGDBRemote &packet);
257
258    bool
259    Handle_vFile_Stat (StringExtractorGDBRemote &packet);
260
261    bool
262    Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
263
264    bool
265    Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
266
267private:
268    bool
269    DebugserverProcessReaped (lldb::pid_t pid);
270
271    static bool
272    ReapDebugserverProcess (void *callback_baton,
273                            lldb::pid_t pid,
274                            bool exited,
275                            int signal,
276                            int status);
277
278    //------------------------------------------------------------------
279    // For GDBRemoteCommunicationServer only
280    //------------------------------------------------------------------
281    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServer);
282};
283
284#endif  // liblldb_GDBRemoteCommunicationServer_h_
285