xref: /llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (revision 3e92a2b013c320ed2b2f6fc183a023fb3b657869)
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         m_process_launch_info.GetFlags().Set (eLaunchFlagDebug);
815         m_process_launch_error = Host::LaunchProcess (m_process_launch_info);
816         if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
817         {
818             return SendOKResponse ();
819         }
820     }
821     return SendErrorResponse (8);
822 }
823 
824 GDBRemoteCommunication::PacketResult
825 GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet)
826 {
827     lldb::pid_t pid = m_process_launch_info.GetProcessID();
828     StreamString response;
829     response.Printf("QC%" PRIx64, pid);
830     if (m_is_platform)
831     {
832         // If we launch a process and this GDB server is acting as a platform,
833         // then we need to clear the process launch state so we can start
834         // launching another process. In order to launch a process a bunch or
835         // packets need to be sent: environment packets, working directory,
836         // disable ASLR, and many more settings. When we launch a process we
837         // then need to know when to clear this information. Currently we are
838         // selecting the 'qC' packet as that packet which seems to make the most
839         // sense.
840         if (pid != LLDB_INVALID_PROCESS_ID)
841         {
842             m_process_launch_info.Clear();
843         }
844     }
845     return SendPacketNoLock (response.GetData(), response.GetSize());
846 }
847 
848 bool
849 GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid)
850 {
851     Mutex::Locker locker (m_spawned_pids_mutex);
852     FreePortForProcess(pid);
853     return m_spawned_pids.erase(pid) > 0;
854 }
855 bool
856 GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton,
857                                                       lldb::pid_t pid,
858                                                       bool exited,
859                                                       int signal,    // Zero for no signal
860                                                       int status)    // Exit value of process if signal is zero
861 {
862     GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
863     server->DebugserverProcessReaped (pid);
864     return true;
865 }
866 
867 bool
868 GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid)
869 {
870     // reap a process that we were debugging (but not debugserver)
871     Mutex::Locker locker (m_spawned_pids_mutex);
872     return m_spawned_pids.erase(pid) > 0;
873 }
874 
875 bool
876 GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton,
877                                                    lldb::pid_t pid,
878                                                    bool exited,
879                                                    int signal,    // Zero for no signal
880                                                    int status)    // Exit value of process if signal is zero
881 {
882     GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
883     server->DebuggedProcessReaped (pid);
884     return true;
885 }
886 
887 GDBRemoteCommunication::PacketResult
888 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
889 {
890 #ifdef _WIN32
891     return SendErrorResponse(9);
892 #else
893     // Spawn a local debugserver as a platform so we can then attach or launch
894     // a process...
895 
896     if (m_is_platform)
897     {
898         // Sleep and wait a bit for debugserver to start to listen...
899         ConnectionFileDescriptor file_conn;
900         Error error;
901         std::string hostname;
902         // TODO: /tmp/ should not be hardcoded. User might want to override /tmp
903         // with the TMPDIR environnement variable
904         packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
905         std::string name;
906         std::string value;
907         uint16_t port = UINT16_MAX;
908         while (packet.GetNameColonValue(name, value))
909         {
910             if (name.compare ("host") == 0)
911                 hostname.swap(value);
912             else if (name.compare ("port") == 0)
913                 port = Args::StringToUInt32(value.c_str(), 0, 0);
914         }
915         if (port == UINT16_MAX)
916             port = GetNextAvailablePort();
917 
918         // Spawn a new thread to accept the port that gets bound after
919         // binding to port 0 (zero).
920 
921         if (error.Success())
922         {
923             // Spawn a debugserver and try to get the port it listens to.
924             ProcessLaunchInfo debugserver_launch_info;
925             if (hostname.empty())
926                 hostname = "localhost";
927             Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
928             if (log)
929                 log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
930 
931             debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
932 
933             error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
934                                              port,
935                                              debugserver_launch_info,
936                                              port);
937 
938             lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
939 
940 
941             if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
942             {
943                 Mutex::Locker locker (m_spawned_pids_mutex);
944                 m_spawned_pids.insert(debugserver_pid);
945                 if (port > 0)
946                     AssociatePortWithProcess(port, debugserver_pid);
947             }
948             else
949             {
950                 if (port > 0)
951                     FreePort (port);
952             }
953 
954             if (error.Success())
955             {
956                 char response[256];
957                 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
958                 assert (response_len < sizeof(response));
959                 PacketResult packet_result = SendPacketNoLock (response, response_len);
960 
961                 if (packet_result != PacketResult::Success)
962                 {
963                     if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
964                         ::kill (debugserver_pid, SIGINT);
965                 }
966                 return packet_result;
967             }
968         }
969     }
970     return SendErrorResponse (9);
971 #endif
972 }
973 
974 bool
975 GDBRemoteCommunicationServer::KillSpawnedProcess (lldb::pid_t pid)
976 {
977     // make sure we know about this process
978     {
979         Mutex::Locker locker (m_spawned_pids_mutex);
980         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
981             return false;
982     }
983 
984     // first try a SIGTERM (standard kill)
985     Host::Kill (pid, SIGTERM);
986 
987     // check if that worked
988     for (size_t i=0; i<10; ++i)
989     {
990         {
991             Mutex::Locker locker (m_spawned_pids_mutex);
992             if (m_spawned_pids.find(pid) == m_spawned_pids.end())
993             {
994                 // it is now killed
995                 return true;
996             }
997         }
998         usleep (10000);
999     }
1000 
1001     // check one more time after the final usleep
1002     {
1003         Mutex::Locker locker (m_spawned_pids_mutex);
1004         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1005             return true;
1006     }
1007 
1008     // the launched process still lives.  Now try killling it again,
1009     // this time with an unblockable signal.
1010     Host::Kill (pid, SIGKILL);
1011 
1012     for (size_t i=0; i<10; ++i)
1013     {
1014         {
1015             Mutex::Locker locker (m_spawned_pids_mutex);
1016             if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1017             {
1018                 // it is now killed
1019                 return true;
1020             }
1021         }
1022         usleep (10000);
1023     }
1024 
1025     // check one more time after the final usleep
1026     // Scope for locker
1027     {
1028         Mutex::Locker locker (m_spawned_pids_mutex);
1029         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1030             return true;
1031     }
1032 
1033     // no luck - the process still lives
1034     return false;
1035 }
1036 
1037 GDBRemoteCommunication::PacketResult
1038 GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
1039 {
1040     packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
1041 
1042     lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
1043 
1044     // verify that we know anything about this pid.
1045     // Scope for locker
1046     {
1047         Mutex::Locker locker (m_spawned_pids_mutex);
1048         if (m_spawned_pids.find(pid) == m_spawned_pids.end())
1049         {
1050             // not a pid we know about
1051             return SendErrorResponse (10);
1052         }
1053     }
1054 
1055     // go ahead and attempt to kill the spawned process
1056     if (KillSpawnedProcess (pid))
1057         return SendOKResponse ();
1058     else
1059         return SendErrorResponse (11);
1060 }
1061 
1062 GDBRemoteCommunication::PacketResult
1063 GDBRemoteCommunicationServer::Handle_k (StringExtractorGDBRemote &packet)
1064 {
1065     // ignore for now if we're lldb_platform
1066     if (m_is_platform)
1067         return SendUnimplementedResponse (packet.GetStringRef().c_str());
1068 
1069     // shutdown all spawned processes
1070     std::set<lldb::pid_t> spawned_pids_copy;
1071 
1072     // copy pids
1073     {
1074         Mutex::Locker locker (m_spawned_pids_mutex);
1075         spawned_pids_copy.insert (m_spawned_pids.begin (), m_spawned_pids.end ());
1076     }
1077 
1078     // nuke the spawned processes
1079     for (auto it = spawned_pids_copy.begin (); it != spawned_pids_copy.end (); ++it)
1080     {
1081         lldb::pid_t spawned_pid = *it;
1082         if (!KillSpawnedProcess (spawned_pid))
1083         {
1084             fprintf (stderr, "%s: failed to kill spawned pid %" PRIu64 ", ignoring.\n", __FUNCTION__, spawned_pid);
1085         }
1086     }
1087 
1088     // TODO figure out how to shut down gracefully at this point
1089     return SendOKResponse ();
1090 }
1091 
1092 GDBRemoteCommunication::PacketResult
1093 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
1094 {
1095     if (m_process_launch_error.Success())
1096         return SendOKResponse();
1097     StreamString response;
1098     response.PutChar('E');
1099     response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
1100     return SendPacketNoLock (response.GetData(), response.GetSize());
1101 }
1102 
1103 GDBRemoteCommunication::PacketResult
1104 GDBRemoteCommunicationServer::Handle_QEnvironment  (StringExtractorGDBRemote &packet)
1105 {
1106     packet.SetFilePos(::strlen ("QEnvironment:"));
1107     const uint32_t bytes_left = packet.GetBytesLeft();
1108     if (bytes_left > 0)
1109     {
1110         m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
1111         return SendOKResponse ();
1112     }
1113     return SendErrorResponse (12);
1114 }
1115 
1116 GDBRemoteCommunication::PacketResult
1117 GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
1118 {
1119     packet.SetFilePos(::strlen ("QLaunchArch:"));
1120     const uint32_t bytes_left = packet.GetBytesLeft();
1121     if (bytes_left > 0)
1122     {
1123         const char* arch_triple = packet.Peek();
1124         ArchSpec arch_spec(arch_triple,NULL);
1125         m_process_launch_info.SetArchitecture(arch_spec);
1126         return SendOKResponse();
1127     }
1128     return SendErrorResponse(13);
1129 }
1130 
1131 GDBRemoteCommunication::PacketResult
1132 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
1133 {
1134     packet.SetFilePos(::strlen ("QSetDisableASLR:"));
1135     if (packet.GetU32(0))
1136         m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
1137     else
1138         m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
1139     return SendOKResponse ();
1140 }
1141 
1142 GDBRemoteCommunication::PacketResult
1143 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
1144 {
1145     packet.SetFilePos(::strlen ("QSetWorkingDir:"));
1146     std::string path;
1147     packet.GetHexByteString(path);
1148     if (m_is_platform)
1149     {
1150 #ifdef _WIN32
1151         // Not implemented on Windows
1152         return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_QSetWorkingDir unimplemented");
1153 #else
1154         // If this packet is sent to a platform, then change the current working directory
1155         if (::chdir(path.c_str()) != 0)
1156             return SendErrorResponse(errno);
1157 #endif
1158     }
1159     else
1160     {
1161         m_process_launch_info.SwapWorkingDirectory (path);
1162     }
1163     return SendOKResponse ();
1164 }
1165 
1166 GDBRemoteCommunication::PacketResult
1167 GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
1168 {
1169     StreamString response;
1170 
1171     if (m_is_platform)
1172     {
1173         // If this packet is sent to a platform, then change the current working directory
1174         char cwd[PATH_MAX];
1175         if (getcwd(cwd, sizeof(cwd)) == NULL)
1176         {
1177             return SendErrorResponse(errno);
1178         }
1179         else
1180         {
1181             response.PutBytesAsRawHex8(cwd, strlen(cwd));
1182             return SendPacketNoLock(response.GetData(), response.GetSize());
1183         }
1184     }
1185     else
1186     {
1187         const char *working_dir = m_process_launch_info.GetWorkingDirectory();
1188         if (working_dir && working_dir[0])
1189         {
1190             response.PutBytesAsRawHex8(working_dir, strlen(working_dir));
1191             return SendPacketNoLock(response.GetData(), response.GetSize());
1192         }
1193         else
1194         {
1195             return SendErrorResponse(14);
1196         }
1197     }
1198 }
1199 
1200 GDBRemoteCommunication::PacketResult
1201 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
1202 {
1203     packet.SetFilePos(::strlen ("QSetSTDIN:"));
1204     ProcessLaunchInfo::FileAction file_action;
1205     std::string path;
1206     packet.GetHexByteString(path);
1207     const bool read = false;
1208     const bool write = true;
1209     if (file_action.Open(STDIN_FILENO, path.c_str(), read, write))
1210     {
1211         m_process_launch_info.AppendFileAction(file_action);
1212         return SendOKResponse ();
1213     }
1214     return SendErrorResponse (15);
1215 }
1216 
1217 GDBRemoteCommunication::PacketResult
1218 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
1219 {
1220     packet.SetFilePos(::strlen ("QSetSTDOUT:"));
1221     ProcessLaunchInfo::FileAction file_action;
1222     std::string path;
1223     packet.GetHexByteString(path);
1224     const bool read = true;
1225     const bool write = false;
1226     if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write))
1227     {
1228         m_process_launch_info.AppendFileAction(file_action);
1229         return SendOKResponse ();
1230     }
1231     return SendErrorResponse (16);
1232 }
1233 
1234 GDBRemoteCommunication::PacketResult
1235 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
1236 {
1237     packet.SetFilePos(::strlen ("QSetSTDERR:"));
1238     ProcessLaunchInfo::FileAction file_action;
1239     std::string path;
1240     packet.GetHexByteString(path);
1241     const bool read = true;
1242     const bool write = false;
1243     if (file_action.Open(STDERR_FILENO, path.c_str(), read, write))
1244     {
1245         m_process_launch_info.AppendFileAction(file_action);
1246         return SendOKResponse ();
1247     }
1248     return SendErrorResponse (17);
1249 }
1250 
1251 GDBRemoteCommunication::PacketResult
1252 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
1253 {
1254     // Send response first before changing m_send_acks to we ack this packet
1255     PacketResult packet_result = SendOKResponse ();
1256     m_send_acks = false;
1257     return packet_result;
1258 }
1259 
1260 GDBRemoteCommunication::PacketResult
1261 GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
1262 {
1263     packet.SetFilePos(::strlen("qPlatform_mkdir:"));
1264     mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
1265     if (packet.GetChar() == ',')
1266     {
1267         std::string path;
1268         packet.GetHexByteString(path);
1269         Error error = Host::MakeDirectory(path.c_str(),mode);
1270         if (error.Success())
1271             return SendPacketNoLock ("OK", 2);
1272         else
1273             return SendErrorResponse(error.GetError());
1274     }
1275     return SendErrorResponse(20);
1276 }
1277 
1278 GDBRemoteCommunication::PacketResult
1279 GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
1280 {
1281     packet.SetFilePos(::strlen("qPlatform_chmod:"));
1282 
1283     mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
1284     if (packet.GetChar() == ',')
1285     {
1286         std::string path;
1287         packet.GetHexByteString(path);
1288         Error error = Host::SetFilePermissions (path.c_str(), mode);
1289         if (error.Success())
1290             return SendPacketNoLock ("OK", 2);
1291         else
1292             return SendErrorResponse(error.GetError());
1293     }
1294     return SendErrorResponse(19);
1295 }
1296 
1297 GDBRemoteCommunication::PacketResult
1298 GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet)
1299 {
1300     packet.SetFilePos(::strlen("vFile:open:"));
1301     std::string path;
1302     packet.GetHexByteStringTerminatedBy(path,',');
1303     if (!path.empty())
1304     {
1305         if (packet.GetChar() == ',')
1306         {
1307             uint32_t flags = packet.GetHexMaxU32(false, 0);
1308             if (packet.GetChar() == ',')
1309             {
1310                 mode_t mode = packet.GetHexMaxU32(false, 0600);
1311                 Error error;
1312                 int fd = ::open (path.c_str(), flags, mode);
1313                 const int save_errno = fd == -1 ? errno : 0;
1314                 StreamString response;
1315                 response.PutChar('F');
1316                 response.Printf("%i", fd);
1317                 if (save_errno)
1318                     response.Printf(",%i", save_errno);
1319                 return SendPacketNoLock(response.GetData(), response.GetSize());
1320             }
1321         }
1322     }
1323     return SendErrorResponse(18);
1324 }
1325 
1326 GDBRemoteCommunication::PacketResult
1327 GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet)
1328 {
1329     packet.SetFilePos(::strlen("vFile:close:"));
1330     int fd = packet.GetS32(-1);
1331     Error error;
1332     int err = -1;
1333     int save_errno = 0;
1334     if (fd >= 0)
1335     {
1336         err = close(fd);
1337         save_errno = err == -1 ? errno : 0;
1338     }
1339     else
1340     {
1341         save_errno = EINVAL;
1342     }
1343     StreamString response;
1344     response.PutChar('F');
1345     response.Printf("%i", err);
1346     if (save_errno)
1347         response.Printf(",%i", save_errno);
1348     return SendPacketNoLock(response.GetData(), response.GetSize());
1349 }
1350 
1351 GDBRemoteCommunication::PacketResult
1352 GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
1353 {
1354 #ifdef _WIN32
1355     // Not implemented on Windows
1356     return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented");
1357 #else
1358     StreamGDBRemote response;
1359     packet.SetFilePos(::strlen("vFile:pread:"));
1360     int fd = packet.GetS32(-1);
1361     if (packet.GetChar() == ',')
1362     {
1363         uint64_t count = packet.GetU64(UINT64_MAX);
1364         if (packet.GetChar() == ',')
1365         {
1366             uint64_t offset = packet.GetU64(UINT32_MAX);
1367             if (count == UINT64_MAX)
1368             {
1369                 response.Printf("F-1:%i", EINVAL);
1370                 return SendPacketNoLock(response.GetData(), response.GetSize());
1371             }
1372 
1373             std::string buffer(count, 0);
1374             const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
1375             const int save_errno = bytes_read == -1 ? errno : 0;
1376             response.PutChar('F');
1377             response.Printf("%zi", bytes_read);
1378             if (save_errno)
1379                 response.Printf(",%i", save_errno);
1380             else
1381             {
1382                 response.PutChar(';');
1383                 response.PutEscapedBytes(&buffer[0], bytes_read);
1384             }
1385             return SendPacketNoLock(response.GetData(), response.GetSize());
1386         }
1387     }
1388     return SendErrorResponse(21);
1389 
1390 #endif
1391 }
1392 
1393 GDBRemoteCommunication::PacketResult
1394 GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
1395 {
1396 #ifdef _WIN32
1397     return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pWrite() unimplemented");
1398 #else
1399     packet.SetFilePos(::strlen("vFile:pwrite:"));
1400 
1401     StreamGDBRemote response;
1402     response.PutChar('F');
1403 
1404     int fd = packet.GetU32(UINT32_MAX);
1405     if (packet.GetChar() == ',')
1406     {
1407         off_t offset = packet.GetU64(UINT32_MAX);
1408         if (packet.GetChar() == ',')
1409         {
1410             std::string buffer;
1411             if (packet.GetEscapedBinaryData(buffer))
1412             {
1413                 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset);
1414                 const int save_errno = bytes_written == -1 ? errno : 0;
1415                 response.Printf("%zi", bytes_written);
1416                 if (save_errno)
1417                     response.Printf(",%i", save_errno);
1418             }
1419             else
1420             {
1421                 response.Printf ("-1,%i", EINVAL);
1422             }
1423             return SendPacketNoLock(response.GetData(), response.GetSize());
1424         }
1425     }
1426     return SendErrorResponse(27);
1427 #endif
1428 }
1429 
1430 GDBRemoteCommunication::PacketResult
1431 GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet)
1432 {
1433     packet.SetFilePos(::strlen("vFile:size:"));
1434     std::string path;
1435     packet.GetHexByteString(path);
1436     if (!path.empty())
1437     {
1438         lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false));
1439         StreamString response;
1440         response.PutChar('F');
1441         response.PutHex64(retcode);
1442         if (retcode == UINT64_MAX)
1443         {
1444             response.PutChar(',');
1445             response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode()
1446         }
1447         return SendPacketNoLock(response.GetData(), response.GetSize());
1448     }
1449     return SendErrorResponse(22);
1450 }
1451 
1452 GDBRemoteCommunication::PacketResult
1453 GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
1454 {
1455     packet.SetFilePos(::strlen("vFile:mode:"));
1456     std::string path;
1457     packet.GetHexByteString(path);
1458     if (!path.empty())
1459     {
1460         Error error;
1461         const uint32_t mode = File::GetPermissions(path.c_str(), error);
1462         StreamString response;
1463         response.Printf("F%u", mode);
1464         if (mode == 0 || error.Fail())
1465             response.Printf(",%i", (int)error.GetError());
1466         return SendPacketNoLock(response.GetData(), response.GetSize());
1467     }
1468     return SendErrorResponse(23);
1469 }
1470 
1471 GDBRemoteCommunication::PacketResult
1472 GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
1473 {
1474     packet.SetFilePos(::strlen("vFile:exists:"));
1475     std::string path;
1476     packet.GetHexByteString(path);
1477     if (!path.empty())
1478     {
1479         bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false));
1480         StreamString response;
1481         response.PutChar('F');
1482         response.PutChar(',');
1483         if (retcode)
1484             response.PutChar('1');
1485         else
1486             response.PutChar('0');
1487         return SendPacketNoLock(response.GetData(), response.GetSize());
1488     }
1489     return SendErrorResponse(24);
1490 }
1491 
1492 GDBRemoteCommunication::PacketResult
1493 GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
1494 {
1495     packet.SetFilePos(::strlen("vFile:symlink:"));
1496     std::string dst, src;
1497     packet.GetHexByteStringTerminatedBy(dst, ',');
1498     packet.GetChar(); // Skip ',' char
1499     packet.GetHexByteString(src);
1500     Error error = Host::Symlink(src.c_str(), dst.c_str());
1501     StreamString response;
1502     response.Printf("F%u,%u", error.GetError(), error.GetError());
1503     return SendPacketNoLock(response.GetData(), response.GetSize());
1504 }
1505 
1506 GDBRemoteCommunication::PacketResult
1507 GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
1508 {
1509     packet.SetFilePos(::strlen("vFile:unlink:"));
1510     std::string path;
1511     packet.GetHexByteString(path);
1512     Error error = Host::Unlink(path.c_str());
1513     StreamString response;
1514     response.Printf("F%u,%u", error.GetError(), error.GetError());
1515     return SendPacketNoLock(response.GetData(), response.GetSize());
1516 }
1517 
1518 GDBRemoteCommunication::PacketResult
1519 GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
1520 {
1521     packet.SetFilePos(::strlen("qPlatform_shell:"));
1522     std::string path;
1523     std::string working_dir;
1524     packet.GetHexByteStringTerminatedBy(path,',');
1525     if (!path.empty())
1526     {
1527         if (packet.GetChar() == ',')
1528         {
1529             // FIXME: add timeout to qPlatform_shell packet
1530             // uint32_t timeout = packet.GetHexMaxU32(false, 32);
1531             uint32_t timeout = 10;
1532             if (packet.GetChar() == ',')
1533                 packet.GetHexByteString(working_dir);
1534             int status, signo;
1535             std::string output;
1536             Error err = Host::RunShellCommand(path.c_str(),
1537                                               working_dir.empty() ? NULL : working_dir.c_str(),
1538                                               &status, &signo, &output, timeout);
1539             StreamGDBRemote response;
1540             if (err.Fail())
1541             {
1542                 response.PutCString("F,");
1543                 response.PutHex32(UINT32_MAX);
1544             }
1545             else
1546             {
1547                 response.PutCString("F,");
1548                 response.PutHex32(status);
1549                 response.PutChar(',');
1550                 response.PutHex32(signo);
1551                 response.PutChar(',');
1552                 response.PutEscapedBytes(output.c_str(), output.size());
1553             }
1554             return SendPacketNoLock(response.GetData(), response.GetSize());
1555         }
1556     }
1557     return SendErrorResponse(24);
1558 }
1559 
1560 GDBRemoteCommunication::PacketResult
1561 GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
1562 {
1563     return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_Stat() unimplemented");
1564 }
1565 
1566 GDBRemoteCommunication::PacketResult
1567 GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
1568 {
1569     packet.SetFilePos(::strlen("vFile:MD5:"));
1570     std::string path;
1571     packet.GetHexByteString(path);
1572     if (!path.empty())
1573     {
1574         uint64_t a,b;
1575         StreamGDBRemote response;
1576         if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false)
1577         {
1578             response.PutCString("F,");
1579             response.PutCString("x");
1580         }
1581         else
1582         {
1583             response.PutCString("F,");
1584             response.PutHex64(a);
1585             response.PutHex64(b);
1586         }
1587         return SendPacketNoLock(response.GetData(), response.GetSize());
1588     }
1589     return SendErrorResponse(25);
1590 }
1591 
1592