1 //===-- GDBRemoteCommunicationServer.cpp ------------------------*- 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 #include <errno.h> 11 12 #include "lldb/Host/Config.h" 13 14 #include "GDBRemoteCommunicationServer.h" 15 16 // C Includes 17 // C++ Includes 18 #include <cstring> 19 20 // Project includes 21 #include "ProcessGDBRemoteLog.h" 22 #include "Utility/StringExtractorGDBRemote.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(const char *comm_name, 28 const char *listener_name) : 29 GDBRemoteCommunication (comm_name, listener_name), 30 m_exit_now (false) 31 { 32 } 33 34 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() 35 { 36 } 37 38 void GDBRemoteCommunicationServer::RegisterPacketHandler( 39 StringExtractorGDBRemote::ServerPacketType packet_type, 40 PacketHandler handler) 41 { 42 m_packet_handlers[packet_type] = std::move(handler); 43 } 44 45 GDBRemoteCommunication::PacketResult 46 GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec, 47 Error &error, 48 bool &interrupt, 49 bool &quit) 50 { 51 StringExtractorGDBRemote packet; 52 53 PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec); 54 if (packet_result == PacketResult::Success) 55 { 56 const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType (); 57 switch (packet_type) 58 { 59 case StringExtractorGDBRemote::eServerPacketType_nack: 60 case StringExtractorGDBRemote::eServerPacketType_ack: 61 break; 62 63 case StringExtractorGDBRemote::eServerPacketType_invalid: 64 error.SetErrorString("invalid packet"); 65 quit = true; 66 break; 67 68 case StringExtractorGDBRemote::eServerPacketType_unimplemented: 69 packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str()); 70 break; 71 72 default: 73 auto handler_it = m_packet_handlers.find(packet_type); 74 if (handler_it == m_packet_handlers.end()) 75 packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str()); 76 else 77 packet_result = handler_it->second (packet, error, interrupt, quit); 78 break; 79 } 80 } 81 else 82 { 83 if (!IsConnected()) 84 { 85 error.SetErrorString("lost connection"); 86 quit = true; 87 } 88 else 89 { 90 error.SetErrorString("timeout"); 91 } 92 } 93 94 // Check if anything occurred that would force us to want to exit. 95 if (m_exit_now) 96 quit = true; 97 98 return packet_result; 99 } 100 101 GDBRemoteCommunication::PacketResult 102 GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *) 103 { 104 // TODO: Log the packet we aren't handling... 105 return SendPacketNoLock ("", 0); 106 } 107 108 109 GDBRemoteCommunication::PacketResult 110 GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err) 111 { 112 char packet[16]; 113 int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err); 114 assert (packet_len < (int)sizeof(packet)); 115 return SendPacketNoLock (packet, packet_len); 116 } 117 118 GDBRemoteCommunication::PacketResult 119 GDBRemoteCommunicationServer::SendIllFormedResponse (const StringExtractorGDBRemote &failed_packet, const char *message) 120 { 121 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS)); 122 if (log) 123 log->Printf ("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", __FUNCTION__, failed_packet.GetStringRef ().c_str (), message ? message : ""); 124 return SendErrorResponse (0x03); 125 } 126 127 GDBRemoteCommunication::PacketResult 128 GDBRemoteCommunicationServer::SendOKResponse () 129 { 130 return SendPacketNoLock ("OK", 2); 131 } 132 133 bool 134 GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) 135 { 136 return GetAck() == PacketResult::Success; 137 } 138