blob: 52b23762d7612784c63facb82dc7cd89108a695a [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"
Greg Claytoncd548032011-02-01 01:31:41 +000021#include "lldb/Host/Host.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Host/TimeValue.h"
23
24// Project includes
Greg Clayton54e7afa2010-07-09 20:39:50 +000025#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "ProcessGDBRemote.h"
27#include "ProcessGDBRemoteLog.h"
28
29using namespace lldb;
30using namespace lldb_private;
31
32//----------------------------------------------------------------------
33// GDBRemoteCommunication constructor
34//----------------------------------------------------------------------
35GDBRemoteCommunication::GDBRemoteCommunication() :
Greg Claytoneecb0f32010-12-04 02:39:47 +000036 Communication("gdb-remote.packets"),
Chris Lattner24943d22010-06-08 16:52:24 +000037 m_send_acks (true),
Greg Claytonc71899e2011-01-18 19:36:39 +000038 m_thread_suffix_supported (false),
Chris Lattner24943d22010-06-08 16:52:24 +000039 m_rx_packet_listener ("gdbremote.rx_packet"),
40 m_sequence_mutex (Mutex::eMutexTypeRecursive),
Greg Claytoncecf3482011-01-20 07:53:45 +000041 m_public_is_running (false),
42 m_private_is_running (false),
Chris Lattner24943d22010-06-08 16:52:24 +000043 m_async_mutex (Mutex::eMutexTypeRecursive),
44 m_async_packet_predicate (false),
45 m_async_packet (),
46 m_async_response (),
47 m_async_timeout (UINT32_MAX),
48 m_async_signal (-1),
49 m_arch(),
50 m_os(),
51 m_vendor(),
Greg Claytoncd548032011-02-01 01:31:41 +000052 m_byte_order(lldb::endian::InlHostByteOrder()),
Chris Lattner24943d22010-06-08 16:52:24 +000053 m_pointer_byte_size(0)
54{
55 m_rx_packet_listener.StartListeningForEvents(this,
56 Communication::eBroadcastBitPacketAvailable |
57 Communication::eBroadcastBitReadThreadDidExit);
58}
59
60//----------------------------------------------------------------------
61// Destructor
62//----------------------------------------------------------------------
63GDBRemoteCommunication::~GDBRemoteCommunication()
64{
65 m_rx_packet_listener.StopListeningForEvents(this,
66 Communication::eBroadcastBitPacketAvailable |
67 Communication::eBroadcastBitReadThreadDidExit);
68 if (IsConnected())
69 {
70 StopReadThread();
71 Disconnect();
72 }
73}
74
75
76char
77GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
78{
79 int checksum = 0;
80
81 // We only need to compute the checksum if we are sending acks
82 if (m_send_acks)
83 {
Greg Clayton54e7afa2010-07-09 20:39:50 +000084 for (size_t i = 0; i < payload_length; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +000085 checksum += payload[i];
86 }
87 return checksum & 255;
88}
89
90size_t
Greg Claytona4881d02011-01-22 07:12:45 +000091GDBRemoteCommunication::SendAck ()
Chris Lattner24943d22010-06-08 16:52:24 +000092{
Greg Claytona4881d02011-01-22 07:12:45 +000093 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: +");
Chris Lattner24943d22010-06-08 16:52:24 +000094 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytona4881d02011-01-22 07:12:45 +000095 char ack_char = '+';
Chris Lattner24943d22010-06-08 16:52:24 +000096 return Write (&ack_char, 1, status, NULL) == 1;
97}
98
99size_t
Greg Claytona4881d02011-01-22 07:12:45 +0000100GDBRemoteCommunication::SendNack ()
101{
102 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: -");
103 ConnectionStatus status = eConnectionStatusSuccess;
104 char nack_char = '-';
105 return Write (&nack_char, 1, status, NULL) == 1;
106}
107
108size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000109GDBRemoteCommunication::SendPacketAndWaitForResponse
110(
111 const char *payload,
112 StringExtractorGDBRemote &response,
113 uint32_t timeout_seconds,
114 bool send_async
115)
116{
117 return SendPacketAndWaitForResponse (payload,
118 ::strlen (payload),
119 response,
120 timeout_seconds,
121 send_async);
122}
123
124size_t
125GDBRemoteCommunication::SendPacketAndWaitForResponse
126(
127 const char *payload,
128 size_t payload_length,
129 StringExtractorGDBRemote &response,
130 uint32_t timeout_seconds,
131 bool send_async
132)
133{
134 Mutex::Locker locker;
135 TimeValue timeout_time;
136 timeout_time = TimeValue::Now();
137 timeout_time.OffsetWithSeconds (timeout_seconds);
Greg Claytondb2bab42011-01-27 09:02:32 +0000138 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000139
Greg Clayton1a679462010-09-03 19:15:43 +0000140 if (GetSequenceMutex (locker))
Chris Lattner24943d22010-06-08 16:52:24 +0000141 {
142 if (SendPacketNoLock (payload, strlen(payload)))
143 return WaitForPacketNoLock (response, &timeout_time);
144 }
145 else
146 {
147 if (send_async)
148 {
149 Mutex::Locker async_locker (m_async_mutex);
150 m_async_packet.assign(payload, payload_length);
151 m_async_timeout = timeout_seconds;
152 m_async_packet_predicate.SetValue (true, eBroadcastNever);
153
Greg Claytondb2bab42011-01-27 09:02:32 +0000154 if (log)
155 log->Printf ("async: async packet = %s", m_async_packet.c_str());
156
Chris Lattner24943d22010-06-08 16:52:24 +0000157 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000158 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000159 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000160 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000161 if (sent_interrupt)
Chris Lattner24943d22010-06-08 16:52:24 +0000162 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000163 if (log)
164 log->Printf ("async: sent interrupt");
165 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
166 {
167 if (log)
168 log->Printf ("async: got response");
169 response = m_async_response;
170 return response.GetStringRef().size();
171 }
172 else
173 {
174 if (log)
175 log->Printf ("async: timed out waiting for response");
176 }
177
178 // Make sure we wait until the continue packet has been sent again...
179 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
180 {
181 if (log)
182 log->Printf ("async: timed out waiting for process to resume");
183 }
184 }
185 else
186 {
187 // We had a racy condition where we went to send the interrupt
188 // yet we were able to get the loc
Chris Lattner24943d22010-06-08 16:52:24 +0000189 }
190 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000191 else
192 {
193 if (log)
194 log->Printf ("async: failed to interrupt");
195 }
Chris Lattner24943d22010-06-08 16:52:24 +0000196 }
197 else
198 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000199 if (log)
200 log->Printf ("mutex taken and send_async == false, aborting packet");
Chris Lattner24943d22010-06-08 16:52:24 +0000201 }
202 }
203 return 0;
204}
205
206//template<typename _Tp>
207//class ScopedValueChanger
208//{
209//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000210// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000211// // instance goes out of scope.
212// ScopedValueChanger (_Tp &value_ref, _Tp value) :
213// m_value_ref (value_ref),
214// m_value (value)
215// {
216// }
217//
218// // This object is going out of scope, change the value pointed to by
219// // m_value_ref to the value we got during construction which was stored in
220// // m_value;
221// ~ScopedValueChanger ()
222// {
223// m_value_ref = m_value;
224// }
225//protected:
Greg Clayton5d187e52011-01-08 20:28:42 +0000226// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000227// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
228//};
229
230StateType
231GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
232(
233 ProcessGDBRemote *process,
234 const char *payload,
235 size_t packet_length,
236 StringExtractorGDBRemote &response
237)
238{
Greg Claytone005f2c2010-11-06 01:53:30 +0000239 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000240 if (log)
241 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
242
243 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000244 StateType state = eStateRunning;
245
Greg Claytonb749a262010-12-03 06:02:24 +0000246 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000247 m_public_is_running.SetValue (true, eBroadcastNever);
Greg Claytondb2bab42011-01-27 09:02:32 +0000248 // Set the starting continue packet into "continue_packet". This packet
249 // make change if we are interrupted and we continue after an async packet...
250 std::string continue_packet(payload, packet_length);
251
Chris Lattner24943d22010-06-08 16:52:24 +0000252 while (state == eStateRunning)
253 {
254 if (log)
Greg Claytondb2bab42011-01-27 09:02:32 +0000255 log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
256 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
257 state = eStateInvalid;
258
259 m_private_is_running.SetValue (true, eBroadcastNever);
260
261 if (log)
262 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000263
264 if (WaitForPacket (response, (TimeValue*)NULL))
265 {
266 if (response.Empty())
267 state = eStateInvalid;
268 else
269 {
270 const char stop_type = response.GetChar();
271 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000272 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000273 switch (stop_type)
274 {
275 case 'T':
276 case 'S':
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000277 if (process->GetStopID() == 0)
278 {
279 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
280 {
281 lldb::pid_t pid = GetCurrentProcessID (1);
282 if (pid != LLDB_INVALID_PROCESS_ID)
283 process->SetID (pid);
284 }
285 process->BuildDynamicRegisterInfo (true);
286 }
287
Greg Claytoncecf3482011-01-20 07:53:45 +0000288 // Privately notify any internal threads that we have stopped
289 // in case we wanted to interrupt our process, yet we might
290 // send a packet and continue without returning control to the
291 // user.
292 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000293 if (m_async_signal != -1)
294 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000295 if (log)
296 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000297
Chris Lattner24943d22010-06-08 16:52:24 +0000298 // Save off the async signal we are supposed to send
299 const int async_signal = m_async_signal;
300 // Clear the async signal member so we don't end up
301 // sending the signal multiple times...
302 m_async_signal = -1;
303 // Check which signal we stopped with
304 uint8_t signo = response.GetHexU8(255);
305 if (signo == async_signal)
306 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000307 if (log)
308 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000309
Chris Lattner24943d22010-06-08 16:52:24 +0000310 // We already stopped with a signal that we wanted
311 // to stop with, so we are done
312 response.SetFilePos (0);
313 }
314 else
315 {
316 // We stopped with a different signal that the one
317 // we wanted to stop with, so now we must resume
318 // with the signal we want
319 char signal_packet[32];
320 int signal_packet_len = 0;
321 signal_packet_len = ::snprintf (signal_packet,
322 sizeof (signal_packet),
323 "C%2.2x",
324 async_signal);
325
Greg Clayton68ca8232011-01-25 02:58:48 +0000326 if (log)
327 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000328 Host::GetSignalAsCString (signo),
329 Host::GetSignalAsCString (async_signal));
330
Greg Claytondb2bab42011-01-27 09:02:32 +0000331 // Set the continue packet to resume...
332 continue_packet.assign(signal_packet, signal_packet_len);
333 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000334 }
335 }
336 else if (m_async_packet_predicate.GetValue())
337 {
338 // We are supposed to send an asynchronous packet while
339 // we are running.
340 m_async_response.Clear();
Greg Claytondb2bab42011-01-27 09:02:32 +0000341 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000342 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000343 if (log)
344 log->Printf ("async: error: empty async packet");
345
346 }
347 else
348 {
349 if (log)
350 log->Printf ("async: sending packet: %s",
351 m_async_packet.c_str());
352
Greg Clayton53d68e72010-07-20 22:52:08 +0000353 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000354 m_async_packet.size(),
355 m_async_response,
356 m_async_timeout,
357 false);
358 }
359 // Let the other thread that was trying to send the async
Greg Claytondb2bab42011-01-27 09:02:32 +0000360 // packet know that the packet has been sent and response is
361 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000362 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
363
Greg Claytondb2bab42011-01-27 09:02:32 +0000364 // Set the continue packet to resume...
365 continue_packet.assign (1, 'c');
366 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000367 }
368 // Stop with signal and thread info
369 state = eStateStopped;
370 break;
371
372 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000373 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000374 // process exited
375 state = eStateExited;
376 break;
377
378 case 'O':
379 // STDOUT
380 {
381 std::string inferior_stdout;
382 inferior_stdout.reserve(response.GetBytesLeft () / 2);
383 char ch;
384 while ((ch = response.GetHexU8()) != '\0')
385 inferior_stdout.append(1, ch);
386 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
387 }
388 break;
389
390 case 'E':
391 // ERROR
392 state = eStateInvalid;
393 break;
394
395 default:
396 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000397 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000398 break;
399 }
400 }
401 }
402 else
403 {
404 if (log)
405 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
406 state = eStateInvalid;
407 }
408 }
409 if (log)
410 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
411 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000412 m_private_is_running.SetValue (false, eBroadcastAlways);
413 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000414 return state;
415}
416
417size_t
418GDBRemoteCommunication::SendPacket (const char *payload)
419{
420 Mutex::Locker locker(m_sequence_mutex);
421 return SendPacketNoLock (payload, ::strlen (payload));
422}
423
424size_t
425GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
426{
427 Mutex::Locker locker(m_sequence_mutex);
428 return SendPacketNoLock (payload, payload_length);
429}
430
431size_t
432GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
433{
434 if (IsConnected())
435 {
436 StreamString packet(0, 4, eByteOrderBig);
437
438 packet.PutChar('$');
439 packet.Write (payload, payload_length);
440 packet.PutChar('#');
441 packet.PutHex8(CalculcateChecksum (payload, payload_length));
442
443 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %s", packet.GetData());
444 ConnectionStatus status = eConnectionStatusSuccess;
445 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
446 if (bytes_written == packet.GetSize())
447 {
448 if (m_send_acks)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000449 {
450 if (GetAck (1) != '+')
451 return 0;
452 }
Chris Lattner24943d22010-06-08 16:52:24 +0000453 }
Johnny Chen515ea542010-09-14 22:10:43 +0000454 else
455 {
456 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "error: failed to send packet: %s", packet.GetData());
457 }
Chris Lattner24943d22010-06-08 16:52:24 +0000458 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000459 }
Chris Lattner24943d22010-06-08 16:52:24 +0000460 return 0;
461}
462
463char
464GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
465{
466 StringExtractorGDBRemote response;
467 if (WaitForPacket (response, timeout_seconds) == 1)
468 return response.GetChar();
469 return 0;
470}
471
472bool
473GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
474{
475 return locker.TryLock (m_sequence_mutex.GetMutex());
476}
477
478bool
479GDBRemoteCommunication::SendAsyncSignal (int signo)
480{
481 m_async_signal = signo;
482 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000483 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000484 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000485 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000486 return true;
487 m_async_signal = -1;
488 return false;
489}
490
Greg Clayton1a679462010-09-03 19:15:43 +0000491// This function takes a mutex locker as a parameter in case the GetSequenceMutex
492// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
493// (the expected result), then it will send the halt packet. If it does succeed
494// then the caller that requested the interrupt will want to keep the sequence
495// locked down so that no one else can send packets while the caller has control.
496// This function usually gets called when we are running and need to stop the
497// target. It can also be used when we are running and and we need to do something
498// else (like read/write memory), so we need to interrupt the running process
499// (gdb remote protocol requires this), and do what we need to do, then resume.
500
Chris Lattner24943d22010-06-08 16:52:24 +0000501bool
Greg Claytona4881d02011-01-22 07:12:45 +0000502GDBRemoteCommunication::SendInterrupt
503(
504 Mutex::Locker& locker,
505 uint32_t seconds_to_wait_for_stop,
506 bool &sent_interrupt,
507 bool &timed_out
508)
Chris Lattner24943d22010-06-08 16:52:24 +0000509{
Greg Claytona4881d02011-01-22 07:12:45 +0000510 sent_interrupt = false;
511 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000512 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000513
Greg Claytondb2bab42011-01-27 09:02:32 +0000514 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000515 {
516 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000517 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000518 {
519 // Someone has the mutex locked waiting for a response or for the
520 // inferior to stop, so send the interrupt on the down low...
521 char ctrl_c = '\x03';
522 ConnectionStatus status = eConnectionStatusSuccess;
523 TimeValue timeout;
524 if (seconds_to_wait_for_stop)
525 {
526 timeout = TimeValue::Now();
527 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
528 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000529 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000530 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000531 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000532 {
Greg Claytona4881d02011-01-22 07:12:45 +0000533 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000534 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000535 {
Greg Clayton1c2aa462011-02-03 01:07:45 +0000536 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
537 {
538 if (log)
539 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
540 return true;
541 }
542 else
543 {
544 if (log)
545 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
546 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000547 }
548 else
549 {
550 if (log)
551 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
Greg Clayton1c2aa462011-02-03 01:07:45 +0000552 return true;
Greg Claytondb2bab42011-01-27 09:02:32 +0000553 }
Chris Lattner24943d22010-06-08 16:52:24 +0000554 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000555 else
556 {
557 if (log)
558 log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
559 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000560 return false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000561 }
562 else
563 {
564 if (log)
565 log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000566 }
567 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000568 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000569}
570
Greg Clayton72e1c782011-01-22 23:43:18 +0000571bool
572GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
573{
574 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
575}
576
577bool
578GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
579{
580 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
581}
582
Chris Lattner24943d22010-06-08 16:52:24 +0000583size_t
584GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
585{
Greg Claytoncecf3482011-01-20 07:53:45 +0000586 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000587 TimeValue timeout_time;
588 timeout_time = TimeValue::Now();
589 timeout_time.OffsetWithSeconds (timeout_seconds);
590 return WaitForPacketNoLock (response, &timeout_time);
591}
592
593size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000594GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000595{
596 Mutex::Locker locker(m_sequence_mutex);
597 return WaitForPacketNoLock (response, timeout_time_ptr);
598}
599
600size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000601GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000602{
603 bool checksum_error = false;
604 response.Clear ();
605
606 EventSP event_sp;
607
608 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
609 {
610 const uint32_t event_type = event_sp->GetType();
611 if (event_type | Communication::eBroadcastBitPacketAvailable)
612 {
613 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
614 if (event_bytes)
615 {
616 const char * packet_data = (const char *)event_bytes->GetBytes();
617 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "read packet: %s", packet_data);
618 const size_t packet_size = event_bytes->GetByteSize();
619 if (packet_data && packet_size > 0)
620 {
621 std::string &response_str = response.GetStringRef();
622 if (packet_data[0] == '$')
623 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000624 bool success = false;
625 if (packet_size < 4)
626 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
627 else if (packet_data[packet_size-3] != '#' ||
628 !::isxdigit (packet_data[packet_size-2]) ||
629 !::isxdigit (packet_data[packet_size-1]))
630 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
631 else
632 success = true;
633
634 if (success)
635 response_str.assign (packet_data + 1, packet_size - 4);
Chris Lattner24943d22010-06-08 16:52:24 +0000636 if (m_send_acks)
637 {
638 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000639 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000640 checksum_error = packet_checksum != actual_checksum;
641 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000642 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000643 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000644 else
Greg Claytona4881d02011-01-22 07:12:45 +0000645 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000646 }
647 }
648 else
649 {
650 response_str.assign (packet_data, packet_size);
651 }
652 return response_str.size();
653 }
654 }
655 }
656 else if (Communication::eBroadcastBitReadThreadDidExit)
657 {
658 // Our read thread exited on us so just fall through and return zero...
659 }
660 }
661 return 0;
662}
663
664void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000665GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
666 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000667{
668 // Put the packet data into the buffer in a thread safe fashion
669 Mutex::Locker locker(m_bytes_mutex);
670 m_bytes.append ((const char *)src, src_len);
671
672 // Parse up the packets into gdb remote packets
673 while (!m_bytes.empty())
674 {
675 // end_idx must be one past the last valid packet byte. Start
676 // it off with an invalid value that is the same as the current
677 // index.
678 size_t end_idx = 0;
679
680 switch (m_bytes[0])
681 {
682 case '+': // Look for ack
683 case '-': // Look for cancel
684 case '\x03': // ^C to halt target
685 end_idx = 1; // The command is one byte long...
686 break;
687
688 case '$':
689 // Look for a standard gdb packet?
690 end_idx = m_bytes.find('#');
691 if (end_idx != std::string::npos)
692 {
693 if (end_idx + 2 < m_bytes.size())
694 {
695 end_idx += 3;
696 }
697 else
698 {
699 // Checksum bytes aren't all here yet
700 end_idx = std::string::npos;
701 }
702 }
703 break;
704
705 default:
706 break;
707 }
708
709 if (end_idx == std::string::npos)
710 {
711 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
712 return;
713 }
714 else if (end_idx > 0)
715 {
716 // We have a valid packet...
717 assert (end_idx <= m_bytes.size());
718 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
719 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
720 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
721 m_bytes.erase(0, end_idx);
722 }
723 else
724 {
725 assert (1 <= m_bytes.size());
726 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
727 m_bytes.erase(0, 1);
728 }
729 }
730}
731
732lldb::pid_t
733GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
734{
735 StringExtractorGDBRemote response;
736 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
737 {
738 if (response.GetChar() == 'Q')
739 if (response.GetChar() == 'C')
740 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
741 }
742 return LLDB_INVALID_PROCESS_ID;
743}
744
745bool
746GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
747{
748 error_str.clear();
749 StringExtractorGDBRemote response;
750 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
751 {
752 if (response.IsOKPacket())
753 return true;
754 if (response.GetChar() == 'E')
755 {
756 // A string the describes what failed when launching...
757 error_str = response.GetStringRef().substr(1);
758 }
759 else
760 {
761 error_str.assign ("unknown error occurred launching process");
762 }
763 }
764 else
765 {
766 error_str.assign ("failed to send the qLaunchSuccess packet");
767 }
768 return false;
769}
770
771int
772GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
773{
774 if (argv && argv[0])
775 {
776 StreamString packet;
777 packet.PutChar('A');
778 const char *arg;
779 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
780 {
781 const int arg_len = strlen(arg);
782 if (i > 0)
783 packet.PutChar(',');
784 packet.Printf("%i,%i,", arg_len * 2, i);
Greg Claytoncd548032011-02-01 01:31:41 +0000785 packet.PutBytesAsRawHex8(arg, arg_len, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000786 }
787
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
801int
802GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
803{
804 if (name_equal_value && name_equal_value[0])
805 {
806 StreamString packet;
807 packet.Printf("QEnvironment:%s", name_equal_value);
808 StringExtractorGDBRemote response;
809 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
810 {
811 if (response.IsOKPacket())
812 return 0;
813 uint8_t error = response.GetError();
814 if (error)
815 return error;
816 }
817 }
818 return -1;
819}
820
821bool
822GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds)
823{
824 m_arch.Clear();
825 m_os.Clear();
826 m_vendor.Clear();
Greg Claytoncd548032011-02-01 01:31:41 +0000827 m_byte_order = lldb::endian::InlHostByteOrder();
Chris Lattner24943d22010-06-08 16:52:24 +0000828 m_pointer_byte_size = 0;
829
830 StringExtractorGDBRemote response;
831 if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false))
832 {
833 if (response.IsUnsupportedPacket())
834 return false;
835
836
837 std::string name;
838 std::string value;
839 while (response.GetNameColonValue(name, value))
840 {
841 if (name.compare("cputype") == 0)
842 {
843 // exception type in big endian hex
844 m_arch.SetCPUType(Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0));
845 }
846 else if (name.compare("cpusubtype") == 0)
847 {
848 // exception count in big endian hex
849 m_arch.SetCPUSubtype(Args::StringToUInt32 (value.c_str(), 0, 0));
850 }
851 else if (name.compare("ostype") == 0)
852 {
853 // exception data in big endian hex
854 m_os.SetCString(value.c_str());
855 }
856 else if (name.compare("vendor") == 0)
857 {
858 m_vendor.SetCString(value.c_str());
859 }
860 else if (name.compare("endian") == 0)
861 {
862 if (value.compare("little") == 0)
863 m_byte_order = eByteOrderLittle;
864 else if (value.compare("big") == 0)
865 m_byte_order = eByteOrderBig;
866 else if (value.compare("pdp") == 0)
867 m_byte_order = eByteOrderPDP;
868 }
869 else if (name.compare("ptrsize") == 0)
870 {
871 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
872 }
873 }
874 }
875 return HostInfoIsValid();
876}
877
878int
879GDBRemoteCommunication::SendAttach
880(
881 lldb::pid_t pid,
882 uint32_t timeout_seconds,
883 StringExtractorGDBRemote& response
884)
885{
886 if (pid != LLDB_INVALID_PROCESS_ID)
887 {
888 StreamString packet;
889 packet.Printf("vAttach;%x", pid);
890
891 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
892 {
893 if (response.IsErrorPacket())
894 return response.GetError();
895 return 0;
896 }
897 }
898 return -1;
899}
900
901const lldb_private::ArchSpec &
902GDBRemoteCommunication::GetHostArchitecture ()
903{
904 if (!HostInfoIsValid ())
905 GetHostInfo (1);
906 return m_arch;
907}
908
909const lldb_private::ConstString &
910GDBRemoteCommunication::GetOSString ()
911{
912 if (!HostInfoIsValid ())
913 GetHostInfo (1);
914 return m_os;
915}
916
917const lldb_private::ConstString &
918GDBRemoteCommunication::GetVendorString()
919{
920 if (!HostInfoIsValid ())
921 GetHostInfo (1);
922 return m_vendor;
923}
924
925lldb::ByteOrder
926GDBRemoteCommunication::GetByteOrder ()
927{
928 if (!HostInfoIsValid ())
929 GetHostInfo (1);
930 return m_byte_order;
931}
932
933uint32_t
934GDBRemoteCommunication::GetAddressByteSize ()
935{
936 if (!HostInfoIsValid ())
937 GetHostInfo (1);
938 return m_pointer_byte_size;
939}
940
941addr_t
942GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
943{
944 char packet[64];
945 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
946 permissions & lldb::ePermissionsReadable ? "r" : "",
947 permissions & lldb::ePermissionsWritable ? "w" : "",
948 permissions & lldb::ePermissionsExecutable ? "x" : "");
949 StringExtractorGDBRemote response;
950 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
951 {
952 if (!response.IsErrorPacket())
953 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
954 }
955 return LLDB_INVALID_ADDRESS;
956}
957
958bool
959GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
960{
961 char packet[64];
962 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
963 StringExtractorGDBRemote response;
964 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
965 {
Sean Callanan6a925532011-01-13 08:53:35 +0000966 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +0000967 return true;
968 }
969 return false;
970}
Jim Ingham3ae449a2010-11-17 02:32:00 +0000971