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