GDBRemoteCommunicationClient.cpp revision 139da72165577f073c14f2d5b86191e2c7b21d4c
1//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11#include "GDBRemoteCommunicationClient.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16#include "llvm/ADT/Triple.h"
17#include "lldb/Interpreter/Args.h"
18#include "lldb/Core/ConnectionFileDescriptor.h"
19#include "lldb/Core/Log.h"
20#include "lldb/Core/State.h"
21#include "lldb/Core/StreamString.h"
22#include "lldb/Host/Endian.h"
23#include "lldb/Host/Host.h"
24#include "lldb/Host/TimeValue.h"
25
26// Project includes
27#include "Utility/StringExtractorGDBRemote.h"
28#include "ProcessGDBRemote.h"
29#include "ProcessGDBRemoteLog.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34//----------------------------------------------------------------------
35// GDBRemoteCommunicationClient constructor
36//----------------------------------------------------------------------
37GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
38    GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
39    m_supports_not_sending_acks (eLazyBoolCalculate),
40    m_supports_thread_suffix (eLazyBoolCalculate),
41    m_supports_vCont_all (eLazyBoolCalculate),
42    m_supports_vCont_any (eLazyBoolCalculate),
43    m_supports_vCont_c (eLazyBoolCalculate),
44    m_supports_vCont_C (eLazyBoolCalculate),
45    m_supports_vCont_s (eLazyBoolCalculate),
46    m_supports_vCont_S (eLazyBoolCalculate),
47    m_qHostInfo_is_valid (eLazyBoolCalculate),
48    m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
49    m_supports_qProcessInfoPID (true),
50    m_supports_qfProcessInfo (true),
51    m_supports_qUserName (true),
52    m_supports_qGroupName (true),
53    m_supports_qThreadStopInfo (true),
54    m_supports_z0 (true),
55    m_supports_z1 (true),
56    m_supports_z2 (true),
57    m_supports_z3 (true),
58    m_supports_z4 (true),
59    m_curr_tid (LLDB_INVALID_THREAD_ID),
60    m_curr_tid_run (LLDB_INVALID_THREAD_ID),
61    m_async_mutex (Mutex::eMutexTypeRecursive),
62    m_async_packet_predicate (false),
63    m_async_packet (),
64    m_async_response (),
65    m_async_signal (-1),
66    m_host_arch(),
67    m_os_version_major (UINT32_MAX),
68    m_os_version_minor (UINT32_MAX),
69    m_os_version_update (UINT32_MAX)
70{
71    m_rx_packet_listener.StartListeningForEvents(this,
72                                                 Communication::eBroadcastBitPacketAvailable  |
73                                                 Communication::eBroadcastBitReadThreadDidExit);
74}
75
76//----------------------------------------------------------------------
77// Destructor
78//----------------------------------------------------------------------
79GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
80{
81    m_rx_packet_listener.StopListeningForEvents(this,
82                                                Communication::eBroadcastBitPacketAvailable  |
83                                                Communication::eBroadcastBitReadThreadDidExit);
84    if (IsConnected())
85    {
86        StopReadThread();
87        Disconnect();
88    }
89}
90
91bool
92GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
93{
94    // Start the read thread after we send the handshake ack since if we
95    // fail to send the handshake ack, there is no reason to continue...
96    if (SendAck())
97        return StartReadThread (error_ptr);
98
99    if (error_ptr)
100        error_ptr->SetErrorString("failed to send the handshake ack");
101    return false;
102}
103
104void
105GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
106{
107    if (m_supports_not_sending_acks == eLazyBoolCalculate)
108    {
109        m_send_acks = true;
110        m_supports_not_sending_acks = eLazyBoolNo;
111
112        StringExtractorGDBRemote response;
113        if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
114        {
115            if (response.IsOKResponse())
116            {
117                m_send_acks = false;
118                m_supports_not_sending_acks = eLazyBoolYes;
119            }
120        }
121    }
122}
123
124void
125GDBRemoteCommunicationClient::ResetDiscoverableSettings()
126{
127    m_supports_not_sending_acks = eLazyBoolCalculate;
128    m_supports_thread_suffix = eLazyBoolCalculate;
129    m_supports_vCont_c = eLazyBoolCalculate;
130    m_supports_vCont_C = eLazyBoolCalculate;
131    m_supports_vCont_s = eLazyBoolCalculate;
132    m_supports_vCont_S = eLazyBoolCalculate;
133    m_qHostInfo_is_valid = eLazyBoolCalculate;
134    m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
135
136    m_supports_qProcessInfoPID = true;
137    m_supports_qfProcessInfo = true;
138    m_supports_qUserName = true;
139    m_supports_qGroupName = true;
140    m_supports_qThreadStopInfo = true;
141    m_supports_z0 = true;
142    m_supports_z1 = true;
143    m_supports_z2 = true;
144    m_supports_z3 = true;
145    m_supports_z4 = true;
146    m_host_arch.Clear();
147}
148
149
150bool
151GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
152{
153    if (m_supports_thread_suffix == eLazyBoolCalculate)
154    {
155        StringExtractorGDBRemote response;
156        m_supports_thread_suffix = eLazyBoolNo;
157        if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
158        {
159            if (response.IsOKResponse())
160                m_supports_thread_suffix = eLazyBoolYes;
161        }
162    }
163    return m_supports_thread_suffix;
164}
165bool
166GDBRemoteCommunicationClient::GetVContSupported (char flavor)
167{
168    if (m_supports_vCont_c == eLazyBoolCalculate)
169    {
170        StringExtractorGDBRemote response;
171        m_supports_vCont_any = eLazyBoolNo;
172        m_supports_vCont_all = eLazyBoolNo;
173        m_supports_vCont_c = eLazyBoolNo;
174        m_supports_vCont_C = eLazyBoolNo;
175        m_supports_vCont_s = eLazyBoolNo;
176        m_supports_vCont_S = eLazyBoolNo;
177        if (SendPacketAndWaitForResponse("vCont?", response, false))
178        {
179            const char *response_cstr = response.GetStringRef().c_str();
180            if (::strstr (response_cstr, ";c"))
181                m_supports_vCont_c = eLazyBoolYes;
182
183            if (::strstr (response_cstr, ";C"))
184                m_supports_vCont_C = eLazyBoolYes;
185
186            if (::strstr (response_cstr, ";s"))
187                m_supports_vCont_s = eLazyBoolYes;
188
189            if (::strstr (response_cstr, ";S"))
190                m_supports_vCont_S = eLazyBoolYes;
191
192            if (m_supports_vCont_c == eLazyBoolYes &&
193                m_supports_vCont_C == eLazyBoolYes &&
194                m_supports_vCont_s == eLazyBoolYes &&
195                m_supports_vCont_S == eLazyBoolYes)
196            {
197                m_supports_vCont_all = eLazyBoolYes;
198            }
199
200            if (m_supports_vCont_c == eLazyBoolYes ||
201                m_supports_vCont_C == eLazyBoolYes ||
202                m_supports_vCont_s == eLazyBoolYes ||
203                m_supports_vCont_S == eLazyBoolYes)
204            {
205                m_supports_vCont_any = eLazyBoolYes;
206            }
207        }
208    }
209
210    switch (flavor)
211    {
212    case 'a': return m_supports_vCont_any;
213    case 'A': return m_supports_vCont_all;
214    case 'c': return m_supports_vCont_c;
215    case 'C': return m_supports_vCont_C;
216    case 's': return m_supports_vCont_s;
217    case 'S': return m_supports_vCont_S;
218    default: break;
219    }
220    return false;
221}
222
223
224size_t
225GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
226(
227    const char *payload,
228    StringExtractorGDBRemote &response,
229    bool send_async
230)
231{
232    return SendPacketAndWaitForResponse (payload,
233                                         ::strlen (payload),
234                                         response,
235                                         send_async);
236}
237
238size_t
239GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
240(
241    const char *payload,
242    size_t payload_length,
243    StringExtractorGDBRemote &response,
244    bool send_async
245)
246{
247    Mutex::Locker locker;
248    TimeValue timeout_time;
249    timeout_time = TimeValue::Now();
250    timeout_time.OffsetWithSeconds (m_packet_timeout);
251    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
252
253    if (GetSequenceMutex (locker))
254    {
255        if (SendPacketNoLock (payload, payload_length))
256            return WaitForPacketNoLock (response, &timeout_time);
257    }
258    else
259    {
260        if (send_async)
261        {
262            Mutex::Locker async_locker (m_async_mutex);
263            m_async_packet.assign(payload, payload_length);
264            m_async_packet_predicate.SetValue (true, eBroadcastNever);
265
266            if (log)
267                log->Printf ("async: async packet = %s", m_async_packet.c_str());
268
269            bool timed_out = false;
270            bool sent_interrupt = false;
271            if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
272            {
273                if (sent_interrupt)
274                {
275                    if (log)
276                        log->Printf ("async: sent interrupt");
277                    if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
278                    {
279                        if (log)
280                            log->Printf ("async: got response");
281                        response = m_async_response;
282                        return response.GetStringRef().size();
283                    }
284                    else
285                    {
286                        if (log)
287                            log->Printf ("async: timed out waiting for response");
288                    }
289
290                    // Make sure we wait until the continue packet has been sent again...
291                    if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
292                    {
293                        if (log)
294                            log->Printf ("async: timed out waiting for process to resume");
295                    }
296                }
297                else
298                {
299                    // We had a racy condition where we went to send the interrupt
300                    // yet we were able to get the loc
301                }
302            }
303            else
304            {
305                if (log)
306                    log->Printf ("async: failed to interrupt");
307            }
308        }
309        else
310        {
311            if (log)
312                log->Printf ("mutex taken and send_async == false, aborting packet");
313        }
314    }
315    return 0;
316}
317
318//template<typename _Tp>
319//class ScopedValueChanger
320//{
321//public:
322//    // Take a value reference and the value to assign it to when this class
323//    // instance goes out of scope.
324//    ScopedValueChanger (_Tp &value_ref, _Tp value) :
325//        m_value_ref (value_ref),
326//        m_value (value)
327//    {
328//    }
329//
330//    // This object is going out of scope, change the value pointed to by
331//    // m_value_ref to the value we got during construction which was stored in
332//    // m_value;
333//    ~ScopedValueChanger ()
334//    {
335//        m_value_ref = m_value;
336//    }
337//protected:
338//    _Tp &m_value_ref;   // A reference to the value we will change when this object destructs
339//    _Tp m_value;        // The value to assign to m_value_ref when this goes out of scope.
340//};
341
342StateType
343GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
344(
345    ProcessGDBRemote *process,
346    const char *payload,
347    size_t packet_length,
348    StringExtractorGDBRemote &response
349)
350{
351    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
352    if (log)
353        log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
354
355    Mutex::Locker locker(m_sequence_mutex);
356    StateType state = eStateRunning;
357
358    BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
359    m_public_is_running.SetValue (true, eBroadcastNever);
360    // Set the starting continue packet into "continue_packet". This packet
361    // make change if we are interrupted and we continue after an async packet...
362    std::string continue_packet(payload, packet_length);
363
364    bool got_stdout = false;
365
366    while (state == eStateRunning)
367    {
368        if (!got_stdout)
369        {
370            if (log)
371                log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
372            if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
373                state = eStateInvalid;
374
375            m_private_is_running.SetValue (true, eBroadcastNever);
376        }
377
378        got_stdout = false;
379
380        if (log)
381            log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__);
382
383        if (WaitForPacket (response, (TimeValue*)NULL))
384        {
385            if (response.Empty())
386                state = eStateInvalid;
387            else
388            {
389                const char stop_type = response.GetChar();
390                if (log)
391                    log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
392                switch (stop_type)
393                {
394                case 'T':
395                case 'S':
396                    if (process->GetStopID() == 0)
397                    {
398                        if (process->GetID() == LLDB_INVALID_PROCESS_ID)
399                        {
400                            lldb::pid_t pid = GetCurrentProcessID ();
401                            if (pid != LLDB_INVALID_PROCESS_ID)
402                                process->SetID (pid);
403                        }
404                        process->BuildDynamicRegisterInfo (true);
405                    }
406
407                    // Privately notify any internal threads that we have stopped
408                    // in case we wanted to interrupt our process, yet we might
409                    // send a packet and continue without returning control to the
410                    // user.
411                    m_private_is_running.SetValue (false, eBroadcastAlways);
412                    if (m_async_signal != -1)
413                    {
414                        if (log)
415                            log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
416
417                        // Save off the async signal we are supposed to send
418                        const int async_signal = m_async_signal;
419                        // Clear the async signal member so we don't end up
420                        // sending the signal multiple times...
421                        m_async_signal = -1;
422                        // Check which signal we stopped with
423                        uint8_t signo = response.GetHexU8(255);
424                        if (signo == async_signal)
425                        {
426                            if (log)
427                                log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
428
429                            // We already stopped with a signal that we wanted
430                            // to stop with, so we are done
431                            response.SetFilePos (0);
432                        }
433                        else
434                        {
435                            // We stopped with a different signal that the one
436                            // we wanted to stop with, so now we must resume
437                            // with the signal we want
438                            char signal_packet[32];
439                            int signal_packet_len = 0;
440                            signal_packet_len = ::snprintf (signal_packet,
441                                                            sizeof (signal_packet),
442                                                            "C%2.2x",
443                                                            async_signal);
444
445                            if (log)
446                                log->Printf ("async: stopped with signal %s, resume with %s",
447                                                   Host::GetSignalAsCString (signo),
448                                                   Host::GetSignalAsCString (async_signal));
449
450                            // Set the continue packet to resume...
451                            continue_packet.assign(signal_packet, signal_packet_len);
452                            continue;
453                        }
454                    }
455                    else if (m_async_packet_predicate.GetValue())
456                    {
457                        // We are supposed to send an asynchronous packet while
458                        // we are running.
459                        m_async_response.Clear();
460                        if (m_async_packet.empty())
461                        {
462                            if (log)
463                                log->Printf ("async: error: empty async packet");
464
465                        }
466                        else
467                        {
468                            if (log)
469                                log->Printf ("async: sending packet: %s",
470                                             m_async_packet.c_str());
471
472                            SendPacketAndWaitForResponse (&m_async_packet[0],
473                                                          m_async_packet.size(),
474                                                          m_async_response,
475                                                          false);
476                        }
477                        // Let the other thread that was trying to send the async
478                        // packet know that the packet has been sent and response is
479                        // ready...
480                        m_async_packet_predicate.SetValue(false, eBroadcastAlways);
481
482                        // Set the continue packet to resume...
483                        continue_packet.assign (1, 'c');
484                        continue;
485                    }
486                    // Stop with signal and thread info
487                    state = eStateStopped;
488                    break;
489
490                case 'W':
491                case 'X':
492                    // process exited
493                    state = eStateExited;
494                    break;
495
496                case 'O':
497                    // STDOUT
498                    {
499                        got_stdout = true;
500                        std::string inferior_stdout;
501                        inferior_stdout.reserve(response.GetBytesLeft () / 2);
502                        char ch;
503                        while ((ch = response.GetHexU8()) != '\0')
504                            inferior_stdout.append(1, ch);
505                        process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
506                    }
507                    break;
508
509                case 'E':
510                    // ERROR
511                    state = eStateInvalid;
512                    break;
513
514                default:
515                    if (log)
516                        log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
517                    state = eStateInvalid;
518                    break;
519                }
520            }
521        }
522        else
523        {
524            if (log)
525                log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
526            state = eStateInvalid;
527        }
528    }
529    if (log)
530        log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
531    response.SetFilePos(0);
532    m_private_is_running.SetValue (false, eBroadcastAlways);
533    m_public_is_running.SetValue (false, eBroadcastAlways);
534    return state;
535}
536
537bool
538GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
539{
540    m_async_signal = signo;
541    bool timed_out = false;
542    bool sent_interrupt = false;
543    Mutex::Locker locker;
544    if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
545        return true;
546    m_async_signal = -1;
547    return false;
548}
549
550// This function takes a mutex locker as a parameter in case the GetSequenceMutex
551// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
552// (the expected result), then it will send the halt packet. If it does succeed
553// then the caller that requested the interrupt will want to keep the sequence
554// locked down so that no one else can send packets while the caller has control.
555// This function usually gets called when we are running and need to stop the
556// target. It can also be used when we are running and and we need to do something
557// else (like read/write memory), so we need to interrupt the running process
558// (gdb remote protocol requires this), and do what we need to do, then resume.
559
560bool
561GDBRemoteCommunicationClient::SendInterrupt
562(
563    Mutex::Locker& locker,
564    uint32_t seconds_to_wait_for_stop,
565    bool &sent_interrupt,
566    bool &timed_out
567)
568{
569    sent_interrupt = false;
570    timed_out = false;
571    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
572
573    if (IsRunning())
574    {
575        // Only send an interrupt if our debugserver is running...
576        if (GetSequenceMutex (locker) == false)
577        {
578            // Someone has the mutex locked waiting for a response or for the
579            // inferior to stop, so send the interrupt on the down low...
580            char ctrl_c = '\x03';
581            ConnectionStatus status = eConnectionStatusSuccess;
582            TimeValue timeout;
583            if (seconds_to_wait_for_stop)
584            {
585                timeout = TimeValue::Now();
586                timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
587            }
588            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
589            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
590            if (bytes_written > 0)
591            {
592                sent_interrupt = true;
593                if (seconds_to_wait_for_stop)
594                {
595                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
596                    {
597                        if (log)
598                            log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__);
599                        return true;
600                    }
601                    else
602                    {
603                        if (log)
604                            log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
605                    }
606                }
607                else
608                {
609                    if (log)
610                        log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
611                    return true;
612                }
613            }
614            else
615            {
616                if (log)
617                    log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__);
618            }
619            return false;
620        }
621        else
622        {
623            if (log)
624                log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
625        }
626    }
627    return true;
628}
629
630lldb::pid_t
631GDBRemoteCommunicationClient::GetCurrentProcessID ()
632{
633    StringExtractorGDBRemote response;
634    if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
635    {
636        if (response.GetChar() == 'Q')
637            if (response.GetChar() == 'C')
638                return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
639    }
640    return LLDB_INVALID_PROCESS_ID;
641}
642
643bool
644GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
645{
646    error_str.clear();
647    StringExtractorGDBRemote response;
648    if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
649    {
650        if (response.IsOKResponse())
651            return true;
652        if (response.GetChar() == 'E')
653        {
654            // A string the describes what failed when launching...
655            error_str = response.GetStringRef().substr(1);
656        }
657        else
658        {
659            error_str.assign ("unknown error occurred launching process");
660        }
661    }
662    else
663    {
664        error_str.assign ("failed to send the qLaunchSuccess packet");
665    }
666    return false;
667}
668
669int
670GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
671{
672    if (argv && argv[0])
673    {
674        StreamString packet;
675        packet.PutChar('A');
676        const char *arg;
677        for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
678        {
679            const int arg_len = strlen(arg);
680            if (i > 0)
681                packet.PutChar(',');
682            packet.Printf("%i,%i,", arg_len * 2, i);
683            packet.PutBytesAsRawHex8 (arg, arg_len);
684        }
685
686        StringExtractorGDBRemote response;
687        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
688        {
689            if (response.IsOKResponse())
690                return 0;
691            uint8_t error = response.GetError();
692            if (error)
693                return error;
694        }
695    }
696    return -1;
697}
698
699int
700GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
701{
702    if (name_equal_value && name_equal_value[0])
703    {
704        StreamString packet;
705        packet.Printf("QEnvironment:%s", name_equal_value);
706        StringExtractorGDBRemote response;
707        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
708        {
709            if (response.IsOKResponse())
710                return 0;
711            uint8_t error = response.GetError();
712            if (error)
713                return error;
714        }
715    }
716    return -1;
717}
718
719int
720GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
721{
722    if (arch && arch[0])
723    {
724        StreamString packet;
725        packet.Printf("QLaunchArch:%s", arch);
726        StringExtractorGDBRemote response;
727        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
728        {
729            if (response.IsOKResponse())
730                return 0;
731            uint8_t error = response.GetError();
732            if (error)
733                return error;
734        }
735    }
736    return -1;
737}
738
739bool
740GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
741                                            uint32_t &minor,
742                                            uint32_t &update)
743{
744    if (GetHostInfo ())
745    {
746        if (m_os_version_major != UINT32_MAX)
747        {
748            major = m_os_version_major;
749            minor = m_os_version_minor;
750            update = m_os_version_update;
751            return true;
752        }
753    }
754    return false;
755}
756
757bool
758GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
759{
760    if (GetHostInfo ())
761    {
762        if (!m_os_build.empty())
763        {
764            s = m_os_build;
765            return true;
766        }
767    }
768    s.clear();
769    return false;
770}
771
772
773bool
774GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
775{
776    if (GetHostInfo ())
777    {
778        if (!m_os_kernel.empty())
779        {
780            s = m_os_kernel;
781            return true;
782        }
783    }
784    s.clear();
785    return false;
786}
787
788bool
789GDBRemoteCommunicationClient::GetHostname (std::string &s)
790{
791    if (GetHostInfo ())
792    {
793        if (!m_hostname.empty())
794        {
795            s = m_hostname;
796            return true;
797        }
798    }
799    s.clear();
800    return false;
801}
802
803ArchSpec
804GDBRemoteCommunicationClient::GetSystemArchitecture ()
805{
806    if (GetHostInfo ())
807        return m_host_arch;
808    return ArchSpec();
809}
810
811
812bool
813GDBRemoteCommunicationClient::GetHostInfo (bool force)
814{
815    if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
816    {
817        m_qHostInfo_is_valid = eLazyBoolNo;
818        StringExtractorGDBRemote response;
819        if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
820        {
821            if (response.IsNormalResponse())
822            {
823                std::string name;
824                std::string value;
825                uint32_t cpu = LLDB_INVALID_CPUTYPE;
826                uint32_t sub = 0;
827                std::string arch_name;
828                std::string os_name;
829                std::string vendor_name;
830                std::string triple;
831                uint32_t pointer_byte_size = 0;
832                StringExtractor extractor;
833                ByteOrder byte_order = eByteOrderInvalid;
834                uint32_t num_keys_decoded = 0;
835                while (response.GetNameColonValue(name, value))
836                {
837                    if (name.compare("cputype") == 0)
838                    {
839                        // exception type in big endian hex
840                        cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
841                        if (cpu != LLDB_INVALID_CPUTYPE)
842                            ++num_keys_decoded;
843                    }
844                    else if (name.compare("cpusubtype") == 0)
845                    {
846                        // exception count in big endian hex
847                        sub = Args::StringToUInt32 (value.c_str(), 0, 0);
848                        if (sub != 0)
849                            ++num_keys_decoded;
850                    }
851                    else if (name.compare("arch") == 0)
852                    {
853                        arch_name.swap (value);
854                        ++num_keys_decoded;
855                    }
856                    else if (name.compare("triple") == 0)
857                    {
858                        // The triple comes as ASCII hex bytes since it contains '-' chars
859                        extractor.GetStringRef().swap(value);
860                        extractor.SetFilePos(0);
861                        extractor.GetHexByteString (triple);
862                        ++num_keys_decoded;
863                    }
864                    else if (name.compare("os_build") == 0)
865                    {
866                        extractor.GetStringRef().swap(value);
867                        extractor.SetFilePos(0);
868                        extractor.GetHexByteString (m_os_build);
869                        ++num_keys_decoded;
870                    }
871                    else if (name.compare("hostname") == 0)
872                    {
873                        extractor.GetStringRef().swap(value);
874                        extractor.SetFilePos(0);
875                        extractor.GetHexByteString (m_hostname);
876                        ++num_keys_decoded;
877                    }
878                    else if (name.compare("os_kernel") == 0)
879                    {
880                        extractor.GetStringRef().swap(value);
881                        extractor.SetFilePos(0);
882                        extractor.GetHexByteString (m_os_kernel);
883                        ++num_keys_decoded;
884                    }
885                    else if (name.compare("ostype") == 0)
886                    {
887                        os_name.swap (value);
888                        ++num_keys_decoded;
889                    }
890                    else if (name.compare("vendor") == 0)
891                    {
892                        vendor_name.swap(value);
893                        ++num_keys_decoded;
894                    }
895                    else if (name.compare("endian") == 0)
896                    {
897                        ++num_keys_decoded;
898                        if (value.compare("little") == 0)
899                            byte_order = eByteOrderLittle;
900                        else if (value.compare("big") == 0)
901                            byte_order = eByteOrderBig;
902                        else if (value.compare("pdp") == 0)
903                            byte_order = eByteOrderPDP;
904                        else
905                            --num_keys_decoded;
906                    }
907                    else if (name.compare("ptrsize") == 0)
908                    {
909                        pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
910                        if (pointer_byte_size != 0)
911                            ++num_keys_decoded;
912                    }
913                    else if (name.compare("os_version") == 0)
914                    {
915                        Args::StringToVersion (value.c_str(),
916                                               m_os_version_major,
917                                               m_os_version_minor,
918                                               m_os_version_update);
919                        if (m_os_version_major != UINT32_MAX)
920                            ++num_keys_decoded;
921                    }
922                }
923
924                if (num_keys_decoded > 0)
925                    m_qHostInfo_is_valid = eLazyBoolYes;
926
927                if (triple.empty())
928                {
929                    if (arch_name.empty())
930                    {
931                        if (cpu != LLDB_INVALID_CPUTYPE)
932                        {
933                            m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
934                            if (pointer_byte_size)
935                            {
936                                assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
937                            }
938                            if (byte_order != eByteOrderInvalid)
939                            {
940                                assert (byte_order == m_host_arch.GetByteOrder());
941                            }
942                            if (!vendor_name.empty())
943                                m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
944                            if (!os_name.empty())
945                                m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
946
947                        }
948                    }
949                    else
950                    {
951                        std::string triple;
952                        triple += arch_name;
953                        triple += '-';
954                        if (vendor_name.empty())
955                            triple += "unknown";
956                        else
957                            triple += vendor_name;
958                        triple += '-';
959                        if (os_name.empty())
960                            triple += "unknown";
961                        else
962                            triple += os_name;
963                        m_host_arch.SetTriple (triple.c_str(), NULL);
964                        if (pointer_byte_size)
965                        {
966                            assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
967                        }
968                        if (byte_order != eByteOrderInvalid)
969                        {
970                            assert (byte_order == m_host_arch.GetByteOrder());
971                        }
972
973                    }
974                }
975                else
976                {
977                    m_host_arch.SetTriple (triple.c_str(), NULL);
978                    if (pointer_byte_size)
979                    {
980                        assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
981                    }
982                    if (byte_order != eByteOrderInvalid)
983                    {
984                        assert (byte_order == m_host_arch.GetByteOrder());
985                    }
986                }
987            }
988        }
989    }
990    return m_qHostInfo_is_valid == eLazyBoolYes;
991}
992
993int
994GDBRemoteCommunicationClient::SendAttach
995(
996    lldb::pid_t pid,
997    StringExtractorGDBRemote& response
998)
999{
1000    if (pid != LLDB_INVALID_PROCESS_ID)
1001    {
1002        char packet[64];
1003        const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid);
1004        assert (packet_len < sizeof(packet));
1005        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1006        {
1007            if (response.IsErrorResponse())
1008                return response.GetError();
1009            return 0;
1010        }
1011    }
1012    return -1;
1013}
1014
1015const lldb_private::ArchSpec &
1016GDBRemoteCommunicationClient::GetHostArchitecture ()
1017{
1018    if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1019        GetHostInfo ();
1020    return m_host_arch;
1021}
1022
1023addr_t
1024GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1025{
1026    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
1027    {
1028        m_supports_alloc_dealloc_memory = eLazyBoolYes;
1029        char packet[64];
1030        const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1031                                           permissions & lldb::ePermissionsReadable ? "r" : "",
1032                                           permissions & lldb::ePermissionsWritable ? "w" : "",
1033                                           permissions & lldb::ePermissionsExecutable ? "x" : "");
1034        assert (packet_len < sizeof(packet));
1035        StringExtractorGDBRemote response;
1036        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1037        {
1038            if (!response.IsErrorResponse())
1039                return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1040        }
1041        else
1042        {
1043            m_supports_alloc_dealloc_memory = eLazyBoolNo;
1044        }
1045    }
1046    return LLDB_INVALID_ADDRESS;
1047}
1048
1049bool
1050GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1051{
1052    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
1053    {
1054        m_supports_alloc_dealloc_memory = eLazyBoolYes;
1055        char packet[64];
1056        const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1057        assert (packet_len < sizeof(packet));
1058        StringExtractorGDBRemote response;
1059        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1060        {
1061            if (response.IsOKResponse())
1062                return true;
1063        }
1064        else
1065        {
1066            m_supports_alloc_dealloc_memory = eLazyBoolNo;
1067        }
1068    }
1069    return false;
1070}
1071
1072int
1073GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1074{
1075    if (path && path[0])
1076    {
1077        StreamString packet;
1078        packet.PutCString("QSetSTDIN:");
1079        packet.PutBytesAsRawHex8(path, strlen(path));
1080
1081        StringExtractorGDBRemote response;
1082        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1083        {
1084            if (response.IsOKResponse())
1085                return 0;
1086            uint8_t error = response.GetError();
1087            if (error)
1088                return error;
1089        }
1090    }
1091    return -1;
1092}
1093
1094int
1095GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1096{
1097    if (path && path[0])
1098    {
1099        StreamString packet;
1100        packet.PutCString("QSetSTDOUT:");
1101        packet.PutBytesAsRawHex8(path, strlen(path));
1102
1103        StringExtractorGDBRemote response;
1104        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1105        {
1106            if (response.IsOKResponse())
1107                return 0;
1108            uint8_t error = response.GetError();
1109            if (error)
1110                return error;
1111        }
1112    }
1113    return -1;
1114}
1115
1116int
1117GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1118{
1119    if (path && path[0])
1120    {
1121        StreamString packet;
1122        packet.PutCString("QSetSTDERR:");
1123        packet.PutBytesAsRawHex8(path, strlen(path));
1124
1125        StringExtractorGDBRemote response;
1126        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1127        {
1128            if (response.IsOKResponse())
1129                return 0;
1130            uint8_t error = response.GetError();
1131            if (error)
1132                return error;
1133        }
1134    }
1135    return -1;
1136}
1137
1138int
1139GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1140{
1141    if (path && path[0])
1142    {
1143        StreamString packet;
1144        packet.PutCString("QSetWorkingDir:");
1145        packet.PutBytesAsRawHex8(path, strlen(path));
1146
1147        StringExtractorGDBRemote response;
1148        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1149        {
1150            if (response.IsOKResponse())
1151                return 0;
1152            uint8_t error = response.GetError();
1153            if (error)
1154                return error;
1155        }
1156    }
1157    return -1;
1158}
1159
1160int
1161GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1162{
1163    char packet[32];
1164    const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1165    assert (packet_len < sizeof(packet));
1166    StringExtractorGDBRemote response;
1167    if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1168    {
1169        if (response.IsOKResponse())
1170            return 0;
1171        uint8_t error = response.GetError();
1172        if (error)
1173            return error;
1174    }
1175    return -1;
1176}
1177
1178bool
1179GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
1180{
1181    if (response.IsNormalResponse())
1182    {
1183        std::string name;
1184        std::string value;
1185        StringExtractor extractor;
1186
1187        while (response.GetNameColonValue(name, value))
1188        {
1189            if (name.compare("pid") == 0)
1190            {
1191                process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1192            }
1193            else if (name.compare("ppid") == 0)
1194            {
1195                process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1196            }
1197            else if (name.compare("uid") == 0)
1198            {
1199                process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1200            }
1201            else if (name.compare("euid") == 0)
1202            {
1203                process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1204            }
1205            else if (name.compare("gid") == 0)
1206            {
1207                process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1208            }
1209            else if (name.compare("egid") == 0)
1210            {
1211                process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1212            }
1213            else if (name.compare("triple") == 0)
1214            {
1215                // The triple comes as ASCII hex bytes since it contains '-' chars
1216                extractor.GetStringRef().swap(value);
1217                extractor.SetFilePos(0);
1218                extractor.GetHexByteString (value);
1219                process_info.GetArchitecture ().SetTriple (value.c_str(), NULL);
1220            }
1221            else if (name.compare("name") == 0)
1222            {
1223                StringExtractor extractor;
1224                // The the process name from ASCII hex bytes since we can't
1225                // control the characters in a process name
1226                extractor.GetStringRef().swap(value);
1227                extractor.SetFilePos(0);
1228                extractor.GetHexByteString (value);
1229                process_info.SetName (value.c_str());
1230            }
1231        }
1232
1233        if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1234            return true;
1235    }
1236    return false;
1237}
1238
1239bool
1240GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
1241{
1242    process_info.Clear();
1243
1244    if (m_supports_qProcessInfoPID)
1245    {
1246        char packet[32];
1247        const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%i", pid);
1248        assert (packet_len < sizeof(packet));
1249        StringExtractorGDBRemote response;
1250        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1251        {
1252            return DecodeProcessInfoResponse (response, process_info);
1253        }
1254        else
1255        {
1256            m_supports_qProcessInfoPID = false;
1257            return false;
1258        }
1259    }
1260    return false;
1261}
1262
1263uint32_t
1264GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1265                                             ProcessInstanceInfoList &process_infos)
1266{
1267    process_infos.Clear();
1268
1269    if (m_supports_qfProcessInfo)
1270    {
1271        StreamString packet;
1272        packet.PutCString ("qfProcessInfo");
1273        if (!match_info.MatchAllProcesses())
1274        {
1275            packet.PutChar (':');
1276            const char *name = match_info.GetProcessInfo().GetName();
1277            bool has_name_match = false;
1278            if (name && name[0])
1279            {
1280                has_name_match = true;
1281                NameMatchType name_match_type = match_info.GetNameMatchType();
1282                switch (name_match_type)
1283                {
1284                case eNameMatchIgnore:
1285                    has_name_match = false;
1286                    break;
1287
1288                case eNameMatchEquals:
1289                    packet.PutCString ("name_match:equals;");
1290                    break;
1291
1292                case eNameMatchContains:
1293                    packet.PutCString ("name_match:contains;");
1294                    break;
1295
1296                case eNameMatchStartsWith:
1297                    packet.PutCString ("name_match:starts_with;");
1298                    break;
1299
1300                case eNameMatchEndsWith:
1301                    packet.PutCString ("name_match:ends_with;");
1302                    break;
1303
1304                case eNameMatchRegularExpression:
1305                    packet.PutCString ("name_match:regex;");
1306                    break;
1307                }
1308                if (has_name_match)
1309                {
1310                    packet.PutCString ("name:");
1311                    packet.PutBytesAsRawHex8(name, ::strlen(name));
1312                    packet.PutChar (';');
1313                }
1314            }
1315
1316            if (match_info.GetProcessInfo().ProcessIDIsValid())
1317                packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
1318            if (match_info.GetProcessInfo().ParentProcessIDIsValid())
1319                packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
1320            if (match_info.GetProcessInfo().UserIDIsValid())
1321                packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
1322            if (match_info.GetProcessInfo().GroupIDIsValid())
1323                packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
1324            if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
1325                packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
1326            if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1327                packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
1328            if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1329                packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
1330            if (match_info.GetProcessInfo().GetArchitecture().IsValid())
1331            {
1332                const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
1333                const llvm::Triple &triple = match_arch.GetTriple();
1334                packet.PutCString("triple:");
1335                packet.PutCStringAsRawHex8(triple.getTriple().c_str());
1336                packet.PutChar (';');
1337            }
1338        }
1339        StringExtractorGDBRemote response;
1340        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1341        {
1342            do
1343            {
1344                ProcessInstanceInfo process_info;
1345                if (!DecodeProcessInfoResponse (response, process_info))
1346                    break;
1347                process_infos.Append(process_info);
1348                response.GetStringRef().clear();
1349                response.SetFilePos(0);
1350            } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
1351        }
1352        else
1353        {
1354            m_supports_qfProcessInfo = false;
1355            return 0;
1356        }
1357    }
1358    return process_infos.GetSize();
1359
1360}
1361
1362bool
1363GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
1364{
1365    if (m_supports_qUserName)
1366    {
1367        char packet[32];
1368        const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
1369        assert (packet_len < sizeof(packet));
1370        StringExtractorGDBRemote response;
1371        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1372        {
1373            if (response.IsNormalResponse())
1374            {
1375                // Make sure we parsed the right number of characters. The response is
1376                // the hex encoded user name and should make up the entire packet.
1377                // If there are any non-hex ASCII bytes, the length won't match below..
1378                if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1379                    return true;
1380            }
1381        }
1382        else
1383        {
1384            m_supports_qUserName = false;
1385            return false;
1386        }
1387    }
1388    return false;
1389
1390}
1391
1392bool
1393GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
1394{
1395    if (m_supports_qGroupName)
1396    {
1397        char packet[32];
1398        const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
1399        assert (packet_len < sizeof(packet));
1400        StringExtractorGDBRemote response;
1401        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1402        {
1403            if (response.IsNormalResponse())
1404            {
1405                // Make sure we parsed the right number of characters. The response is
1406                // the hex encoded group name and should make up the entire packet.
1407                // If there are any non-hex ASCII bytes, the length won't match below..
1408                if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1409                    return true;
1410            }
1411        }
1412        else
1413        {
1414            m_supports_qGroupName = false;
1415            return false;
1416        }
1417    }
1418    return false;
1419}
1420
1421void
1422GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
1423{
1424    uint32_t i;
1425    TimeValue start_time, end_time;
1426    uint64_t total_time_nsec;
1427    float packets_per_second;
1428    if (SendSpeedTestPacket (0, 0))
1429    {
1430        for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
1431        {
1432            for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
1433            {
1434                start_time = TimeValue::Now();
1435                for (i=0; i<num_packets; ++i)
1436                {
1437                    SendSpeedTestPacket (send_size, recv_size);
1438                }
1439                end_time = TimeValue::Now();
1440                total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
1441                packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond;
1442                printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%09.9llu sec for %f packets/sec.\n",
1443                        num_packets,
1444                        send_size,
1445                        recv_size,
1446                        total_time_nsec / TimeValue::NanoSecondPerSecond,
1447                        total_time_nsec % TimeValue::NanoSecondPerSecond,
1448                        packets_per_second);
1449                if (recv_size == 0)
1450                    recv_size = 32;
1451            }
1452            if (send_size == 0)
1453                send_size = 32;
1454        }
1455    }
1456    else
1457    {
1458        start_time = TimeValue::Now();
1459        for (i=0; i<num_packets; ++i)
1460        {
1461            GetCurrentProcessID ();
1462        }
1463        end_time = TimeValue::Now();
1464        total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
1465        packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond;
1466        printf ("%u 'qC' packets packets in 0x%llu%09.9llu sec for %f packets/sec.\n",
1467                num_packets,
1468                total_time_nsec / TimeValue::NanoSecondPerSecond,
1469                total_time_nsec % TimeValue::NanoSecondPerSecond,
1470                packets_per_second);
1471    }
1472}
1473
1474bool
1475GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
1476{
1477    StreamString packet;
1478    packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
1479    uint32_t bytes_left = send_size;
1480    while (bytes_left > 0)
1481    {
1482        if (bytes_left >= 26)
1483        {
1484            packet.PutCString("abcdefghijklmnopqrstuvwxyz");
1485            bytes_left -= 26;
1486        }
1487        else
1488        {
1489            packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
1490            bytes_left = 0;
1491        }
1492    }
1493
1494    StringExtractorGDBRemote response;
1495    return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
1496    return false;
1497}
1498
1499uint16_t
1500GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
1501{
1502    StringExtractorGDBRemote response;
1503    if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
1504    {
1505        std::string name;
1506        std::string value;
1507        uint16_t port = 0;
1508        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1509        while (response.GetNameColonValue(name, value))
1510        {
1511            if (name.size() == 4 && name.compare("port") == 0)
1512                port = Args::StringToUInt32(value.c_str(), 0, 0);
1513            if (name.size() == 3 && name.compare("pid") == 0)
1514                pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
1515        }
1516        return port;
1517    }
1518    return 0;
1519}
1520
1521bool
1522GDBRemoteCommunicationClient::SetCurrentThread (int tid)
1523{
1524    if (m_curr_tid == tid)
1525        return true;
1526
1527    char packet[32];
1528    int packet_len;
1529    if (tid <= 0)
1530        packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
1531    else
1532        packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
1533    assert (packet_len + 1 < sizeof(packet));
1534    StringExtractorGDBRemote response;
1535    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1536    {
1537        if (response.IsOKResponse())
1538        {
1539            m_curr_tid = tid;
1540            return true;
1541        }
1542    }
1543    return false;
1544}
1545
1546bool
1547GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
1548{
1549    if (m_curr_tid_run == tid)
1550        return true;
1551
1552    char packet[32];
1553    int packet_len;
1554    if (tid <= 0)
1555        packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
1556    else
1557        packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
1558
1559    assert (packet_len + 1 < sizeof(packet));
1560    StringExtractorGDBRemote response;
1561    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1562    {
1563        if (response.IsOKResponse())
1564        {
1565            m_curr_tid_run = tid;
1566            return true;
1567        }
1568    }
1569    return false;
1570}
1571
1572bool
1573GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
1574{
1575    if (SendPacketAndWaitForResponse("?", 1, response, false))
1576        return response.IsNormalResponse();
1577    return false;
1578}
1579
1580bool
1581GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
1582{
1583    if (m_supports_qThreadStopInfo)
1584    {
1585        char packet[256];
1586        int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
1587        assert (packet_len < sizeof(packet));
1588        if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1589        {
1590            if (response.IsNormalResponse())
1591                return true;
1592            else
1593                return false;
1594        }
1595        else
1596        {
1597            m_supports_qThreadStopInfo = false;
1598        }
1599    }
1600//    if (SetCurrentThread (tid))
1601//        return GetStopReply (response);
1602    return false;
1603}
1604
1605
1606uint8_t
1607GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert,  addr_t addr, uint32_t length)
1608{
1609    switch (type)
1610    {
1611    case eBreakpointSoftware:   if (!m_supports_z0) return UINT8_MAX; break;
1612    case eBreakpointHardware:   if (!m_supports_z1) return UINT8_MAX; break;
1613    case eWatchpointWrite:      if (!m_supports_z2) return UINT8_MAX; break;
1614    case eWatchpointRead:       if (!m_supports_z3) return UINT8_MAX; break;
1615    case eWatchpointReadWrite:  if (!m_supports_z4) return UINT8_MAX; break;
1616    default:                    return UINT8_MAX;
1617    }
1618
1619    char packet[64];
1620    const int packet_len = ::snprintf (packet,
1621                                       sizeof(packet),
1622                                       "%c%i,%llx,%x",
1623                                       insert ? 'Z' : 'z',
1624                                       type,
1625                                       addr,
1626                                       length);
1627
1628    assert (packet_len + 1 < sizeof(packet));
1629    StringExtractorGDBRemote response;
1630    if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
1631    {
1632        if (response.IsOKResponse())
1633            return 0;
1634        else if (response.IsErrorResponse())
1635            return response.GetError();
1636    }
1637    else
1638    {
1639        switch (type)
1640        {
1641            case eBreakpointSoftware:   m_supports_z0 = false; break;
1642            case eBreakpointHardware:   m_supports_z1 = false; break;
1643            case eWatchpointWrite:      m_supports_z2 = false; break;
1644            case eWatchpointRead:       m_supports_z3 = false; break;
1645            case eWatchpointReadWrite:  m_supports_z4 = false; break;
1646            default:                    break;
1647        }
1648    }
1649
1650    return UINT8_MAX;
1651}
1652