blob: 20af4b44a1c7e4b23b214f29889f0b063563630a [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);
Greg Claytondb2bab42011-01-27 09:02:32 +0000137 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000138
Greg Clayton1a679462010-09-03 19:15:43 +0000139 if (GetSequenceMutex (locker))
Chris Lattner24943d22010-06-08 16:52:24 +0000140 {
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
Greg Claytondb2bab42011-01-27 09:02:32 +0000153 if (log)
154 log->Printf ("async: async packet = %s", m_async_packet.c_str());
155
Chris Lattner24943d22010-06-08 16:52:24 +0000156 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000157 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000158 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000159 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000160 if (sent_interrupt)
Chris Lattner24943d22010-06-08 16:52:24 +0000161 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000162 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
Chris Lattner24943d22010-06-08 16:52:24 +0000188 }
189 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000190 else
191 {
192 if (log)
193 log->Printf ("async: failed to interrupt");
194 }
Chris Lattner24943d22010-06-08 16:52:24 +0000195 }
196 else
197 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000198 if (log)
199 log->Printf ("mutex taken and send_async == false, aborting packet");
Chris Lattner24943d22010-06-08 16:52:24 +0000200 }
201 }
202 return 0;
203}
204
205//template<typename _Tp>
206//class ScopedValueChanger
207//{
208//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000209// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000210// // 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:
Greg Clayton5d187e52011-01-08 20:28:42 +0000225// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000226// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
227//};
228
229StateType
230GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
231(
232 ProcessGDBRemote *process,
233 const char *payload,
234 size_t packet_length,
235 StringExtractorGDBRemote &response
236)
237{
Greg Claytone005f2c2010-11-06 01:53:30 +0000238 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000239 if (log)
240 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
241
242 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000243 StateType state = eStateRunning;
244
Greg Claytonb749a262010-12-03 06:02:24 +0000245 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000246 m_public_is_running.SetValue (true, eBroadcastNever);
Greg Claytondb2bab42011-01-27 09:02:32 +0000247 // 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
Chris Lattner24943d22010-06-08 16:52:24 +0000251 while (state == eStateRunning)
252 {
253 if (log)
Greg Claytondb2bab42011-01-27 09:02:32 +0000254 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__);
Chris Lattner24943d22010-06-08 16:52:24 +0000262
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)
Greg Clayton68ca8232011-01-25 02:58:48 +0000271 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000272 switch (stop_type)
273 {
274 case 'T':
275 case 'S':
Greg Claytoncecf3482011-01-20 07:53:45 +0000276 // 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);
Chris Lattner24943d22010-06-08 16:52:24 +0000281 if (m_async_signal != -1)
282 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000283 if (log)
284 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000285
Chris Lattner24943d22010-06-08 16:52:24 +0000286 // 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 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000295 if (log)
296 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000297
Chris Lattner24943d22010-06-08 16:52:24 +0000298 // 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
Greg Clayton68ca8232011-01-25 02:58:48 +0000314 if (log)
315 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000316 Host::GetSignalAsCString (signo),
317 Host::GetSignalAsCString (async_signal));
318
Greg Claytondb2bab42011-01-27 09:02:32 +0000319 // Set the continue packet to resume...
320 continue_packet.assign(signal_packet, signal_packet_len);
321 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000322 }
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();
Greg Claytondb2bab42011-01-27 09:02:32 +0000329 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000330 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000331 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
Greg Clayton53d68e72010-07-20 22:52:08 +0000341 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000342 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
Greg Claytondb2bab42011-01-27 09:02:32 +0000348 // packet know that the packet has been sent and response is
349 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000350 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
351
Greg Claytondb2bab42011-01-27 09:02:32 +0000352 // Set the continue packet to resume...
353 continue_packet.assign (1, 'c');
354 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000355 }
356 // Stop with signal and thread info
357 state = eStateStopped;
358 break;
359
360 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000361 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000362 // 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)
Greg Clayton68ca8232011-01-25 02:58:48 +0000385 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000386 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);
Greg Claytoncecf3482011-01-20 07:53:45 +0000400 m_private_is_running.SetValue (false, eBroadcastAlways);
401 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000402 return state;
403}
404
405size_t
406GDBRemoteCommunication::SendPacket (const char *payload)
407{
408 Mutex::Locker locker(m_sequence_mutex);
409 return SendPacketNoLock (payload, ::strlen (payload));
410}
411
412size_t
413GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
414{
415 Mutex::Locker locker(m_sequence_mutex);
416 return SendPacketNoLock (payload, payload_length);
417}
418
419size_t
420GDBRemoteCommunication::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)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000437 {
438 if (GetAck (1) != '+')
439 return 0;
440 }
Chris Lattner24943d22010-06-08 16:52:24 +0000441 }
Johnny Chen515ea542010-09-14 22:10:43 +0000442 else
443 {
444 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "error: failed to send packet: %s", packet.GetData());
445 }
Chris Lattner24943d22010-06-08 16:52:24 +0000446 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000447 }
Chris Lattner24943d22010-06-08 16:52:24 +0000448 return 0;
449}
450
451char
452GDBRemoteCommunication::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
460bool
461GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
462{
463 return locker.TryLock (m_sequence_mutex.GetMutex());
464}
465
466bool
467GDBRemoteCommunication::SendAsyncSignal (int signo)
468{
469 m_async_signal = signo;
470 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000471 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000472 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000473 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000474 return true;
475 m_async_signal = -1;
476 return false;
477}
478
Greg Clayton1a679462010-09-03 19:15:43 +0000479// 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
Chris Lattner24943d22010-06-08 16:52:24 +0000489bool
Greg Claytona4881d02011-01-22 07:12:45 +0000490GDBRemoteCommunication::SendInterrupt
491(
492 Mutex::Locker& locker,
493 uint32_t seconds_to_wait_for_stop,
494 bool &sent_interrupt,
495 bool &timed_out
496)
Chris Lattner24943d22010-06-08 16:52:24 +0000497{
Greg Claytona4881d02011-01-22 07:12:45 +0000498 sent_interrupt = false;
499 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000500 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000501
Greg Claytondb2bab42011-01-27 09:02:32 +0000502 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000503 {
504 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000505 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000506 {
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 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000517 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000518 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000519 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000520 {
Greg Claytona4881d02011-01-22 07:12:45 +0000521 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000522 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000523 {
Greg Claytona4881d02011-01-22 07:12:45 +0000524 m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out);
Greg Claytondb2bab42011-01-27 09:02:32 +0000525 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 }
Chris Lattner24943d22010-06-08 16:52:24 +0000534 return true;
535 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000536 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__);
Chris Lattner24943d22010-06-08 16:52:24 +0000546 }
547 }
548 return false;
549}
550
Greg Clayton72e1c782011-01-22 23:43:18 +0000551bool
552GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
553{
554 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
555}
556
557bool
558GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
559{
560 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
561}
562
Chris Lattner24943d22010-06-08 16:52:24 +0000563size_t
564GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
565{
Greg Claytoncecf3482011-01-20 07:53:45 +0000566 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000567 TimeValue timeout_time;
568 timeout_time = TimeValue::Now();
569 timeout_time.OffsetWithSeconds (timeout_seconds);
570 return WaitForPacketNoLock (response, &timeout_time);
571}
572
573size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000574GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000575{
576 Mutex::Locker locker(m_sequence_mutex);
577 return WaitForPacketNoLock (response, timeout_time_ptr);
578}
579
580size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000581GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000582{
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 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000604 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);
Chris Lattner24943d22010-06-08 16:52:24 +0000616 if (m_send_acks)
617 {
618 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000619 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000620 checksum_error = packet_checksum != actual_checksum;
621 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000622 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000623 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000624 else
Greg Claytona4881d02011-01-22 07:12:45 +0000625 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000626 }
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
644void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000645GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
646 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000647{
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
712lldb::pid_t
713GDBRemoteCommunication::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
725bool
726GDBRemoteCommunication::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
751int
752GDBRemoteCommunication::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
781int
782GDBRemoteCommunication::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
801bool
802GDBRemoteCommunication::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
858int
859GDBRemoteCommunication::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
881const lldb_private::ArchSpec &
882GDBRemoteCommunication::GetHostArchitecture ()
883{
884 if (!HostInfoIsValid ())
885 GetHostInfo (1);
886 return m_arch;
887}
888
889const lldb_private::ConstString &
890GDBRemoteCommunication::GetOSString ()
891{
892 if (!HostInfoIsValid ())
893 GetHostInfo (1);
894 return m_os;
895}
896
897const lldb_private::ConstString &
898GDBRemoteCommunication::GetVendorString()
899{
900 if (!HostInfoIsValid ())
901 GetHostInfo (1);
902 return m_vendor;
903}
904
905lldb::ByteOrder
906GDBRemoteCommunication::GetByteOrder ()
907{
908 if (!HostInfoIsValid ())
909 GetHostInfo (1);
910 return m_byte_order;
911}
912
913uint32_t
914GDBRemoteCommunication::GetAddressByteSize ()
915{
916 if (!HostInfoIsValid ())
917 GetHostInfo (1);
918 return m_pointer_byte_size;
919}
920
921addr_t
922GDBRemoteCommunication::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
938bool
939GDBRemoteCommunication::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 {
Sean Callanan6a925532011-01-13 08:53:35 +0000946 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +0000947 return true;
948 }
949 return false;
950}
Jim Ingham3ae449a2010-11-17 02:32:00 +0000951