blob: aa100840936a614ceec2aa249ebebcc51f061878 [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() :
Greg Claytoneecb0f32010-12-04 02:39:47 +000035 Communication("gdb-remote.packets"),
Chris Lattner24943d22010-06-08 16:52:24 +000036 m_send_acks (true),
Greg Claytonc71899e2011-01-18 19:36:39 +000037 m_thread_suffix_supported (false),
Chris Lattner24943d22010-06-08 16:52:24 +000038 m_rx_packet_listener ("gdbremote.rx_packet"),
39 m_sequence_mutex (Mutex::eMutexTypeRecursive),
Greg Claytoncecf3482011-01-20 07:53:45 +000040 m_public_is_running (false),
41 m_private_is_running (false),
Chris Lattner24943d22010-06-08 16:52:24 +000042 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//----------------------------------------------------------------------
62GDBRemoteCommunication::~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
75char
76GDBRemoteCommunication::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 {
Greg Clayton54e7afa2010-07-09 20:39:50 +000083 for (size_t i = 0; i < payload_length; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +000084 checksum += payload[i];
85 }
86 return checksum & 255;
87}
88
89size_t
Greg Claytona4881d02011-01-22 07:12:45 +000090GDBRemoteCommunication::SendAck ()
Chris Lattner24943d22010-06-08 16:52:24 +000091{
Greg Claytona4881d02011-01-22 07:12:45 +000092 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: +");
Chris Lattner24943d22010-06-08 16:52:24 +000093 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytona4881d02011-01-22 07:12:45 +000094 char ack_char = '+';
Chris Lattner24943d22010-06-08 16:52:24 +000095 return Write (&ack_char, 1, status, NULL) == 1;
96}
97
98size_t
Greg Claytona4881d02011-01-22 07:12:45 +000099GDBRemoteCommunication::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
107size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000108GDBRemoteCommunication::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
123size_t
124GDBRemoteCommunication::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
Greg Clayton1a679462010-09-03 19:15:43 +0000138 if (GetSequenceMutex (locker))
Chris Lattner24943d22010-06-08 16:52:24 +0000139 {
140 if (SendPacketNoLock (payload, strlen(payload)))
141 return WaitForPacketNoLock (response, &timeout_time);
142 }
143 else
144 {
145 if (send_async)
146 {
147 Mutex::Locker async_locker (m_async_mutex);
148 m_async_packet.assign(payload, payload_length);
149 m_async_timeout = timeout_seconds;
150 m_async_packet_predicate.SetValue (true, eBroadcastNever);
151
152 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000153 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000154 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000155 {
156 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
157 {
158 response = m_async_response;
159 return response.GetStringRef().size();
160 }
161 }
162// if (timed_out)
163// m_error.SetErrorString("Timeout.");
164// else
165// m_error.SetErrorString("Unknown error.");
166 }
167 else
168 {
169// m_error.SetErrorString("Sequence mutex is locked.");
170 }
171 }
172 return 0;
173}
174
175//template<typename _Tp>
176//class ScopedValueChanger
177//{
178//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000179// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000180// // instance goes out of scope.
181// ScopedValueChanger (_Tp &value_ref, _Tp value) :
182// m_value_ref (value_ref),
183// m_value (value)
184// {
185// }
186//
187// // This object is going out of scope, change the value pointed to by
188// // m_value_ref to the value we got during construction which was stored in
189// // m_value;
190// ~ScopedValueChanger ()
191// {
192// m_value_ref = m_value;
193// }
194//protected:
Greg Clayton5d187e52011-01-08 20:28:42 +0000195// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000196// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
197//};
198
199StateType
200GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
201(
202 ProcessGDBRemote *process,
203 const char *payload,
204 size_t packet_length,
205 StringExtractorGDBRemote &response
206)
207{
Greg Claytone005f2c2010-11-06 01:53:30 +0000208 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000209 if (log)
210 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
211
212 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000213 StateType state = eStateRunning;
214
215 if (SendPacket(payload, packet_length) == 0)
216 state = eStateInvalid;
217
Greg Claytonb749a262010-12-03 06:02:24 +0000218 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000219 m_public_is_running.SetValue (true, eBroadcastNever);
220 m_private_is_running.SetValue (true, eBroadcastNever);
Jim Ingham3ae449a2010-11-17 02:32:00 +0000221
Chris Lattner24943d22010-06-08 16:52:24 +0000222 while (state == eStateRunning)
223 {
224 if (log)
225 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...)", __FUNCTION__);
226
227 if (WaitForPacket (response, (TimeValue*)NULL))
228 {
229 if (response.Empty())
230 state = eStateInvalid;
231 else
232 {
233 const char stop_type = response.GetChar();
234 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000235 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000236 switch (stop_type)
237 {
238 case 'T':
239 case 'S':
Greg Claytoncecf3482011-01-20 07:53:45 +0000240 // Privately notify any internal threads that we have stopped
241 // in case we wanted to interrupt our process, yet we might
242 // send a packet and continue without returning control to the
243 // user.
244 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000245 if (m_async_signal != -1)
246 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000247 if (log)
248 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000249
Chris Lattner24943d22010-06-08 16:52:24 +0000250 // Save off the async signal we are supposed to send
251 const int async_signal = m_async_signal;
252 // Clear the async signal member so we don't end up
253 // sending the signal multiple times...
254 m_async_signal = -1;
255 // Check which signal we stopped with
256 uint8_t signo = response.GetHexU8(255);
257 if (signo == async_signal)
258 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000259 if (log)
260 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000261
Chris Lattner24943d22010-06-08 16:52:24 +0000262 // We already stopped with a signal that we wanted
263 // to stop with, so we are done
264 response.SetFilePos (0);
265 }
266 else
267 {
268 // We stopped with a different signal that the one
269 // we wanted to stop with, so now we must resume
270 // with the signal we want
271 char signal_packet[32];
272 int signal_packet_len = 0;
273 signal_packet_len = ::snprintf (signal_packet,
274 sizeof (signal_packet),
275 "C%2.2x",
276 async_signal);
277
Greg Clayton68ca8232011-01-25 02:58:48 +0000278 if (log)
279 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000280 Host::GetSignalAsCString (signo),
281 Host::GetSignalAsCString (async_signal));
282
Chris Lattner24943d22010-06-08 16:52:24 +0000283 if (SendPacket(signal_packet, signal_packet_len) == 0)
284 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000285 if (log)
286 log->Printf ("async: error: failed to resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000287 Host::GetSignalAsCString (async_signal));
Greg Claytoncecf3482011-01-20 07:53:45 +0000288 state = eStateExited;
Chris Lattner24943d22010-06-08 16:52:24 +0000289 break;
290 }
291 else
Greg Claytoncecf3482011-01-20 07:53:45 +0000292 {
293 m_private_is_running.SetValue (true, eBroadcastNever);
Chris Lattner24943d22010-06-08 16:52:24 +0000294 continue;
Greg Claytoncecf3482011-01-20 07:53:45 +0000295 }
Chris Lattner24943d22010-06-08 16:52:24 +0000296 }
297 }
298 else if (m_async_packet_predicate.GetValue())
299 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000300 if (log)
301 log->Printf ("async: send async packet: %s",
302 m_async_packet.c_str());
Greg Claytonb4d1d332010-09-03 21:14:27 +0000303
Chris Lattner24943d22010-06-08 16:52:24 +0000304 // We are supposed to send an asynchronous packet while
305 // we are running.
306 m_async_response.Clear();
307 if (!m_async_packet.empty())
308 {
Greg Clayton53d68e72010-07-20 22:52:08 +0000309 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000310 m_async_packet.size(),
311 m_async_response,
312 m_async_timeout,
313 false);
314 }
315 // Let the other thread that was trying to send the async
316 // packet know that the packet has been sent.
317 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
318
Greg Clayton68ca8232011-01-25 02:58:48 +0000319 if (log)
320 log->Printf ("async: resume after async response received: %s",
321 m_async_response.GetStringRef().c_str());
Greg Claytonb4d1d332010-09-03 21:14:27 +0000322
Chris Lattner24943d22010-06-08 16:52:24 +0000323 // Continue again
324 if (SendPacket("c", 1) == 0)
325 {
Greg Claytoncecf3482011-01-20 07:53:45 +0000326 // Failed to send the continue packet
327 state = eStateExited;
Chris Lattner24943d22010-06-08 16:52:24 +0000328 break;
329 }
330 else
Greg Claytoncecf3482011-01-20 07:53:45 +0000331 {
332 m_private_is_running.SetValue (true, eBroadcastNever);
Chris Lattner24943d22010-06-08 16:52:24 +0000333 continue;
Greg Claytoncecf3482011-01-20 07:53:45 +0000334 }
Chris Lattner24943d22010-06-08 16:52:24 +0000335 }
336 // Stop with signal and thread info
337 state = eStateStopped;
338 break;
339
340 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000341 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000342 // process exited
343 state = eStateExited;
344 break;
345
346 case 'O':
347 // STDOUT
348 {
349 std::string inferior_stdout;
350 inferior_stdout.reserve(response.GetBytesLeft () / 2);
351 char ch;
352 while ((ch = response.GetHexU8()) != '\0')
353 inferior_stdout.append(1, ch);
354 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
355 }
356 break;
357
358 case 'E':
359 // ERROR
360 state = eStateInvalid;
361 break;
362
363 default:
364 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000365 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000366 break;
367 }
368 }
369 }
370 else
371 {
372 if (log)
373 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
374 state = eStateInvalid;
375 }
376 }
377 if (log)
378 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
379 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000380 m_private_is_running.SetValue (false, eBroadcastAlways);
381 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000382 return state;
383}
384
385size_t
386GDBRemoteCommunication::SendPacket (const char *payload)
387{
388 Mutex::Locker locker(m_sequence_mutex);
389 return SendPacketNoLock (payload, ::strlen (payload));
390}
391
392size_t
393GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
394{
395 Mutex::Locker locker(m_sequence_mutex);
396 return SendPacketNoLock (payload, payload_length);
397}
398
399size_t
400GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
401{
402 if (IsConnected())
403 {
404 StreamString packet(0, 4, eByteOrderBig);
405
406 packet.PutChar('$');
407 packet.Write (payload, payload_length);
408 packet.PutChar('#');
409 packet.PutHex8(CalculcateChecksum (payload, payload_length));
410
411 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %s", packet.GetData());
412 ConnectionStatus status = eConnectionStatusSuccess;
413 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
414 if (bytes_written == packet.GetSize())
415 {
416 if (m_send_acks)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000417 {
418 if (GetAck (1) != '+')
419 return 0;
420 }
Chris Lattner24943d22010-06-08 16:52:24 +0000421 }
Johnny Chen515ea542010-09-14 22:10:43 +0000422 else
423 {
424 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "error: failed to send packet: %s", packet.GetData());
425 }
Chris Lattner24943d22010-06-08 16:52:24 +0000426 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000427 }
Chris Lattner24943d22010-06-08 16:52:24 +0000428 return 0;
429}
430
431char
432GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
433{
434 StringExtractorGDBRemote response;
435 if (WaitForPacket (response, timeout_seconds) == 1)
436 return response.GetChar();
437 return 0;
438}
439
440bool
441GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
442{
443 return locker.TryLock (m_sequence_mutex.GetMutex());
444}
445
446bool
447GDBRemoteCommunication::SendAsyncSignal (int signo)
448{
449 m_async_signal = signo;
450 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000451 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000452 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000453 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000454 return true;
455 m_async_signal = -1;
456 return false;
457}
458
Greg Clayton1a679462010-09-03 19:15:43 +0000459// This function takes a mutex locker as a parameter in case the GetSequenceMutex
460// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
461// (the expected result), then it will send the halt packet. If it does succeed
462// then the caller that requested the interrupt will want to keep the sequence
463// locked down so that no one else can send packets while the caller has control.
464// This function usually gets called when we are running and need to stop the
465// target. It can also be used when we are running and and we need to do something
466// else (like read/write memory), so we need to interrupt the running process
467// (gdb remote protocol requires this), and do what we need to do, then resume.
468
Chris Lattner24943d22010-06-08 16:52:24 +0000469bool
Greg Claytona4881d02011-01-22 07:12:45 +0000470GDBRemoteCommunication::SendInterrupt
471(
472 Mutex::Locker& locker,
473 uint32_t seconds_to_wait_for_stop,
474 bool &sent_interrupt,
475 bool &timed_out
476)
Chris Lattner24943d22010-06-08 16:52:24 +0000477{
Greg Claytona4881d02011-01-22 07:12:45 +0000478 sent_interrupt = false;
479 timed_out = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000480
481 if (IsConnected() && IsRunning())
482 {
483 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000484 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000485 {
486 // Someone has the mutex locked waiting for a response or for the
487 // inferior to stop, so send the interrupt on the down low...
488 char ctrl_c = '\x03';
489 ConnectionStatus status = eConnectionStatusSuccess;
490 TimeValue timeout;
491 if (seconds_to_wait_for_stop)
492 {
493 timeout = TimeValue::Now();
494 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
495 }
Greg Clayton68ca8232011-01-25 02:58:48 +0000496 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Chris Lattner24943d22010-06-08 16:52:24 +0000497 if (Write (&ctrl_c, 1, status, NULL) > 0)
498 {
Greg Claytona4881d02011-01-22 07:12:45 +0000499 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000500 if (seconds_to_wait_for_stop)
Greg Claytona4881d02011-01-22 07:12:45 +0000501 m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out);
Chris Lattner24943d22010-06-08 16:52:24 +0000502 return true;
503 }
504 }
505 }
506 return false;
507}
508
Greg Clayton72e1c782011-01-22 23:43:18 +0000509bool
510GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
511{
512 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
513}
514
515bool
516GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
517{
518 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
519}
520
Chris Lattner24943d22010-06-08 16:52:24 +0000521size_t
522GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
523{
Greg Claytoncecf3482011-01-20 07:53:45 +0000524 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000525 TimeValue timeout_time;
526 timeout_time = TimeValue::Now();
527 timeout_time.OffsetWithSeconds (timeout_seconds);
528 return WaitForPacketNoLock (response, &timeout_time);
529}
530
531size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000532GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000533{
534 Mutex::Locker locker(m_sequence_mutex);
535 return WaitForPacketNoLock (response, timeout_time_ptr);
536}
537
538size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000539GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000540{
541 bool checksum_error = false;
542 response.Clear ();
543
544 EventSP event_sp;
545
546 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
547 {
548 const uint32_t event_type = event_sp->GetType();
549 if (event_type | Communication::eBroadcastBitPacketAvailable)
550 {
551 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
552 if (event_bytes)
553 {
554 const char * packet_data = (const char *)event_bytes->GetBytes();
555 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "read packet: %s", packet_data);
556 const size_t packet_size = event_bytes->GetByteSize();
557 if (packet_data && packet_size > 0)
558 {
559 std::string &response_str = response.GetStringRef();
560 if (packet_data[0] == '$')
561 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000562 bool success = false;
563 if (packet_size < 4)
564 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
565 else if (packet_data[packet_size-3] != '#' ||
566 !::isxdigit (packet_data[packet_size-2]) ||
567 !::isxdigit (packet_data[packet_size-1]))
568 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
569 else
570 success = true;
571
572 if (success)
573 response_str.assign (packet_data + 1, packet_size - 4);
Chris Lattner24943d22010-06-08 16:52:24 +0000574 if (m_send_acks)
575 {
576 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000577 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000578 checksum_error = packet_checksum != actual_checksum;
579 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000580 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000581 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000582 else
Greg Claytona4881d02011-01-22 07:12:45 +0000583 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000584 }
585 }
586 else
587 {
588 response_str.assign (packet_data, packet_size);
589 }
590 return response_str.size();
591 }
592 }
593 }
594 else if (Communication::eBroadcastBitReadThreadDidExit)
595 {
596 // Our read thread exited on us so just fall through and return zero...
597 }
598 }
599 return 0;
600}
601
602void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000603GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
604 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000605{
606 // Put the packet data into the buffer in a thread safe fashion
607 Mutex::Locker locker(m_bytes_mutex);
608 m_bytes.append ((const char *)src, src_len);
609
610 // Parse up the packets into gdb remote packets
611 while (!m_bytes.empty())
612 {
613 // end_idx must be one past the last valid packet byte. Start
614 // it off with an invalid value that is the same as the current
615 // index.
616 size_t end_idx = 0;
617
618 switch (m_bytes[0])
619 {
620 case '+': // Look for ack
621 case '-': // Look for cancel
622 case '\x03': // ^C to halt target
623 end_idx = 1; // The command is one byte long...
624 break;
625
626 case '$':
627 // Look for a standard gdb packet?
628 end_idx = m_bytes.find('#');
629 if (end_idx != std::string::npos)
630 {
631 if (end_idx + 2 < m_bytes.size())
632 {
633 end_idx += 3;
634 }
635 else
636 {
637 // Checksum bytes aren't all here yet
638 end_idx = std::string::npos;
639 }
640 }
641 break;
642
643 default:
644 break;
645 }
646
647 if (end_idx == std::string::npos)
648 {
649 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
650 return;
651 }
652 else if (end_idx > 0)
653 {
654 // We have a valid packet...
655 assert (end_idx <= m_bytes.size());
656 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
657 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
658 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
659 m_bytes.erase(0, end_idx);
660 }
661 else
662 {
663 assert (1 <= m_bytes.size());
664 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
665 m_bytes.erase(0, 1);
666 }
667 }
668}
669
670lldb::pid_t
671GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
672{
673 StringExtractorGDBRemote response;
674 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
675 {
676 if (response.GetChar() == 'Q')
677 if (response.GetChar() == 'C')
678 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
679 }
680 return LLDB_INVALID_PROCESS_ID;
681}
682
683bool
684GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
685{
686 error_str.clear();
687 StringExtractorGDBRemote response;
688 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
689 {
690 if (response.IsOKPacket())
691 return true;
692 if (response.GetChar() == 'E')
693 {
694 // A string the describes what failed when launching...
695 error_str = response.GetStringRef().substr(1);
696 }
697 else
698 {
699 error_str.assign ("unknown error occurred launching process");
700 }
701 }
702 else
703 {
704 error_str.assign ("failed to send the qLaunchSuccess packet");
705 }
706 return false;
707}
708
709int
710GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
711{
712 if (argv && argv[0])
713 {
714 StreamString packet;
715 packet.PutChar('A');
716 const char *arg;
717 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
718 {
719 const int arg_len = strlen(arg);
720 if (i > 0)
721 packet.PutChar(',');
722 packet.Printf("%i,%i,", arg_len * 2, i);
723 packet.PutBytesAsRawHex8(arg, arg_len, eByteOrderHost, eByteOrderHost);
724 }
725
726 StringExtractorGDBRemote response;
727 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
728 {
729 if (response.IsOKPacket())
730 return 0;
731 uint8_t error = response.GetError();
732 if (error)
733 return error;
734 }
735 }
736 return -1;
737}
738
739int
740GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
741{
742 if (name_equal_value && name_equal_value[0])
743 {
744 StreamString packet;
745 packet.Printf("QEnvironment:%s", name_equal_value);
746 StringExtractorGDBRemote response;
747 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
748 {
749 if (response.IsOKPacket())
750 return 0;
751 uint8_t error = response.GetError();
752 if (error)
753 return error;
754 }
755 }
756 return -1;
757}
758
759bool
760GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds)
761{
762 m_arch.Clear();
763 m_os.Clear();
764 m_vendor.Clear();
765 m_byte_order = eByteOrderHost;
766 m_pointer_byte_size = 0;
767
768 StringExtractorGDBRemote response;
769 if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false))
770 {
771 if (response.IsUnsupportedPacket())
772 return false;
773
774
775 std::string name;
776 std::string value;
777 while (response.GetNameColonValue(name, value))
778 {
779 if (name.compare("cputype") == 0)
780 {
781 // exception type in big endian hex
782 m_arch.SetCPUType(Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0));
783 }
784 else if (name.compare("cpusubtype") == 0)
785 {
786 // exception count in big endian hex
787 m_arch.SetCPUSubtype(Args::StringToUInt32 (value.c_str(), 0, 0));
788 }
789 else if (name.compare("ostype") == 0)
790 {
791 // exception data in big endian hex
792 m_os.SetCString(value.c_str());
793 }
794 else if (name.compare("vendor") == 0)
795 {
796 m_vendor.SetCString(value.c_str());
797 }
798 else if (name.compare("endian") == 0)
799 {
800 if (value.compare("little") == 0)
801 m_byte_order = eByteOrderLittle;
802 else if (value.compare("big") == 0)
803 m_byte_order = eByteOrderBig;
804 else if (value.compare("pdp") == 0)
805 m_byte_order = eByteOrderPDP;
806 }
807 else if (name.compare("ptrsize") == 0)
808 {
809 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
810 }
811 }
812 }
813 return HostInfoIsValid();
814}
815
816int
817GDBRemoteCommunication::SendAttach
818(
819 lldb::pid_t pid,
820 uint32_t timeout_seconds,
821 StringExtractorGDBRemote& response
822)
823{
824 if (pid != LLDB_INVALID_PROCESS_ID)
825 {
826 StreamString packet;
827 packet.Printf("vAttach;%x", pid);
828
829 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
830 {
831 if (response.IsErrorPacket())
832 return response.GetError();
833 return 0;
834 }
835 }
836 return -1;
837}
838
839const lldb_private::ArchSpec &
840GDBRemoteCommunication::GetHostArchitecture ()
841{
842 if (!HostInfoIsValid ())
843 GetHostInfo (1);
844 return m_arch;
845}
846
847const lldb_private::ConstString &
848GDBRemoteCommunication::GetOSString ()
849{
850 if (!HostInfoIsValid ())
851 GetHostInfo (1);
852 return m_os;
853}
854
855const lldb_private::ConstString &
856GDBRemoteCommunication::GetVendorString()
857{
858 if (!HostInfoIsValid ())
859 GetHostInfo (1);
860 return m_vendor;
861}
862
863lldb::ByteOrder
864GDBRemoteCommunication::GetByteOrder ()
865{
866 if (!HostInfoIsValid ())
867 GetHostInfo (1);
868 return m_byte_order;
869}
870
871uint32_t
872GDBRemoteCommunication::GetAddressByteSize ()
873{
874 if (!HostInfoIsValid ())
875 GetHostInfo (1);
876 return m_pointer_byte_size;
877}
878
879addr_t
880GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
881{
882 char packet[64];
883 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
884 permissions & lldb::ePermissionsReadable ? "r" : "",
885 permissions & lldb::ePermissionsWritable ? "w" : "",
886 permissions & lldb::ePermissionsExecutable ? "x" : "");
887 StringExtractorGDBRemote response;
888 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
889 {
890 if (!response.IsErrorPacket())
891 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
892 }
893 return LLDB_INVALID_ADDRESS;
894}
895
896bool
897GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
898{
899 char packet[64];
900 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
901 StringExtractorGDBRemote response;
902 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
903 {
Sean Callanan6a925532011-01-13 08:53:35 +0000904 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +0000905 return true;
906 }
907 return false;
908}
Jim Ingham3ae449a2010-11-17 02:32:00 +0000909