blob: faee6776a839e0f82ab293934369f1a7119bf5dc [file] [log] [blame]
Greg Clayton61d043b2011-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
10
11#include "GDBRemoteCommunicationServer.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16#include "llvm/ADT/Triple.h"
17#include "lldb/Interpreter/Args.h"
18#include "lldb/Core/ConnectionFileDescriptor.h"
19#include "lldb/Core/Log.h"
20#include "lldb/Core/State.h"
21#include "lldb/Core/StreamString.h"
22#include "lldb/Host/Host.h"
23#include "lldb/Host/TimeValue.h"
24
25// Project includes
26#include "Utility/StringExtractorGDBRemote.h"
27#include "ProcessGDBRemote.h"
28#include "ProcessGDBRemoteLog.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33//----------------------------------------------------------------------
34// GDBRemoteCommunicationServer constructor
35//----------------------------------------------------------------------
36GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() :
37 GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"),
Greg Clayton58e26e02011-03-24 04:28:38 +000038 m_async_thread (LLDB_INVALID_HOST_THREAD)
Greg Clayton61d043b2011-03-22 04:00:09 +000039{
40}
41
42//----------------------------------------------------------------------
43// Destructor
44//----------------------------------------------------------------------
45GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
46{
47}
48
49
50//void *
51//GDBRemoteCommunicationServer::AsyncThread (void *arg)
52//{
53// GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
54//
55// LogSP log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
56// if (log)
57// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
58//
59// StringExtractorGDBRemote packet;
60//
61// while ()
62// {
63// if (packet.
64// }
65//
66// if (log)
67// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
68//
69// process->m_async_thread = LLDB_INVALID_HOST_THREAD;
70// return NULL;
71//}
72//
73bool
Greg Claytoncb8977d2011-03-23 00:09:55 +000074GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_ptr,
Greg Clayton58e26e02011-03-24 04:28:38 +000075 Error &error,
Greg Claytoncb8977d2011-03-23 00:09:55 +000076 bool &interrupt,
77 bool &quit)
Greg Clayton61d043b2011-03-22 04:00:09 +000078{
79 StringExtractorGDBRemote packet;
Greg Claytoncb8977d2011-03-23 00:09:55 +000080 if (WaitForPacketNoLock (packet, timeout_ptr))
Greg Clayton61d043b2011-03-22 04:00:09 +000081 {
82 const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
83 switch (packet_type)
84 {
85 case StringExtractorGDBRemote::eServerPacketType_nack:
86 case StringExtractorGDBRemote::eServerPacketType_ack:
87 break;
88
89 case StringExtractorGDBRemote::eServerPacketType_invalid:
Greg Clayton58e26e02011-03-24 04:28:38 +000090 error.SetErrorString("invalid packet");
Greg Claytoncb8977d2011-03-23 00:09:55 +000091 quit = true;
92 break;
93
94 case StringExtractorGDBRemote::eServerPacketType_interrupt:
Greg Clayton58e26e02011-03-24 04:28:38 +000095 error.SetErrorString("interrupt received");
Greg Claytoncb8977d2011-03-23 00:09:55 +000096 interrupt = true;
97 break;
98
Greg Clayton61d043b2011-03-22 04:00:09 +000099 case StringExtractorGDBRemote::eServerPacketType_unimplemented:
100 return SendUnimplementedResponse () > 0;
101
102 case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
103 return Handle_qHostInfo ();
Greg Clayton58e26e02011-03-24 04:28:38 +0000104
105 case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
106 return Handle_QStartNoAckMode ();
Greg Clayton61d043b2011-03-22 04:00:09 +0000107 }
108 return true;
109 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000110 else
111 {
112 if (!IsConnected())
113 error.SetErrorString("lost connection");
114 else
115 error.SetErrorString("timeout");
116 }
117
Greg Clayton61d043b2011-03-22 04:00:09 +0000118 return false;
119}
120
121size_t
122GDBRemoteCommunicationServer::SendUnimplementedResponse ()
123{
124 return SendPacket ("");
125}
126
Greg Clayton58e26e02011-03-24 04:28:38 +0000127size_t
128GDBRemoteCommunicationServer::SendOKResponse ()
129{
130 return SendPacket ("OK");
131}
132
133bool
134GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
135{
136 if (StartReadThread(error_ptr))
137 return GetAck();
138 return false;
139}
Greg Clayton61d043b2011-03-22 04:00:09 +0000140
141bool
142GDBRemoteCommunicationServer::Handle_qHostInfo ()
143{
144 StreamString response;
145
146 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
147
148 ArchSpec host_arch (Host::GetArchitecture ());
Greg Clayton61d043b2011-03-22 04:00:09 +0000149 const llvm::Triple &host_triple = host_arch.GetTriple();
Greg Clayton58e26e02011-03-24 04:28:38 +0000150 response.PutCString("triple:");
151 response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
152 response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
Greg Clayton61d043b2011-03-22 04:00:09 +0000153
Greg Clayton58e26e02011-03-24 04:28:38 +0000154 uint32_t cpu = host_arch.GetMachOCPUType();
155 uint32_t sub = host_arch.GetMachOCPUSubType();
156 if (cpu != LLDB_INVALID_CPUTYPE)
157 response.Printf ("cputype:%u;", cpu);
158 if (sub != LLDB_INVALID_CPUTYPE)
159 response.Printf ("cpusubtype:%u;", sub);
160
Greg Clayton61d043b2011-03-22 04:00:09 +0000161 switch (lldb::endian::InlHostByteOrder())
162 {
163 case eByteOrderBig: response.PutCString ("endian:big;"); break;
164 case eByteOrderLittle: response.PutCString ("endian:little;"); break;
165 case eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
166 default: response.PutCString ("endian:unknown;"); break;
167 }
168
Greg Clayton58e26e02011-03-24 04:28:38 +0000169 uint32_t major = UINT32_MAX;
170 uint32_t minor = UINT32_MAX;
171 uint32_t update = UINT32_MAX;
172 if (Host::GetOSVersion (major, minor, update))
173 {
174 if (major != UINT32_MAX)
175 {
176 response.Printf("os_version:%u", major);
177 if (minor != UINT32_MAX)
178 {
179 response.Printf(".%u", minor);
180 if (update != UINT32_MAX)
181 response.Printf(".%u", update);
182 }
183 response.PutChar(';');
184 }
185 }
186
187 std::string s;
188 if (Host::GetOSBuildString (s))
189 {
190 response.PutCString ("os_build:");
191 response.PutCStringAsRawHex8(s.c_str());
192 response.PutChar(';');
193 }
194 if (Host::GetOSKernelDescription (s))
195 {
196 response.PutCString ("os_kernel:");
197 response.PutCStringAsRawHex8(s.c_str());
198 response.PutChar(';');
199 }
200 if (Host::GetHostname (s))
201 {
202 response.PutCString ("hostname:");
203 response.PutCStringAsRawHex8(s.c_str());
204 response.PutChar(';');
205 }
206
Greg Clayton61d043b2011-03-22 04:00:09 +0000207 return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0;
208}
Greg Clayton58e26e02011-03-24 04:28:38 +0000209
210
211bool
212GDBRemoteCommunicationServer::Handle_QStartNoAckMode ()
213{
214 SendOKResponse ();
215 m_send_acks = false;
216 return true;
217}