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