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