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