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