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