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