]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
Vendor import of (stripped) lldb trunk r242221:
[FreeBSD/FreeBSD.git] / source / Plugins / Process / gdb-remote / GDBRemoteCommunicationServer.cpp
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 using namespace lldb_private::process_gdb_remote;
27
28 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(const char *comm_name,
29                                                            const char *listener_name) :
30     GDBRemoteCommunication (comm_name, listener_name),
31     m_exit_now (false)
32 {
33 }
34
35 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
36 {
37 }
38
39 void GDBRemoteCommunicationServer::RegisterPacketHandler(
40         StringExtractorGDBRemote::ServerPacketType packet_type,
41         PacketHandler handler)
42 {
43     m_packet_handlers[packet_type] = std::move(handler);
44 }
45
46 GDBRemoteCommunication::PacketResult
47 GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
48                                                         Error &error,
49                                                         bool &interrupt,
50                                                         bool &quit)
51 {
52     StringExtractorGDBRemote packet;
53
54     PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec, false);
55     if (packet_result == PacketResult::Success)
56     {
57         const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
58         switch (packet_type)
59         {
60         case StringExtractorGDBRemote::eServerPacketType_nack:
61         case StringExtractorGDBRemote::eServerPacketType_ack:
62             break;
63
64         case StringExtractorGDBRemote::eServerPacketType_invalid:
65             error.SetErrorString("invalid packet");
66             quit = true;
67             break;
68
69         case StringExtractorGDBRemote::eServerPacketType_unimplemented:
70             packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
71             break;
72
73         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());
77             else
78                 packet_result = handler_it->second (packet, error, interrupt, quit);
79             break;
80         }
81     }
82     else
83     {
84         if (!IsConnected())
85         {
86             error.SetErrorString("lost connection");
87             quit = true;
88         }
89         else
90         {
91             error.SetErrorString("timeout");
92         }
93     }
94
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;
100 }
101
102 GDBRemoteCommunication::PacketResult
103 GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
104 {
105     // TODO: Log the packet we aren't handling...
106     return SendPacketNoLock ("", 0);
107 }
108
109
110 GDBRemoteCommunication::PacketResult
111 GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
112 {
113     char packet[16];
114     int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
115     assert (packet_len < (int)sizeof(packet));
116     return SendPacketNoLock (packet, packet_len);
117 }
118
119 GDBRemoteCommunication::PacketResult
120 GDBRemoteCommunicationServer::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 }
127
128 GDBRemoteCommunication::PacketResult
129 GDBRemoteCommunicationServer::SendOKResponse ()
130 {
131     return SendPacketNoLock ("OK", 2);
132 }
133
134 bool
135 GDBRemoteCommunicationServer::HandshakeWithClient()
136 {
137     return GetAck() == PacketResult::Success;
138 }