1254721Semaste//===-- GDBRemoteCommunication.h --------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef liblldb_GDBRemoteCommunication_h_
11254721Semaste#define liblldb_GDBRemoteCommunication_h_
12254721Semaste
13254721Semaste// C Includes
14254721Semaste// C++ Includes
15254721Semaste#include <list>
16254721Semaste#include <string>
17254721Semaste
18254721Semaste// Other libraries and framework includes
19254721Semaste// Project includes
20254721Semaste#include "lldb/lldb-public.h"
21254721Semaste#include "lldb/Core/Communication.h"
22254721Semaste#include "lldb/Core/Listener.h"
23254721Semaste#include "lldb/Host/Mutex.h"
24254721Semaste#include "lldb/Host/Predicate.h"
25254721Semaste#include "lldb/Host/TimeValue.h"
26254721Semaste
27254721Semaste#include "Utility/StringExtractorGDBRemote.h"
28254721Semaste
29254721Semasteclass ProcessGDBRemote;
30254721Semaste
31254721Semasteclass GDBRemoteCommunication : public lldb_private::Communication
32254721Semaste{
33254721Semastepublic:
34254721Semaste    enum
35254721Semaste    {
36254721Semaste        eBroadcastBitRunPacketSent = kLoUserBroadcastBit
37254721Semaste    };
38269024Semaste
39269024Semaste    enum class PacketResult
40269024Semaste    {
41269024Semaste        Success = 0,        // Success
42269024Semaste        ErrorSendFailed,    // Error sending the packet
43269024Semaste        ErrorSendAck,       // Didn't get an ack back after sending a packet
44269024Semaste        ErrorReplyFailed,   // Error getting the reply
45269024Semaste        ErrorReplyTimeout,  // Timed out waiting for reply
46269024Semaste        ErrorReplyInvalid,  // Got a reply but it wasn't valid for the packet that was sent
47269024Semaste        ErrorReplyAck,      // Sending reply ack failed
48269024Semaste        ErrorDisconnected,  // We were disconnected
49269024Semaste        ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
50269024Semaste    };
51254721Semaste    //------------------------------------------------------------------
52254721Semaste    // Constructors and Destructors
53254721Semaste    //------------------------------------------------------------------
54254721Semaste    GDBRemoteCommunication(const char *comm_name,
55254721Semaste                           const char *listener_name,
56254721Semaste                           bool is_platform);
57254721Semaste
58254721Semaste    virtual
59254721Semaste    ~GDBRemoteCommunication();
60254721Semaste
61269024Semaste    PacketResult
62254721Semaste    GetAck ();
63254721Semaste
64254721Semaste    size_t
65254721Semaste    SendAck ();
66254721Semaste
67254721Semaste    size_t
68254721Semaste    SendNack ();
69254721Semaste
70254721Semaste    char
71254721Semaste    CalculcateChecksum (const char *payload,
72254721Semaste                        size_t payload_length);
73254721Semaste
74254721Semaste    bool
75254721Semaste    GetSequenceMutex (lldb_private::Mutex::Locker& locker, const char *failure_message = NULL);
76254721Semaste
77254721Semaste    bool
78254721Semaste    CheckForPacket (const uint8_t *src,
79254721Semaste                    size_t src_len,
80254721Semaste                    StringExtractorGDBRemote &packet);
81254721Semaste    bool
82254721Semaste    IsRunning() const
83254721Semaste    {
84254721Semaste        return m_public_is_running.GetValue();
85254721Semaste    }
86254721Semaste
87254721Semaste    bool
88254721Semaste    GetSendAcks ()
89254721Semaste    {
90254721Semaste        return m_send_acks;
91254721Semaste    }
92254721Semaste
93254721Semaste    //------------------------------------------------------------------
94254721Semaste    // Client and server must implement these pure virtual functions
95254721Semaste    //------------------------------------------------------------------
96254721Semaste    virtual bool
97254721Semaste    GetThreadSuffixSupported () = 0;
98254721Semaste
99254721Semaste    //------------------------------------------------------------------
100254721Semaste    // Set the global packet timeout.
101254721Semaste    //
102254721Semaste    // For clients, this is the timeout that gets used when sending
103254721Semaste    // packets and waiting for responses. For servers, this might not
104254721Semaste    // get used, and if it doesn't this should be moved to the
105254721Semaste    // GDBRemoteCommunicationClient.
106254721Semaste    //------------------------------------------------------------------
107254721Semaste    uint32_t
108254721Semaste    SetPacketTimeout (uint32_t packet_timeout)
109254721Semaste    {
110254721Semaste        const uint32_t old_packet_timeout = m_packet_timeout;
111254721Semaste        m_packet_timeout = packet_timeout;
112254721Semaste        return old_packet_timeout;
113254721Semaste    }
114254721Semaste
115254721Semaste    uint32_t
116254721Semaste    GetPacketTimeoutInMicroSeconds () const
117254721Semaste    {
118254721Semaste        return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
119254721Semaste    }
120254721Semaste    //------------------------------------------------------------------
121254721Semaste    // Start a debugserver instance on the current host using the
122254721Semaste    // supplied connection URL.
123254721Semaste    //------------------------------------------------------------------
124254721Semaste    lldb_private::Error
125269024Semaste    StartDebugserverProcess (const char *hostname,
126269024Semaste                             uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
127269024Semaste                             lldb_private::ProcessLaunchInfo &launch_info,
128269024Semaste                             uint16_t &out_port);
129254721Semaste
130254721Semaste    void
131254721Semaste    DumpHistory(lldb_private::Stream &strm);
132254721Semaste
133254721Semasteprotected:
134254721Semaste
135254721Semaste    class History
136254721Semaste    {
137254721Semaste    public:
138254721Semaste        enum PacketType
139254721Semaste        {
140254721Semaste            ePacketTypeInvalid = 0,
141254721Semaste            ePacketTypeSend,
142254721Semaste            ePacketTypeRecv
143254721Semaste        };
144254721Semaste
145254721Semaste        struct Entry
146254721Semaste        {
147254721Semaste            Entry() :
148254721Semaste                packet(),
149254721Semaste                type (ePacketTypeInvalid),
150254721Semaste                bytes_transmitted (0),
151254721Semaste                packet_idx (0),
152254721Semaste                tid (LLDB_INVALID_THREAD_ID)
153254721Semaste            {
154254721Semaste            }
155254721Semaste
156254721Semaste            void
157254721Semaste            Clear ()
158254721Semaste            {
159254721Semaste                packet.clear();
160254721Semaste                type = ePacketTypeInvalid;
161254721Semaste                bytes_transmitted = 0;
162254721Semaste                packet_idx = 0;
163254721Semaste                tid = LLDB_INVALID_THREAD_ID;
164254721Semaste            }
165254721Semaste            std::string packet;
166254721Semaste            PacketType type;
167254721Semaste            uint32_t bytes_transmitted;
168254721Semaste            uint32_t packet_idx;
169254721Semaste            lldb::tid_t tid;
170254721Semaste        };
171254721Semaste
172254721Semaste        History (uint32_t size);
173254721Semaste
174254721Semaste        ~History ();
175254721Semaste
176254721Semaste        // For single char packets for ack, nack and /x03
177254721Semaste        void
178254721Semaste        AddPacket (char packet_char,
179254721Semaste                   PacketType type,
180254721Semaste                   uint32_t bytes_transmitted);
181254721Semaste        void
182254721Semaste        AddPacket (const std::string &src,
183254721Semaste                   uint32_t src_len,
184254721Semaste                   PacketType type,
185254721Semaste                   uint32_t bytes_transmitted);
186254721Semaste
187254721Semaste        void
188254721Semaste        Dump (lldb_private::Stream &strm) const;
189254721Semaste
190254721Semaste        void
191254721Semaste        Dump (lldb_private::Log *log) const;
192254721Semaste
193254721Semaste        bool
194254721Semaste        DidDumpToLog () const
195254721Semaste        {
196254721Semaste            return m_dumped_to_log;
197254721Semaste        }
198254721Semaste
199254721Semasteprotected:
200254721Semaste        uint32_t
201254721Semaste        GetFirstSavedPacketIndex () const
202254721Semaste        {
203254721Semaste            if (m_total_packet_count < m_packets.size())
204254721Semaste                return 0;
205254721Semaste            else
206254721Semaste                return m_curr_idx + 1;
207254721Semaste        }
208254721Semaste
209254721Semaste        uint32_t
210254721Semaste        GetNumPacketsInHistory () const
211254721Semaste        {
212254721Semaste            if (m_total_packet_count < m_packets.size())
213254721Semaste                return m_total_packet_count;
214254721Semaste            else
215254721Semaste                return (uint32_t)m_packets.size();
216254721Semaste        }
217254721Semaste
218254721Semaste        uint32_t
219254721Semaste        GetNextIndex()
220254721Semaste        {
221254721Semaste            ++m_total_packet_count;
222254721Semaste            const uint32_t idx = m_curr_idx;
223254721Semaste            m_curr_idx = NormalizeIndex(idx + 1);
224254721Semaste            return idx;
225254721Semaste        }
226254721Semaste
227254721Semaste        uint32_t
228254721Semaste        NormalizeIndex (uint32_t i) const
229254721Semaste        {
230254721Semaste            return i % m_packets.size();
231254721Semaste        }
232254721Semaste
233254721Semaste
234254721Semaste        std::vector<Entry> m_packets;
235254721Semaste        uint32_t m_curr_idx;
236254721Semaste        uint32_t m_total_packet_count;
237254721Semaste        mutable bool m_dumped_to_log;
238254721Semaste    };
239254721Semaste
240269024Semaste    PacketResult
241254721Semaste    SendPacket (const char *payload,
242254721Semaste                size_t payload_length);
243254721Semaste
244269024Semaste    PacketResult
245254721Semaste    SendPacketNoLock (const char *payload,
246254721Semaste                      size_t payload_length);
247254721Semaste
248269024Semaste    PacketResult
249254721Semaste    WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
250254721Semaste                                                uint32_t timeout_usec);
251254721Semaste
252254721Semaste    bool
253254721Semaste    WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
254254721Semaste
255254721Semaste    //------------------------------------------------------------------
256254721Semaste    // Classes that inherit from GDBRemoteCommunication can see and modify these
257254721Semaste    //------------------------------------------------------------------
258254721Semaste    uint32_t m_packet_timeout;
259269024Semaste#ifdef ENABLE_MUTEX_ERROR_CHECKING
260254721Semaste    lldb_private::TrackingMutex m_sequence_mutex;
261254721Semaste#else
262254721Semaste    lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
263254721Semaste#endif
264254721Semaste    lldb_private::Predicate<bool> m_public_is_running;
265254721Semaste    lldb_private::Predicate<bool> m_private_is_running;
266254721Semaste    History m_history;
267254721Semaste    bool m_send_acks;
268254721Semaste    bool m_is_platform; // Set to true if this class represents a platform,
269254721Semaste                        // false if this class represents a debug session for
270254721Semaste                        // a single process
271254721Semaste
272254721Semaste
273269024Semaste    lldb_private::Error
274269024Semaste    StartListenThread (const char *hostname = "localhost",
275269024Semaste                       uint16_t port = 0);
276254721Semaste
277269024Semaste    bool
278269024Semaste    JoinListenThread ();
279254721Semaste
280269024Semaste    static lldb::thread_result_t
281269024Semaste    ListenThread (lldb::thread_arg_t arg);
282269024Semaste
283254721Semasteprivate:
284269024Semaste
285269024Semaste    lldb::thread_t m_listen_thread;
286269024Semaste    std::string m_listen_url;
287269024Semaste
288269024Semaste
289254721Semaste    //------------------------------------------------------------------
290254721Semaste    // For GDBRemoteCommunication only
291254721Semaste    //------------------------------------------------------------------
292254721Semaste    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
293254721Semaste};
294254721Semaste
295254721Semaste#endif  // liblldb_GDBRemoteCommunication_h_
296