]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Plugins / Process / gdb-remote / GDBRemoteCommunication.h
1 //===-- GDBRemoteCommunication.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_GDBRemoteCommunication_h_
11 #define liblldb_GDBRemoteCommunication_h_
12
13 // C Includes
14 // C++ Includes
15 #include <list>
16 #include <string>
17
18 // Other libraries and framework includes
19 // Project includes
20 #include "lldb/lldb-public.h"
21 #include "lldb/Core/Communication.h"
22 #include "lldb/Core/Listener.h"
23 #include "lldb/Host/Mutex.h"
24 #include "lldb/Host/Predicate.h"
25 #include "lldb/Host/TimeValue.h"
26
27 #include "Utility/StringExtractorGDBRemote.h"
28
29 class ProcessGDBRemote;
30
31 class GDBRemoteCommunication : public lldb_private::Communication
32 {
33 public:
34     enum
35     {
36         eBroadcastBitRunPacketSent = kLoUserBroadcastBit
37     };
38     
39     enum class PacketResult
40     {
41         Success = 0,        // Success
42         ErrorSendFailed,    // Error sending the packet
43         ErrorSendAck,       // Didn't get an ack back after sending a packet
44         ErrorReplyFailed,   // Error getting the reply
45         ErrorReplyTimeout,  // Timed out waiting for reply
46         ErrorReplyInvalid,  // Got a reply but it wasn't valid for the packet that was sent
47         ErrorReplyAck,      // Sending reply ack failed
48         ErrorDisconnected,  // We were disconnected
49         ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
50     };
51     //------------------------------------------------------------------
52     // Constructors and Destructors
53     //------------------------------------------------------------------
54     GDBRemoteCommunication(const char *comm_name, 
55                            const char *listener_name,
56                            bool is_platform);
57
58     virtual
59     ~GDBRemoteCommunication();
60
61     PacketResult
62     GetAck ();
63
64     size_t
65     SendAck ();
66
67     size_t
68     SendNack ();
69
70     char
71     CalculcateChecksum (const char *payload,
72                         size_t payload_length);
73
74     bool
75     GetSequenceMutex (lldb_private::Mutex::Locker& locker, const char *failure_message = NULL);
76
77     bool
78     CheckForPacket (const uint8_t *src, 
79                     size_t src_len, 
80                     StringExtractorGDBRemote &packet);
81     bool
82     IsRunning() const
83     {
84         return m_public_is_running.GetValue();
85     }
86
87     bool
88     GetSendAcks ()
89     {
90         return m_send_acks;
91     }
92
93     //------------------------------------------------------------------
94     // Client and server must implement these pure virtual functions
95     //------------------------------------------------------------------
96     virtual bool
97     GetThreadSuffixSupported () = 0;
98
99     //------------------------------------------------------------------
100     // Set the global packet timeout.
101     //
102     // For clients, this is the timeout that gets used when sending
103     // packets and waiting for responses. For servers, this might not
104     // get used, and if it doesn't this should be moved to the
105     // GDBRemoteCommunicationClient.
106     //------------------------------------------------------------------
107     uint32_t 
108     SetPacketTimeout (uint32_t packet_timeout)
109     {
110         const uint32_t old_packet_timeout = m_packet_timeout;
111         m_packet_timeout = packet_timeout;
112         return old_packet_timeout;
113     }
114
115     uint32_t
116     GetPacketTimeoutInMicroSeconds () const
117     {
118         return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
119     }
120     //------------------------------------------------------------------
121     // Start a debugserver instance on the current host using the
122     // supplied connection URL.
123     //------------------------------------------------------------------
124     lldb_private::Error
125     StartDebugserverProcess (const char *hostname,
126                              uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
127                              lldb_private::ProcessLaunchInfo &launch_info,
128                              uint16_t &out_port);
129
130     void
131     DumpHistory(lldb_private::Stream &strm);
132     
133 protected:
134
135     class History
136     {
137     public:
138         enum PacketType
139         {
140             ePacketTypeInvalid = 0,
141             ePacketTypeSend,
142             ePacketTypeRecv
143         };
144
145         struct Entry
146         {
147             Entry() :
148                 packet(),
149                 type (ePacketTypeInvalid),
150                 bytes_transmitted (0),
151                 packet_idx (0),
152                 tid (LLDB_INVALID_THREAD_ID)
153             {
154             }
155             
156             void
157             Clear ()
158             {
159                 packet.clear();
160                 type = ePacketTypeInvalid;
161                 bytes_transmitted = 0;
162                 packet_idx = 0;
163                 tid = LLDB_INVALID_THREAD_ID;
164             }
165             std::string packet;
166             PacketType type;
167             uint32_t bytes_transmitted;
168             uint32_t packet_idx;
169             lldb::tid_t tid;
170         };
171
172         History (uint32_t size);
173         
174         ~History ();
175
176         // For single char packets for ack, nack and /x03
177         void
178         AddPacket (char packet_char,
179                    PacketType type,
180                    uint32_t bytes_transmitted);
181         void
182         AddPacket (const std::string &src,
183                    uint32_t src_len,
184                    PacketType type,
185                    uint32_t bytes_transmitted);
186         
187         void
188         Dump (lldb_private::Stream &strm) const;
189
190         void
191         Dump (lldb_private::Log *log) const;
192
193         bool
194         DidDumpToLog () const
195         {
196             return m_dumped_to_log;
197         }
198     
199 protected:
200         uint32_t
201         GetFirstSavedPacketIndex () const
202         {
203             if (m_total_packet_count < m_packets.size())
204                 return 0;
205             else
206                 return m_curr_idx + 1;
207         }
208
209         uint32_t
210         GetNumPacketsInHistory () const
211         {
212             if (m_total_packet_count < m_packets.size())
213                 return m_total_packet_count;
214             else
215                 return (uint32_t)m_packets.size();
216         }
217
218         uint32_t
219         GetNextIndex()
220         {
221             ++m_total_packet_count;
222             const uint32_t idx = m_curr_idx;
223             m_curr_idx = NormalizeIndex(idx + 1);
224             return idx;
225         }
226
227         uint32_t
228         NormalizeIndex (uint32_t i) const
229         {
230             return i % m_packets.size();
231         }
232
233         
234         std::vector<Entry> m_packets;
235         uint32_t m_curr_idx;
236         uint32_t m_total_packet_count;
237         mutable bool m_dumped_to_log;
238     };
239
240     PacketResult
241     SendPacket (const char *payload,
242                 size_t payload_length);
243
244     PacketResult
245     SendPacketNoLock (const char *payload, 
246                       size_t payload_length);
247
248     PacketResult
249     WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response, 
250                                                 uint32_t timeout_usec);
251
252     bool
253     WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
254
255     //------------------------------------------------------------------
256     // Classes that inherit from GDBRemoteCommunication can see and modify these
257     //------------------------------------------------------------------
258     uint32_t m_packet_timeout;
259 #ifdef ENABLE_MUTEX_ERROR_CHECKING
260     lldb_private::TrackingMutex m_sequence_mutex;
261 #else
262     lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
263 #endif
264     lldb_private::Predicate<bool> m_public_is_running;
265     lldb_private::Predicate<bool> m_private_is_running;
266     History m_history;
267     bool m_send_acks;
268     bool m_is_platform; // Set to true if this class represents a platform,
269                         // false if this class represents a debug session for
270                         // a single process
271     
272
273     lldb_private::Error
274     StartListenThread (const char *hostname = "localhost",
275                        uint16_t port = 0);
276
277     bool
278     JoinListenThread ();
279
280     static lldb::thread_result_t
281     ListenThread (lldb::thread_arg_t arg);
282
283 private:
284     
285     lldb::thread_t m_listen_thread;
286     std::string m_listen_url;
287     
288
289     //------------------------------------------------------------------
290     // For GDBRemoteCommunication only
291     //------------------------------------------------------------------
292     DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
293 };
294
295 #endif  // liblldb_GDBRemoteCommunication_h_