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