blob: dac675ee943235cb94208ac0ddf7d2022b460f7a [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
Kate Stoneb9c1b512016-09-06 20:57:50 +000028GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
29 const char *comm_name, const char *listener_name)
30 : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {}
Todd Fialaaf245d12014-06-30 21:05:18 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
Greg Clayton576d8832011-03-22 04:00:09 +000033
Tamas Berghammere13c2732015-02-11 10:29:30 +000034void GDBRemoteCommunicationServer::RegisterPacketHandler(
Kate Stoneb9c1b512016-09-06 20:57:50 +000035 StringExtractorGDBRemote::ServerPacketType packet_type,
36 PacketHandler handler) {
37 m_packet_handlers[packet_type] = std::move(handler);
Tamas Berghammere13c2732015-02-11 10:29:30 +000038}
39
Todd Fialaaf245d12014-06-30 21:05:18 +000040GDBRemoteCommunication::PacketResult
Pavel Labath1eff73c2016-11-24 10:54:49 +000041GDBRemoteCommunicationServer::GetPacketAndSendResponse(
Zachary Turner97206d52017-05-12 04:51:55 +000042 Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000043 StringExtractorGDBRemote packet;
Todd Fialaaf245d12014-06-30 21:05:18 +000044
Pavel Labath1eff73c2016-11-24 10:54:49 +000045 PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 if (packet_result == PacketResult::Success) {
47 const StringExtractorGDBRemote::ServerPacketType packet_type =
48 packet.GetServerPacketType();
49 switch (packet_type) {
50 case StringExtractorGDBRemote::eServerPacketType_nack:
51 case StringExtractorGDBRemote::eServerPacketType_ack:
52 break;
Greg Clayton576d8832011-03-22 04:00:09 +000053
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 case StringExtractorGDBRemote::eServerPacketType_invalid:
55 error.SetErrorString("invalid packet");
56 quit = true;
57 break;
Greg Claytond314e812011-03-23 00:09:55 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 case StringExtractorGDBRemote::eServerPacketType_unimplemented:
60 packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str());
61 break;
Greg Clayton576d8832011-03-22 04:00:09 +000062
Kate Stoneb9c1b512016-09-06 20:57:50 +000063 default:
64 auto handler_it = m_packet_handlers.find(packet_type);
65 if (handler_it == m_packet_handlers.end())
66 packet_result =
67 SendUnimplementedResponse(packet.GetStringRef().c_str());
68 else
69 packet_result = handler_it->second(packet, error, interrupt, quit);
70 break;
Greg Clayton576d8832011-03-22 04:00:09 +000071 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 } else {
73 if (!IsConnected()) {
74 error.SetErrorString("lost connection");
75 quit = true;
76 } else {
77 error.SetErrorString("timeout");
Greg Clayton1cb64962011-03-24 04:28:38 +000078 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 }
Todd Fialaaf245d12014-06-30 21:05:18 +000080
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 // Check if anything occurred that would force us to want to exit.
82 if (m_exit_now)
83 quit = true;
Todd Fialaaf245d12014-06-30 21:05:18 +000084
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 return packet_result;
Greg Clayton576d8832011-03-22 04:00:09 +000086}
87
Greg Clayton3dedae12013-12-06 21:45:27 +000088GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +000089GDBRemoteCommunicationServer::SendUnimplementedResponse(const char *) {
90 // TODO: Log the packet we aren't handling...
91 return SendPacketNoLock("");
Greg Clayton32e0a752011-03-30 18:16:51 +000092}
93
Todd Fialaaf245d12014-06-30 21:05:18 +000094GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +000095GDBRemoteCommunicationServer::SendErrorResponse(uint8_t err) {
96 char packet[16];
97 int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
98 assert(packet_len < (int)sizeof(packet));
99 return SendPacketNoLock(llvm::StringRef(packet, packet_len));
Todd Fialaaf245d12014-06-30 21:05:18 +0000100}
Greg Clayton32e0a752011-03-30 18:16:51 +0000101
Greg Clayton3dedae12013-12-06 21:45:27 +0000102GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103GDBRemoteCommunicationServer::SendIllFormedResponse(
104 const StringExtractorGDBRemote &failed_packet, const char *message) {
105 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
106 if (log)
107 log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
108 __FUNCTION__, failed_packet.GetStringRef().c_str(),
109 message ? message : "");
110 return SendErrorResponse(0x03);
Greg Clayton1cb64962011-03-24 04:28:38 +0000111}
112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113GDBRemoteCommunication::PacketResult
114GDBRemoteCommunicationServer::SendOKResponse() {
115 return SendPacketNoLock("OK");
116}
117
118bool GDBRemoteCommunicationServer::HandshakeWithClient() {
119 return GetAck() == PacketResult::Success;
Greg Clayton1cb64962011-03-24 04:28:38 +0000120}