GDBRemoteCommunication.cpp revision 940b103224f3062578c7a7e6e76d8bf4a7956f2a
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 "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/Host.h"
23#include "lldb/Host/TimeValue.h"
24
25// Project includes
26#include "Utility/StringExtractorGDBRemote.h"
27#include "ProcessGDBRemote.h"
28#include "ProcessGDBRemoteLog.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33//----------------------------------------------------------------------
34// GDBRemoteCommunication constructor
35//----------------------------------------------------------------------
36GDBRemoteCommunication::GDBRemoteCommunication() :
37    Communication("gdb-remote.packets"),
38    m_supports_not_sending_acks (eLazyBoolCalculate),
39    m_supports_thread_suffix (eLazyBoolCalculate),
40    m_supports_qHostInfo (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_rx_packet_listener ("gdbremote.rx_packet"),
48    m_sequence_mutex (Mutex::eMutexTypeRecursive),
49    m_public_is_running (false),
50    m_private_is_running (false),
51    m_async_mutex (Mutex::eMutexTypeRecursive),
52    m_async_packet_predicate (false),
53    m_async_packet (),
54    m_async_response (),
55    m_async_timeout (UINT32_MAX),
56    m_async_signal (-1),
57    m_arch(),
58    m_os(),
59    m_vendor(),
60    m_byte_order(lldb::endian::InlHostByteOrder()),
61    m_pointer_byte_size(0)
62{
63    m_rx_packet_listener.StartListeningForEvents(this,
64                                                 Communication::eBroadcastBitPacketAvailable  |
65                                                 Communication::eBroadcastBitReadThreadDidExit);
66}
67
68//----------------------------------------------------------------------
69// Destructor
70//----------------------------------------------------------------------
71GDBRemoteCommunication::~GDBRemoteCommunication()
72{
73    m_rx_packet_listener.StopListeningForEvents(this,
74                                                Communication::eBroadcastBitPacketAvailable  |
75                                                Communication::eBroadcastBitReadThreadDidExit);
76    if (IsConnected())
77    {
78        StopReadThread();
79        Disconnect();
80    }
81}
82
83
84char
85GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
86{
87    int checksum = 0;
88
89    // We only need to compute the checksum if we are sending acks
90    if (GetSendAcks ())
91    {
92        for (size_t i = 0; i < payload_length; ++i)
93            checksum += payload[i];
94    }
95    return checksum & 255;
96}
97
98size_t
99GDBRemoteCommunication::SendAck ()
100{
101    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
102    if (log)
103        log->Printf ("send packet: +");
104    ConnectionStatus status = eConnectionStatusSuccess;
105    char ack_char = '+';
106    return Write (&ack_char, 1, status, NULL) == 1;
107}
108
109size_t
110GDBRemoteCommunication::SendNack ()
111{
112    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
113    if (log)
114        log->Printf ("send packet: -");
115    ConnectionStatus status = eConnectionStatusSuccess;
116    char nack_char = '-';
117    return Write (&nack_char, 1, status, NULL) == 1;
118}
119
120bool
121GDBRemoteCommunication::GetSendAcks ()
122{
123    if (m_supports_not_sending_acks == eLazyBoolCalculate)
124    {
125        StringExtractorGDBRemote response;
126        m_supports_not_sending_acks = eLazyBoolNo;
127        if (SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
128        {
129            if (response.IsOKPacket())
130                m_supports_not_sending_acks = eLazyBoolYes;
131        }
132    }
133    return m_supports_not_sending_acks != eLazyBoolYes;
134}
135
136void
137GDBRemoteCommunication::ResetDiscoverableSettings()
138{
139    m_supports_not_sending_acks = eLazyBoolCalculate;
140    m_supports_thread_suffix = eLazyBoolCalculate;
141    m_supports_qHostInfo = eLazyBoolCalculate;
142    m_supports_vCont_c = eLazyBoolCalculate;
143    m_supports_vCont_C = eLazyBoolCalculate;
144    m_supports_vCont_s = eLazyBoolCalculate;
145    m_supports_vCont_S = eLazyBoolCalculate;
146    m_arch.Clear();
147    m_os.Clear();
148    m_vendor.Clear();
149    m_byte_order = lldb::endian::InlHostByteOrder();
150    m_pointer_byte_size = 0;
151}
152
153
154bool
155GDBRemoteCommunication::GetThreadSuffixSupported ()
156{
157    if (m_supports_thread_suffix == eLazyBoolCalculate)
158    {
159        StringExtractorGDBRemote response;
160        m_supports_thread_suffix = eLazyBoolNo;
161        if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false))
162        {
163            if (response.IsOKPacket())
164                m_supports_thread_suffix = eLazyBoolYes;
165        }
166    }
167    return m_supports_thread_suffix;
168}
169bool
170GDBRemoteCommunication::GetVContSupported (char flavor)
171{
172    if (m_supports_vCont_c == eLazyBoolCalculate)
173    {
174        StringExtractorGDBRemote response;
175        m_supports_vCont_any = eLazyBoolNo;
176        m_supports_vCont_all = eLazyBoolNo;
177        m_supports_vCont_c = eLazyBoolNo;
178        m_supports_vCont_C = eLazyBoolNo;
179        m_supports_vCont_s = eLazyBoolNo;
180        m_supports_vCont_S = eLazyBoolNo;
181        if (SendPacketAndWaitForResponse("vCont?", response, 1, false))
182        {
183            const char *response_cstr = response.GetStringRef().c_str();
184            if (::strstr (response_cstr, ";c"))
185                m_supports_vCont_c = eLazyBoolYes;
186
187            if (::strstr (response_cstr, ";C"))
188                m_supports_vCont_C = eLazyBoolYes;
189
190            if (::strstr (response_cstr, ";s"))
191                m_supports_vCont_s = eLazyBoolYes;
192
193            if (::strstr (response_cstr, ";S"))
194                m_supports_vCont_S = eLazyBoolYes;
195
196            if (m_supports_vCont_c == eLazyBoolYes &&
197                m_supports_vCont_C == eLazyBoolYes &&
198                m_supports_vCont_s == eLazyBoolYes &&
199                m_supports_vCont_S == eLazyBoolYes)
200            {
201                m_supports_vCont_all = eLazyBoolYes;
202            }
203
204            if (m_supports_vCont_c == eLazyBoolYes ||
205                m_supports_vCont_C == eLazyBoolYes ||
206                m_supports_vCont_s == eLazyBoolYes ||
207                m_supports_vCont_S == eLazyBoolYes)
208            {
209                m_supports_vCont_any = eLazyBoolYes;
210            }
211        }
212    }
213
214    switch (flavor)
215    {
216    case 'a': return m_supports_vCont_any;
217    case 'A': return m_supports_vCont_all;
218    case 'c': return m_supports_vCont_c;
219    case 'C': return m_supports_vCont_C;
220    case 's': return m_supports_vCont_s;
221    case 'S': return m_supports_vCont_S;
222    default: break;
223    }
224    return false;
225}
226
227
228size_t
229GDBRemoteCommunication::SendPacketAndWaitForResponse
230(
231    const char *payload,
232    StringExtractorGDBRemote &response,
233    uint32_t timeout_seconds,
234    bool send_async
235)
236{
237    return SendPacketAndWaitForResponse (payload,
238                                         ::strlen (payload),
239                                         response,
240                                         timeout_seconds,
241                                         send_async);
242}
243
244size_t
245GDBRemoteCommunication::SendPacketAndWaitForResponse
246(
247    const char *payload,
248    size_t payload_length,
249    StringExtractorGDBRemote &response,
250    uint32_t timeout_seconds,
251    bool send_async
252)
253{
254    Mutex::Locker locker;
255    TimeValue timeout_time;
256    timeout_time = TimeValue::Now();
257    timeout_time.OffsetWithSeconds (timeout_seconds);
258    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
259
260    if (GetSequenceMutex (locker))
261    {
262        if (SendPacketNoLock (payload, strlen(payload)))
263            return WaitForPacketNoLock (response, &timeout_time);
264    }
265    else
266    {
267        if (send_async)
268        {
269            Mutex::Locker async_locker (m_async_mutex);
270            m_async_packet.assign(payload, payload_length);
271            m_async_timeout = timeout_seconds;
272            m_async_packet_predicate.SetValue (true, eBroadcastNever);
273
274            if (log)
275                log->Printf ("async: async packet = %s", m_async_packet.c_str());
276
277            bool timed_out = false;
278            bool sent_interrupt = false;
279            if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
280            {
281                if (sent_interrupt)
282                {
283                    if (log)
284                        log->Printf ("async: sent interrupt");
285                    if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
286                    {
287                        if (log)
288                            log->Printf ("async: got response");
289                        response = m_async_response;
290                        return response.GetStringRef().size();
291                    }
292                    else
293                    {
294                        if (log)
295                            log->Printf ("async: timed out waiting for response");
296                    }
297
298                    // Make sure we wait until the continue packet has been sent again...
299                    if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
300                    {
301                        if (log)
302                            log->Printf ("async: timed out waiting for process to resume");
303                    }
304                }
305                else
306                {
307                    // We had a racy condition where we went to send the interrupt
308                    // yet we were able to get the loc
309                }
310            }
311            else
312            {
313                if (log)
314                    log->Printf ("async: failed to interrupt");
315            }
316        }
317        else
318        {
319            if (log)
320                log->Printf ("mutex taken and send_async == false, aborting packet");
321        }
322    }
323    return 0;
324}
325
326//template<typename _Tp>
327//class ScopedValueChanger
328//{
329//public:
330//    // Take a value reference and the value to assign it to when this class
331//    // instance goes out of scope.
332//    ScopedValueChanger (_Tp &value_ref, _Tp value) :
333//        m_value_ref (value_ref),
334//        m_value (value)
335//    {
336//    }
337//
338//    // This object is going out of scope, change the value pointed to by
339//    // m_value_ref to the value we got during construction which was stored in
340//    // m_value;
341//    ~ScopedValueChanger ()
342//    {
343//        m_value_ref = m_value;
344//    }
345//protected:
346//    _Tp &m_value_ref;   // A reference to the value we will change when this object destructs
347//    _Tp m_value;        // The value to assign to m_value_ref when this goes out of scope.
348//};
349
350StateType
351GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
352(
353    ProcessGDBRemote *process,
354    const char *payload,
355    size_t packet_length,
356    StringExtractorGDBRemote &response
357)
358{
359    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
360    if (log)
361        log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
362
363    Mutex::Locker locker(m_sequence_mutex);
364    StateType state = eStateRunning;
365
366    BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
367    m_public_is_running.SetValue (true, eBroadcastNever);
368    // Set the starting continue packet into "continue_packet". This packet
369    // make change if we are interrupted and we continue after an async packet...
370    std::string continue_packet(payload, packet_length);
371
372    while (state == eStateRunning)
373    {
374        if (log)
375            log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
376        if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
377            state = eStateInvalid;
378
379        m_private_is_running.SetValue (true, eBroadcastNever);
380
381        if (log)
382            log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
383
384        if (WaitForPacket (response, (TimeValue*)NULL))
385        {
386            if (response.Empty())
387                state = eStateInvalid;
388            else
389            {
390                const char stop_type = response.GetChar();
391                if (log)
392                    log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
393                switch (stop_type)
394                {
395                case 'T':
396                case 'S':
397                    if (process->GetStopID() == 0)
398                    {
399                        if (process->GetID() == LLDB_INVALID_PROCESS_ID)
400                        {
401                            lldb::pid_t pid = GetCurrentProcessID (1);
402                            if (pid != LLDB_INVALID_PROCESS_ID)
403                                process->SetID (pid);
404                        }
405                        process->BuildDynamicRegisterInfo (true);
406                    }
407
408                    // Privately notify any internal threads that we have stopped
409                    // in case we wanted to interrupt our process, yet we might
410                    // send a packet and continue without returning control to the
411                    // user.
412                    m_private_is_running.SetValue (false, eBroadcastAlways);
413                    if (m_async_signal != -1)
414                    {
415                        if (log)
416                            log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
417
418                        // Save off the async signal we are supposed to send
419                        const int async_signal = m_async_signal;
420                        // Clear the async signal member so we don't end up
421                        // sending the signal multiple times...
422                        m_async_signal = -1;
423                        // Check which signal we stopped with
424                        uint8_t signo = response.GetHexU8(255);
425                        if (signo == async_signal)
426                        {
427                            if (log)
428                                log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
429
430                            // We already stopped with a signal that we wanted
431                            // to stop with, so we are done
432                            response.SetFilePos (0);
433                        }
434                        else
435                        {
436                            // We stopped with a different signal that the one
437                            // we wanted to stop with, so now we must resume
438                            // with the signal we want
439                            char signal_packet[32];
440                            int signal_packet_len = 0;
441                            signal_packet_len = ::snprintf (signal_packet,
442                                                            sizeof (signal_packet),
443                                                            "C%2.2x",
444                                                            async_signal);
445
446                            if (log)
447                                log->Printf ("async: stopped with signal %s, resume with %s",
448                                                   Host::GetSignalAsCString (signo),
449                                                   Host::GetSignalAsCString (async_signal));
450
451                            // Set the continue packet to resume...
452                            continue_packet.assign(signal_packet, signal_packet_len);
453                            continue;
454                        }
455                    }
456                    else if (m_async_packet_predicate.GetValue())
457                    {
458                        // We are supposed to send an asynchronous packet while
459                        // we are running.
460                        m_async_response.Clear();
461                        if (m_async_packet.empty())
462                        {
463                            if (log)
464                                log->Printf ("async: error: empty async packet");
465
466                        }
467                        else
468                        {
469                            if (log)
470                                log->Printf ("async: sending packet: %s",
471                                             m_async_packet.c_str());
472
473                            SendPacketAndWaitForResponse (&m_async_packet[0],
474                                                          m_async_packet.size(),
475                                                          m_async_response,
476                                                          m_async_timeout,
477                                                          false);
478                        }
479                        // Let the other thread that was trying to send the async
480                        // packet know that the packet has been sent and response is
481                        // ready...
482                        m_async_packet_predicate.SetValue(false, eBroadcastAlways);
483
484                        // Set the continue packet to resume...
485                        continue_packet.assign (1, 'c');
486                        continue;
487                    }
488                    // Stop with signal and thread info
489                    state = eStateStopped;
490                    break;
491
492                case 'W':
493                case 'X':
494                    // process exited
495                    state = eStateExited;
496                    break;
497
498                case 'O':
499                    // STDOUT
500                    {
501                        std::string inferior_stdout;
502                        inferior_stdout.reserve(response.GetBytesLeft () / 2);
503                        char ch;
504                        while ((ch = response.GetHexU8()) != '\0')
505                            inferior_stdout.append(1, ch);
506                        process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
507                    }
508                    break;
509
510                case 'E':
511                    // ERROR
512                    state = eStateInvalid;
513                    break;
514
515                default:
516                    if (log)
517                        log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
518                    break;
519                }
520            }
521        }
522        else
523        {
524            if (log)
525                log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
526            state = eStateInvalid;
527        }
528    }
529    if (log)
530        log->Printf ("GDBRemoteCommunication::%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
537size_t
538GDBRemoteCommunication::SendPacket (const char *payload)
539{
540    Mutex::Locker locker(m_sequence_mutex);
541    return SendPacketNoLock (payload, ::strlen (payload));
542}
543
544size_t
545GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
546{
547    Mutex::Locker locker(m_sequence_mutex);
548    return SendPacketNoLock (payload, payload_length);
549}
550
551size_t
552GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
553{
554    if (IsConnected())
555    {
556        StreamString packet(0, 4, eByteOrderBig);
557
558        packet.PutChar('$');
559        packet.Write (payload, payload_length);
560        packet.PutChar('#');
561        packet.PutHex8(CalculcateChecksum (payload, payload_length));
562
563        LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
564        if (log)
565            log->Printf ("send packet: %s", packet.GetData());
566        ConnectionStatus status = eConnectionStatusSuccess;
567        size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
568        if (bytes_written == packet.GetSize())
569        {
570            if (GetSendAcks ())
571            {
572                if (GetAck (1) != '+')
573                    return 0;
574            }
575        }
576        else
577        {
578            LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
579            if (log)
580                log->Printf ("error: failed to send packet: %s", packet.GetData());
581        }
582        return bytes_written;
583    }
584    return 0;
585}
586
587char
588GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
589{
590    StringExtractorGDBRemote response;
591    if (WaitForPacket (response, timeout_seconds) == 1)
592        return response.GetChar();
593    return 0;
594}
595
596bool
597GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
598{
599    return locker.TryLock (m_sequence_mutex.GetMutex());
600}
601
602bool
603GDBRemoteCommunication::SendAsyncSignal (int signo)
604{
605    m_async_signal = signo;
606    bool timed_out = false;
607    bool sent_interrupt = false;
608    Mutex::Locker locker;
609    if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
610        return true;
611    m_async_signal = -1;
612    return false;
613}
614
615// This function takes a mutex locker as a parameter in case the GetSequenceMutex
616// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
617// (the expected result), then it will send the halt packet. If it does succeed
618// then the caller that requested the interrupt will want to keep the sequence
619// locked down so that no one else can send packets while the caller has control.
620// This function usually gets called when we are running and need to stop the
621// target. It can also be used when we are running and and we need to do something
622// else (like read/write memory), so we need to interrupt the running process
623// (gdb remote protocol requires this), and do what we need to do, then resume.
624
625bool
626GDBRemoteCommunication::SendInterrupt
627(
628    Mutex::Locker& locker,
629    uint32_t seconds_to_wait_for_stop,
630    bool &sent_interrupt,
631    bool &timed_out
632)
633{
634    sent_interrupt = false;
635    timed_out = false;
636    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
637
638    if (IsRunning())
639    {
640        // Only send an interrupt if our debugserver is running...
641        if (GetSequenceMutex (locker) == false)
642        {
643            // Someone has the mutex locked waiting for a response or for the
644            // inferior to stop, so send the interrupt on the down low...
645            char ctrl_c = '\x03';
646            ConnectionStatus status = eConnectionStatusSuccess;
647            TimeValue timeout;
648            if (seconds_to_wait_for_stop)
649            {
650                timeout = TimeValue::Now();
651                timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
652            }
653            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
654            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
655            if (bytes_written > 0)
656            {
657                sent_interrupt = true;
658                if (seconds_to_wait_for_stop)
659                {
660                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
661                    {
662                        if (log)
663                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
664                        return true;
665                    }
666                    else
667                    {
668                        if (log)
669                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
670                    }
671                }
672                else
673                {
674                    if (log)
675                        log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
676                    return true;
677                }
678            }
679            else
680            {
681                if (log)
682                    log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
683            }
684            return false;
685        }
686        else
687        {
688            if (log)
689                log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
690        }
691    }
692    return true;
693}
694
695bool
696GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
697{
698    return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
699}
700
701bool
702GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
703{
704    return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
705}
706
707size_t
708GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
709{
710    Mutex::Locker locker(m_sequence_mutex);
711    TimeValue timeout_time;
712    timeout_time = TimeValue::Now();
713    timeout_time.OffsetWithSeconds (timeout_seconds);
714    return WaitForPacketNoLock (response, &timeout_time);
715}
716
717size_t
718GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
719{
720    Mutex::Locker locker(m_sequence_mutex);
721    return WaitForPacketNoLock (response, timeout_time_ptr);
722}
723
724size_t
725GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
726{
727    bool checksum_error = false;
728    response.Clear ();
729
730    EventSP event_sp;
731
732    if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
733    {
734        const uint32_t event_type = event_sp->GetType();
735        if (event_type | Communication::eBroadcastBitPacketAvailable)
736        {
737            const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
738            if (event_bytes)
739            {
740                const char * packet_data =  (const char *)event_bytes->GetBytes();
741                LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
742                if (log)
743                    log->Printf ("read packet: %s", packet_data);
744                const size_t packet_size =  event_bytes->GetByteSize();
745                if (packet_data && packet_size > 0)
746                {
747                    std::string &response_str = response.GetStringRef();
748                    if (packet_data[0] == '$')
749                    {
750                        bool success = false;
751                        if (packet_size < 4)
752                            ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
753                        else if (packet_data[packet_size-3] != '#' ||
754                                 !::isxdigit (packet_data[packet_size-2]) ||
755                                 !::isxdigit (packet_data[packet_size-1]))
756                            ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
757                        else
758                            success = true;
759
760                        if (success)
761                            response_str.assign (packet_data + 1, packet_size - 4);
762                        if (GetSendAcks ())
763                        {
764                            char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
765                            char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
766                            checksum_error = packet_checksum != actual_checksum;
767                            // Send the ack or nack if needed
768                            if (checksum_error || !success)
769                                SendNack();
770                            else
771                                SendAck();
772                        }
773                    }
774                    else
775                    {
776                        response_str.assign (packet_data, packet_size);
777                    }
778                    return response_str.size();
779                }
780            }
781        }
782        else if (Communication::eBroadcastBitReadThreadDidExit)
783        {
784            // Our read thread exited on us so just fall through and return zero...
785        }
786    }
787    return 0;
788}
789
790void
791GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
792                                            ConnectionStatus status)
793{
794    // Put the packet data into the buffer in a thread safe fashion
795    Mutex::Locker locker(m_bytes_mutex);
796    m_bytes.append ((const char *)src, src_len);
797
798    // Parse up the packets into gdb remote packets
799    while (!m_bytes.empty())
800    {
801        // end_idx must be one past the last valid packet byte. Start
802        // it off with an invalid value that is the same as the current
803        // index.
804        size_t end_idx = 0;
805
806        switch (m_bytes[0])
807        {
808            case '+':       // Look for ack
809            case '-':       // Look for cancel
810            case '\x03':    // ^C to halt target
811                end_idx = 1;  // The command is one byte long...
812                break;
813
814            case '$':
815                // Look for a standard gdb packet?
816                end_idx = m_bytes.find('#');
817                if (end_idx != std::string::npos)
818                {
819                    if (end_idx + 2 < m_bytes.size())
820                    {
821                        end_idx += 3;
822                    }
823                    else
824                    {
825                        // Checksum bytes aren't all here yet
826                        end_idx = std::string::npos;
827                    }
828                }
829                break;
830
831            default:
832                break;
833        }
834
835        if (end_idx == std::string::npos)
836        {
837            //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
838            return;
839        }
840        else if (end_idx > 0)
841        {
842            // We have a valid packet...
843            assert (end_idx <= m_bytes.size());
844            std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
845            ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
846            BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
847            m_bytes.erase(0, end_idx);
848        }
849        else
850        {
851            assert (1 <= m_bytes.size());
852            ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
853            m_bytes.erase(0, 1);
854        }
855    }
856}
857
858lldb::pid_t
859GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
860{
861    StringExtractorGDBRemote response;
862    if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
863    {
864        if (response.GetChar() == 'Q')
865            if (response.GetChar() == 'C')
866                return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
867    }
868    return LLDB_INVALID_PROCESS_ID;
869}
870
871bool
872GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
873{
874    error_str.clear();
875    StringExtractorGDBRemote response;
876    if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
877    {
878        if (response.IsOKPacket())
879            return true;
880        if (response.GetChar() == 'E')
881        {
882            // A string the describes what failed when launching...
883            error_str = response.GetStringRef().substr(1);
884        }
885        else
886        {
887            error_str.assign ("unknown error occurred launching process");
888        }
889    }
890    else
891    {
892        error_str.assign ("failed to send the qLaunchSuccess packet");
893    }
894    return false;
895}
896
897int
898GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
899{
900    if (argv && argv[0])
901    {
902        StreamString packet;
903        packet.PutChar('A');
904        const char *arg;
905        for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
906        {
907            const int arg_len = strlen(arg);
908            if (i > 0)
909                packet.PutChar(',');
910            packet.Printf("%i,%i,", arg_len * 2, i);
911            packet.PutBytesAsRawHex8(arg, arg_len, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
912        }
913
914        StringExtractorGDBRemote response;
915        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
916        {
917            if (response.IsOKPacket())
918                return 0;
919            uint8_t error = response.GetError();
920            if (error)
921                return error;
922        }
923    }
924    return -1;
925}
926
927int
928GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
929{
930    if (name_equal_value && name_equal_value[0])
931    {
932        StreamString packet;
933        packet.Printf("QEnvironment:%s", name_equal_value);
934        StringExtractorGDBRemote response;
935        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
936        {
937            if (response.IsOKPacket())
938                return 0;
939            uint8_t error = response.GetError();
940            if (error)
941                return error;
942        }
943    }
944    return -1;
945}
946
947bool
948GDBRemoteCommunication::GetHostInfo ()
949{
950    if (m_supports_qHostInfo == eLazyBoolCalculate)
951    {
952        m_supports_qHostInfo = eLazyBoolNo;
953
954        StringExtractorGDBRemote response;
955        if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false))
956        {
957            if (response.IsUnsupportedPacket())
958                return false;
959
960            m_supports_qHostInfo = eLazyBoolYes;
961
962            std::string name;
963            std::string value;
964            uint32_t cpu = LLDB_INVALID_CPUTYPE;
965            uint32_t sub = 0;
966
967            while (response.GetNameColonValue(name, value))
968            {
969                if (name.compare("cputype") == 0)
970                {
971                    // exception type in big endian hex
972                    cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
973                }
974                else if (name.compare("cpusubtype") == 0)
975                {
976                    // exception count in big endian hex
977                    sub = Args::StringToUInt32 (value.c_str(), 0, 0);
978                }
979                else if (name.compare("ostype") == 0)
980                {
981                    // exception data in big endian hex
982                    m_os.SetCString(value.c_str());
983                }
984                else if (name.compare("vendor") == 0)
985                {
986                    m_vendor.SetCString(value.c_str());
987                }
988                else if (name.compare("endian") == 0)
989                {
990                    if (value.compare("little") == 0)
991                        m_byte_order = eByteOrderLittle;
992                    else if (value.compare("big") == 0)
993                        m_byte_order = eByteOrderBig;
994                    else if (value.compare("pdp") == 0)
995                        m_byte_order = eByteOrderPDP;
996                }
997                else if (name.compare("ptrsize") == 0)
998                {
999                    m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
1000                }
1001            }
1002
1003            if (cpu != LLDB_INVALID_CPUTYPE)
1004                m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
1005        }
1006    }
1007    return m_supports_qHostInfo == eLazyBoolYes;
1008}
1009
1010int
1011GDBRemoteCommunication::SendAttach
1012(
1013    lldb::pid_t pid,
1014    uint32_t timeout_seconds,
1015    StringExtractorGDBRemote& response
1016)
1017{
1018    if (pid != LLDB_INVALID_PROCESS_ID)
1019    {
1020        StreamString packet;
1021        packet.Printf("vAttach;%x", pid);
1022
1023        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
1024        {
1025            if (response.IsErrorPacket())
1026                return response.GetError();
1027            return 0;
1028        }
1029    }
1030    return -1;
1031}
1032
1033const lldb_private::ArchSpec &
1034GDBRemoteCommunication::GetHostArchitecture ()
1035{
1036    if (!HostInfoIsValid ())
1037        GetHostInfo ();
1038    return m_arch;
1039}
1040
1041const lldb_private::ConstString &
1042GDBRemoteCommunication::GetOSString ()
1043{
1044    if (!HostInfoIsValid ())
1045        GetHostInfo ();
1046    return m_os;
1047}
1048
1049const lldb_private::ConstString &
1050GDBRemoteCommunication::GetVendorString()
1051{
1052    if (!HostInfoIsValid ())
1053        GetHostInfo ();
1054    return m_vendor;
1055}
1056
1057lldb::ByteOrder
1058GDBRemoteCommunication::GetByteOrder ()
1059{
1060    if (!HostInfoIsValid ())
1061        GetHostInfo ();
1062    return m_byte_order;
1063}
1064
1065uint32_t
1066GDBRemoteCommunication::GetAddressByteSize ()
1067{
1068    if (!HostInfoIsValid ())
1069        GetHostInfo ();
1070    return m_pointer_byte_size;
1071}
1072
1073addr_t
1074GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
1075{
1076    char packet[64];
1077    ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1078                permissions & lldb::ePermissionsReadable ? "r" : "",
1079                permissions & lldb::ePermissionsWritable ? "w" : "",
1080                permissions & lldb::ePermissionsExecutable ? "x" : "");
1081    StringExtractorGDBRemote response;
1082    if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1083    {
1084        if (!response.IsErrorPacket())
1085            return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1086    }
1087    return LLDB_INVALID_ADDRESS;
1088}
1089
1090bool
1091GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
1092{
1093    char packet[64];
1094    snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1095    StringExtractorGDBRemote response;
1096    if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1097    {
1098        if (response.IsOKPacket())
1099            return true;
1100    }
1101    return false;
1102}
1103
1104