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