GDBRemoteCommunication.cpp revision a2f7423310044cf76d8d52aa9153b7fd8b226b49
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                    state = eStateInvalid;
519                    break;
520                }
521            }
522        }
523        else
524        {
525            if (log)
526                log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
527            state = eStateInvalid;
528        }
529    }
530    if (log)
531        log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
532    response.SetFilePos(0);
533    m_private_is_running.SetValue (false, eBroadcastAlways);
534    m_public_is_running.SetValue (false, eBroadcastAlways);
535    return state;
536}
537
538size_t
539GDBRemoteCommunication::SendPacket (const char *payload)
540{
541    Mutex::Locker locker(m_sequence_mutex);
542    return SendPacketNoLock (payload, ::strlen (payload));
543}
544
545size_t
546GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
547{
548    Mutex::Locker locker(m_sequence_mutex);
549    return SendPacketNoLock (payload, payload_length);
550}
551
552size_t
553GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
554{
555    if (IsConnected())
556    {
557        StreamString packet(0, 4, eByteOrderBig);
558
559        packet.PutChar('$');
560        packet.Write (payload, payload_length);
561        packet.PutChar('#');
562        packet.PutHex8(CalculcateChecksum (payload, payload_length));
563
564        LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
565        if (log)
566            log->Printf ("send packet: %s", packet.GetData());
567        ConnectionStatus status = eConnectionStatusSuccess;
568        size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
569        if (bytes_written == packet.GetSize())
570        {
571            if (GetSendAcks ())
572            {
573                if (GetAck (1) != '+')
574                    return 0;
575            }
576        }
577        else
578        {
579            LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
580            if (log)
581                log->Printf ("error: failed to send packet: %s", packet.GetData());
582        }
583        return bytes_written;
584    }
585    return 0;
586}
587
588char
589GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
590{
591    StringExtractorGDBRemote response;
592    if (WaitForPacket (response, timeout_seconds) == 1)
593        return response.GetChar();
594    return 0;
595}
596
597bool
598GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
599{
600    return locker.TryLock (m_sequence_mutex.GetMutex());
601}
602
603bool
604GDBRemoteCommunication::SendAsyncSignal (int signo)
605{
606    m_async_signal = signo;
607    bool timed_out = false;
608    bool sent_interrupt = false;
609    Mutex::Locker locker;
610    if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
611        return true;
612    m_async_signal = -1;
613    return false;
614}
615
616// This function takes a mutex locker as a parameter in case the GetSequenceMutex
617// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
618// (the expected result), then it will send the halt packet. If it does succeed
619// then the caller that requested the interrupt will want to keep the sequence
620// locked down so that no one else can send packets while the caller has control.
621// This function usually gets called when we are running and need to stop the
622// target. It can also be used when we are running and and we need to do something
623// else (like read/write memory), so we need to interrupt the running process
624// (gdb remote protocol requires this), and do what we need to do, then resume.
625
626bool
627GDBRemoteCommunication::SendInterrupt
628(
629    Mutex::Locker& locker,
630    uint32_t seconds_to_wait_for_stop,
631    bool &sent_interrupt,
632    bool &timed_out
633)
634{
635    sent_interrupt = false;
636    timed_out = false;
637    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
638
639    if (IsRunning())
640    {
641        // Only send an interrupt if our debugserver is running...
642        if (GetSequenceMutex (locker) == false)
643        {
644            // Someone has the mutex locked waiting for a response or for the
645            // inferior to stop, so send the interrupt on the down low...
646            char ctrl_c = '\x03';
647            ConnectionStatus status = eConnectionStatusSuccess;
648            TimeValue timeout;
649            if (seconds_to_wait_for_stop)
650            {
651                timeout = TimeValue::Now();
652                timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
653            }
654            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
655            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
656            if (bytes_written > 0)
657            {
658                sent_interrupt = true;
659                if (seconds_to_wait_for_stop)
660                {
661                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
662                    {
663                        if (log)
664                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
665                        return true;
666                    }
667                    else
668                    {
669                        if (log)
670                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
671                    }
672                }
673                else
674                {
675                    if (log)
676                        log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
677                    return true;
678                }
679            }
680            else
681            {
682                if (log)
683                    log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
684            }
685            return false;
686        }
687        else
688        {
689            if (log)
690                log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
691        }
692    }
693    return true;
694}
695
696bool
697GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
698{
699    return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
700}
701
702bool
703GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
704{
705    return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
706}
707
708size_t
709GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
710{
711    Mutex::Locker locker(m_sequence_mutex);
712    TimeValue timeout_time;
713    timeout_time = TimeValue::Now();
714    timeout_time.OffsetWithSeconds (timeout_seconds);
715    return WaitForPacketNoLock (response, &timeout_time);
716}
717
718size_t
719GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
720{
721    Mutex::Locker locker(m_sequence_mutex);
722    return WaitForPacketNoLock (response, timeout_time_ptr);
723}
724
725size_t
726GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
727{
728    bool checksum_error = false;
729    response.Clear ();
730
731    EventSP event_sp;
732
733    if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
734    {
735        const uint32_t event_type = event_sp->GetType();
736        if (event_type | Communication::eBroadcastBitPacketAvailable)
737        {
738            const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
739            if (event_bytes)
740            {
741                const char * packet_data =  (const char *)event_bytes->GetBytes();
742                LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
743                if (log)
744                    log->Printf ("read packet: %s", packet_data);
745                const size_t packet_size =  event_bytes->GetByteSize();
746                if (packet_data && packet_size > 0)
747                {
748                    std::string &response_str = response.GetStringRef();
749                    if (packet_data[0] == '$')
750                    {
751                        bool success = false;
752                        if (packet_size < 4)
753                            ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
754                        else if (packet_data[packet_size-3] != '#' ||
755                                 !::isxdigit (packet_data[packet_size-2]) ||
756                                 !::isxdigit (packet_data[packet_size-1]))
757                            ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
758                        else
759                            success = true;
760
761                        if (success)
762                            response_str.assign (packet_data + 1, packet_size - 4);
763                        if (GetSendAcks ())
764                        {
765                            char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
766                            char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
767                            checksum_error = packet_checksum != actual_checksum;
768                            // Send the ack or nack if needed
769                            if (checksum_error || !success)
770                                SendNack();
771                            else
772                                SendAck();
773                        }
774                    }
775                    else
776                    {
777                        response_str.assign (packet_data, packet_size);
778                    }
779                    return response_str.size();
780                }
781            }
782        }
783        else if (Communication::eBroadcastBitReadThreadDidExit)
784        {
785            // Our read thread exited on us so just fall through and return zero...
786        }
787    }
788    return 0;
789}
790
791void
792GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
793                                            ConnectionStatus status)
794{
795    // Put the packet data into the buffer in a thread safe fashion
796    Mutex::Locker locker(m_bytes_mutex);
797    m_bytes.append ((const char *)src, src_len);
798
799    // Parse up the packets into gdb remote packets
800    while (!m_bytes.empty())
801    {
802        // end_idx must be one past the last valid packet byte. Start
803        // it off with an invalid value that is the same as the current
804        // index.
805        size_t end_idx = 0;
806
807        switch (m_bytes[0])
808        {
809            case '+':       // Look for ack
810            case '-':       // Look for cancel
811            case '\x03':    // ^C to halt target
812                end_idx = 1;  // The command is one byte long...
813                break;
814
815            case '$':
816                // Look for a standard gdb packet?
817                end_idx = m_bytes.find('#');
818                if (end_idx != std::string::npos)
819                {
820                    if (end_idx + 2 < m_bytes.size())
821                    {
822                        end_idx += 3;
823                    }
824                    else
825                    {
826                        // Checksum bytes aren't all here yet
827                        end_idx = std::string::npos;
828                    }
829                }
830                break;
831
832            default:
833                break;
834        }
835
836        if (end_idx == std::string::npos)
837        {
838            //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
839            return;
840        }
841        else if (end_idx > 0)
842        {
843            // We have a valid packet...
844            assert (end_idx <= m_bytes.size());
845            std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
846            ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
847            BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
848            m_bytes.erase(0, end_idx);
849        }
850        else
851        {
852            assert (1 <= m_bytes.size());
853            ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
854            m_bytes.erase(0, 1);
855        }
856    }
857}
858
859lldb::pid_t
860GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
861{
862    StringExtractorGDBRemote response;
863    if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
864    {
865        if (response.GetChar() == 'Q')
866            if (response.GetChar() == 'C')
867                return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
868    }
869    return LLDB_INVALID_PROCESS_ID;
870}
871
872bool
873GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
874{
875    error_str.clear();
876    StringExtractorGDBRemote response;
877    if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
878    {
879        if (response.IsOKPacket())
880            return true;
881        if (response.GetChar() == 'E')
882        {
883            // A string the describes what failed when launching...
884            error_str = response.GetStringRef().substr(1);
885        }
886        else
887        {
888            error_str.assign ("unknown error occurred launching process");
889        }
890    }
891    else
892    {
893        error_str.assign ("failed to send the qLaunchSuccess packet");
894    }
895    return false;
896}
897
898int
899GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
900{
901    if (argv && argv[0])
902    {
903        StreamString packet;
904        packet.PutChar('A');
905        const char *arg;
906        for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
907        {
908            const int arg_len = strlen(arg);
909            if (i > 0)
910                packet.PutChar(',');
911            packet.Printf("%i,%i,", arg_len * 2, i);
912            packet.PutBytesAsRawHex8 (arg, arg_len);
913        }
914
915        StringExtractorGDBRemote response;
916        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
917        {
918            if (response.IsOKPacket())
919                return 0;
920            uint8_t error = response.GetError();
921            if (error)
922                return error;
923        }
924    }
925    return -1;
926}
927
928int
929GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
930{
931    if (name_equal_value && name_equal_value[0])
932    {
933        StreamString packet;
934        packet.Printf("QEnvironment:%s", name_equal_value);
935        StringExtractorGDBRemote response;
936        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
937        {
938            if (response.IsOKPacket())
939                return 0;
940            uint8_t error = response.GetError();
941            if (error)
942                return error;
943        }
944    }
945    return -1;
946}
947
948bool
949GDBRemoteCommunication::GetHostInfo ()
950{
951    if (m_supports_qHostInfo == eLazyBoolCalculate)
952    {
953        m_supports_qHostInfo = eLazyBoolNo;
954
955        StringExtractorGDBRemote response;
956        if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false))
957        {
958            if (response.IsUnsupportedPacket())
959                return false;
960
961            m_supports_qHostInfo = eLazyBoolYes;
962
963            std::string name;
964            std::string value;
965            uint32_t cpu = LLDB_INVALID_CPUTYPE;
966            uint32_t sub = 0;
967
968            while (response.GetNameColonValue(name, value))
969            {
970                if (name.compare("cputype") == 0)
971                {
972                    // exception type in big endian hex
973                    cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
974                }
975                else if (name.compare("cpusubtype") == 0)
976                {
977                    // exception count in big endian hex
978                    sub = Args::StringToUInt32 (value.c_str(), 0, 0);
979                }
980                else if (name.compare("ostype") == 0)
981                {
982                    // exception data in big endian hex
983                    m_os.SetCString(value.c_str());
984                }
985                else if (name.compare("vendor") == 0)
986                {
987                    m_vendor.SetCString(value.c_str());
988                }
989                else if (name.compare("endian") == 0)
990                {
991                    if (value.compare("little") == 0)
992                        m_byte_order = eByteOrderLittle;
993                    else if (value.compare("big") == 0)
994                        m_byte_order = eByteOrderBig;
995                    else if (value.compare("pdp") == 0)
996                        m_byte_order = eByteOrderPDP;
997                }
998                else if (name.compare("ptrsize") == 0)
999                {
1000                    m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
1001                }
1002            }
1003
1004            if (cpu != LLDB_INVALID_CPUTYPE)
1005                m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
1006        }
1007    }
1008    return m_supports_qHostInfo == eLazyBoolYes;
1009}
1010
1011int
1012GDBRemoteCommunication::SendAttach
1013(
1014    lldb::pid_t pid,
1015    uint32_t timeout_seconds,
1016    StringExtractorGDBRemote& response
1017)
1018{
1019    if (pid != LLDB_INVALID_PROCESS_ID)
1020    {
1021        StreamString packet;
1022        packet.Printf("vAttach;%x", pid);
1023
1024        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
1025        {
1026            if (response.IsErrorPacket())
1027                return response.GetError();
1028            return 0;
1029        }
1030    }
1031    return -1;
1032}
1033
1034const lldb_private::ArchSpec &
1035GDBRemoteCommunication::GetHostArchitecture ()
1036{
1037    if (!HostInfoIsValid ())
1038        GetHostInfo ();
1039    return m_arch;
1040}
1041
1042const lldb_private::ConstString &
1043GDBRemoteCommunication::GetOSString ()
1044{
1045    if (!HostInfoIsValid ())
1046        GetHostInfo ();
1047    return m_os;
1048}
1049
1050const lldb_private::ConstString &
1051GDBRemoteCommunication::GetVendorString()
1052{
1053    if (!HostInfoIsValid ())
1054        GetHostInfo ();
1055    return m_vendor;
1056}
1057
1058lldb::ByteOrder
1059GDBRemoteCommunication::GetByteOrder ()
1060{
1061    if (!HostInfoIsValid ())
1062        GetHostInfo ();
1063    return m_byte_order;
1064}
1065
1066uint32_t
1067GDBRemoteCommunication::GetAddressByteSize ()
1068{
1069    if (!HostInfoIsValid ())
1070        GetHostInfo ();
1071    return m_pointer_byte_size;
1072}
1073
1074addr_t
1075GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
1076{
1077    char packet[64];
1078    ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1079                permissions & lldb::ePermissionsReadable ? "r" : "",
1080                permissions & lldb::ePermissionsWritable ? "w" : "",
1081                permissions & lldb::ePermissionsExecutable ? "x" : "");
1082    StringExtractorGDBRemote response;
1083    if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1084    {
1085        if (!response.IsErrorPacket())
1086            return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1087    }
1088    return LLDB_INVALID_ADDRESS;
1089}
1090
1091bool
1092GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
1093{
1094    char packet[64];
1095    snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1096    StringExtractorGDBRemote response;
1097    if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1098    {
1099        if (response.IsOKPacket())
1100            return true;
1101    }
1102    return false;
1103}
1104
1105int
1106GDBRemoteCommunication::SetSTDIN (char const *path)
1107{
1108    if (path && path[0])
1109    {
1110        StreamString packet;
1111        packet.PutCString("QSetSTDIN:");
1112        packet.PutBytesAsRawHex8(path, strlen(path));
1113
1114        StringExtractorGDBRemote response;
1115        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false))
1116        {
1117            if (response.IsOKPacket())
1118                return 0;
1119            uint8_t error = response.GetError();
1120            if (error)
1121                return error;
1122        }
1123    }
1124    return -1;
1125}
1126
1127int
1128GDBRemoteCommunication::SetSTDOUT (char const *path)
1129{
1130    if (path && path[0])
1131    {
1132        StreamString packet;
1133        packet.PutCString("QSetSTDOUT:");
1134        packet.PutBytesAsRawHex8(path, strlen(path));
1135
1136        StringExtractorGDBRemote response;
1137        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false))
1138        {
1139            if (response.IsOKPacket())
1140                return 0;
1141            uint8_t error = response.GetError();
1142            if (error)
1143                return error;
1144        }
1145    }
1146    return -1;
1147}
1148
1149int
1150GDBRemoteCommunication::SetSTDERR (char const *path)
1151{
1152    if (path && path[0])
1153    {
1154        StreamString packet;
1155        packet.PutCString("QSetSTDERR:");
1156        packet.PutBytesAsRawHex8(path, strlen(path));
1157
1158        StringExtractorGDBRemote response;
1159        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false))
1160        {
1161            if (response.IsOKPacket())
1162                return 0;
1163            uint8_t error = response.GetError();
1164            if (error)
1165                return error;
1166        }
1167    }
1168    return -1;
1169}
1170
1171int
1172GDBRemoteCommunication::SetWorkingDir (char const *path)
1173{
1174    if (path && path[0])
1175    {
1176        StreamString packet;
1177        packet.PutCString("QSetWorkingDir:");
1178        packet.PutBytesAsRawHex8(path, strlen(path));
1179
1180        StringExtractorGDBRemote response;
1181        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false))
1182        {
1183            if (response.IsOKPacket())
1184                return 0;
1185            uint8_t error = response.GetError();
1186            if (error)
1187                return error;
1188        }
1189    }
1190    return -1;
1191}
1192
1193int
1194GDBRemoteCommunication::SetDisableASLR (bool enable)
1195{
1196    StreamString packet;
1197    packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
1198
1199    StringExtractorGDBRemote response;
1200    if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false))
1201    {
1202        if (response.IsOKPacket())
1203            return 0;
1204        uint8_t error = response.GetError();
1205        if (error)
1206            return error;
1207    }
1208    return -1;
1209}
1210