GDBRemoteCommunication.cpp revision 9ac497bc11512d221b3962e4f883eeac07db188a
1//===-- GDBRemoteCommunication.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 "GDBRemoteCommunication.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16#include "lldb/Interpreter/Args.h"
17#include "lldb/Core/ConnectionFileDescriptor.h"
18#include "lldb/Core/Log.h"
19#include "lldb/Core/State.h"
20#include "lldb/Core/StreamString.h"
21#include "lldb/Host/TimeValue.h"
22
23// Project includes
24#include "Utility/StringExtractorGDBRemote.h"
25#include "ProcessGDBRemote.h"
26#include "ProcessGDBRemoteLog.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31//----------------------------------------------------------------------
32// GDBRemoteCommunication constructor
33//----------------------------------------------------------------------
34GDBRemoteCommunication::GDBRemoteCommunication() :
35    Communication("gdb-remote.packets", true),
36    m_send_acks (true),
37    m_rx_packet_listener ("gdbremote.rx_packet"),
38    m_sequence_mutex (Mutex::eMutexTypeRecursive),
39    m_is_running (false),
40    m_async_mutex (Mutex::eMutexTypeRecursive),
41    m_async_packet_predicate (false),
42    m_async_packet (),
43    m_async_response (),
44    m_async_timeout (UINT32_MAX),
45    m_async_signal (-1),
46    m_arch(),
47    m_os(),
48    m_vendor(),
49    m_byte_order(eByteOrderHost),
50    m_pointer_byte_size(0)
51{
52    m_rx_packet_listener.StartListeningForEvents(this,
53                                                 Communication::eBroadcastBitPacketAvailable  |
54                                                 Communication::eBroadcastBitReadThreadDidExit);
55}
56
57//----------------------------------------------------------------------
58// Destructor
59//----------------------------------------------------------------------
60GDBRemoteCommunication::~GDBRemoteCommunication()
61{
62    m_rx_packet_listener.StopListeningForEvents(this,
63                                                Communication::eBroadcastBitPacketAvailable  |
64                                                Communication::eBroadcastBitReadThreadDidExit);
65    if (IsConnected())
66    {
67        StopReadThread();
68        Disconnect();
69    }
70}
71
72
73char
74GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
75{
76    int checksum = 0;
77
78    // We only need to compute the checksum if we are sending acks
79    if (m_send_acks)
80    {
81        for (size_t i = 0; i < payload_length; ++i)
82            checksum += payload[i];
83    }
84    return checksum & 255;
85}
86
87size_t
88GDBRemoteCommunication::SendAck (char ack_char)
89{
90    Mutex::Locker locker(m_sequence_mutex);
91    ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %c", ack_char);
92    ConnectionStatus status = eConnectionStatusSuccess;
93    return Write (&ack_char, 1, status, NULL) == 1;
94}
95
96size_t
97GDBRemoteCommunication::SendPacketAndWaitForResponse
98(
99    const char *payload,
100    StringExtractorGDBRemote &response,
101    uint32_t timeout_seconds,
102    bool send_async
103)
104{
105    return SendPacketAndWaitForResponse (payload,
106                                         ::strlen (payload),
107                                         response,
108                                         timeout_seconds,
109                                         send_async);
110}
111
112size_t
113GDBRemoteCommunication::SendPacketAndWaitForResponse
114(
115    const char *payload,
116    size_t payload_length,
117    StringExtractorGDBRemote &response,
118    uint32_t timeout_seconds,
119    bool send_async
120)
121{
122    Mutex::Locker locker;
123    TimeValue timeout_time;
124    timeout_time = TimeValue::Now();
125    timeout_time.OffsetWithSeconds (timeout_seconds);
126
127    if (GetSequenceMutex (locker))
128    {
129        if (SendPacketNoLock (payload, strlen(payload)))
130            return WaitForPacketNoLock (response, &timeout_time);
131    }
132    else
133    {
134        if (send_async)
135        {
136            Mutex::Locker async_locker (m_async_mutex);
137            m_async_packet.assign(payload, payload_length);
138            m_async_timeout = timeout_seconds;
139            m_async_packet_predicate.SetValue (true, eBroadcastNever);
140
141            bool timed_out = false;
142            if (SendInterrupt(locker, 1, &timed_out))
143            {
144                if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
145                {
146                    response = m_async_response;
147                    return response.GetStringRef().size();
148                }
149            }
150//            if (timed_out)
151//                m_error.SetErrorString("Timeout.");
152//            else
153//                m_error.SetErrorString("Unknown error.");
154        }
155        else
156        {
157//            m_error.SetErrorString("Sequence mutex is locked.");
158        }
159    }
160    return 0;
161}
162
163//template<typename _Tp>
164//class ScopedValueChanger
165//{
166//public:
167//    // Take a value reference and the value to assing it to when this class
168//    // instance goes out of scope.
169//    ScopedValueChanger (_Tp &value_ref, _Tp value) :
170//        m_value_ref (value_ref),
171//        m_value (value)
172//    {
173//    }
174//
175//    // This object is going out of scope, change the value pointed to by
176//    // m_value_ref to the value we got during construction which was stored in
177//    // m_value;
178//    ~ScopedValueChanger ()
179//    {
180//        m_value_ref = m_value;
181//    }
182//protected:
183//    _Tp &m_value_ref;   // A reference to the value we wil change when this object destructs
184//    _Tp m_value;        // The value to assign to m_value_ref when this goes out of scope.
185//};
186
187StateType
188GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
189(
190    ProcessGDBRemote *process,
191    const char *payload,
192    size_t packet_length,
193    StringExtractorGDBRemote &response
194)
195{
196    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
197    LogSP async_log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_ASYNC));
198    if (log)
199        log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
200
201    Mutex::Locker locker(m_sequence_mutex);
202//    ScopedValueChanger<bool> restore_running_to_false (m_is_running, false);
203    StateType state = eStateRunning;
204
205    if (SendPacket(payload, packet_length) == 0)
206        state = eStateInvalid;
207
208    m_is_running.SetValue (true, eBroadcastAlways);
209
210    while (state == eStateRunning)
211    {
212        log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
213        if (log)
214            log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...)", __FUNCTION__);
215
216        if (WaitForPacket (response, (TimeValue*)NULL))
217        {
218            log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
219            async_log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_ASYNC);
220            if (response.Empty())
221                state = eStateInvalid;
222            else
223            {
224                const char stop_type = response.GetChar();
225                if (log)
226                    log->Printf ("GDBRemoteCommunication::%s () got '%c' packet", __FUNCTION__, stop_type);
227                switch (stop_type)
228                {
229                case 'T':
230                case 'S':
231                    if (m_async_signal != -1)
232                    {
233                        if (async_log)
234                            async_log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
235
236                        // Save off the async signal we are supposed to send
237                        const int async_signal = m_async_signal;
238                        // Clear the async signal member so we don't end up
239                        // sending the signal multiple times...
240                        m_async_signal = -1;
241                        // Check which signal we stopped with
242                        uint8_t signo = response.GetHexU8(255);
243                        if (signo == async_signal)
244                        {
245                            if (async_log)
246                                async_log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
247
248                            // We already stopped with a signal that we wanted
249                            // to stop with, so we are done
250                            response.SetFilePos (0);
251                        }
252                        else
253                        {
254                            // We stopped with a different signal that the one
255                            // we wanted to stop with, so now we must resume
256                            // with the signal we want
257                            char signal_packet[32];
258                            int signal_packet_len = 0;
259                            signal_packet_len = ::snprintf (signal_packet,
260                                                            sizeof (signal_packet),
261                                                            "C%2.2x",
262                                                            async_signal);
263
264                            if (async_log)
265                                async_log->Printf ("async: stopped with signal %s, resume with %s",
266                                                   Host::GetSignalAsCString (signo),
267                                                   Host::GetSignalAsCString (async_signal));
268
269                            if (SendPacket(signal_packet, signal_packet_len) == 0)
270                            {
271                                if (async_log)
272                                    async_log->Printf ("async: error: failed to resume with %s",
273                                                       Host::GetSignalAsCString (async_signal));
274                                state = eStateInvalid;
275                                break;
276                            }
277                            else
278                                continue;
279                        }
280                    }
281                    else if (m_async_packet_predicate.GetValue())
282                    {
283                        if (async_log)
284                            async_log->Printf ("async: send async packet: %s",
285                                               m_async_packet.c_str());
286
287                        // We are supposed to send an asynchronous packet while
288                        // we are running.
289                        m_async_response.Clear();
290                        if (!m_async_packet.empty())
291                        {
292                            SendPacketAndWaitForResponse (&m_async_packet[0],
293                                                          m_async_packet.size(),
294                                                          m_async_response,
295                                                          m_async_timeout,
296                                                          false);
297                        }
298                        // Let the other thread that was trying to send the async
299                        // packet know that the packet has been sent.
300                        m_async_packet_predicate.SetValue(false, eBroadcastAlways);
301
302                        if (async_log)
303                            async_log->Printf ("async: resume after async response received: %s",
304                                               m_async_response.GetStringRef().c_str());
305
306                        // Continue again
307                        if (SendPacket("c", 1) == 0)
308                        {
309                            state = eStateInvalid;
310                            break;
311                        }
312                        else
313                            continue;
314                    }
315                    // Stop with signal and thread info
316                    state = eStateStopped;
317                    break;
318
319                case 'W':
320                    // process exited
321                    state = eStateExited;
322                    break;
323
324                case 'O':
325                    // STDOUT
326                    {
327                        std::string inferior_stdout;
328                        inferior_stdout.reserve(response.GetBytesLeft () / 2);
329                        char ch;
330                        while ((ch = response.GetHexU8()) != '\0')
331                            inferior_stdout.append(1, ch);
332                        process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
333                    }
334                    break;
335
336                case 'E':
337                    // ERROR
338                    state = eStateInvalid;
339                    break;
340
341                default:
342                    if (log)
343                        log->Printf ("GDBRemoteCommunication::%s () got unrecognized async packet: '%s'", __FUNCTION__, stop_type);
344                    break;
345                }
346            }
347        }
348        else
349        {
350            log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
351            if (log)
352                log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
353            state = eStateInvalid;
354        }
355    }
356    log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
357    if (log)
358        log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
359    response.SetFilePos(0);
360    m_is_running.SetValue (false, eBroadcastOnChange);
361    return state;
362}
363
364size_t
365GDBRemoteCommunication::SendPacket (const char *payload)
366{
367    Mutex::Locker locker(m_sequence_mutex);
368    return SendPacketNoLock (payload, ::strlen (payload));
369}
370
371size_t
372GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
373{
374    Mutex::Locker locker(m_sequence_mutex);
375    return SendPacketNoLock (payload, payload_length);
376}
377
378size_t
379GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
380{
381    if (IsConnected())
382    {
383        StreamString packet(0, 4, eByteOrderBig);
384
385        packet.PutChar('$');
386        packet.Write (payload, payload_length);
387        packet.PutChar('#');
388        packet.PutHex8(CalculcateChecksum (payload, payload_length));
389
390        ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %s", packet.GetData());
391        ConnectionStatus status = eConnectionStatusSuccess;
392        size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
393        if (bytes_written == packet.GetSize())
394        {
395            if (m_send_acks)
396            {
397                if (GetAck (1) != '+')
398                    return 0;
399            }
400        }
401        else
402        {
403            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "error: failed to send packet: %s", packet.GetData());
404        }
405        return bytes_written;
406    }
407    return 0;
408}
409
410char
411GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
412{
413    StringExtractorGDBRemote response;
414    if (WaitForPacket (response, timeout_seconds) == 1)
415        return response.GetChar();
416    return 0;
417}
418
419bool
420GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
421{
422    return locker.TryLock (m_sequence_mutex.GetMutex());
423}
424
425bool
426GDBRemoteCommunication::SendAsyncSignal (int signo)
427{
428    m_async_signal = signo;
429    bool timed_out = false;
430    Mutex::Locker locker;
431    if (SendInterrupt (locker, 1, &timed_out))
432        return true;
433    m_async_signal = -1;
434    return false;
435}
436
437// This function takes a mutex locker as a parameter in case the GetSequenceMutex
438// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
439// (the expected result), then it will send the halt packet. If it does succeed
440// then the caller that requested the interrupt will want to keep the sequence
441// locked down so that no one else can send packets while the caller has control.
442// This function usually gets called when we are running and need to stop the
443// target. It can also be used when we are running and and we need to do something
444// else (like read/write memory), so we need to interrupt the running process
445// (gdb remote protocol requires this), and do what we need to do, then resume.
446
447bool
448GDBRemoteCommunication::SendInterrupt (Mutex::Locker& locker, uint32_t seconds_to_wait_for_stop, bool *timed_out)
449{
450    if (timed_out)
451        *timed_out = false;
452
453    if (IsConnected() && IsRunning())
454    {
455        // Only send an interrupt if our debugserver is running...
456        if (GetSequenceMutex (locker) == false)
457        {
458            // Someone has the mutex locked waiting for a response or for the
459            // inferior to stop, so send the interrupt on the down low...
460            char ctrl_c = '\x03';
461            ConnectionStatus status = eConnectionStatusSuccess;
462            TimeValue timeout;
463            if (seconds_to_wait_for_stop)
464            {
465                timeout = TimeValue::Now();
466                timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
467            }
468            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: \\x03");
469            if (Write (&ctrl_c, 1, status, NULL) > 0)
470            {
471                if (seconds_to_wait_for_stop)
472                    m_is_running.WaitForValueEqualTo (false, &timeout, timed_out);
473                return true;
474            }
475        }
476    }
477    return false;
478}
479
480size_t
481GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
482{
483    TimeValue timeout_time;
484    timeout_time = TimeValue::Now();
485    timeout_time.OffsetWithSeconds (timeout_seconds);
486    return WaitForPacketNoLock (response, &timeout_time);
487}
488
489size_t
490GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, TimeValue* timeout_time_ptr)
491{
492    Mutex::Locker locker(m_sequence_mutex);
493    return WaitForPacketNoLock (response, timeout_time_ptr);
494}
495
496size_t
497GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, TimeValue* timeout_time_ptr)
498{
499    bool checksum_error = false;
500    response.Clear ();
501
502    EventSP event_sp;
503
504    if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
505    {
506        const uint32_t event_type = event_sp->GetType();
507        if (event_type | Communication::eBroadcastBitPacketAvailable)
508        {
509            const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
510            if (event_bytes)
511            {
512                const char * packet_data =  (const char *)event_bytes->GetBytes();
513                ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "read packet: %s", packet_data);
514                const size_t packet_size =  event_bytes->GetByteSize();
515                if (packet_data && packet_size > 0)
516                {
517                    std::string &response_str = response.GetStringRef();
518                    if (packet_data[0] == '$')
519                    {
520                        assert (packet_size >= 4);  // Must have at least '$#CC' where CC is checksum
521                        assert (packet_data[packet_size-3] == '#');
522                        assert (::isxdigit (packet_data[packet_size-2]));  // Must be checksum hex byte
523                        assert (::isxdigit (packet_data[packet_size-1]));  // Must be checksum hex byte
524                        response_str.assign (packet_data + 1, packet_size - 4);
525                        if (m_send_acks)
526                        {
527                            char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
528                            char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
529                            checksum_error = packet_checksum != actual_checksum;
530                            // Send the ack or nack if needed
531                            if (checksum_error)
532                                SendAck('-');
533                            else
534                                SendAck('+');
535                        }
536                    }
537                    else
538                    {
539                        response_str.assign (packet_data, packet_size);
540                    }
541                    return response_str.size();
542                }
543            }
544        }
545        else if (Communication::eBroadcastBitReadThreadDidExit)
546        {
547            // Our read thread exited on us so just fall through and return zero...
548        }
549    }
550    return 0;
551}
552
553void
554GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
555                                            ConnectionStatus status)
556{
557    // Put the packet data into the buffer in a thread safe fashion
558    Mutex::Locker locker(m_bytes_mutex);
559    m_bytes.append ((const char *)src, src_len);
560
561    // Parse up the packets into gdb remote packets
562    while (!m_bytes.empty())
563    {
564        // end_idx must be one past the last valid packet byte. Start
565        // it off with an invalid value that is the same as the current
566        // index.
567        size_t end_idx = 0;
568
569        switch (m_bytes[0])
570        {
571            case '+':       // Look for ack
572            case '-':       // Look for cancel
573            case '\x03':    // ^C to halt target
574                end_idx = 1;  // The command is one byte long...
575                break;
576
577            case '$':
578                // Look for a standard gdb packet?
579                end_idx = m_bytes.find('#');
580                if (end_idx != std::string::npos)
581                {
582                    if (end_idx + 2 < m_bytes.size())
583                    {
584                        end_idx += 3;
585                    }
586                    else
587                    {
588                        // Checksum bytes aren't all here yet
589                        end_idx = std::string::npos;
590                    }
591                }
592                break;
593
594            default:
595                break;
596        }
597
598        if (end_idx == std::string::npos)
599        {
600            //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
601            return;
602        }
603        else if (end_idx > 0)
604        {
605            // We have a valid packet...
606            assert (end_idx <= m_bytes.size());
607            std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
608            ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
609            BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
610            m_bytes.erase(0, end_idx);
611        }
612        else
613        {
614            assert (1 <= m_bytes.size());
615            ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
616            m_bytes.erase(0, 1);
617        }
618    }
619}
620
621lldb::pid_t
622GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
623{
624    StringExtractorGDBRemote response;
625    if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
626    {
627        if (response.GetChar() == 'Q')
628            if (response.GetChar() == 'C')
629                return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
630    }
631    return LLDB_INVALID_PROCESS_ID;
632}
633
634bool
635GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
636{
637    error_str.clear();
638    StringExtractorGDBRemote response;
639    if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
640    {
641        if (response.IsOKPacket())
642            return true;
643        if (response.GetChar() == 'E')
644        {
645            // A string the describes what failed when launching...
646            error_str = response.GetStringRef().substr(1);
647        }
648        else
649        {
650            error_str.assign ("unknown error occurred launching process");
651        }
652    }
653    else
654    {
655        error_str.assign ("failed to send the qLaunchSuccess packet");
656    }
657    return false;
658}
659
660int
661GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
662{
663    if (argv && argv[0])
664    {
665        StreamString packet;
666        packet.PutChar('A');
667        const char *arg;
668        for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
669        {
670            const int arg_len = strlen(arg);
671            if (i > 0)
672                packet.PutChar(',');
673            packet.Printf("%i,%i,", arg_len * 2, i);
674            packet.PutBytesAsRawHex8(arg, arg_len, eByteOrderHost, eByteOrderHost);
675        }
676
677        StringExtractorGDBRemote response;
678        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
679        {
680            if (response.IsOKPacket())
681                return 0;
682            uint8_t error = response.GetError();
683            if (error)
684                return error;
685        }
686    }
687    return -1;
688}
689
690int
691GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
692{
693    if (name_equal_value && name_equal_value[0])
694    {
695        StreamString packet;
696        packet.Printf("QEnvironment:%s", name_equal_value);
697        StringExtractorGDBRemote response;
698        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
699        {
700            if (response.IsOKPacket())
701                return 0;
702            uint8_t error = response.GetError();
703            if (error)
704                return error;
705        }
706    }
707    return -1;
708}
709
710bool
711GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds)
712{
713    m_arch.Clear();
714    m_os.Clear();
715    m_vendor.Clear();
716    m_byte_order = eByteOrderHost;
717    m_pointer_byte_size = 0;
718
719    StringExtractorGDBRemote response;
720    if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false))
721    {
722        if (response.IsUnsupportedPacket())
723            return false;
724
725
726        std::string name;
727        std::string value;
728        while (response.GetNameColonValue(name, value))
729        {
730            if (name.compare("cputype") == 0)
731            {
732                // exception type in big endian hex
733                m_arch.SetCPUType(Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0));
734            }
735            else if (name.compare("cpusubtype") == 0)
736            {
737                // exception count in big endian hex
738                m_arch.SetCPUSubtype(Args::StringToUInt32 (value.c_str(), 0, 0));
739            }
740            else if (name.compare("ostype") == 0)
741            {
742                // exception data in big endian hex
743                m_os.SetCString(value.c_str());
744            }
745            else if (name.compare("vendor") == 0)
746            {
747                m_vendor.SetCString(value.c_str());
748            }
749            else if (name.compare("endian") == 0)
750            {
751                if (value.compare("little") == 0)
752                    m_byte_order = eByteOrderLittle;
753                else if (value.compare("big") == 0)
754                    m_byte_order = eByteOrderBig;
755                else if (value.compare("pdp") == 0)
756                    m_byte_order = eByteOrderPDP;
757            }
758            else if (name.compare("ptrsize") == 0)
759            {
760                m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
761            }
762        }
763    }
764    return HostInfoIsValid();
765}
766
767int
768GDBRemoteCommunication::SendAttach
769(
770    lldb::pid_t pid,
771    uint32_t timeout_seconds,
772    StringExtractorGDBRemote& response
773)
774{
775    if (pid != LLDB_INVALID_PROCESS_ID)
776    {
777        StreamString packet;
778        packet.Printf("vAttach;%x", pid);
779
780        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
781        {
782            if (response.IsErrorPacket())
783                return response.GetError();
784            return 0;
785        }
786    }
787    return -1;
788}
789
790const lldb_private::ArchSpec &
791GDBRemoteCommunication::GetHostArchitecture ()
792{
793    if (!HostInfoIsValid ())
794        GetHostInfo (1);
795    return m_arch;
796}
797
798const lldb_private::ConstString &
799GDBRemoteCommunication::GetOSString ()
800{
801    if (!HostInfoIsValid ())
802        GetHostInfo (1);
803    return m_os;
804}
805
806const lldb_private::ConstString &
807GDBRemoteCommunication::GetVendorString()
808{
809    if (!HostInfoIsValid ())
810        GetHostInfo (1);
811    return m_vendor;
812}
813
814lldb::ByteOrder
815GDBRemoteCommunication::GetByteOrder ()
816{
817    if (!HostInfoIsValid ())
818        GetHostInfo (1);
819    return m_byte_order;
820}
821
822uint32_t
823GDBRemoteCommunication::GetAddressByteSize ()
824{
825    if (!HostInfoIsValid ())
826        GetHostInfo (1);
827    return m_pointer_byte_size;
828}
829
830addr_t
831GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
832{
833    char packet[64];
834    ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
835                permissions & lldb::ePermissionsReadable ? "r" : "",
836                permissions & lldb::ePermissionsWritable ? "w" : "",
837                permissions & lldb::ePermissionsExecutable ? "x" : "");
838    StringExtractorGDBRemote response;
839    if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
840    {
841        if (!response.IsErrorPacket())
842            return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
843    }
844    return LLDB_INVALID_ADDRESS;
845}
846
847bool
848GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
849{
850    char packet[64];
851    snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
852    StringExtractorGDBRemote response;
853    if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
854    {
855        if (!response.IsOKPacket())
856            return true;
857    }
858    return false;
859}
860
861bool
862GDBRemoteCommunication::WaitForIsRunning (uint32_t timeout_sec)
863{
864    TimeValue timeout;
865    if (timeout_sec)
866    {
867        timeout = TimeValue::Now();
868        timeout.OffsetWithSeconds (timeout_sec);
869    }
870    bool timed_out = false;
871    m_is_running.WaitForValueEqualTo (true, &timeout, &timed_out);
872    return timed_out;
873}
874
875
876