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