xref: /llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (revision 9f37737311b90a9b60883184f0130c20d7a92dd3)
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 "GDBRemoteCommunicationServer.h"
13 #include "lldb/Core/StreamGDBRemote.h"
14 
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"
24 #include "lldb/Host/Endian.h"
25 #include "lldb/Host/File.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Host/TimeValue.h"
28 #include "lldb/Target/Process.h"
29 
30 // Project includes
31 #include "Utility/StringExtractorGDBRemote.h"
32 #include "ProcessGDBRemote.h"
33 #include "ProcessGDBRemoteLog.h"
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 //----------------------------------------------------------------------
39 // GDBRemoteCommunicationServer constructor
40 //----------------------------------------------------------------------
41 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) :
42     GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform),
43     m_async_thread (LLDB_INVALID_HOST_THREAD),
44     m_process_launch_info (),
45     m_process_launch_error (),
46     m_spawned_pids (),
47     m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
48     m_proc_infos (),
49     m_proc_infos_index (0),
50     m_port_map (),
51     m_port_offset(0)
52 {
53 }
54 
55 //----------------------------------------------------------------------
56 // Destructor
57 //----------------------------------------------------------------------
58 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
59 {
60 }
61 
62 
63 //void *
64 //GDBRemoteCommunicationServer::AsyncThread (void *arg)
65 //{
66 //    GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
67 //
68 //    Log *log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
69 //    if (log)
70 //        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
71 //
72 //    StringExtractorGDBRemote packet;
73 //
74 //    while ()
75 //    {
76 //        if (packet.
77 //    }
78 //
79 //    if (log)
80 //        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
81 //
82 //    process->m_async_thread = LLDB_INVALID_HOST_THREAD;
83 //    return NULL;
84 //}
85 //
86 bool
87 GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
88                                                         Error &error,
89                                                         bool &interrupt,
90                                                         bool &quit)
91 {
92     StringExtractorGDBRemote packet;
93     PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
94     if (packet_result == PacketResult::Success)
95     {
96         const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
97         switch (packet_type)
98         {
99         case StringExtractorGDBRemote::eServerPacketType_nack:
100         case StringExtractorGDBRemote::eServerPacketType_ack:
101             break;
102 
103         case StringExtractorGDBRemote::eServerPacketType_invalid:
104             error.SetErrorString("invalid packet");
105             quit = true;
106             break;
107 
108         case StringExtractorGDBRemote::eServerPacketType_interrupt:
109             error.SetErrorString("interrupt received");
110             interrupt = true;
111             break;
112 
113         default:
114         case StringExtractorGDBRemote::eServerPacketType_unimplemented:
115             packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
116             break;
117 
118         case StringExtractorGDBRemote::eServerPacketType_A:
119             packet_result = Handle_A (packet);
120             break;
121 
122         case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
123             packet_result = Handle_qfProcessInfo (packet);
124             break;
125 
126         case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
127             packet_result = Handle_qsProcessInfo (packet);
128             break;
129 
130         case StringExtractorGDBRemote::eServerPacketType_qC:
131             packet_result = Handle_qC (packet);
132             break;
133 
134         case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
135             packet_result = Handle_qHostInfo (packet);
136             break;
137 
138         case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer:
139             packet_result = Handle_qLaunchGDBServer (packet);
140             break;
141 
142         case StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess:
143             packet_result = Handle_qKillSpawnedProcess (packet);
144             break;
145 
146         case StringExtractorGDBRemote::eServerPacketType_k:
147             packet_result = Handle_k (packet);
148             break;
149 
150         case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess:
151             packet_result = Handle_qLaunchSuccess (packet);
152             break;
153 
154         case StringExtractorGDBRemote::eServerPacketType_qGroupName:
155             packet_result = Handle_qGroupName (packet);
156             break;
157 
158         case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
159             packet_result = Handle_qProcessInfoPID (packet);
160             break;
161 
162         case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
163             packet_result = Handle_qSpeedTest (packet);
164             break;
165 
166         case StringExtractorGDBRemote::eServerPacketType_qUserName:
167             packet_result = Handle_qUserName (packet);
168             break;
169 
170         case StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir:
171             packet_result = Handle_qGetWorkingDir(packet);
172             break;
173 
174         case StringExtractorGDBRemote::eServerPacketType_QEnvironment:
175             packet_result = Handle_QEnvironment (packet);
176             break;
177 
178         case StringExtractorGDBRemote::eServerPacketType_QLaunchArch:
179             packet_result = Handle_QLaunchArch (packet);
180             break;
181 
182         case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR:
183             packet_result = Handle_QSetDisableASLR (packet);
184             break;
185 
186         case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN:
187             packet_result = Handle_QSetSTDIN (packet);
188             break;
189 
190         case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT:
191             packet_result = Handle_QSetSTDOUT (packet);
192             break;
193 
194         case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR:
195             packet_result = Handle_QSetSTDERR (packet);
196             break;
197 
198         case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir:
199             packet_result = Handle_QSetWorkingDir (packet);
200             break;
201 
202         case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
203             packet_result = Handle_QStartNoAckMode (packet);
204             break;
205 
206         case StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir:
207             packet_result = Handle_qPlatform_mkdir (packet);
208             break;
209 
210         case StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod:
211             packet_result = Handle_qPlatform_chmod (packet);
212             break;
213 
214         case StringExtractorGDBRemote::eServerPacketType_qPlatform_shell:
215             packet_result = Handle_qPlatform_shell (packet);
216             break;
217 
218         case StringExtractorGDBRemote::eServerPacketType_vFile_open:
219             packet_result = Handle_vFile_Open (packet);
220             break;
221 
222         case StringExtractorGDBRemote::eServerPacketType_vFile_close:
223             packet_result = Handle_vFile_Close (packet);
224             break;
225 
226         case StringExtractorGDBRemote::eServerPacketType_vFile_pread:
227             packet_result = Handle_vFile_pRead (packet);
228             break;
229 
230         case StringExtractorGDBRemote::eServerPacketType_vFile_pwrite:
231             packet_result = Handle_vFile_pWrite (packet);
232             break;
233 
234         case StringExtractorGDBRemote::eServerPacketType_vFile_size:
235             packet_result = Handle_vFile_Size (packet);
236             break;
237 
238         case StringExtractorGDBRemote::eServerPacketType_vFile_mode:
239             packet_result = Handle_vFile_Mode (packet);
240             break;
241 
242         case StringExtractorGDBRemote::eServerPacketType_vFile_exists:
243             packet_result = Handle_vFile_Exists (packet);
244             break;
245 
246         case StringExtractorGDBRemote::eServerPacketType_vFile_stat:
247             packet_result = Handle_vFile_Stat (packet);
248             break;
249 
250         case StringExtractorGDBRemote::eServerPacketType_vFile_md5:
251             packet_result = Handle_vFile_MD5 (packet);
252             break;
253 
254         case StringExtractorGDBRemote::eServerPacketType_vFile_symlink:
255             packet_result = Handle_vFile_symlink (packet);
256             break;
257 
258         case StringExtractorGDBRemote::eServerPacketType_vFile_unlink:
259             packet_result = Handle_vFile_unlink (packet);
260             break;
261         }
262     }
263     else
264     {
265         if (!IsConnected())
266         {
267             error.SetErrorString("lost connection");
268             quit = true;
269         }
270         else
271         {
272             error.SetErrorString("timeout");
273         }
274     }
275     return packet_result == PacketResult::Success;
276 }
277 
278 lldb_private::Error
279 GDBRemoteCommunicationServer::SetLaunchArguments (const char *const args[], int argc)
280 {
281     if ((argc < 1) || !args || !args[0] || !args[0][0])
282         return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
283 
284     m_process_launch_info.SetArguments (const_cast<const char**> (args), true);
285     return lldb_private::Error ();
286 }
287 
288 lldb_private::Error
289 GDBRemoteCommunicationServer::SetLaunchFlags (unsigned int launch_flags)
290 {
291     m_process_launch_info.GetFlags ().Set (launch_flags);
292     return lldb_private::Error ();
293 }
294 
295 lldb_private::Error
296 GDBRemoteCommunicationServer::LaunchProcess ()
297 {
298     if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
299         return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
300 
301     // specify the process monitor if not already set.  This should
302     // generally be what happens since we need to reap started
303     // processes.
304     if (!m_process_launch_info.GetMonitorProcessCallback ())
305         m_process_launch_info.SetMonitorProcessCallback(ReapDebuggedProcess, this, false);
306 
307     lldb_private::Error error = Host::LaunchProcess (m_process_launch_info);
308     if (!error.Success ())
309     {
310         fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
311         return error;
312     }
313 
314     printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
315 
316     // add to list of spawned processes.  On an lldb-gdbserver, we
317     // would expect there to be only one.
318     lldb::pid_t pid;
319     if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID )
320     {
321         Mutex::Locker locker (m_spawned_pids_mutex);
322         m_spawned_pids.insert(pid);
323     }
324 
325     return error;
326 }
327 
328 GDBRemoteCommunication::PacketResult
329 GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
330 {
331     // TODO: Log the packet we aren't handling...
332     return SendPacketNoLock ("", 0);
333 }
334 
335 GDBRemoteCommunication::PacketResult
336 GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
337 {
338     char packet[16];
339     int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
340     assert (packet_len < (int)sizeof(packet));
341     return SendPacketNoLock (packet, packet_len);
342 }
343 
344 
345 GDBRemoteCommunication::PacketResult
346 GDBRemoteCommunicationServer::SendOKResponse ()
347 {
348     return SendPacketNoLock ("OK", 2);
349 }
350 
351 bool
352 GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
353 {
354     return GetAck() == PacketResult::Success;
355 }
356 
357 GDBRemoteCommunication::PacketResult
358 GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet)
359 {
360     StreamString response;
361 
362     // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
363 
364     ArchSpec host_arch (Host::GetArchitecture ());
365     const llvm::Triple &host_triple = host_arch.GetTriple();
366     response.PutCString("triple:");
367     response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
368     response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
369 
370     const char* distribution_id = host_arch.GetDistributionId ().AsCString ();
371     if (distribution_id)
372     {
373         response.PutCString("distribution_id:");
374         response.PutCStringAsRawHex8(distribution_id);
375         response.PutCString(";");
376     }
377 
378     uint32_t cpu = host_arch.GetMachOCPUType();
379     uint32_t sub = host_arch.GetMachOCPUSubType();
380     if (cpu != LLDB_INVALID_CPUTYPE)
381         response.Printf ("cputype:%u;", cpu);
382     if (sub != LLDB_INVALID_CPUTYPE)
383         response.Printf ("cpusubtype:%u;", sub);
384 
385     if (cpu == ArchSpec::kCore_arm_any)
386         response.Printf("watchpoint_exceptions_received:before;");   // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
387     else
388         response.Printf("watchpoint_exceptions_received:after;");
389 
390     switch (lldb::endian::InlHostByteOrder())
391     {
392     case eByteOrderBig:     response.PutCString ("endian:big;"); break;
393     case eByteOrderLittle:  response.PutCString ("endian:little;"); break;
394     case eByteOrderPDP:     response.PutCString ("endian:pdp;"); break;
395     default:                response.PutCString ("endian:unknown;"); break;
396     }
397 
398     uint32_t major = UINT32_MAX;
399     uint32_t minor = UINT32_MAX;
400     uint32_t update = UINT32_MAX;
401     if (Host::GetOSVersion (major, minor, update))
402     {
403         if (major != UINT32_MAX)
404         {
405             response.Printf("os_version:%u", major);
406             if (minor != UINT32_MAX)
407             {
408                 response.Printf(".%u", minor);
409                 if (update != UINT32_MAX)
410                     response.Printf(".%u", update);
411             }
412             response.PutChar(';');
413         }
414     }
415 
416     std::string s;
417     if (Host::GetOSBuildString (s))
418     {
419         response.PutCString ("os_build:");
420         response.PutCStringAsRawHex8(s.c_str());
421         response.PutChar(';');
422     }
423     if (Host::GetOSKernelDescription (s))
424     {
425         response.PutCString ("os_kernel:");
426         response.PutCStringAsRawHex8(s.c_str());
427         response.PutChar(';');
428     }
429 #if defined(__APPLE__)
430 
431 #if defined(__arm__)
432     // For iOS devices, we are connected through a USB Mux so we never pretend
433     // to actually have a hostname as far as the remote lldb that is connecting
434     // to this lldb-platform is concerned
435     response.PutCString ("hostname:");
436     response.PutCStringAsRawHex8("localhost");
437     response.PutChar(';');
438 #else   // #if defined(__arm__)
439     if (Host::GetHostname (s))
440     {
441         response.PutCString ("hostname:");
442         response.PutCStringAsRawHex8(s.c_str());
443         response.PutChar(';');
444     }
445 
446 #endif  // #if defined(__arm__)
447 
448 #else   // #if defined(__APPLE__)
449     if (Host::GetHostname (s))
450     {
451         response.PutCString ("hostname:");
452         response.PutCStringAsRawHex8(s.c_str());
453         response.PutChar(';');
454     }
455 #endif  // #if defined(__APPLE__)
456 
457     return SendPacketNoLock (response.GetData(), response.GetSize());
458 }
459 
460 static void
461 CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response)
462 {
463     response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
464                      proc_info.GetProcessID(),
465                      proc_info.GetParentProcessID(),
466                      proc_info.GetUserID(),
467                      proc_info.GetGroupID(),
468                      proc_info.GetEffectiveUserID(),
469                      proc_info.GetEffectiveGroupID());
470     response.PutCString ("name:");
471     response.PutCStringAsRawHex8(proc_info.GetName());
472     response.PutChar(';');
473     const ArchSpec &proc_arch = proc_info.GetArchitecture();
474     if (proc_arch.IsValid())
475     {
476         const llvm::Triple &proc_triple = proc_arch.GetTriple();
477         response.PutCString("triple:");
478         response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
479         response.PutChar(';');
480     }
481 }
482 
483 GDBRemoteCommunication::PacketResult
484 GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
485 {
486     // Packet format: "qProcessInfoPID:%i" where %i is the pid
487     packet.SetFilePos(::strlen ("qProcessInfoPID:"));
488     lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
489     if (pid != LLDB_INVALID_PROCESS_ID)
490     {
491         ProcessInstanceInfo proc_info;
492         if (Host::GetProcessInfo(pid, proc_info))
493         {
494             StreamString response;
495             CreateProcessInfoResponse (proc_info, response);
496             return SendPacketNoLock (response.GetData(), response.GetSize());
497         }
498     }
499     return SendErrorResponse (1);
500 }
501 
502 GDBRemoteCommunication::PacketResult
503 GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
504 {
505     m_proc_infos_index = 0;
506     m_proc_infos.Clear();
507 
508     ProcessInstanceInfoMatch match_info;
509     packet.SetFilePos(::strlen ("qfProcessInfo"));
510     if (packet.GetChar() == ':')
511     {
512 
513         std::string key;
514         std::string value;
515         while (packet.GetNameColonValue(key, value))
516         {
517             bool success = true;
518             if (key.compare("name") == 0)
519             {
520                 StringExtractor extractor;
521                 extractor.GetStringRef().swap(value);
522                 extractor.GetHexByteString (value);
523                 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false);
524             }
525             else if (key.compare("name_match") == 0)
526             {
527                 if (value.compare("equals") == 0)
528                 {
529                     match_info.SetNameMatchType (eNameMatchEquals);
530                 }
531                 else if (value.compare("starts_with") == 0)
532                 {
533                     match_info.SetNameMatchType (eNameMatchStartsWith);
534                 }
535                 else if (value.compare("ends_with") == 0)
536                 {
537                     match_info.SetNameMatchType (eNameMatchEndsWith);
538                 }
539                 else if (value.compare("contains") == 0)
540                 {
541                     match_info.SetNameMatchType (eNameMatchContains);
542                 }
543                 else if (value.compare("regex") == 0)
544                 {
545                     match_info.SetNameMatchType (eNameMatchRegularExpression);
546                 }
547                 else
548                 {
549                     success = false;
550                 }
551             }
552             else if (key.compare("pid") == 0)
553             {
554                 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
555             }
556             else if (key.compare("parent_pid") == 0)
557             {
558                 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
559             }
560             else if (key.compare("uid") == 0)
561             {
562                 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
563             }
564             else if (key.compare("gid") == 0)
565             {
566                 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
567             }
568             else if (key.compare("euid") == 0)
569             {
570                 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
571             }
572             else if (key.compare("egid") == 0)
573             {
574                 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
575             }
576             else if (key.compare("all_users") == 0)
577             {
578                 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
579             }
580             else if (key.compare("triple") == 0)
581             {
582                 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL);
583             }
584             else
585             {
586                 success = false;
587             }
588 
589             if (!success)
590                 return SendErrorResponse (2);
591         }
592     }
593 
594     if (Host::FindProcesses (match_info, m_proc_infos))
595     {
596         // We found something, return the first item by calling the get
597         // subsequent process info packet handler...
598         return Handle_qsProcessInfo (packet);
599     }
600     return SendErrorResponse (3);
601 }
602 
603 GDBRemoteCommunication::PacketResult
604 GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
605 {
606     if (m_proc_infos_index < m_proc_infos.GetSize())
607     {
608         StreamString response;
609         CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
610         ++m_proc_infos_index;
611         return SendPacketNoLock (response.GetData(), response.GetSize());
612     }
613     return SendErrorResponse (4);
614 }
615 
616 GDBRemoteCommunication::PacketResult
617 GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet)
618 {
619     // Packet format: "qUserName:%i" where %i is the uid
620     packet.SetFilePos(::strlen ("qUserName:"));
621     uint32_t uid = packet.GetU32 (UINT32_MAX);
622     if (uid != UINT32_MAX)
623     {
624         std::string name;
625         if (Host::GetUserName (uid, name))
626         {
627             StreamString response;
628             response.PutCStringAsRawHex8 (name.c_str());
629             return SendPacketNoLock (response.GetData(), response.GetSize());
630         }
631     }
632     return SendErrorResponse (5);
633 
634 }
635 
636 GDBRemoteCommunication::PacketResult
637 GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet)
638 {
639     // Packet format: "qGroupName:%i" where %i is the gid
640     packet.SetFilePos(::strlen ("qGroupName:"));
641     uint32_t gid = packet.GetU32 (UINT32_MAX);
642     if (gid != UINT32_MAX)
643     {
644         std::string name;
645         if (Host::GetGroupName (gid, name))
646         {
647             StreamString response;
648             response.PutCStringAsRawHex8 (name.c_str());
649             return SendPacketNoLock (response.GetData(), response.GetSize());
650         }
651     }
652     return SendErrorResponse (6);
653 }
654 
655 GDBRemoteCommunication::PacketResult
656 GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
657 {
658     packet.SetFilePos(::strlen ("qSpeedTest:"));
659 
660     std::string key;
661     std::string value;
662     bool success = packet.GetNameColonValue(key, value);
663     if (success && key.compare("response_size") == 0)
664     {
665         uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success);
666         if (success)
667         {
668             if (response_size == 0)
669                 return SendOKResponse();
670             StreamString response;
671             uint32_t bytes_left = response_size;
672             response.PutCString("data:");
673             while (bytes_left > 0)
674             {
675                 if (bytes_left >= 26)
676                 {
677                     response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
678                     bytes_left -= 26;
679                 }
680                 else
681                 {
682                     response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
683                     bytes_left = 0;
684                 }
685             }
686             return SendPacketNoLock (response.GetData(), response.GetSize());
687         }
688     }
689     return SendErrorResponse (7);
690 }
691 
692 
693 static void *
694 AcceptPortFromInferior (void *arg)
695 {
696     const char *connect_url = (const char *)arg;
697     ConnectionFileDescriptor file_conn;
698     Error error;
699     if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess)
700     {
701         char pid_str[256];
702         ::memset (pid_str, 0, sizeof(pid_str));
703         ConnectionStatus status;
704         const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), 0, status, NULL);
705         if (pid_str_len > 0)
706         {
707             int pid = atoi (pid_str);
708             return (void *)(intptr_t)pid;
709         }
710     }
711     return NULL;
712 }
713 //
714 //static bool
715 //WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
716 //{
717 //    const int time_delta_usecs = 100000;
718 //    const int num_retries = timeout_in_seconds/time_delta_usecs;
719 //    for (int i=0; i<num_retries; i++)
720 //    {
721 //        struct proc_bsdinfo bsd_info;
722 //        int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO,
723 //                                    (uint64_t) 0,
724 //                                    &bsd_info,
725 //                                    PROC_PIDTBSDINFO_SIZE);
726 //
727 //        switch (error)
728 //        {
729 //            case EINVAL:
730 //            case ENOTSUP:
731 //            case ESRCH:
732 //            case EPERM:
733 //                return false;
734 //
735 //            default:
736 //                break;
737 //
738 //            case 0:
739 //                if (bsd_info.pbi_status == SSTOP)
740 //                    return true;
741 //        }
742 //        ::usleep (time_delta_usecs);
743 //    }
744 //    return false;
745 //}
746 
747 GDBRemoteCommunication::PacketResult
748 GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet)
749 {
750     // The 'A' packet is the most over designed packet ever here with
751     // redundant argument indexes, redundant argument lengths and needed hex
752     // encoded argument string values. Really all that is needed is a comma
753     // separated hex encoded argument value list, but we will stay true to the
754     // documented version of the 'A' packet here...
755 
756     packet.SetFilePos(1); // Skip the 'A'
757     bool success = true;
758     while (success && packet.GetBytesLeft() > 0)
759     {
760         // Decode the decimal argument string length. This length is the
761         // number of hex nibbles in the argument string value.
762         const uint32_t arg_len = packet.GetU32(UINT32_MAX);
763         if (arg_len == UINT32_MAX)
764             success = false;
765         else
766         {
767             // Make sure the argument hex string length is followed by a comma
768             if (packet.GetChar() != ',')
769                 success = false;
770             else
771             {
772                 // Decode the argument index. We ignore this really becuase
773                 // who would really send down the arguments in a random order???
774                 const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
775                 if (arg_idx == UINT32_MAX)
776                     success = false;
777                 else
778                 {
779                     // Make sure the argument index is followed by a comma
780                     if (packet.GetChar() != ',')
781                         success = false;
782                     else
783                     {
784                         // Decode the argument string value from hex bytes
785                         // back into a UTF8 string and make sure the length
786                         // matches the one supplied in the packet
787                         std::string arg;
788                         if (packet.GetHexByteString(arg) != (arg_len / 2))
789                             success = false;
790                         else
791                         {
792                             // If there are any bytes lft
793                             if (packet.GetBytesLeft())
794                             {
795                                 if (packet.GetChar() != ',')
796                                     success = false;
797                             }
798 
799                             if (success)
800                             {
801                                 if (arg_idx == 0)
802                                     m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
803                                 m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
804                             }
805                         }
806                     }
807                 }
808             }
809         }
810     }
811 
812     if (success)
813     {
814         // FIXME: remove linux restriction once eLaunchFlagDebug is supported
815 #if !defined (__linux__)
816         m_process_launch_info.GetFlags().Set (eLaunchFlagDebug);
817 #endif
818         m_process_launch_error = LaunchProcess ();
819         if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
820         {
821             return SendOKResponse ();
822         }
823     }
824     return SendErrorResponse (8);
825 }
826 
827 GDBRemoteCommunication::PacketResult
828 GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet)
829 {
830     lldb::pid_t pid = m_process_launch_info.GetProcessID();
831     StreamString response;
832     response.Printf("QC%" PRIx64, pid);
833     if (m_is_platform)
834     {
835         // If we launch a process and this GDB server is acting as a platform,
836         // then we need to clear the process launch state so we can start
837         // launching another process. In order to launch a process a bunch or
838         // packets need to be sent: environment packets, working directory,
839         // disable ASLR, and many more settings. When we launch a process we
840         // then need to know when to clear this information. Currently we are
841         // selecting the 'qC' packet as that packet which seems to make the most
842         // sense.
843         if (pid != LLDB_INVALID_PROCESS_ID)
844         {
845             m_process_launch_info.Clear();
846         }
847     }
848     return SendPacketNoLock (response.GetData(), response.GetSize());
849 }
850 
851 bool
852 GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid)
853 {
854     Mutex::Locker locker (m_spawned_pids_mutex);
855     FreePortForProcess(pid);
856     return m_spawned_pids.erase(pid) > 0;
857 }
858 bool
859 GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton,
860                                                       lldb::pid_t pid,
861                                                       bool exited,
862                                                       int signal,    // Zero for no signal
863                                                       int status)    // Exit value of process if signal is zero
864 {
865     GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
866     server->DebugserverProcessReaped (pid);
867     return true;
868 }
869 
870 bool
871 GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid)
872 {
873     // reap a process that we were debugging (but not debugserver)
874     Mutex::Locker locker (m_spawned_pids_mutex);
875     return m_spawned_pids.erase(pid) > 0;
876 }
877 
878 bool
879 GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton,
880                                                    lldb::pid_t pid,
881                                                    bool exited,
882                                                    int signal,    // Zero for no signal
883                                                    int status)    // Exit value of process if signal is zero
884 {
885     GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
886     server->DebuggedProcessReaped (pid);
887     return true;
888 }
889 
890 GDBRemoteCommunication::PacketResult
891 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
892 {
893 #ifdef _WIN32
894     return SendErrorResponse(9);
895 #else
896     // Spawn a local debugserver as a platform so we can then attach or launch
897     // a process...
898 
899     if (m_is_platform)
900     {
901         // Sleep and wait a bit for debugserver to start to listen...
902         ConnectionFileDescriptor file_conn;
903         Error error;
904         std::string hostname;
905         // TODO: /tmp/ should not be hardcoded. User might want to override /tmp
906         // with the TMPDIR environnement variable
907         packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
908         std::string name;
909         std::string value;
910         uint16_t port = UINT16_MAX;
911         while (packet.GetNameColonValue(name, value))
912         {
913             if (name.compare ("host") == 0)
914                 hostname.swap(value);
915             else if (name.compare ("port") == 0)
916                 port = Args::StringToUInt32(value.c_str(), 0, 0);
917         }
918         if (port == UINT16_MAX)
919             port = GetNextAvailablePort();
920 
921         // Spawn a new thread to accept the port that gets bound after
922         // binding to port 0 (zero).
923 
924         if (error.Success())
925         {
926             // Spawn a debugserver and try to get the port it listens to.
927             ProcessLaunchInfo debugserver_launch_info;
928             if (hostname.empty())
929                 hostname = "localhost";
930             Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
931             if (log)
932                 log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
933 
934             debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
935 
936             error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
937                                              port,
938                                              debugserver_launch_info,
939                                              port);
940 
941             lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
942 
943 
944             if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
945             {
946                 Mutex::Locker locker (m_spawned_pids_mutex);
947                 m_spawned_pids.insert(debugserver_pid);
948                 if (port > 0)
949                     AssociatePortWithProcess(port, debugserver_pid);
950             }
951             else
952             {
953                 if (port > 0)
954                     FreePort (port);
955             }
956 
957             if (error.Success())
958             {
959                 char response[256];
960                 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
961                 assert (response_len < sizeof(response));
962                 PacketResult packet_result = SendPacketNoLock (response, response_len);
963 
964                 if (packet_result != PacketResult::Success)
965                 {
966                     if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
967                         ::kill (debugserver_pid, SIGINT);
968                 }
969                 return packet_result;
970             }
971         }
972     }
973     return SendErrorResponse (9);
974 #endif
975 }
976 
977 bool
978 GDBRemoteCommunicationServer::KillSpawnedProcess (lldb::pid_t pid)
979 {
980     // make sure we know about this process
981     {
982         Mutex::Locker locker (m_spawned_pids_mutex);
983         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
984             return false;
985     }
986 
987     // first try a SIGTERM (standard kill)
988     Host::Kill (pid, SIGTERM);
989 
990     // check if that worked
991     for (size_t i=0; i<10; ++i)
992     {
993         {
994             Mutex::Locker locker (m_spawned_pids_mutex);
995             if (m_spawned_pids.find(pid) == m_spawned_pids.end())
996             {
997                 // it is now killed
998                 return true;
999             }
1000         }
1001         usleep (10000);
1002     }
1003 
1004     // check one more time after the final usleep
1005     {
1006         Mutex::Locker locker (m_spawned_pids_mutex);
1007         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1008             return true;
1009     }
1010 
1011     // the launched process still lives.  Now try killling it again,
1012     // this time with an unblockable signal.
1013     Host::Kill (pid, SIGKILL);
1014 
1015     for (size_t i=0; i<10; ++i)
1016     {
1017         {
1018             Mutex::Locker locker (m_spawned_pids_mutex);
1019             if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1020             {
1021                 // it is now killed
1022                 return true;
1023             }
1024         }
1025         usleep (10000);
1026     }
1027 
1028     // check one more time after the final usleep
1029     // Scope for locker
1030     {
1031         Mutex::Locker locker (m_spawned_pids_mutex);
1032         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1033             return true;
1034     }
1035 
1036     // no luck - the process still lives
1037     return false;
1038 }
1039 
1040 GDBRemoteCommunication::PacketResult
1041 GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
1042 {
1043     packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
1044 
1045     lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
1046 
1047     // verify that we know anything about this pid.
1048     // Scope for locker
1049     {
1050         Mutex::Locker locker (m_spawned_pids_mutex);
1051         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1052         {
1053             // not a pid we know about
1054             return SendErrorResponse (10);
1055         }
1056     }
1057 
1058     // go ahead and attempt to kill the spawned process
1059     if (KillSpawnedProcess (pid))
1060         return SendOKResponse ();
1061     else
1062         return SendErrorResponse (11);
1063 }
1064 
1065 GDBRemoteCommunication::PacketResult
1066 GDBRemoteCommunicationServer::Handle_k (StringExtractorGDBRemote &packet)
1067 {
1068     // ignore for now if we're lldb_platform
1069     if (m_is_platform)
1070         return SendUnimplementedResponse (packet.GetStringRef().c_str());
1071 
1072     // shutdown all spawned processes
1073     std::set<lldb::pid_t> spawned_pids_copy;
1074 
1075     // copy pids
1076     {
1077         Mutex::Locker locker (m_spawned_pids_mutex);
1078         spawned_pids_copy.insert (m_spawned_pids.begin (), m_spawned_pids.end ());
1079     }
1080 
1081     // nuke the spawned processes
1082     for (auto it = spawned_pids_copy.begin (); it != spawned_pids_copy.end (); ++it)
1083     {
1084         lldb::pid_t spawned_pid = *it;
1085         if (!KillSpawnedProcess (spawned_pid))
1086         {
1087             fprintf (stderr, "%s: failed to kill spawned pid %" PRIu64 ", ignoring.\n", __FUNCTION__, spawned_pid);
1088         }
1089     }
1090 
1091     // TODO figure out how to shut down gracefully at this point
1092     return SendOKResponse ();
1093 }
1094 
1095 GDBRemoteCommunication::PacketResult
1096 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
1097 {
1098     if (m_process_launch_error.Success())
1099         return SendOKResponse();
1100     StreamString response;
1101     response.PutChar('E');
1102     response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
1103     return SendPacketNoLock (response.GetData(), response.GetSize());
1104 }
1105 
1106 GDBRemoteCommunication::PacketResult
1107 GDBRemoteCommunicationServer::Handle_QEnvironment  (StringExtractorGDBRemote &packet)
1108 {
1109     packet.SetFilePos(::strlen ("QEnvironment:"));
1110     const uint32_t bytes_left = packet.GetBytesLeft();
1111     if (bytes_left > 0)
1112     {
1113         m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
1114         return SendOKResponse ();
1115     }
1116     return SendErrorResponse (12);
1117 }
1118 
1119 GDBRemoteCommunication::PacketResult
1120 GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
1121 {
1122     packet.SetFilePos(::strlen ("QLaunchArch:"));
1123     const uint32_t bytes_left = packet.GetBytesLeft();
1124     if (bytes_left > 0)
1125     {
1126         const char* arch_triple = packet.Peek();
1127         ArchSpec arch_spec(arch_triple,NULL);
1128         m_process_launch_info.SetArchitecture(arch_spec);
1129         return SendOKResponse();
1130     }
1131     return SendErrorResponse(13);
1132 }
1133 
1134 GDBRemoteCommunication::PacketResult
1135 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
1136 {
1137     packet.SetFilePos(::strlen ("QSetDisableASLR:"));
1138     if (packet.GetU32(0))
1139         m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
1140     else
1141         m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
1142     return SendOKResponse ();
1143 }
1144 
1145 GDBRemoteCommunication::PacketResult
1146 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
1147 {
1148     packet.SetFilePos(::strlen ("QSetWorkingDir:"));
1149     std::string path;
1150     packet.GetHexByteString(path);
1151     if (m_is_platform)
1152     {
1153 #ifdef _WIN32
1154         // Not implemented on Windows
1155         return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_QSetWorkingDir unimplemented");
1156 #else
1157         // If this packet is sent to a platform, then change the current working directory
1158         if (::chdir(path.c_str()) != 0)
1159             return SendErrorResponse(errno);
1160 #endif
1161     }
1162     else
1163     {
1164         m_process_launch_info.SwapWorkingDirectory (path);
1165     }
1166     return SendOKResponse ();
1167 }
1168 
1169 GDBRemoteCommunication::PacketResult
1170 GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
1171 {
1172     StreamString response;
1173 
1174     if (m_is_platform)
1175     {
1176         // If this packet is sent to a platform, then change the current working directory
1177         char cwd[PATH_MAX];
1178         if (getcwd(cwd, sizeof(cwd)) == NULL)
1179         {
1180             return SendErrorResponse(errno);
1181         }
1182         else
1183         {
1184             response.PutBytesAsRawHex8(cwd, strlen(cwd));
1185             return SendPacketNoLock(response.GetData(), response.GetSize());
1186         }
1187     }
1188     else
1189     {
1190         const char *working_dir = m_process_launch_info.GetWorkingDirectory();
1191         if (working_dir && working_dir[0])
1192         {
1193             response.PutBytesAsRawHex8(working_dir, strlen(working_dir));
1194             return SendPacketNoLock(response.GetData(), response.GetSize());
1195         }
1196         else
1197         {
1198             return SendErrorResponse(14);
1199         }
1200     }
1201 }
1202 
1203 GDBRemoteCommunication::PacketResult
1204 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
1205 {
1206     packet.SetFilePos(::strlen ("QSetSTDIN:"));
1207     ProcessLaunchInfo::FileAction file_action;
1208     std::string path;
1209     packet.GetHexByteString(path);
1210     const bool read = false;
1211     const bool write = true;
1212     if (file_action.Open(STDIN_FILENO, path.c_str(), read, write))
1213     {
1214         m_process_launch_info.AppendFileAction(file_action);
1215         return SendOKResponse ();
1216     }
1217     return SendErrorResponse (15);
1218 }
1219 
1220 GDBRemoteCommunication::PacketResult
1221 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
1222 {
1223     packet.SetFilePos(::strlen ("QSetSTDOUT:"));
1224     ProcessLaunchInfo::FileAction file_action;
1225     std::string path;
1226     packet.GetHexByteString(path);
1227     const bool read = true;
1228     const bool write = false;
1229     if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write))
1230     {
1231         m_process_launch_info.AppendFileAction(file_action);
1232         return SendOKResponse ();
1233     }
1234     return SendErrorResponse (16);
1235 }
1236 
1237 GDBRemoteCommunication::PacketResult
1238 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
1239 {
1240     packet.SetFilePos(::strlen ("QSetSTDERR:"));
1241     ProcessLaunchInfo::FileAction file_action;
1242     std::string path;
1243     packet.GetHexByteString(path);
1244     const bool read = true;
1245     const bool write = false;
1246     if (file_action.Open(STDERR_FILENO, path.c_str(), read, write))
1247     {
1248         m_process_launch_info.AppendFileAction(file_action);
1249         return SendOKResponse ();
1250     }
1251     return SendErrorResponse (17);
1252 }
1253 
1254 GDBRemoteCommunication::PacketResult
1255 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
1256 {
1257     // Send response first before changing m_send_acks to we ack this packet
1258     PacketResult packet_result = SendOKResponse ();
1259     m_send_acks = false;
1260     return packet_result;
1261 }
1262 
1263 GDBRemoteCommunication::PacketResult
1264 GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
1265 {
1266     packet.SetFilePos(::strlen("qPlatform_mkdir:"));
1267     mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
1268     if (packet.GetChar() == ',')
1269     {
1270         std::string path;
1271         packet.GetHexByteString(path);
1272         Error error = Host::MakeDirectory(path.c_str(),mode);
1273         if (error.Success())
1274             return SendPacketNoLock ("OK", 2);
1275         else
1276             return SendErrorResponse(error.GetError());
1277     }
1278     return SendErrorResponse(20);
1279 }
1280 
1281 GDBRemoteCommunication::PacketResult
1282 GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
1283 {
1284     packet.SetFilePos(::strlen("qPlatform_chmod:"));
1285 
1286     mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
1287     if (packet.GetChar() == ',')
1288     {
1289         std::string path;
1290         packet.GetHexByteString(path);
1291         Error error = Host::SetFilePermissions (path.c_str(), mode);
1292         if (error.Success())
1293             return SendPacketNoLock ("OK", 2);
1294         else
1295             return SendErrorResponse(error.GetError());
1296     }
1297     return SendErrorResponse(19);
1298 }
1299 
1300 GDBRemoteCommunication::PacketResult
1301 GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet)
1302 {
1303     packet.SetFilePos(::strlen("vFile:open:"));
1304     std::string path;
1305     packet.GetHexByteStringTerminatedBy(path,',');
1306     if (!path.empty())
1307     {
1308         if (packet.GetChar() == ',')
1309         {
1310             uint32_t flags = packet.GetHexMaxU32(false, 0);
1311             if (packet.GetChar() == ',')
1312             {
1313                 mode_t mode = packet.GetHexMaxU32(false, 0600);
1314                 Error error;
1315                 int fd = ::open (path.c_str(), flags, mode);
1316                 const int save_errno = fd == -1 ? errno : 0;
1317                 StreamString response;
1318                 response.PutChar('F');
1319                 response.Printf("%i", fd);
1320                 if (save_errno)
1321                     response.Printf(",%i", save_errno);
1322                 return SendPacketNoLock(response.GetData(), response.GetSize());
1323             }
1324         }
1325     }
1326     return SendErrorResponse(18);
1327 }
1328 
1329 GDBRemoteCommunication::PacketResult
1330 GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet)
1331 {
1332     packet.SetFilePos(::strlen("vFile:close:"));
1333     int fd = packet.GetS32(-1);
1334     Error error;
1335     int err = -1;
1336     int save_errno = 0;
1337     if (fd >= 0)
1338     {
1339         err = close(fd);
1340         save_errno = err == -1 ? errno : 0;
1341     }
1342     else
1343     {
1344         save_errno = EINVAL;
1345     }
1346     StreamString response;
1347     response.PutChar('F');
1348     response.Printf("%i", err);
1349     if (save_errno)
1350         response.Printf(",%i", save_errno);
1351     return SendPacketNoLock(response.GetData(), response.GetSize());
1352 }
1353 
1354 GDBRemoteCommunication::PacketResult
1355 GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
1356 {
1357 #ifdef _WIN32
1358     // Not implemented on Windows
1359     return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented");
1360 #else
1361     StreamGDBRemote response;
1362     packet.SetFilePos(::strlen("vFile:pread:"));
1363     int fd = packet.GetS32(-1);
1364     if (packet.GetChar() == ',')
1365     {
1366         uint64_t count = packet.GetU64(UINT64_MAX);
1367         if (packet.GetChar() == ',')
1368         {
1369             uint64_t offset = packet.GetU64(UINT32_MAX);
1370             if (count == UINT64_MAX)
1371             {
1372                 response.Printf("F-1:%i", EINVAL);
1373                 return SendPacketNoLock(response.GetData(), response.GetSize());
1374             }
1375 
1376             std::string buffer(count, 0);
1377             const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
1378             const int save_errno = bytes_read == -1 ? errno : 0;
1379             response.PutChar('F');
1380             response.Printf("%zi", bytes_read);
1381             if (save_errno)
1382                 response.Printf(",%i", save_errno);
1383             else
1384             {
1385                 response.PutChar(';');
1386                 response.PutEscapedBytes(&buffer[0], bytes_read);
1387             }
1388             return SendPacketNoLock(response.GetData(), response.GetSize());
1389         }
1390     }
1391     return SendErrorResponse(21);
1392 
1393 #endif
1394 }
1395 
1396 GDBRemoteCommunication::PacketResult
1397 GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
1398 {
1399 #ifdef _WIN32
1400     return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pWrite() unimplemented");
1401 #else
1402     packet.SetFilePos(::strlen("vFile:pwrite:"));
1403 
1404     StreamGDBRemote response;
1405     response.PutChar('F');
1406 
1407     int fd = packet.GetU32(UINT32_MAX);
1408     if (packet.GetChar() == ',')
1409     {
1410         off_t offset = packet.GetU64(UINT32_MAX);
1411         if (packet.GetChar() == ',')
1412         {
1413             std::string buffer;
1414             if (packet.GetEscapedBinaryData(buffer))
1415             {
1416                 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset);
1417                 const int save_errno = bytes_written == -1 ? errno : 0;
1418                 response.Printf("%zi", bytes_written);
1419                 if (save_errno)
1420                     response.Printf(",%i", save_errno);
1421             }
1422             else
1423             {
1424                 response.Printf ("-1,%i", EINVAL);
1425             }
1426             return SendPacketNoLock(response.GetData(), response.GetSize());
1427         }
1428     }
1429     return SendErrorResponse(27);
1430 #endif
1431 }
1432 
1433 GDBRemoteCommunication::PacketResult
1434 GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet)
1435 {
1436     packet.SetFilePos(::strlen("vFile:size:"));
1437     std::string path;
1438     packet.GetHexByteString(path);
1439     if (!path.empty())
1440     {
1441         lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false));
1442         StreamString response;
1443         response.PutChar('F');
1444         response.PutHex64(retcode);
1445         if (retcode == UINT64_MAX)
1446         {
1447             response.PutChar(',');
1448             response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode()
1449         }
1450         return SendPacketNoLock(response.GetData(), response.GetSize());
1451     }
1452     return SendErrorResponse(22);
1453 }
1454 
1455 GDBRemoteCommunication::PacketResult
1456 GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
1457 {
1458     packet.SetFilePos(::strlen("vFile:mode:"));
1459     std::string path;
1460     packet.GetHexByteString(path);
1461     if (!path.empty())
1462     {
1463         Error error;
1464         const uint32_t mode = File::GetPermissions(path.c_str(), error);
1465         StreamString response;
1466         response.Printf("F%u", mode);
1467         if (mode == 0 || error.Fail())
1468             response.Printf(",%i", (int)error.GetError());
1469         return SendPacketNoLock(response.GetData(), response.GetSize());
1470     }
1471     return SendErrorResponse(23);
1472 }
1473 
1474 GDBRemoteCommunication::PacketResult
1475 GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
1476 {
1477     packet.SetFilePos(::strlen("vFile:exists:"));
1478     std::string path;
1479     packet.GetHexByteString(path);
1480     if (!path.empty())
1481     {
1482         bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false));
1483         StreamString response;
1484         response.PutChar('F');
1485         response.PutChar(',');
1486         if (retcode)
1487             response.PutChar('1');
1488         else
1489             response.PutChar('0');
1490         return SendPacketNoLock(response.GetData(), response.GetSize());
1491     }
1492     return SendErrorResponse(24);
1493 }
1494 
1495 GDBRemoteCommunication::PacketResult
1496 GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
1497 {
1498     packet.SetFilePos(::strlen("vFile:symlink:"));
1499     std::string dst, src;
1500     packet.GetHexByteStringTerminatedBy(dst, ',');
1501     packet.GetChar(); // Skip ',' char
1502     packet.GetHexByteString(src);
1503     Error error = Host::Symlink(src.c_str(), dst.c_str());
1504     StreamString response;
1505     response.Printf("F%u,%u", error.GetError(), error.GetError());
1506     return SendPacketNoLock(response.GetData(), response.GetSize());
1507 }
1508 
1509 GDBRemoteCommunication::PacketResult
1510 GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
1511 {
1512     packet.SetFilePos(::strlen("vFile:unlink:"));
1513     std::string path;
1514     packet.GetHexByteString(path);
1515     Error error = Host::Unlink(path.c_str());
1516     StreamString response;
1517     response.Printf("F%u,%u", error.GetError(), error.GetError());
1518     return SendPacketNoLock(response.GetData(), response.GetSize());
1519 }
1520 
1521 GDBRemoteCommunication::PacketResult
1522 GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
1523 {
1524     packet.SetFilePos(::strlen("qPlatform_shell:"));
1525     std::string path;
1526     std::string working_dir;
1527     packet.GetHexByteStringTerminatedBy(path,',');
1528     if (!path.empty())
1529     {
1530         if (packet.GetChar() == ',')
1531         {
1532             // FIXME: add timeout to qPlatform_shell packet
1533             // uint32_t timeout = packet.GetHexMaxU32(false, 32);
1534             uint32_t timeout = 10;
1535             if (packet.GetChar() == ',')
1536                 packet.GetHexByteString(working_dir);
1537             int status, signo;
1538             std::string output;
1539             Error err = Host::RunShellCommand(path.c_str(),
1540                                               working_dir.empty() ? NULL : working_dir.c_str(),
1541                                               &status, &signo, &output, timeout);
1542             StreamGDBRemote response;
1543             if (err.Fail())
1544             {
1545                 response.PutCString("F,");
1546                 response.PutHex32(UINT32_MAX);
1547             }
1548             else
1549             {
1550                 response.PutCString("F,");
1551                 response.PutHex32(status);
1552                 response.PutChar(',');
1553                 response.PutHex32(signo);
1554                 response.PutChar(',');
1555                 response.PutEscapedBytes(output.c_str(), output.size());
1556             }
1557             return SendPacketNoLock(response.GetData(), response.GetSize());
1558         }
1559     }
1560     return SendErrorResponse(24);
1561 }
1562 
1563 GDBRemoteCommunication::PacketResult
1564 GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
1565 {
1566     return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_Stat() unimplemented");
1567 }
1568 
1569 GDBRemoteCommunication::PacketResult
1570 GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
1571 {
1572     packet.SetFilePos(::strlen("vFile:MD5:"));
1573     std::string path;
1574     packet.GetHexByteString(path);
1575     if (!path.empty())
1576     {
1577         uint64_t a,b;
1578         StreamGDBRemote response;
1579         if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false)
1580         {
1581             response.PutCString("F,");
1582             response.PutCString("x");
1583         }
1584         else
1585         {
1586             response.PutCString("F,");
1587             response.PutHex64(a);
1588             response.PutHex64(b);
1589         }
1590         return SendPacketNoLock(response.GetData(), response.GetSize());
1591     }
1592     return SendErrorResponse(25);
1593 }
1594 
1595