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