blob: 21f9eda2b8741fd651913bff060793cf845be3b0 [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
12#include "GDBRemoteCommunicationServer.h"
Daniel Maleae0f8f572013-08-26 23:57:52 +000013#include "lldb/Core/StreamGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000014
15// C Includes
16// C++ Includes
17// Other libraries and framework includes
18#include "llvm/ADT/Triple.h"
19#include "lldb/Interpreter/Args.h"
20#include "lldb/Core/ConnectionFileDescriptor.h"
21#include "lldb/Core/Log.h"
22#include "lldb/Core/State.h"
23#include "lldb/Core/StreamString.h"
Enrico Granataf2bbf712011-07-15 02:26:42 +000024#include "lldb/Host/Endian.h"
Daniel Maleae0f8f572013-08-26 23:57:52 +000025#include "lldb/Host/File.h"
Greg Clayton576d8832011-03-22 04:00:09 +000026#include "lldb/Host/Host.h"
27#include "lldb/Host/TimeValue.h"
Todd Fialab8b49ec2014-01-28 00:34:23 +000028#include "lldb/Target/Platform.h"
Greg Clayton8b82f082011-04-12 05:54:46 +000029#include "lldb/Target/Process.h"
Greg Clayton576d8832011-03-22 04:00:09 +000030
31// Project includes
32#include "Utility/StringExtractorGDBRemote.h"
33#include "ProcessGDBRemote.h"
34#include "ProcessGDBRemoteLog.h"
35
36using namespace lldb;
37using namespace lldb_private;
38
39//----------------------------------------------------------------------
40// GDBRemoteCommunicationServer constructor
41//----------------------------------------------------------------------
Greg Clayton8b82f082011-04-12 05:54:46 +000042GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) :
43 GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform),
Todd Fialab8b49ec2014-01-28 00:34:23 +000044 m_platform_sp (Platform::GetDefaultPlatform ()),
Greg Clayton8b82f082011-04-12 05:54:46 +000045 m_async_thread (LLDB_INVALID_HOST_THREAD),
46 m_process_launch_info (),
47 m_process_launch_error (),
Daniel Maleae0f8f572013-08-26 23:57:52 +000048 m_spawned_pids (),
49 m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
Greg Clayton8b82f082011-04-12 05:54:46 +000050 m_proc_infos (),
51 m_proc_infos_index (0),
Greg Clayton2b98c562013-11-22 18:53:12 +000052 m_port_map (),
53 m_port_offset(0)
Greg Clayton576d8832011-03-22 04:00:09 +000054{
55}
56
Todd Fialab8b49ec2014-01-28 00:34:23 +000057GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform,
58 const lldb::PlatformSP& platform_sp) :
59 GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform),
60 m_platform_sp (platform_sp),
61 m_async_thread (LLDB_INVALID_HOST_THREAD),
62 m_process_launch_info (),
63 m_process_launch_error (),
64 m_spawned_pids (),
65 m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
66 m_proc_infos (),
67 m_proc_infos_index (0),
68 m_port_map (),
69 m_port_offset(0)
70{
71 assert(platform_sp);
72}
73
Greg Clayton576d8832011-03-22 04:00:09 +000074//----------------------------------------------------------------------
75// Destructor
76//----------------------------------------------------------------------
77GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
78{
79}
80
81
82//void *
83//GDBRemoteCommunicationServer::AsyncThread (void *arg)
84//{
85// GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
86//
Greg Clayton5160ce52013-03-27 23:08:40 +000087// Log *log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton576d8832011-03-22 04:00:09 +000088// if (log)
89// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
90//
91// StringExtractorGDBRemote packet;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +000092//
Greg Clayton576d8832011-03-22 04:00:09 +000093// while ()
94// {
95// if (packet.
96// }
97//
98// if (log)
99// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
100//
101// process->m_async_thread = LLDB_INVALID_HOST_THREAD;
102// return NULL;
103//}
104//
105bool
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000106GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
Greg Clayton1cb64962011-03-24 04:28:38 +0000107 Error &error,
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000108 bool &interrupt,
Greg Claytond314e812011-03-23 00:09:55 +0000109 bool &quit)
Greg Clayton576d8832011-03-22 04:00:09 +0000110{
111 StringExtractorGDBRemote packet;
Greg Clayton3dedae12013-12-06 21:45:27 +0000112 PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
113 if (packet_result == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000114 {
115 const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
116 switch (packet_type)
117 {
Greg Clayton3dedae12013-12-06 21:45:27 +0000118 case StringExtractorGDBRemote::eServerPacketType_nack:
119 case StringExtractorGDBRemote::eServerPacketType_ack:
120 break;
Greg Clayton576d8832011-03-22 04:00:09 +0000121
Greg Clayton3dedae12013-12-06 21:45:27 +0000122 case StringExtractorGDBRemote::eServerPacketType_invalid:
123 error.SetErrorString("invalid packet");
124 quit = true;
125 break;
Greg Claytond314e812011-03-23 00:09:55 +0000126
Greg Clayton3dedae12013-12-06 21:45:27 +0000127 case StringExtractorGDBRemote::eServerPacketType_interrupt:
128 error.SetErrorString("interrupt received");
129 interrupt = true;
130 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000131
Greg Clayton3dedae12013-12-06 21:45:27 +0000132 default:
133 case StringExtractorGDBRemote::eServerPacketType_unimplemented:
134 packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
135 break;
Greg Clayton576d8832011-03-22 04:00:09 +0000136
Greg Clayton3dedae12013-12-06 21:45:27 +0000137 case StringExtractorGDBRemote::eServerPacketType_A:
138 packet_result = Handle_A (packet);
139 break;
Greg Clayton32e0a752011-03-30 18:16:51 +0000140
Greg Clayton3dedae12013-12-06 21:45:27 +0000141 case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
142 packet_result = Handle_qfProcessInfo (packet);
143 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000144
Greg Clayton3dedae12013-12-06 21:45:27 +0000145 case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
146 packet_result = Handle_qsProcessInfo (packet);
147 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000148
Greg Clayton3dedae12013-12-06 21:45:27 +0000149 case StringExtractorGDBRemote::eServerPacketType_qC:
150 packet_result = Handle_qC (packet);
151 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000152
Greg Clayton3dedae12013-12-06 21:45:27 +0000153 case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
154 packet_result = Handle_qHostInfo (packet);
155 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000156
Greg Clayton3dedae12013-12-06 21:45:27 +0000157 case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer:
158 packet_result = Handle_qLaunchGDBServer (packet);
159 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000160
Greg Clayton3dedae12013-12-06 21:45:27 +0000161 case StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess:
162 packet_result = Handle_qKillSpawnedProcess (packet);
163 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000164
Todd Fiala403edc52014-01-23 22:05:44 +0000165 case StringExtractorGDBRemote::eServerPacketType_k:
166 packet_result = Handle_k (packet);
167 break;
168
Greg Clayton3dedae12013-12-06 21:45:27 +0000169 case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess:
170 packet_result = Handle_qLaunchSuccess (packet);
171 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000172
Greg Clayton3dedae12013-12-06 21:45:27 +0000173 case StringExtractorGDBRemote::eServerPacketType_qGroupName:
174 packet_result = Handle_qGroupName (packet);
175 break;
Greg Clayton32e0a752011-03-30 18:16:51 +0000176
Greg Clayton3dedae12013-12-06 21:45:27 +0000177 case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
178 packet_result = Handle_qProcessInfoPID (packet);
179 break;
Greg Clayton32e0a752011-03-30 18:16:51 +0000180
Greg Clayton3dedae12013-12-06 21:45:27 +0000181 case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
182 packet_result = Handle_qSpeedTest (packet);
183 break;
Greg Clayton32e0a752011-03-30 18:16:51 +0000184
Greg Clayton3dedae12013-12-06 21:45:27 +0000185 case StringExtractorGDBRemote::eServerPacketType_qUserName:
186 packet_result = Handle_qUserName (packet);
187 break;
Greg Clayton32e0a752011-03-30 18:16:51 +0000188
Greg Clayton3dedae12013-12-06 21:45:27 +0000189 case StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir:
190 packet_result = Handle_qGetWorkingDir(packet);
191 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000192
Greg Clayton3dedae12013-12-06 21:45:27 +0000193 case StringExtractorGDBRemote::eServerPacketType_QEnvironment:
194 packet_result = Handle_QEnvironment (packet);
195 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000196
Greg Clayton3dedae12013-12-06 21:45:27 +0000197 case StringExtractorGDBRemote::eServerPacketType_QLaunchArch:
198 packet_result = Handle_QLaunchArch (packet);
199 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000200
Greg Clayton3dedae12013-12-06 21:45:27 +0000201 case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR:
202 packet_result = Handle_QSetDisableASLR (packet);
203 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000204
Jim Ingham106d0282014-06-25 02:32:56 +0000205 case StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError:
206 packet_result = Handle_QSetDetachOnError (packet);
207 break;
208
Greg Clayton3dedae12013-12-06 21:45:27 +0000209 case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN:
210 packet_result = Handle_QSetSTDIN (packet);
211 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000212
Greg Clayton3dedae12013-12-06 21:45:27 +0000213 case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT:
214 packet_result = Handle_QSetSTDOUT (packet);
215 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000216
Greg Clayton3dedae12013-12-06 21:45:27 +0000217 case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR:
218 packet_result = Handle_QSetSTDERR (packet);
219 break;
Greg Clayton8b82f082011-04-12 05:54:46 +0000220
Greg Clayton3dedae12013-12-06 21:45:27 +0000221 case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir:
222 packet_result = Handle_QSetWorkingDir (packet);
223 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000224
Greg Clayton3dedae12013-12-06 21:45:27 +0000225 case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
226 packet_result = Handle_QStartNoAckMode (packet);
227 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000228
Greg Clayton3dedae12013-12-06 21:45:27 +0000229 case StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir:
230 packet_result = Handle_qPlatform_mkdir (packet);
231 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000232
Greg Clayton3dedae12013-12-06 21:45:27 +0000233 case StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod:
234 packet_result = Handle_qPlatform_chmod (packet);
235 break;
Greg Claytonfbb76342013-11-20 21:07:01 +0000236
Greg Clayton3dedae12013-12-06 21:45:27 +0000237 case StringExtractorGDBRemote::eServerPacketType_qPlatform_shell:
238 packet_result = Handle_qPlatform_shell (packet);
239 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000240
Greg Clayton3dedae12013-12-06 21:45:27 +0000241 case StringExtractorGDBRemote::eServerPacketType_vFile_open:
242 packet_result = Handle_vFile_Open (packet);
243 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000244
Greg Clayton3dedae12013-12-06 21:45:27 +0000245 case StringExtractorGDBRemote::eServerPacketType_vFile_close:
246 packet_result = Handle_vFile_Close (packet);
247 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000248
Greg Clayton3dedae12013-12-06 21:45:27 +0000249 case StringExtractorGDBRemote::eServerPacketType_vFile_pread:
250 packet_result = Handle_vFile_pRead (packet);
251 break;
Daniel Maleae0f8f572013-08-26 23:57:52 +0000252
Greg Clayton3dedae12013-12-06 21:45:27 +0000253 case StringExtractorGDBRemote::eServerPacketType_vFile_pwrite:
254 packet_result = Handle_vFile_pWrite (packet);
255 break;
Daniel Maleae0f8f572013-08-26 23:57:52 +0000256
Greg Clayton3dedae12013-12-06 21:45:27 +0000257 case StringExtractorGDBRemote::eServerPacketType_vFile_size:
258 packet_result = Handle_vFile_Size (packet);
259 break;
Daniel Maleae0f8f572013-08-26 23:57:52 +0000260
Greg Clayton3dedae12013-12-06 21:45:27 +0000261 case StringExtractorGDBRemote::eServerPacketType_vFile_mode:
262 packet_result = Handle_vFile_Mode (packet);
263 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000264
Greg Clayton3dedae12013-12-06 21:45:27 +0000265 case StringExtractorGDBRemote::eServerPacketType_vFile_exists:
266 packet_result = Handle_vFile_Exists (packet);
267 break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000268
Greg Clayton3dedae12013-12-06 21:45:27 +0000269 case StringExtractorGDBRemote::eServerPacketType_vFile_stat:
270 packet_result = Handle_vFile_Stat (packet);
271 break;
Greg Claytonfbb76342013-11-20 21:07:01 +0000272
Greg Clayton3dedae12013-12-06 21:45:27 +0000273 case StringExtractorGDBRemote::eServerPacketType_vFile_md5:
274 packet_result = Handle_vFile_MD5 (packet);
275 break;
276
277 case StringExtractorGDBRemote::eServerPacketType_vFile_symlink:
278 packet_result = Handle_vFile_symlink (packet);
279 break;
280
281 case StringExtractorGDBRemote::eServerPacketType_vFile_unlink:
282 packet_result = Handle_vFile_unlink (packet);
283 break;
Greg Clayton576d8832011-03-22 04:00:09 +0000284 }
Greg Clayton576d8832011-03-22 04:00:09 +0000285 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000286 else
287 {
288 if (!IsConnected())
Greg Clayton3dedae12013-12-06 21:45:27 +0000289 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000290 error.SetErrorString("lost connection");
Greg Clayton3dedae12013-12-06 21:45:27 +0000291 quit = true;
292 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000293 else
Greg Clayton3dedae12013-12-06 21:45:27 +0000294 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000295 error.SetErrorString("timeout");
Greg Clayton3dedae12013-12-06 21:45:27 +0000296 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000297 }
Greg Clayton3dedae12013-12-06 21:45:27 +0000298 return packet_result == PacketResult::Success;
Greg Clayton576d8832011-03-22 04:00:09 +0000299}
300
Todd Fiala403edc52014-01-23 22:05:44 +0000301lldb_private::Error
Todd Fiala3e92a2b2014-01-24 00:52:53 +0000302GDBRemoteCommunicationServer::SetLaunchArguments (const char *const args[], int argc)
Todd Fiala403edc52014-01-23 22:05:44 +0000303{
304 if ((argc < 1) || !args || !args[0] || !args[0][0])
Todd Fiala3e92a2b2014-01-24 00:52:53 +0000305 return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
Todd Fiala403edc52014-01-23 22:05:44 +0000306
Todd Fiala403edc52014-01-23 22:05:44 +0000307 m_process_launch_info.SetArguments (const_cast<const char**> (args), true);
Todd Fiala3e92a2b2014-01-24 00:52:53 +0000308 return lldb_private::Error ();
309}
310
311lldb_private::Error
312GDBRemoteCommunicationServer::SetLaunchFlags (unsigned int launch_flags)
313{
Todd Fiala403edc52014-01-23 22:05:44 +0000314 m_process_launch_info.GetFlags ().Set (launch_flags);
Todd Fiala3e92a2b2014-01-24 00:52:53 +0000315 return lldb_private::Error ();
316}
317
318lldb_private::Error
319GDBRemoteCommunicationServer::LaunchProcess ()
320{
321 if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
322 return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
323
324 // specify the process monitor if not already set. This should
325 // generally be what happens since we need to reap started
326 // processes.
327 if (!m_process_launch_info.GetMonitorProcessCallback ())
328 m_process_launch_info.SetMonitorProcessCallback(ReapDebuggedProcess, this, false);
Todd Fiala403edc52014-01-23 22:05:44 +0000329
Todd Fialab8b49ec2014-01-28 00:34:23 +0000330 lldb_private::Error error = m_platform_sp->LaunchProcess (m_process_launch_info);
Todd Fiala403edc52014-01-23 22:05:44 +0000331 if (!error.Success ())
332 {
Todd Fiala3e92a2b2014-01-24 00:52:53 +0000333 fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
Todd Fiala403edc52014-01-23 22:05:44 +0000334 return error;
335 }
336
Todd Fiala3e92a2b2014-01-24 00:52:53 +0000337 printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
Todd Fiala403edc52014-01-23 22:05:44 +0000338
339 // add to list of spawned processes. On an lldb-gdbserver, we
340 // would expect there to be only one.
341 lldb::pid_t pid;
342 if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID )
343 {
344 Mutex::Locker locker (m_spawned_pids_mutex);
345 m_spawned_pids.insert(pid);
346 }
347
348 return error;
349}
350
Greg Clayton3dedae12013-12-06 21:45:27 +0000351GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000352GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
Greg Clayton576d8832011-03-22 04:00:09 +0000353{
Greg Clayton32e0a752011-03-30 18:16:51 +0000354 // TODO: Log the packet we aren't handling...
Greg Clayton37a0a242012-04-11 00:24:49 +0000355 return SendPacketNoLock ("", 0);
Greg Clayton576d8832011-03-22 04:00:09 +0000356}
357
Greg Clayton3dedae12013-12-06 21:45:27 +0000358GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000359GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
360{
361 char packet[16];
362 int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
Andy Gibbsa297a972013-06-19 19:04:53 +0000363 assert (packet_len < (int)sizeof(packet));
Greg Clayton37a0a242012-04-11 00:24:49 +0000364 return SendPacketNoLock (packet, packet_len);
Greg Clayton32e0a752011-03-30 18:16:51 +0000365}
366
367
Greg Clayton3dedae12013-12-06 21:45:27 +0000368GDBRemoteCommunication::PacketResult
Greg Clayton1cb64962011-03-24 04:28:38 +0000369GDBRemoteCommunicationServer::SendOKResponse ()
370{
Greg Clayton37a0a242012-04-11 00:24:49 +0000371 return SendPacketNoLock ("OK", 2);
Greg Clayton1cb64962011-03-24 04:28:38 +0000372}
373
374bool
375GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
376{
Greg Clayton3dedae12013-12-06 21:45:27 +0000377 return GetAck() == PacketResult::Success;
Greg Clayton1cb64962011-03-24 04:28:38 +0000378}
Greg Clayton576d8832011-03-22 04:00:09 +0000379
Greg Clayton3dedae12013-12-06 21:45:27 +0000380GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000381GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet)
Greg Clayton576d8832011-03-22 04:00:09 +0000382{
383 StreamString response;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000384
Greg Clayton576d8832011-03-22 04:00:09 +0000385 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
386
387 ArchSpec host_arch (Host::GetArchitecture ());
Greg Clayton576d8832011-03-22 04:00:09 +0000388 const llvm::Triple &host_triple = host_arch.GetTriple();
Greg Clayton1cb64962011-03-24 04:28:38 +0000389 response.PutCString("triple:");
390 response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
391 response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
Greg Clayton576d8832011-03-22 04:00:09 +0000392
Todd Fialaa9ddb0e2014-01-18 03:02:39 +0000393 const char* distribution_id = host_arch.GetDistributionId ().AsCString ();
394 if (distribution_id)
395 {
396 response.PutCString("distribution_id:");
397 response.PutCStringAsRawHex8(distribution_id);
398 response.PutCString(";");
399 }
400
Greg Clayton1cb64962011-03-24 04:28:38 +0000401 uint32_t cpu = host_arch.GetMachOCPUType();
402 uint32_t sub = host_arch.GetMachOCPUSubType();
403 if (cpu != LLDB_INVALID_CPUTYPE)
404 response.Printf ("cputype:%u;", cpu);
405 if (sub != LLDB_INVALID_CPUTYPE)
406 response.Printf ("cpusubtype:%u;", sub);
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000407
Enrico Granata1c5431a2012-07-13 23:55:22 +0000408 if (cpu == ArchSpec::kCore_arm_any)
Enrico Granataf04a2192012-07-13 23:18:48 +0000409 response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
410 else
411 response.Printf("watchpoint_exceptions_received:after;");
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000412
Greg Clayton576d8832011-03-22 04:00:09 +0000413 switch (lldb::endian::InlHostByteOrder())
414 {
415 case eByteOrderBig: response.PutCString ("endian:big;"); break;
416 case eByteOrderLittle: response.PutCString ("endian:little;"); break;
417 case eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
418 default: response.PutCString ("endian:unknown;"); break;
419 }
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000420
Greg Clayton1cb64962011-03-24 04:28:38 +0000421 uint32_t major = UINT32_MAX;
422 uint32_t minor = UINT32_MAX;
423 uint32_t update = UINT32_MAX;
424 if (Host::GetOSVersion (major, minor, update))
425 {
426 if (major != UINT32_MAX)
427 {
428 response.Printf("os_version:%u", major);
429 if (minor != UINT32_MAX)
430 {
431 response.Printf(".%u", minor);
432 if (update != UINT32_MAX)
433 response.Printf(".%u", update);
434 }
435 response.PutChar(';');
436 }
437 }
438
439 std::string s;
440 if (Host::GetOSBuildString (s))
441 {
442 response.PutCString ("os_build:");
443 response.PutCStringAsRawHex8(s.c_str());
444 response.PutChar(';');
445 }
446 if (Host::GetOSKernelDescription (s))
447 {
448 response.PutCString ("os_kernel:");
449 response.PutCStringAsRawHex8(s.c_str());
450 response.PutChar(';');
451 }
Greg Clayton2b98c562013-11-22 18:53:12 +0000452#if defined(__APPLE__)
453
Jason Molendaa3329782014-03-29 18:54:20 +0000454#if defined(__arm__) || defined(__arm64__)
Greg Clayton2b98c562013-11-22 18:53:12 +0000455 // For iOS devices, we are connected through a USB Mux so we never pretend
456 // to actually have a hostname as far as the remote lldb that is connecting
457 // to this lldb-platform is concerned
458 response.PutCString ("hostname:");
Greg Clayton16810922014-02-27 19:38:18 +0000459 response.PutCStringAsRawHex8("127.0.0.1");
Greg Clayton2b98c562013-11-22 18:53:12 +0000460 response.PutChar(';');
Jason Molendaa3329782014-03-29 18:54:20 +0000461#else // #if defined(__arm__) || defined(__arm64__)
Greg Clayton1cb64962011-03-24 04:28:38 +0000462 if (Host::GetHostname (s))
463 {
464 response.PutCString ("hostname:");
465 response.PutCStringAsRawHex8(s.c_str());
466 response.PutChar(';');
467 }
Jason Molendaa3329782014-03-29 18:54:20 +0000468#endif // #if defined(__arm__) || defined(__arm64__)
Greg Clayton2b98c562013-11-22 18:53:12 +0000469
470#else // #if defined(__APPLE__)
471 if (Host::GetHostname (s))
472 {
473 response.PutCString ("hostname:");
474 response.PutCStringAsRawHex8(s.c_str());
475 response.PutChar(';');
476 }
477#endif // #if defined(__APPLE__)
478
Greg Clayton3dedae12013-12-06 21:45:27 +0000479 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton576d8832011-03-22 04:00:09 +0000480}
Greg Clayton1cb64962011-03-24 04:28:38 +0000481
Greg Clayton32e0a752011-03-30 18:16:51 +0000482static void
Greg Clayton8b82f082011-04-12 05:54:46 +0000483CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response)
Greg Clayton32e0a752011-03-30 18:16:51 +0000484{
Daniel Malead01b2952012-11-29 21:49:15 +0000485 response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
Greg Clayton32e0a752011-03-30 18:16:51 +0000486 proc_info.GetProcessID(),
487 proc_info.GetParentProcessID(),
Greg Clayton8b82f082011-04-12 05:54:46 +0000488 proc_info.GetUserID(),
489 proc_info.GetGroupID(),
Greg Clayton32e0a752011-03-30 18:16:51 +0000490 proc_info.GetEffectiveUserID(),
491 proc_info.GetEffectiveGroupID());
492 response.PutCString ("name:");
493 response.PutCStringAsRawHex8(proc_info.GetName());
494 response.PutChar(';');
495 const ArchSpec &proc_arch = proc_info.GetArchitecture();
496 if (proc_arch.IsValid())
497 {
498 const llvm::Triple &proc_triple = proc_arch.GetTriple();
499 response.PutCString("triple:");
500 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
501 response.PutChar(';');
502 }
503}
Greg Clayton1cb64962011-03-24 04:28:38 +0000504
Greg Clayton3dedae12013-12-06 21:45:27 +0000505GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000506GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
Greg Clayton1cb64962011-03-24 04:28:38 +0000507{
Greg Clayton32e0a752011-03-30 18:16:51 +0000508 // Packet format: "qProcessInfoPID:%i" where %i is the pid
Greg Clayton8b82f082011-04-12 05:54:46 +0000509 packet.SetFilePos(::strlen ("qProcessInfoPID:"));
Greg Clayton32e0a752011-03-30 18:16:51 +0000510 lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
511 if (pid != LLDB_INVALID_PROCESS_ID)
512 {
Greg Clayton8b82f082011-04-12 05:54:46 +0000513 ProcessInstanceInfo proc_info;
Greg Clayton32e0a752011-03-30 18:16:51 +0000514 if (Host::GetProcessInfo(pid, proc_info))
515 {
516 StreamString response;
517 CreateProcessInfoResponse (proc_info, response);
Greg Clayton37a0a242012-04-11 00:24:49 +0000518 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton32e0a752011-03-30 18:16:51 +0000519 }
520 }
521 return SendErrorResponse (1);
522}
523
Greg Clayton3dedae12013-12-06 21:45:27 +0000524GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000525GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
526{
527 m_proc_infos_index = 0;
528 m_proc_infos.Clear();
529
Greg Clayton8b82f082011-04-12 05:54:46 +0000530 ProcessInstanceInfoMatch match_info;
531 packet.SetFilePos(::strlen ("qfProcessInfo"));
Greg Clayton32e0a752011-03-30 18:16:51 +0000532 if (packet.GetChar() == ':')
533 {
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000534
Greg Clayton32e0a752011-03-30 18:16:51 +0000535 std::string key;
536 std::string value;
537 while (packet.GetNameColonValue(key, value))
538 {
539 bool success = true;
540 if (key.compare("name") == 0)
541 {
542 StringExtractor extractor;
543 extractor.GetStringRef().swap(value);
544 extractor.GetHexByteString (value);
Greg Clayton144f3a92011-11-15 03:53:30 +0000545 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000546 }
547 else if (key.compare("name_match") == 0)
548 {
549 if (value.compare("equals") == 0)
550 {
551 match_info.SetNameMatchType (eNameMatchEquals);
552 }
553 else if (value.compare("starts_with") == 0)
554 {
555 match_info.SetNameMatchType (eNameMatchStartsWith);
556 }
557 else if (value.compare("ends_with") == 0)
558 {
559 match_info.SetNameMatchType (eNameMatchEndsWith);
560 }
561 else if (value.compare("contains") == 0)
562 {
563 match_info.SetNameMatchType (eNameMatchContains);
564 }
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000565 else if (value.compare("regex") == 0)
Greg Clayton32e0a752011-03-30 18:16:51 +0000566 {
567 match_info.SetNameMatchType (eNameMatchRegularExpression);
568 }
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000569 else
Greg Clayton32e0a752011-03-30 18:16:51 +0000570 {
571 success = false;
572 }
573 }
574 else if (key.compare("pid") == 0)
575 {
576 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
577 }
578 else if (key.compare("parent_pid") == 0)
579 {
580 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
581 }
582 else if (key.compare("uid") == 0)
583 {
Greg Clayton8b82f082011-04-12 05:54:46 +0000584 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
Greg Clayton32e0a752011-03-30 18:16:51 +0000585 }
586 else if (key.compare("gid") == 0)
587 {
Greg Clayton8b82f082011-04-12 05:54:46 +0000588 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
Greg Clayton32e0a752011-03-30 18:16:51 +0000589 }
590 else if (key.compare("euid") == 0)
591 {
592 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
593 }
594 else if (key.compare("egid") == 0)
595 {
596 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
597 }
598 else if (key.compare("all_users") == 0)
599 {
600 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
601 }
602 else if (key.compare("triple") == 0)
603 {
Greg Claytoneb0103f2011-04-07 22:46:35 +0000604 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL);
Greg Clayton32e0a752011-03-30 18:16:51 +0000605 }
606 else
607 {
608 success = false;
609 }
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000610
Greg Clayton32e0a752011-03-30 18:16:51 +0000611 if (!success)
612 return SendErrorResponse (2);
613 }
614 }
615
616 if (Host::FindProcesses (match_info, m_proc_infos))
617 {
618 // We found something, return the first item by calling the get
619 // subsequent process info packet handler...
620 return Handle_qsProcessInfo (packet);
621 }
622 return SendErrorResponse (3);
623}
624
Greg Clayton3dedae12013-12-06 21:45:27 +0000625GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000626GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
627{
628 if (m_proc_infos_index < m_proc_infos.GetSize())
629 {
630 StreamString response;
631 CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
632 ++m_proc_infos_index;
Greg Clayton37a0a242012-04-11 00:24:49 +0000633 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton32e0a752011-03-30 18:16:51 +0000634 }
635 return SendErrorResponse (4);
636}
637
Greg Clayton3dedae12013-12-06 21:45:27 +0000638GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000639GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet)
640{
641 // Packet format: "qUserName:%i" where %i is the uid
Greg Clayton8b82f082011-04-12 05:54:46 +0000642 packet.SetFilePos(::strlen ("qUserName:"));
Greg Clayton32e0a752011-03-30 18:16:51 +0000643 uint32_t uid = packet.GetU32 (UINT32_MAX);
644 if (uid != UINT32_MAX)
645 {
646 std::string name;
647 if (Host::GetUserName (uid, name))
648 {
649 StreamString response;
650 response.PutCStringAsRawHex8 (name.c_str());
Greg Clayton37a0a242012-04-11 00:24:49 +0000651 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton32e0a752011-03-30 18:16:51 +0000652 }
653 }
654 return SendErrorResponse (5);
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000655
Greg Clayton32e0a752011-03-30 18:16:51 +0000656}
657
Greg Clayton3dedae12013-12-06 21:45:27 +0000658GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +0000659GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet)
660{
661 // Packet format: "qGroupName:%i" where %i is the gid
Greg Clayton8b82f082011-04-12 05:54:46 +0000662 packet.SetFilePos(::strlen ("qGroupName:"));
Greg Clayton32e0a752011-03-30 18:16:51 +0000663 uint32_t gid = packet.GetU32 (UINT32_MAX);
664 if (gid != UINT32_MAX)
665 {
666 std::string name;
667 if (Host::GetGroupName (gid, name))
668 {
669 StreamString response;
670 response.PutCStringAsRawHex8 (name.c_str());
Greg Clayton37a0a242012-04-11 00:24:49 +0000671 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton32e0a752011-03-30 18:16:51 +0000672 }
673 }
674 return SendErrorResponse (6);
675}
676
Greg Clayton3dedae12013-12-06 21:45:27 +0000677GDBRemoteCommunication::PacketResult
Greg Clayton9b1e1cd2011-04-04 18:18:57 +0000678GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
679{
Greg Clayton8b82f082011-04-12 05:54:46 +0000680 packet.SetFilePos(::strlen ("qSpeedTest:"));
Greg Clayton9b1e1cd2011-04-04 18:18:57 +0000681
682 std::string key;
683 std::string value;
684 bool success = packet.GetNameColonValue(key, value);
685 if (success && key.compare("response_size") == 0)
686 {
687 uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success);
688 if (success)
689 {
690 if (response_size == 0)
691 return SendOKResponse();
692 StreamString response;
693 uint32_t bytes_left = response_size;
694 response.PutCString("data:");
695 while (bytes_left > 0)
696 {
697 if (bytes_left >= 26)
698 {
699 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
700 bytes_left -= 26;
701 }
702 else
703 {
704 response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
705 bytes_left = 0;
706 }
707 }
Greg Clayton37a0a242012-04-11 00:24:49 +0000708 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton9b1e1cd2011-04-04 18:18:57 +0000709 }
710 }
711 return SendErrorResponse (7);
712}
Greg Clayton8b82f082011-04-12 05:54:46 +0000713
Greg Clayton8b82f082011-04-12 05:54:46 +0000714//
715//static bool
716//WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
717//{
718// const int time_delta_usecs = 100000;
719// const int num_retries = timeout_in_seconds/time_delta_usecs;
720// for (int i=0; i<num_retries; i++)
721// {
722// struct proc_bsdinfo bsd_info;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000723// int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO,
724// (uint64_t) 0,
725// &bsd_info,
Greg Clayton8b82f082011-04-12 05:54:46 +0000726// PROC_PIDTBSDINFO_SIZE);
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000727//
Greg Clayton8b82f082011-04-12 05:54:46 +0000728// switch (error)
729// {
730// case EINVAL:
731// case ENOTSUP:
732// case ESRCH:
733// case EPERM:
734// return false;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000735//
Greg Clayton8b82f082011-04-12 05:54:46 +0000736// default:
737// break;
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000738//
Greg Clayton8b82f082011-04-12 05:54:46 +0000739// case 0:
740// if (bsd_info.pbi_status == SSTOP)
741// return true;
742// }
743// ::usleep (time_delta_usecs);
744// }
745// return false;
746//}
747
Greg Clayton3dedae12013-12-06 21:45:27 +0000748GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +0000749GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet)
750{
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000751 // The 'A' packet is the most over designed packet ever here with
752 // redundant argument indexes, redundant argument lengths and needed hex
753 // encoded argument string values. Really all that is needed is a comma
Greg Clayton8b82f082011-04-12 05:54:46 +0000754 // separated hex encoded argument value list, but we will stay true to the
755 // documented version of the 'A' packet here...
756
757 packet.SetFilePos(1); // Skip the 'A'
758 bool success = true;
759 while (success && packet.GetBytesLeft() > 0)
760 {
761 // Decode the decimal argument string length. This length is the
762 // number of hex nibbles in the argument string value.
763 const uint32_t arg_len = packet.GetU32(UINT32_MAX);
764 if (arg_len == UINT32_MAX)
765 success = false;
766 else
767 {
768 // Make sure the argument hex string length is followed by a comma
769 if (packet.GetChar() != ',')
770 success = false;
771 else
772 {
773 // Decode the argument index. We ignore this really becuase
774 // who would really send down the arguments in a random order???
775 const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
776 if (arg_idx == UINT32_MAX)
777 success = false;
778 else
779 {
780 // Make sure the argument index is followed by a comma
781 if (packet.GetChar() != ',')
782 success = false;
783 else
784 {
785 // Decode the argument string value from hex bytes
786 // back into a UTF8 string and make sure the length
787 // matches the one supplied in the packet
788 std::string arg;
789 if (packet.GetHexByteString(arg) != (arg_len / 2))
790 success = false;
791 else
792 {
793 // If there are any bytes lft
794 if (packet.GetBytesLeft())
795 {
796 if (packet.GetChar() != ',')
797 success = false;
798 }
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000799
Greg Clayton8b82f082011-04-12 05:54:46 +0000800 if (success)
801 {
802 if (arg_idx == 0)
803 m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
804 m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
805 }
806 }
807 }
808 }
809 }
810 }
811 }
812
813 if (success)
814 {
Todd Fiala9f377372014-01-27 20:44:50 +0000815 // FIXME: remove linux restriction once eLaunchFlagDebug is supported
816#if !defined (__linux__)
Greg Clayton8b82f082011-04-12 05:54:46 +0000817 m_process_launch_info.GetFlags().Set (eLaunchFlagDebug);
Todd Fiala9f377372014-01-27 20:44:50 +0000818#endif
819 m_process_launch_error = LaunchProcess ();
Greg Clayton8b82f082011-04-12 05:54:46 +0000820 if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
821 {
822 return SendOKResponse ();
823 }
824 }
825 return SendErrorResponse (8);
826}
827
Greg Clayton3dedae12013-12-06 21:45:27 +0000828GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +0000829GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet)
830{
831 lldb::pid_t pid = m_process_launch_info.GetProcessID();
832 StreamString response;
Daniel Malead01b2952012-11-29 21:49:15 +0000833 response.Printf("QC%" PRIx64, pid);
Greg Clayton8b82f082011-04-12 05:54:46 +0000834 if (m_is_platform)
835 {
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000836 // If we launch a process and this GDB server is acting as a platform,
837 // then we need to clear the process launch state so we can start
Greg Clayton8b82f082011-04-12 05:54:46 +0000838 // launching another process. In order to launch a process a bunch or
839 // packets need to be sent: environment packets, working directory,
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000840 // disable ASLR, and many more settings. When we launch a process we
Greg Clayton8b82f082011-04-12 05:54:46 +0000841 // then need to know when to clear this information. Currently we are
842 // selecting the 'qC' packet as that packet which seems to make the most
843 // sense.
844 if (pid != LLDB_INVALID_PROCESS_ID)
845 {
846 m_process_launch_info.Clear();
847 }
848 }
Greg Clayton37a0a242012-04-11 00:24:49 +0000849 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton8b82f082011-04-12 05:54:46 +0000850}
851
852bool
Daniel Maleae0f8f572013-08-26 23:57:52 +0000853GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid)
854{
855 Mutex::Locker locker (m_spawned_pids_mutex);
Greg Clayton29b8fc42013-11-21 01:44:58 +0000856 FreePortForProcess(pid);
Daniel Maleae0f8f572013-08-26 23:57:52 +0000857 return m_spawned_pids.erase(pid) > 0;
858}
859bool
860GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton,
861 lldb::pid_t pid,
862 bool exited,
863 int signal, // Zero for no signal
864 int status) // Exit value of process if signal is zero
865{
866 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
867 server->DebugserverProcessReaped (pid);
868 return true;
869}
870
Todd Fiala3e92a2b2014-01-24 00:52:53 +0000871bool
872GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid)
873{
874 // reap a process that we were debugging (but not debugserver)
875 Mutex::Locker locker (m_spawned_pids_mutex);
876 return m_spawned_pids.erase(pid) > 0;
877}
878
879bool
880GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton,
881 lldb::pid_t pid,
882 bool exited,
883 int signal, // Zero for no signal
884 int status) // Exit value of process if signal is zero
885{
886 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
887 server->DebuggedProcessReaped (pid);
888 return true;
889}
890
Greg Clayton3dedae12013-12-06 21:45:27 +0000891GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +0000892GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
893{
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000894#ifdef _WIN32
Deepak Panickal263fde02014-01-14 11:34:44 +0000895 return SendErrorResponse(9);
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000896#else
Greg Clayton8b82f082011-04-12 05:54:46 +0000897 // Spawn a local debugserver as a platform so we can then attach or launch
898 // a process...
899
900 if (m_is_platform)
901 {
902 // Sleep and wait a bit for debugserver to start to listen...
903 ConnectionFileDescriptor file_conn;
Greg Clayton8b82f082011-04-12 05:54:46 +0000904 Error error;
Daniel Maleae0f8f572013-08-26 23:57:52 +0000905 std::string hostname;
Sylvestre Ledrufaa63ce2013-09-28 15:57:37 +0000906 // TODO: /tmp/ should not be hardcoded. User might want to override /tmp
907 // with the TMPDIR environnement variable
Greg Clayton29b8fc42013-11-21 01:44:58 +0000908 packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
909 std::string name;
910 std::string value;
911 uint16_t port = UINT16_MAX;
912 while (packet.GetNameColonValue(name, value))
Greg Clayton8b82f082011-04-12 05:54:46 +0000913 {
Greg Clayton29b8fc42013-11-21 01:44:58 +0000914 if (name.compare ("host") == 0)
915 hostname.swap(value);
916 else if (name.compare ("port") == 0)
917 port = Args::StringToUInt32(value.c_str(), 0, 0);
Greg Clayton8b82f082011-04-12 05:54:46 +0000918 }
Greg Clayton29b8fc42013-11-21 01:44:58 +0000919 if (port == UINT16_MAX)
920 port = GetNextAvailablePort();
921
922 // Spawn a new thread to accept the port that gets bound after
923 // binding to port 0 (zero).
Greg Claytonfbb76342013-11-20 21:07:01 +0000924
Greg Clayton29b8fc42013-11-21 01:44:58 +0000925 if (error.Success())
926 {
927 // Spawn a debugserver and try to get the port it listens to.
928 ProcessLaunchInfo debugserver_launch_info;
Greg Clayton29b8fc42013-11-21 01:44:58 +0000929 if (hostname.empty())
Greg Clayton16810922014-02-27 19:38:18 +0000930 hostname = "127.0.0.1";
Greg Clayton29b8fc42013-11-21 01:44:58 +0000931 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
932 if (log)
Greg Claytonfda4fab2014-01-10 22:24:11 +0000933 log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000934
Greg Clayton29b8fc42013-11-21 01:44:58 +0000935 debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
936
Greg Claytonfda4fab2014-01-10 22:24:11 +0000937 error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
938 port,
Greg Clayton00fe87b2013-12-05 22:58:22 +0000939 debugserver_launch_info,
940 port);
Greg Clayton29b8fc42013-11-21 01:44:58 +0000941
942 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
Sylvestre Ledrub027bd22013-09-28 14:35:00 +0000943
Greg Claytonfbb76342013-11-20 21:07:01 +0000944
Greg Clayton29b8fc42013-11-21 01:44:58 +0000945 if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
946 {
947 Mutex::Locker locker (m_spawned_pids_mutex);
948 m_spawned_pids.insert(debugserver_pid);
949 if (port > 0)
950 AssociatePortWithProcess(port, debugserver_pid);
951 }
952 else
953 {
954 if (port > 0)
955 FreePort (port);
956 }
957
958 if (error.Success())
959 {
Greg Clayton91a9b2472013-12-04 19:19:12 +0000960 char response[256];
961 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
Ed Masted494b292014-03-20 17:34:26 +0000962 assert (response_len < (int)sizeof(response));
Greg Clayton3dedae12013-12-06 21:45:27 +0000963 PacketResult packet_result = SendPacketNoLock (response, response_len);
Greg Clayton29b8fc42013-11-21 01:44:58 +0000964
Greg Clayton3dedae12013-12-06 21:45:27 +0000965 if (packet_result != PacketResult::Success)
Greg Clayton29b8fc42013-11-21 01:44:58 +0000966 {
967 if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
968 ::kill (debugserver_pid, SIGINT);
969 }
Greg Clayton3dedae12013-12-06 21:45:27 +0000970 return packet_result;
Greg Clayton29b8fc42013-11-21 01:44:58 +0000971 }
Greg Clayton8b82f082011-04-12 05:54:46 +0000972 }
973 }
Daniel Maleae0f8f572013-08-26 23:57:52 +0000974 return SendErrorResponse (9);
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000975#endif
Greg Clayton8b82f082011-04-12 05:54:46 +0000976}
977
Todd Fiala403edc52014-01-23 22:05:44 +0000978bool
979GDBRemoteCommunicationServer::KillSpawnedProcess (lldb::pid_t pid)
980{
981 // make sure we know about this process
982 {
983 Mutex::Locker locker (m_spawned_pids_mutex);
984 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
985 return false;
986 }
987
988 // first try a SIGTERM (standard kill)
989 Host::Kill (pid, SIGTERM);
990
991 // check if that worked
992 for (size_t i=0; i<10; ++i)
993 {
994 {
995 Mutex::Locker locker (m_spawned_pids_mutex);
996 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
997 {
998 // it is now killed
999 return true;
1000 }
1001 }
1002 usleep (10000);
1003 }
1004
1005 // check one more time after the final usleep
1006 {
1007 Mutex::Locker locker (m_spawned_pids_mutex);
1008 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1009 return true;
1010 }
1011
1012 // the launched process still lives. Now try killling it again,
1013 // this time with an unblockable signal.
1014 Host::Kill (pid, SIGKILL);
1015
1016 for (size_t i=0; i<10; ++i)
1017 {
1018 {
1019 Mutex::Locker locker (m_spawned_pids_mutex);
1020 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1021 {
1022 // it is now killed
1023 return true;
1024 }
1025 }
1026 usleep (10000);
1027 }
1028
1029 // check one more time after the final usleep
1030 // Scope for locker
1031 {
1032 Mutex::Locker locker (m_spawned_pids_mutex);
1033 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1034 return true;
1035 }
1036
1037 // no luck - the process still lives
1038 return false;
1039}
1040
Greg Clayton3dedae12013-12-06 21:45:27 +00001041GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001042GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
1043{
Todd Fiala403edc52014-01-23 22:05:44 +00001044 packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
Sylvestre Ledrub027bd22013-09-28 14:35:00 +00001045
Todd Fiala403edc52014-01-23 22:05:44 +00001046 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
1047
1048 // verify that we know anything about this pid.
1049 // Scope for locker
Daniel Maleae0f8f572013-08-26 23:57:52 +00001050 {
Todd Fiala403edc52014-01-23 22:05:44 +00001051 Mutex::Locker locker (m_spawned_pids_mutex);
1052 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
Daniel Maleae0f8f572013-08-26 23:57:52 +00001053 {
Todd Fiala403edc52014-01-23 22:05:44 +00001054 // not a pid we know about
1055 return SendErrorResponse (10);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001056 }
1057 }
Todd Fiala403edc52014-01-23 22:05:44 +00001058
1059 // go ahead and attempt to kill the spawned process
1060 if (KillSpawnedProcess (pid))
1061 return SendOKResponse ();
1062 else
1063 return SendErrorResponse (11);
1064}
1065
1066GDBRemoteCommunication::PacketResult
1067GDBRemoteCommunicationServer::Handle_k (StringExtractorGDBRemote &packet)
1068{
1069 // ignore for now if we're lldb_platform
1070 if (m_is_platform)
1071 return SendUnimplementedResponse (packet.GetStringRef().c_str());
1072
1073 // shutdown all spawned processes
1074 std::set<lldb::pid_t> spawned_pids_copy;
1075
1076 // copy pids
1077 {
1078 Mutex::Locker locker (m_spawned_pids_mutex);
1079 spawned_pids_copy.insert (m_spawned_pids.begin (), m_spawned_pids.end ());
1080 }
1081
1082 // nuke the spawned processes
1083 for (auto it = spawned_pids_copy.begin (); it != spawned_pids_copy.end (); ++it)
1084 {
1085 lldb::pid_t spawned_pid = *it;
1086 if (!KillSpawnedProcess (spawned_pid))
1087 {
1088 fprintf (stderr, "%s: failed to kill spawned pid %" PRIu64 ", ignoring.\n", __FUNCTION__, spawned_pid);
1089 }
1090 }
1091
1092 // TODO figure out how to shut down gracefully at this point
1093 return SendOKResponse ();
Daniel Maleae0f8f572013-08-26 23:57:52 +00001094}
1095
Greg Clayton3dedae12013-12-06 21:45:27 +00001096GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +00001097GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
1098{
1099 if (m_process_launch_error.Success())
1100 return SendOKResponse();
Sylvestre Ledrub027bd22013-09-28 14:35:00 +00001101 StreamString response;
Greg Clayton8b82f082011-04-12 05:54:46 +00001102 response.PutChar('E');
1103 response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
Greg Clayton37a0a242012-04-11 00:24:49 +00001104 return SendPacketNoLock (response.GetData(), response.GetSize());
Greg Clayton8b82f082011-04-12 05:54:46 +00001105}
1106
Greg Clayton3dedae12013-12-06 21:45:27 +00001107GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +00001108GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet)
1109{
1110 packet.SetFilePos(::strlen ("QEnvironment:"));
1111 const uint32_t bytes_left = packet.GetBytesLeft();
1112 if (bytes_left > 0)
1113 {
1114 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
1115 return SendOKResponse ();
1116 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001117 return SendErrorResponse (12);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001118}
1119
Greg Clayton3dedae12013-12-06 21:45:27 +00001120GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001121GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
1122{
1123 packet.SetFilePos(::strlen ("QLaunchArch:"));
1124 const uint32_t bytes_left = packet.GetBytesLeft();
1125 if (bytes_left > 0)
1126 {
1127 const char* arch_triple = packet.Peek();
1128 ArchSpec arch_spec(arch_triple,NULL);
1129 m_process_launch_info.SetArchitecture(arch_spec);
1130 return SendOKResponse();
1131 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001132 return SendErrorResponse(13);
Greg Clayton8b82f082011-04-12 05:54:46 +00001133}
1134
Greg Clayton3dedae12013-12-06 21:45:27 +00001135GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +00001136GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
1137{
1138 packet.SetFilePos(::strlen ("QSetDisableASLR:"));
1139 if (packet.GetU32(0))
1140 m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
1141 else
1142 m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
1143 return SendOKResponse ();
1144}
1145
Greg Clayton3dedae12013-12-06 21:45:27 +00001146GDBRemoteCommunication::PacketResult
Jim Ingham106d0282014-06-25 02:32:56 +00001147GDBRemoteCommunicationServer::Handle_QSetDetachOnError (StringExtractorGDBRemote &packet)
1148{
1149 packet.SetFilePos(::strlen ("QSetDetachOnError:"));
1150 if (packet.GetU32(0))
1151 m_process_launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
1152 else
1153 m_process_launch_info.GetFlags().Clear (eLaunchFlagDetachOnError);
1154 return SendOKResponse ();
1155}
1156
1157GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +00001158GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
1159{
1160 packet.SetFilePos(::strlen ("QSetWorkingDir:"));
1161 std::string path;
1162 packet.GetHexByteString(path);
Greg Claytonfbb76342013-11-20 21:07:01 +00001163 if (m_is_platform)
1164 {
Colin Riley909bb7a2013-11-26 15:10:46 +00001165#ifdef _WIN32
1166 // Not implemented on Windows
1167 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_QSetWorkingDir unimplemented");
1168#else
Greg Claytonfbb76342013-11-20 21:07:01 +00001169 // If this packet is sent to a platform, then change the current working directory
1170 if (::chdir(path.c_str()) != 0)
1171 return SendErrorResponse(errno);
Colin Riley909bb7a2013-11-26 15:10:46 +00001172#endif
Greg Claytonfbb76342013-11-20 21:07:01 +00001173 }
1174 else
1175 {
1176 m_process_launch_info.SwapWorkingDirectory (path);
1177 }
Greg Clayton8b82f082011-04-12 05:54:46 +00001178 return SendOKResponse ();
1179}
1180
Greg Clayton3dedae12013-12-06 21:45:27 +00001181GDBRemoteCommunication::PacketResult
Greg Claytonfbb76342013-11-20 21:07:01 +00001182GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
1183{
1184 StreamString response;
1185
1186 if (m_is_platform)
1187 {
1188 // If this packet is sent to a platform, then change the current working directory
1189 char cwd[PATH_MAX];
1190 if (getcwd(cwd, sizeof(cwd)) == NULL)
1191 {
1192 return SendErrorResponse(errno);
1193 }
1194 else
1195 {
1196 response.PutBytesAsRawHex8(cwd, strlen(cwd));
Greg Clayton3dedae12013-12-06 21:45:27 +00001197 return SendPacketNoLock(response.GetData(), response.GetSize());
Greg Claytonfbb76342013-11-20 21:07:01 +00001198 }
1199 }
1200 else
1201 {
1202 const char *working_dir = m_process_launch_info.GetWorkingDirectory();
1203 if (working_dir && working_dir[0])
1204 {
1205 response.PutBytesAsRawHex8(working_dir, strlen(working_dir));
Greg Clayton3dedae12013-12-06 21:45:27 +00001206 return SendPacketNoLock(response.GetData(), response.GetSize());
Greg Claytonfbb76342013-11-20 21:07:01 +00001207 }
1208 else
1209 {
Greg Clayton2b98c562013-11-22 18:53:12 +00001210 return SendErrorResponse(14);
Greg Claytonfbb76342013-11-20 21:07:01 +00001211 }
1212 }
1213}
1214
Greg Clayton3dedae12013-12-06 21:45:27 +00001215GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +00001216GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
1217{
1218 packet.SetFilePos(::strlen ("QSetSTDIN:"));
1219 ProcessLaunchInfo::FileAction file_action;
1220 std::string path;
1221 packet.GetHexByteString(path);
1222 const bool read = false;
1223 const bool write = true;
1224 if (file_action.Open(STDIN_FILENO, path.c_str(), read, write))
1225 {
1226 m_process_launch_info.AppendFileAction(file_action);
1227 return SendOKResponse ();
1228 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001229 return SendErrorResponse (15);
Greg Clayton8b82f082011-04-12 05:54:46 +00001230}
1231
Greg Clayton3dedae12013-12-06 21:45:27 +00001232GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +00001233GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
1234{
1235 packet.SetFilePos(::strlen ("QSetSTDOUT:"));
1236 ProcessLaunchInfo::FileAction file_action;
1237 std::string path;
1238 packet.GetHexByteString(path);
1239 const bool read = true;
1240 const bool write = false;
1241 if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write))
1242 {
1243 m_process_launch_info.AppendFileAction(file_action);
1244 return SendOKResponse ();
1245 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001246 return SendErrorResponse (16);
Greg Clayton8b82f082011-04-12 05:54:46 +00001247}
1248
Greg Clayton3dedae12013-12-06 21:45:27 +00001249GDBRemoteCommunication::PacketResult
Greg Clayton8b82f082011-04-12 05:54:46 +00001250GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
1251{
1252 packet.SetFilePos(::strlen ("QSetSTDERR:"));
1253 ProcessLaunchInfo::FileAction file_action;
1254 std::string path;
1255 packet.GetHexByteString(path);
1256 const bool read = true;
Greg Clayton9845a8d2012-03-06 04:01:04 +00001257 const bool write = false;
Greg Clayton8b82f082011-04-12 05:54:46 +00001258 if (file_action.Open(STDERR_FILENO, path.c_str(), read, write))
1259 {
1260 m_process_launch_info.AppendFileAction(file_action);
1261 return SendOKResponse ();
1262 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001263 return SendErrorResponse (17);
Greg Clayton8b82f082011-04-12 05:54:46 +00001264}
1265
Greg Clayton3dedae12013-12-06 21:45:27 +00001266GDBRemoteCommunication::PacketResult
Greg Clayton32e0a752011-03-30 18:16:51 +00001267GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
1268{
1269 // Send response first before changing m_send_acks to we ack this packet
Greg Clayton3dedae12013-12-06 21:45:27 +00001270 PacketResult packet_result = SendOKResponse ();
Greg Clayton1cb64962011-03-24 04:28:38 +00001271 m_send_acks = false;
Greg Clayton3dedae12013-12-06 21:45:27 +00001272 return packet_result;
Greg Clayton1cb64962011-03-24 04:28:38 +00001273}
Daniel Maleae0f8f572013-08-26 23:57:52 +00001274
Greg Clayton3dedae12013-12-06 21:45:27 +00001275GDBRemoteCommunication::PacketResult
Greg Claytonfbb76342013-11-20 21:07:01 +00001276GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
Daniel Maleae0f8f572013-08-26 23:57:52 +00001277{
Greg Claytonfbb76342013-11-20 21:07:01 +00001278 packet.SetFilePos(::strlen("qPlatform_mkdir:"));
Daniel Maleae0f8f572013-08-26 23:57:52 +00001279 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
Greg Clayton2b98c562013-11-22 18:53:12 +00001280 if (packet.GetChar() == ',')
1281 {
1282 std::string path;
1283 packet.GetHexByteString(path);
1284 Error error = Host::MakeDirectory(path.c_str(),mode);
1285 if (error.Success())
1286 return SendPacketNoLock ("OK", 2);
1287 else
1288 return SendErrorResponse(error.GetError());
1289 }
1290 return SendErrorResponse(20);
Greg Claytonfbb76342013-11-20 21:07:01 +00001291}
1292
Greg Clayton3dedae12013-12-06 21:45:27 +00001293GDBRemoteCommunication::PacketResult
Greg Claytonfbb76342013-11-20 21:07:01 +00001294GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
1295{
1296 packet.SetFilePos(::strlen("qPlatform_chmod:"));
1297
1298 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
Greg Clayton2b98c562013-11-22 18:53:12 +00001299 if (packet.GetChar() == ',')
1300 {
1301 std::string path;
1302 packet.GetHexByteString(path);
1303 Error error = Host::SetFilePermissions (path.c_str(), mode);
1304 if (error.Success())
1305 return SendPacketNoLock ("OK", 2);
1306 else
1307 return SendErrorResponse(error.GetError());
1308 }
1309 return SendErrorResponse(19);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001310}
1311
Greg Clayton3dedae12013-12-06 21:45:27 +00001312GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001313GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet)
1314{
1315 packet.SetFilePos(::strlen("vFile:open:"));
1316 std::string path;
1317 packet.GetHexByteStringTerminatedBy(path,',');
Greg Clayton2b98c562013-11-22 18:53:12 +00001318 if (!path.empty())
1319 {
1320 if (packet.GetChar() == ',')
1321 {
1322 uint32_t flags = packet.GetHexMaxU32(false, 0);
1323 if (packet.GetChar() == ',')
1324 {
1325 mode_t mode = packet.GetHexMaxU32(false, 0600);
1326 Error error;
1327 int fd = ::open (path.c_str(), flags, mode);
Greg Clayton2b98c562013-11-22 18:53:12 +00001328 const int save_errno = fd == -1 ? errno : 0;
1329 StreamString response;
1330 response.PutChar('F');
1331 response.Printf("%i", fd);
1332 if (save_errno)
1333 response.Printf(",%i", save_errno);
1334 return SendPacketNoLock(response.GetData(), response.GetSize());
1335 }
1336 }
1337 }
1338 return SendErrorResponse(18);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001339}
1340
Greg Clayton3dedae12013-12-06 21:45:27 +00001341GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001342GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet)
1343{
1344 packet.SetFilePos(::strlen("vFile:close:"));
1345 int fd = packet.GetS32(-1);
1346 Error error;
1347 int err = -1;
1348 int save_errno = 0;
1349 if (fd >= 0)
1350 {
1351 err = close(fd);
1352 save_errno = err == -1 ? errno : 0;
1353 }
1354 else
1355 {
1356 save_errno = EINVAL;
1357 }
1358 StreamString response;
1359 response.PutChar('F');
1360 response.Printf("%i", err);
1361 if (save_errno)
1362 response.Printf(",%i", save_errno);
Greg Clayton2b98c562013-11-22 18:53:12 +00001363 return SendPacketNoLock(response.GetData(), response.GetSize());
Daniel Maleae0f8f572013-08-26 23:57:52 +00001364}
1365
Greg Clayton3dedae12013-12-06 21:45:27 +00001366GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001367GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
1368{
Virgile Belloae12a362013-08-27 16:21:49 +00001369#ifdef _WIN32
1370 // Not implemented on Windows
Greg Clayton2b98c562013-11-22 18:53:12 +00001371 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented");
Virgile Belloae12a362013-08-27 16:21:49 +00001372#else
Daniel Maleae0f8f572013-08-26 23:57:52 +00001373 StreamGDBRemote response;
1374 packet.SetFilePos(::strlen("vFile:pread:"));
1375 int fd = packet.GetS32(-1);
Greg Clayton2b98c562013-11-22 18:53:12 +00001376 if (packet.GetChar() == ',')
Daniel Maleae0f8f572013-08-26 23:57:52 +00001377 {
Greg Clayton2b98c562013-11-22 18:53:12 +00001378 uint64_t count = packet.GetU64(UINT64_MAX);
1379 if (packet.GetChar() == ',')
1380 {
1381 uint64_t offset = packet.GetU64(UINT32_MAX);
1382 if (count == UINT64_MAX)
1383 {
1384 response.Printf("F-1:%i", EINVAL);
1385 return SendPacketNoLock(response.GetData(), response.GetSize());
1386 }
1387
1388 std::string buffer(count, 0);
1389 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
1390 const int save_errno = bytes_read == -1 ? errno : 0;
1391 response.PutChar('F');
1392 response.Printf("%zi", bytes_read);
1393 if (save_errno)
1394 response.Printf(",%i", save_errno);
1395 else
1396 {
1397 response.PutChar(';');
1398 response.PutEscapedBytes(&buffer[0], bytes_read);
1399 }
1400 return SendPacketNoLock(response.GetData(), response.GetSize());
1401 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00001402 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001403 return SendErrorResponse(21);
1404
Virgile Belloae12a362013-08-27 16:21:49 +00001405#endif
Daniel Maleae0f8f572013-08-26 23:57:52 +00001406}
1407
Greg Clayton3dedae12013-12-06 21:45:27 +00001408GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001409GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
1410{
Virgile Belloae12a362013-08-27 16:21:49 +00001411#ifdef _WIN32
Greg Clayton2b98c562013-11-22 18:53:12 +00001412 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pWrite() unimplemented");
Virgile Belloae12a362013-08-27 16:21:49 +00001413#else
Daniel Maleae0f8f572013-08-26 23:57:52 +00001414 packet.SetFilePos(::strlen("vFile:pwrite:"));
1415
1416 StreamGDBRemote response;
1417 response.PutChar('F');
1418
1419 int fd = packet.GetU32(UINT32_MAX);
Greg Clayton2b98c562013-11-22 18:53:12 +00001420 if (packet.GetChar() == ',')
Daniel Maleae0f8f572013-08-26 23:57:52 +00001421 {
Greg Clayton2b98c562013-11-22 18:53:12 +00001422 off_t offset = packet.GetU64(UINT32_MAX);
1423 if (packet.GetChar() == ',')
1424 {
1425 std::string buffer;
1426 if (packet.GetEscapedBinaryData(buffer))
1427 {
1428 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset);
1429 const int save_errno = bytes_written == -1 ? errno : 0;
1430 response.Printf("%zi", bytes_written);
1431 if (save_errno)
1432 response.Printf(",%i", save_errno);
1433 }
1434 else
1435 {
1436 response.Printf ("-1,%i", EINVAL);
1437 }
1438 return SendPacketNoLock(response.GetData(), response.GetSize());
1439 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00001440 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001441 return SendErrorResponse(27);
Virgile Belloae12a362013-08-27 16:21:49 +00001442#endif
Daniel Maleae0f8f572013-08-26 23:57:52 +00001443}
1444
Greg Clayton3dedae12013-12-06 21:45:27 +00001445GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001446GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet)
1447{
1448 packet.SetFilePos(::strlen("vFile:size:"));
1449 std::string path;
1450 packet.GetHexByteString(path);
Greg Clayton2b98c562013-11-22 18:53:12 +00001451 if (!path.empty())
Daniel Maleae0f8f572013-08-26 23:57:52 +00001452 {
Greg Clayton2b98c562013-11-22 18:53:12 +00001453 lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false));
1454 StreamString response;
1455 response.PutChar('F');
1456 response.PutHex64(retcode);
1457 if (retcode == UINT64_MAX)
1458 {
1459 response.PutChar(',');
1460 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode()
1461 }
1462 return SendPacketNoLock(response.GetData(), response.GetSize());
Daniel Maleae0f8f572013-08-26 23:57:52 +00001463 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001464 return SendErrorResponse(22);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001465}
1466
Greg Clayton3dedae12013-12-06 21:45:27 +00001467GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001468GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
1469{
1470 packet.SetFilePos(::strlen("vFile:mode:"));
1471 std::string path;
1472 packet.GetHexByteString(path);
Greg Clayton2b98c562013-11-22 18:53:12 +00001473 if (!path.empty())
1474 {
1475 Error error;
1476 const uint32_t mode = File::GetPermissions(path.c_str(), error);
1477 StreamString response;
1478 response.Printf("F%u", mode);
1479 if (mode == 0 || error.Fail())
1480 response.Printf(",%i", (int)error.GetError());
1481 return SendPacketNoLock(response.GetData(), response.GetSize());
1482 }
1483 return SendErrorResponse(23);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001484}
1485
Greg Clayton3dedae12013-12-06 21:45:27 +00001486GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001487GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
1488{
1489 packet.SetFilePos(::strlen("vFile:exists:"));
1490 std::string path;
1491 packet.GetHexByteString(path);
Greg Clayton2b98c562013-11-22 18:53:12 +00001492 if (!path.empty())
1493 {
1494 bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false));
1495 StreamString response;
1496 response.PutChar('F');
1497 response.PutChar(',');
1498 if (retcode)
1499 response.PutChar('1');
1500 else
1501 response.PutChar('0');
1502 return SendPacketNoLock(response.GetData(), response.GetSize());
1503 }
1504 return SendErrorResponse(24);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001505}
1506
Greg Clayton3dedae12013-12-06 21:45:27 +00001507GDBRemoteCommunication::PacketResult
Greg Claytonfbb76342013-11-20 21:07:01 +00001508GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
Daniel Maleae0f8f572013-08-26 23:57:52 +00001509{
Greg Claytonfbb76342013-11-20 21:07:01 +00001510 packet.SetFilePos(::strlen("vFile:symlink:"));
1511 std::string dst, src;
1512 packet.GetHexByteStringTerminatedBy(dst, ',');
1513 packet.GetChar(); // Skip ',' char
1514 packet.GetHexByteString(src);
1515 Error error = Host::Symlink(src.c_str(), dst.c_str());
1516 StreamString response;
1517 response.Printf("F%u,%u", error.GetError(), error.GetError());
Greg Clayton2b98c562013-11-22 18:53:12 +00001518 return SendPacketNoLock(response.GetData(), response.GetSize());
Greg Claytonfbb76342013-11-20 21:07:01 +00001519}
1520
Greg Clayton3dedae12013-12-06 21:45:27 +00001521GDBRemoteCommunication::PacketResult
Greg Claytonfbb76342013-11-20 21:07:01 +00001522GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
1523{
1524 packet.SetFilePos(::strlen("vFile:unlink:"));
1525 std::string path;
1526 packet.GetHexByteString(path);
1527 Error error = Host::Unlink(path.c_str());
1528 StreamString response;
1529 response.Printf("F%u,%u", error.GetError(), error.GetError());
Greg Clayton2b98c562013-11-22 18:53:12 +00001530 return SendPacketNoLock(response.GetData(), response.GetSize());
Greg Claytonfbb76342013-11-20 21:07:01 +00001531}
1532
Greg Clayton3dedae12013-12-06 21:45:27 +00001533GDBRemoteCommunication::PacketResult
Greg Claytonfbb76342013-11-20 21:07:01 +00001534GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
1535{
1536 packet.SetFilePos(::strlen("qPlatform_shell:"));
Daniel Maleae0f8f572013-08-26 23:57:52 +00001537 std::string path;
1538 std::string working_dir;
1539 packet.GetHexByteStringTerminatedBy(path,',');
Greg Clayton2b98c562013-11-22 18:53:12 +00001540 if (!path.empty())
Daniel Maleae0f8f572013-08-26 23:57:52 +00001541 {
Greg Clayton2b98c562013-11-22 18:53:12 +00001542 if (packet.GetChar() == ',')
1543 {
1544 // FIXME: add timeout to qPlatform_shell packet
1545 // uint32_t timeout = packet.GetHexMaxU32(false, 32);
1546 uint32_t timeout = 10;
1547 if (packet.GetChar() == ',')
1548 packet.GetHexByteString(working_dir);
1549 int status, signo;
1550 std::string output;
1551 Error err = Host::RunShellCommand(path.c_str(),
1552 working_dir.empty() ? NULL : working_dir.c_str(),
1553 &status, &signo, &output, timeout);
1554 StreamGDBRemote response;
1555 if (err.Fail())
1556 {
1557 response.PutCString("F,");
1558 response.PutHex32(UINT32_MAX);
1559 }
1560 else
1561 {
1562 response.PutCString("F,");
1563 response.PutHex32(status);
1564 response.PutChar(',');
1565 response.PutHex32(signo);
1566 response.PutChar(',');
1567 response.PutEscapedBytes(output.c_str(), output.size());
1568 }
1569 return SendPacketNoLock(response.GetData(), response.GetSize());
1570 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00001571 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001572 return SendErrorResponse(24);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001573}
1574
Greg Clayton3dedae12013-12-06 21:45:27 +00001575GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001576GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
1577{
Greg Clayton2b98c562013-11-22 18:53:12 +00001578 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_Stat() unimplemented");
Daniel Maleae0f8f572013-08-26 23:57:52 +00001579}
1580
Greg Clayton3dedae12013-12-06 21:45:27 +00001581GDBRemoteCommunication::PacketResult
Daniel Maleae0f8f572013-08-26 23:57:52 +00001582GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
1583{
Greg Clayton2b98c562013-11-22 18:53:12 +00001584 packet.SetFilePos(::strlen("vFile:MD5:"));
Daniel Maleae0f8f572013-08-26 23:57:52 +00001585 std::string path;
1586 packet.GetHexByteString(path);
Greg Clayton2b98c562013-11-22 18:53:12 +00001587 if (!path.empty())
Daniel Maleae0f8f572013-08-26 23:57:52 +00001588 {
Greg Clayton2b98c562013-11-22 18:53:12 +00001589 uint64_t a,b;
1590 StreamGDBRemote response;
1591 if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false)
1592 {
1593 response.PutCString("F,");
1594 response.PutCString("x");
1595 }
1596 else
1597 {
1598 response.PutCString("F,");
1599 response.PutHex64(a);
1600 response.PutHex64(b);
1601 }
1602 return SendPacketNoLock(response.GetData(), response.GetSize());
Daniel Maleae0f8f572013-08-26 23:57:52 +00001603 }
Greg Clayton2b98c562013-11-22 18:53:12 +00001604 return SendErrorResponse(25);
Daniel Maleae0f8f572013-08-26 23:57:52 +00001605}
Greg Clayton2b98c562013-11-22 18:53:12 +00001606