blob: ddcd4cbbeb0979052ae577a5544dfdd92b09a891 [file] [log] [blame]
Greg Clayton576d8832011-03-22 04:00:09 +00001//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Greg Clayton576d8832011-03-22 04:00:09 +00006//
7//===----------------------------------------------------------------------===//
8
Sylvestre Ledrud28b9932013-09-28 15:23:41 +00009#include <errno.h>
Greg Clayton576d8832011-03-22 04:00:09 +000010
Zachary Turner0ec7baa2014-07-01 00:18:46 +000011#include "lldb/Host/Config.h"
12
Greg Clayton576d8832011-03-22 04:00:09 +000013#include "GDBRemoteCommunicationServer.h"
14
Todd Fialaaf245d12014-06-30 21:05:18 +000015#include <cstring>
Greg Clayton576d8832011-03-22 04:00:09 +000016
Greg Clayton576d8832011-03-22 04:00:09 +000017#include "ProcessGDBRemoteLog.h"
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +000018#include "lldb/Utility/StreamString.h"
Pavel Labath9af71b32018-03-20 16:14:00 +000019#include "lldb/Utility/StringExtractorGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000020
21using namespace lldb;
22using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000023using namespace lldb_private::process_gdb_remote;
Greg Clayton576d8832011-03-22 04:00:09 +000024
Kate Stoneb9c1b512016-09-06 20:57:50 +000025GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
26 const char *comm_name, const char *listener_name)
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +000027 : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {
28 RegisterPacketHandler(
29 StringExtractorGDBRemote::eServerPacketType_QEnableErrorStrings,
30 [this](StringExtractorGDBRemote packet, Status &error, bool &interrupt,
31 bool &quit) { return this->Handle_QErrorStringEnable(packet); });
32}
Todd Fialaaf245d12014-06-30 21:05:18 +000033
Kate Stoneb9c1b512016-09-06 20:57:50 +000034GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
Greg Clayton576d8832011-03-22 04:00:09 +000035
Tamas Berghammere13c2732015-02-11 10:29:30 +000036void GDBRemoteCommunicationServer::RegisterPacketHandler(
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 StringExtractorGDBRemote::ServerPacketType packet_type,
38 PacketHandler handler) {
39 m_packet_handlers[packet_type] = std::move(handler);
Tamas Berghammere13c2732015-02-11 10:29:30 +000040}
41
Todd Fialaaf245d12014-06-30 21:05:18 +000042GDBRemoteCommunication::PacketResult
Pavel Labath1eff73c2016-11-24 10:54:49 +000043GDBRemoteCommunicationServer::GetPacketAndSendResponse(
Zachary Turner97206d52017-05-12 04:51:55 +000044 Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 StringExtractorGDBRemote packet;
Todd Fialaaf245d12014-06-30 21:05:18 +000046
Pavel Labath1eff73c2016-11-24 10:54:49 +000047 PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 if (packet_result == PacketResult::Success) {
49 const StringExtractorGDBRemote::ServerPacketType packet_type =
50 packet.GetServerPacketType();
51 switch (packet_type) {
52 case StringExtractorGDBRemote::eServerPacketType_nack:
53 case StringExtractorGDBRemote::eServerPacketType_ack:
54 break;
Greg Clayton576d8832011-03-22 04:00:09 +000055
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 case StringExtractorGDBRemote::eServerPacketType_invalid:
57 error.SetErrorString("invalid packet");
58 quit = true;
59 break;
Greg Claytond314e812011-03-23 00:09:55 +000060
Kate Stoneb9c1b512016-09-06 20:57:50 +000061 case StringExtractorGDBRemote::eServerPacketType_unimplemented:
62 packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str());
63 break;
Greg Clayton576d8832011-03-22 04:00:09 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 default:
66 auto handler_it = m_packet_handlers.find(packet_type);
67 if (handler_it == m_packet_handlers.end())
68 packet_result =
69 SendUnimplementedResponse(packet.GetStringRef().c_str());
70 else
71 packet_result = handler_it->second(packet, error, interrupt, quit);
72 break;
Greg Clayton576d8832011-03-22 04:00:09 +000073 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 } else {
75 if (!IsConnected()) {
76 error.SetErrorString("lost connection");
77 quit = true;
78 } else {
79 error.SetErrorString("timeout");
Greg Clayton1cb64962011-03-24 04:28:38 +000080 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 }
Todd Fialaaf245d12014-06-30 21:05:18 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 // Check if anything occurred that would force us to want to exit.
84 if (m_exit_now)
85 quit = true;
Todd Fialaaf245d12014-06-30 21:05:18 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 return packet_result;
Greg Clayton576d8832011-03-22 04:00:09 +000088}
89
Greg Clayton3dedae12013-12-06 21:45:27 +000090GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +000091GDBRemoteCommunicationServer::SendUnimplementedResponse(const char *) {
92 // TODO: Log the packet we aren't handling...
93 return SendPacketNoLock("");
Greg Clayton32e0a752011-03-30 18:16:51 +000094}
95
Todd Fialaaf245d12014-06-30 21:05:18 +000096GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +000097GDBRemoteCommunicationServer::SendErrorResponse(uint8_t err) {
98 char packet[16];
99 int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
100 assert(packet_len < (int)sizeof(packet));
101 return SendPacketNoLock(llvm::StringRef(packet, packet_len));
Todd Fialaaf245d12014-06-30 21:05:18 +0000102}
Greg Clayton32e0a752011-03-30 18:16:51 +0000103
Greg Clayton3dedae12013-12-06 21:45:27 +0000104GDBRemoteCommunication::PacketResult
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000105GDBRemoteCommunicationServer::SendErrorResponse(const Status &error) {
106 if (m_send_error_strings) {
107 lldb_private::StreamString packet;
108 packet.Printf("E%2.2x;", static_cast<uint8_t>(error.GetError()));
109 packet.PutCStringAsRawHex8(error.AsCString());
110 return SendPacketNoLock(packet.GetString());
111 } else
112 return SendErrorResponse(error.GetError());
113}
114
115GDBRemoteCommunication::PacketResult
116GDBRemoteCommunicationServer::Handle_QErrorStringEnable(
117 StringExtractorGDBRemote &packet) {
118 m_send_error_strings = true;
119 return SendOKResponse();
120}
121
122GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123GDBRemoteCommunicationServer::SendIllFormedResponse(
124 const StringExtractorGDBRemote &failed_packet, const char *message) {
125 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
126 if (log)
127 log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
128 __FUNCTION__, failed_packet.GetStringRef().c_str(),
129 message ? message : "");
130 return SendErrorResponse(0x03);
Greg Clayton1cb64962011-03-24 04:28:38 +0000131}
132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133GDBRemoteCommunication::PacketResult
134GDBRemoteCommunicationServer::SendOKResponse() {
135 return SendPacketNoLock("OK");
136}
137
138bool GDBRemoteCommunicationServer::HandshakeWithClient() {
139 return GetAck() == PacketResult::Success;
Greg Clayton1cb64962011-03-24 04:28:38 +0000140}