blob: 409efdfa2f742aa3a2efed215051b317aa357357 [file] [log] [blame]
Greg Clayton576d8832011-03-22 04:00:09 +00001//===-- 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
Sylvestre Ledrud28b9932013-09-28 15:23:41 +000010#include <errno.h>
Greg Clayton576d8832011-03-22 04:00:09 +000011
Zachary Turner0ec7baa2014-07-01 00:18:46 +000012#include "lldb/Host/Config.h"
13
Greg Clayton576d8832011-03-22 04:00:09 +000014#include "GDBRemoteCommunicationServer.h"
15
16// C Includes
17// C++ Includes
Todd Fialaaf245d12014-06-30 21:05:18 +000018#include <cstring>
Greg Clayton576d8832011-03-22 04:00:09 +000019
20// Project includes
Greg Clayton576d8832011-03-22 04:00:09 +000021#include "ProcessGDBRemoteLog.h"
Tamas Berghammere13c2732015-02-11 10:29:30 +000022#include "Utility/StringExtractorGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000023
24using namespace lldb;
25using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000026using namespace lldb_private::process_gdb_remote;
Greg Clayton576d8832011-03-22 04:00:09 +000027
Tamas Berghammere13c2732015-02-11 10:29:30 +000028GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(const char *comm_name,
29 const char *listener_name) :
30 GDBRemoteCommunication (comm_name, listener_name),
31 m_exit_now (false)
Todd Fialaaf245d12014-06-30 21:05:18 +000032{
Todd Fialaaf245d12014-06-30 21:05:18 +000033}
34
Greg Clayton576d8832011-03-22 04:00:09 +000035GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
36{
37}
38
Tamas Berghammere13c2732015-02-11 10:29:30 +000039void GDBRemoteCommunicationServer::RegisterPacketHandler(
40 StringExtractorGDBRemote::ServerPacketType packet_type,
41 PacketHandler handler)
42{
43 m_packet_handlers[packet_type] = std::move(handler);
44}
45
Todd Fialaaf245d12014-06-30 21:05:18 +000046GDBRemoteCommunication::PacketResult
Sylvestre Ledrub027bd22013-09-28 14:35:00 +000047GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
Greg Clayton1cb64962011-03-24 04:28:38 +000048 Error &error,
Sylvestre Ledrub027bd22013-09-28 14:35:00 +000049 bool &interrupt,
Greg Claytond314e812011-03-23 00:09:55 +000050 bool &quit)
Greg Clayton576d8832011-03-22 04:00:09 +000051{
52 StringExtractorGDBRemote packet;
Todd Fialaaf245d12014-06-30 21:05:18 +000053
Greg Clayton3dedae12013-12-06 21:45:27 +000054 PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
55 if (packet_result == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +000056 {
57 const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
58 switch (packet_type)
59 {
Greg Clayton3dedae12013-12-06 21:45:27 +000060 case StringExtractorGDBRemote::eServerPacketType_nack:
61 case StringExtractorGDBRemote::eServerPacketType_ack:
62 break;
Greg Clayton576d8832011-03-22 04:00:09 +000063
Greg Clayton3dedae12013-12-06 21:45:27 +000064 case StringExtractorGDBRemote::eServerPacketType_invalid:
65 error.SetErrorString("invalid packet");
66 quit = true;
67 break;
Greg Claytond314e812011-03-23 00:09:55 +000068
Greg Clayton3dedae12013-12-06 21:45:27 +000069 case StringExtractorGDBRemote::eServerPacketType_unimplemented:
70 packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
71 break;
Greg Clayton576d8832011-03-22 04:00:09 +000072
Tamas Berghammere13c2732015-02-11 10:29:30 +000073 default:
74 auto handler_it = m_packet_handlers.find(packet_type);
75 if (handler_it == m_packet_handlers.end())
76 packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
Todd Fialaaf245d12014-06-30 21:05:18 +000077 else
Tamas Berghammere13c2732015-02-11 10:29:30 +000078 packet_result = handler_it->second (packet, error, interrupt, quit);
Todd Fiala1109ed42014-09-10 21:28:38 +000079 break;
Greg Clayton576d8832011-03-22 04:00:09 +000080 }
Greg Clayton576d8832011-03-22 04:00:09 +000081 }
Greg Clayton1cb64962011-03-24 04:28:38 +000082 else
83 {
84 if (!IsConnected())
Greg Clayton3dedae12013-12-06 21:45:27 +000085 {
Greg Clayton1cb64962011-03-24 04:28:38 +000086 error.SetErrorString("lost connection");
Greg Clayton3dedae12013-12-06 21:45:27 +000087 quit = true;
88 }
Greg Clayton1cb64962011-03-24 04:28:38 +000089 else
Greg Clayton3dedae12013-12-06 21:45:27 +000090 {
Greg Clayton1cb64962011-03-24 04:28:38 +000091 error.SetErrorString("timeout");
Greg Clayton3dedae12013-12-06 21:45:27 +000092 }
Greg Clayton1cb64962011-03-24 04:28:38 +000093 }
Todd Fialaaf245d12014-06-30 21:05:18 +000094
95 // Check if anything occurred that would force us to want to exit.
96 if (m_exit_now)
97 quit = true;
98
99 return packet_result;
Greg Clayton576d8832011-03-22 04:00:09 +0000100}
101
Greg Clayton3dedae12013-12-06 21:45:27 +0000102GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000103GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
Greg Clayton576d8832011-03-22 04:00:09 +0000104{
Greg Clayton32e0a752011-03-30 18:16:51 +0000105 // TODO: Log the packet we aren't handling...
Greg Clayton37a0a242012-04-11 00:24:49 +0000106 return SendPacketNoLock ("", 0);
Greg Clayton576d8832011-03-22 04:00:09 +0000107}
108
Todd Fialaaf245d12014-06-30 21:05:18 +0000109
Greg Clayton3dedae12013-12-06 21:45:27 +0000110GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000111GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
112{
113 char packet[16];
114 int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
Andy Gibbsa297a972013-06-19 19:04:53 +0000115 assert (packet_len < (int)sizeof(packet));
Greg Clayton37a0a242012-04-11 00:24:49 +0000116 return SendPacketNoLock (packet, packet_len);
Greg Clayton32e0a752011-03-30 18:16:51 +0000117}
118
Todd Fialaaf245d12014-06-30 21:05:18 +0000119GDBRemoteCommunication::PacketResult
120GDBRemoteCommunicationServer::SendIllFormedResponse (const StringExtractorGDBRemote &failed_packet, const char *message)
121{
122 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
123 if (log)
124 log->Printf ("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", __FUNCTION__, failed_packet.GetStringRef ().c_str (), message ? message : "");
125 return SendErrorResponse (0x03);
126}
Greg Clayton32e0a752011-03-30 18:16:51 +0000127
Greg Clayton3dedae12013-12-06 21:45:27 +0000128GDBRemoteCommunication::PacketResult
Greg Clayton1cb64962011-03-24 04:28:38 +0000129GDBRemoteCommunicationServer::SendOKResponse ()
130{
Greg Clayton37a0a242012-04-11 00:24:49 +0000131 return SendPacketNoLock ("OK", 2);
Greg Clayton1cb64962011-03-24 04:28:38 +0000132}
133
134bool
135GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
136{
Greg Clayton3dedae12013-12-06 21:45:27 +0000137 return GetAck() == PacketResult::Success;
Greg Clayton1cb64962011-03-24 04:28:38 +0000138}