blob: 6442e21b224c7496ff1ed8e56bc836ed8945214c [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 Clayton0bfda0b2011-02-05 02:25:06 +000093 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
94 if (log)
95 log->Printf ("send packet: +");
Chris Lattner24943d22010-06-08 16:52:24 +000096 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytona4881d02011-01-22 07:12:45 +000097 char ack_char = '+';
Chris Lattner24943d22010-06-08 16:52:24 +000098 return Write (&ack_char, 1, status, NULL) == 1;
99}
100
101size_t
Greg Claytona4881d02011-01-22 07:12:45 +0000102GDBRemoteCommunication::SendNack ()
103{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000104 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
105 if (log)
106 log->Printf ("send packet: -");
Greg Claytona4881d02011-01-22 07:12:45 +0000107 ConnectionStatus status = eConnectionStatusSuccess;
108 char nack_char = '-';
109 return Write (&nack_char, 1, status, NULL) == 1;
110}
111
112size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000113GDBRemoteCommunication::SendPacketAndWaitForResponse
114(
115 const char *payload,
116 StringExtractorGDBRemote &response,
117 uint32_t timeout_seconds,
118 bool send_async
119)
120{
121 return SendPacketAndWaitForResponse (payload,
122 ::strlen (payload),
123 response,
124 timeout_seconds,
125 send_async);
126}
127
128size_t
129GDBRemoteCommunication::SendPacketAndWaitForResponse
130(
131 const char *payload,
132 size_t payload_length,
133 StringExtractorGDBRemote &response,
134 uint32_t timeout_seconds,
135 bool send_async
136)
137{
138 Mutex::Locker locker;
139 TimeValue timeout_time;
140 timeout_time = TimeValue::Now();
141 timeout_time.OffsetWithSeconds (timeout_seconds);
Greg Claytondb2bab42011-01-27 09:02:32 +0000142 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000143
Greg Clayton1a679462010-09-03 19:15:43 +0000144 if (GetSequenceMutex (locker))
Chris Lattner24943d22010-06-08 16:52:24 +0000145 {
146 if (SendPacketNoLock (payload, strlen(payload)))
147 return WaitForPacketNoLock (response, &timeout_time);
148 }
149 else
150 {
151 if (send_async)
152 {
153 Mutex::Locker async_locker (m_async_mutex);
154 m_async_packet.assign(payload, payload_length);
155 m_async_timeout = timeout_seconds;
156 m_async_packet_predicate.SetValue (true, eBroadcastNever);
157
Greg Claytondb2bab42011-01-27 09:02:32 +0000158 if (log)
159 log->Printf ("async: async packet = %s", m_async_packet.c_str());
160
Chris Lattner24943d22010-06-08 16:52:24 +0000161 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000162 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000163 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000164 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000165 if (sent_interrupt)
Chris Lattner24943d22010-06-08 16:52:24 +0000166 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000167 if (log)
168 log->Printf ("async: sent interrupt");
169 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
170 {
171 if (log)
172 log->Printf ("async: got response");
173 response = m_async_response;
174 return response.GetStringRef().size();
175 }
176 else
177 {
178 if (log)
179 log->Printf ("async: timed out waiting for response");
180 }
181
182 // Make sure we wait until the continue packet has been sent again...
183 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
184 {
185 if (log)
186 log->Printf ("async: timed out waiting for process to resume");
187 }
188 }
189 else
190 {
191 // We had a racy condition where we went to send the interrupt
192 // yet we were able to get the loc
Chris Lattner24943d22010-06-08 16:52:24 +0000193 }
194 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000195 else
196 {
197 if (log)
198 log->Printf ("async: failed to interrupt");
199 }
Chris Lattner24943d22010-06-08 16:52:24 +0000200 }
201 else
202 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000203 if (log)
204 log->Printf ("mutex taken and send_async == false, aborting packet");
Chris Lattner24943d22010-06-08 16:52:24 +0000205 }
206 }
207 return 0;
208}
209
210//template<typename _Tp>
211//class ScopedValueChanger
212//{
213//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000214// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000215// // instance goes out of scope.
216// ScopedValueChanger (_Tp &value_ref, _Tp value) :
217// m_value_ref (value_ref),
218// m_value (value)
219// {
220// }
221//
222// // This object is going out of scope, change the value pointed to by
223// // m_value_ref to the value we got during construction which was stored in
224// // m_value;
225// ~ScopedValueChanger ()
226// {
227// m_value_ref = m_value;
228// }
229//protected:
Greg Clayton5d187e52011-01-08 20:28:42 +0000230// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000231// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
232//};
233
234StateType
235GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
236(
237 ProcessGDBRemote *process,
238 const char *payload,
239 size_t packet_length,
240 StringExtractorGDBRemote &response
241)
242{
Greg Claytone005f2c2010-11-06 01:53:30 +0000243 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000244 if (log)
245 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
246
247 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000248 StateType state = eStateRunning;
249
Greg Claytonb749a262010-12-03 06:02:24 +0000250 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000251 m_public_is_running.SetValue (true, eBroadcastNever);
Greg Claytondb2bab42011-01-27 09:02:32 +0000252 // Set the starting continue packet into "continue_packet". This packet
253 // make change if we are interrupted and we continue after an async packet...
254 std::string continue_packet(payload, packet_length);
255
Chris Lattner24943d22010-06-08 16:52:24 +0000256 while (state == eStateRunning)
257 {
258 if (log)
Greg Claytondb2bab42011-01-27 09:02:32 +0000259 log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
260 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
261 state = eStateInvalid;
262
263 m_private_is_running.SetValue (true, eBroadcastNever);
264
265 if (log)
266 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000267
268 if (WaitForPacket (response, (TimeValue*)NULL))
269 {
270 if (response.Empty())
271 state = eStateInvalid;
272 else
273 {
274 const char stop_type = response.GetChar();
275 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000276 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000277 switch (stop_type)
278 {
279 case 'T':
280 case 'S':
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000281 if (process->GetStopID() == 0)
282 {
283 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
284 {
285 lldb::pid_t pid = GetCurrentProcessID (1);
286 if (pid != LLDB_INVALID_PROCESS_ID)
287 process->SetID (pid);
288 }
289 process->BuildDynamicRegisterInfo (true);
290 }
291
Greg Claytoncecf3482011-01-20 07:53:45 +0000292 // Privately notify any internal threads that we have stopped
293 // in case we wanted to interrupt our process, yet we might
294 // send a packet and continue without returning control to the
295 // user.
296 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000297 if (m_async_signal != -1)
298 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000299 if (log)
300 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000301
Chris Lattner24943d22010-06-08 16:52:24 +0000302 // Save off the async signal we are supposed to send
303 const int async_signal = m_async_signal;
304 // Clear the async signal member so we don't end up
305 // sending the signal multiple times...
306 m_async_signal = -1;
307 // Check which signal we stopped with
308 uint8_t signo = response.GetHexU8(255);
309 if (signo == async_signal)
310 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000311 if (log)
312 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000313
Chris Lattner24943d22010-06-08 16:52:24 +0000314 // We already stopped with a signal that we wanted
315 // to stop with, so we are done
316 response.SetFilePos (0);
317 }
318 else
319 {
320 // We stopped with a different signal that the one
321 // we wanted to stop with, so now we must resume
322 // with the signal we want
323 char signal_packet[32];
324 int signal_packet_len = 0;
325 signal_packet_len = ::snprintf (signal_packet,
326 sizeof (signal_packet),
327 "C%2.2x",
328 async_signal);
329
Greg Clayton68ca8232011-01-25 02:58:48 +0000330 if (log)
331 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000332 Host::GetSignalAsCString (signo),
333 Host::GetSignalAsCString (async_signal));
334
Greg Claytondb2bab42011-01-27 09:02:32 +0000335 // Set the continue packet to resume...
336 continue_packet.assign(signal_packet, signal_packet_len);
337 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000338 }
339 }
340 else if (m_async_packet_predicate.GetValue())
341 {
342 // We are supposed to send an asynchronous packet while
343 // we are running.
344 m_async_response.Clear();
Greg Claytondb2bab42011-01-27 09:02:32 +0000345 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000346 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000347 if (log)
348 log->Printf ("async: error: empty async packet");
349
350 }
351 else
352 {
353 if (log)
354 log->Printf ("async: sending packet: %s",
355 m_async_packet.c_str());
356
Greg Clayton53d68e72010-07-20 22:52:08 +0000357 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000358 m_async_packet.size(),
359 m_async_response,
360 m_async_timeout,
361 false);
362 }
363 // Let the other thread that was trying to send the async
Greg Claytondb2bab42011-01-27 09:02:32 +0000364 // packet know that the packet has been sent and response is
365 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000366 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
367
Greg Claytondb2bab42011-01-27 09:02:32 +0000368 // Set the continue packet to resume...
369 continue_packet.assign (1, 'c');
370 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000371 }
372 // Stop with signal and thread info
373 state = eStateStopped;
374 break;
375
376 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000377 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000378 // process exited
379 state = eStateExited;
380 break;
381
382 case 'O':
383 // STDOUT
384 {
385 std::string inferior_stdout;
386 inferior_stdout.reserve(response.GetBytesLeft () / 2);
387 char ch;
388 while ((ch = response.GetHexU8()) != '\0')
389 inferior_stdout.append(1, ch);
390 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
391 }
392 break;
393
394 case 'E':
395 // ERROR
396 state = eStateInvalid;
397 break;
398
399 default:
400 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000401 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000402 break;
403 }
404 }
405 }
406 else
407 {
408 if (log)
409 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
410 state = eStateInvalid;
411 }
412 }
413 if (log)
414 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
415 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000416 m_private_is_running.SetValue (false, eBroadcastAlways);
417 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000418 return state;
419}
420
421size_t
422GDBRemoteCommunication::SendPacket (const char *payload)
423{
424 Mutex::Locker locker(m_sequence_mutex);
425 return SendPacketNoLock (payload, ::strlen (payload));
426}
427
428size_t
429GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
430{
431 Mutex::Locker locker(m_sequence_mutex);
432 return SendPacketNoLock (payload, payload_length);
433}
434
435size_t
436GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
437{
438 if (IsConnected())
439 {
440 StreamString packet(0, 4, eByteOrderBig);
441
442 packet.PutChar('$');
443 packet.Write (payload, payload_length);
444 packet.PutChar('#');
445 packet.PutHex8(CalculcateChecksum (payload, payload_length));
446
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000447 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
448 if (log)
449 log->Printf ("send packet: %s", packet.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000450 ConnectionStatus status = eConnectionStatusSuccess;
451 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
452 if (bytes_written == packet.GetSize())
453 {
454 if (m_send_acks)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000455 {
456 if (GetAck (1) != '+')
457 return 0;
458 }
Chris Lattner24943d22010-06-08 16:52:24 +0000459 }
Johnny Chen515ea542010-09-14 22:10:43 +0000460 else
461 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000462 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
463 if (log)
464 log->Printf ("error: failed to send packet: %s", packet.GetData());
Johnny Chen515ea542010-09-14 22:10:43 +0000465 }
Chris Lattner24943d22010-06-08 16:52:24 +0000466 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000467 }
Chris Lattner24943d22010-06-08 16:52:24 +0000468 return 0;
469}
470
471char
472GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
473{
474 StringExtractorGDBRemote response;
475 if (WaitForPacket (response, timeout_seconds) == 1)
476 return response.GetChar();
477 return 0;
478}
479
480bool
481GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
482{
483 return locker.TryLock (m_sequence_mutex.GetMutex());
484}
485
486bool
487GDBRemoteCommunication::SendAsyncSignal (int signo)
488{
489 m_async_signal = signo;
490 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000491 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000492 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000493 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000494 return true;
495 m_async_signal = -1;
496 return false;
497}
498
Greg Clayton1a679462010-09-03 19:15:43 +0000499// This function takes a mutex locker as a parameter in case the GetSequenceMutex
500// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
501// (the expected result), then it will send the halt packet. If it does succeed
502// then the caller that requested the interrupt will want to keep the sequence
503// locked down so that no one else can send packets while the caller has control.
504// This function usually gets called when we are running and need to stop the
505// target. It can also be used when we are running and and we need to do something
506// else (like read/write memory), so we need to interrupt the running process
507// (gdb remote protocol requires this), and do what we need to do, then resume.
508
Chris Lattner24943d22010-06-08 16:52:24 +0000509bool
Greg Claytona4881d02011-01-22 07:12:45 +0000510GDBRemoteCommunication::SendInterrupt
511(
512 Mutex::Locker& locker,
513 uint32_t seconds_to_wait_for_stop,
514 bool &sent_interrupt,
515 bool &timed_out
516)
Chris Lattner24943d22010-06-08 16:52:24 +0000517{
Greg Claytona4881d02011-01-22 07:12:45 +0000518 sent_interrupt = false;
519 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000520 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000521
Greg Claytondb2bab42011-01-27 09:02:32 +0000522 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000523 {
524 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000525 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000526 {
527 // Someone has the mutex locked waiting for a response or for the
528 // inferior to stop, so send the interrupt on the down low...
529 char ctrl_c = '\x03';
530 ConnectionStatus status = eConnectionStatusSuccess;
531 TimeValue timeout;
532 if (seconds_to_wait_for_stop)
533 {
534 timeout = TimeValue::Now();
535 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
536 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000537 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000538 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000539 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000540 {
Greg Claytona4881d02011-01-22 07:12:45 +0000541 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000542 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000543 {
Greg Clayton1c2aa462011-02-03 01:07:45 +0000544 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
545 {
546 if (log)
547 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
548 return true;
549 }
550 else
551 {
552 if (log)
553 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
554 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000555 }
556 else
557 {
558 if (log)
559 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
Greg Clayton1c2aa462011-02-03 01:07:45 +0000560 return true;
Greg Claytondb2bab42011-01-27 09:02:32 +0000561 }
Chris Lattner24943d22010-06-08 16:52:24 +0000562 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000563 else
564 {
565 if (log)
566 log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
567 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000568 return false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000569 }
570 else
571 {
572 if (log)
573 log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000574 }
575 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000576 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000577}
578
Greg Clayton72e1c782011-01-22 23:43:18 +0000579bool
580GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
581{
582 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
583}
584
585bool
586GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
587{
588 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
589}
590
Chris Lattner24943d22010-06-08 16:52:24 +0000591size_t
592GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
593{
Greg Claytoncecf3482011-01-20 07:53:45 +0000594 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000595 TimeValue timeout_time;
596 timeout_time = TimeValue::Now();
597 timeout_time.OffsetWithSeconds (timeout_seconds);
598 return WaitForPacketNoLock (response, &timeout_time);
599}
600
601size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000602GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000603{
604 Mutex::Locker locker(m_sequence_mutex);
605 return WaitForPacketNoLock (response, timeout_time_ptr);
606}
607
608size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000609GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000610{
611 bool checksum_error = false;
612 response.Clear ();
613
614 EventSP event_sp;
615
616 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
617 {
618 const uint32_t event_type = event_sp->GetType();
619 if (event_type | Communication::eBroadcastBitPacketAvailable)
620 {
621 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
622 if (event_bytes)
623 {
624 const char * packet_data = (const char *)event_bytes->GetBytes();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000625 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
626 if (log)
627 log->Printf ("read packet: %s", packet_data);
Chris Lattner24943d22010-06-08 16:52:24 +0000628 const size_t packet_size = event_bytes->GetByteSize();
629 if (packet_data && packet_size > 0)
630 {
631 std::string &response_str = response.GetStringRef();
632 if (packet_data[0] == '$')
633 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000634 bool success = false;
635 if (packet_size < 4)
636 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
637 else if (packet_data[packet_size-3] != '#' ||
638 !::isxdigit (packet_data[packet_size-2]) ||
639 !::isxdigit (packet_data[packet_size-1]))
640 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
641 else
642 success = true;
643
644 if (success)
645 response_str.assign (packet_data + 1, packet_size - 4);
Chris Lattner24943d22010-06-08 16:52:24 +0000646 if (m_send_acks)
647 {
648 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000649 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000650 checksum_error = packet_checksum != actual_checksum;
651 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000652 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000653 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000654 else
Greg Claytona4881d02011-01-22 07:12:45 +0000655 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000656 }
657 }
658 else
659 {
660 response_str.assign (packet_data, packet_size);
661 }
662 return response_str.size();
663 }
664 }
665 }
666 else if (Communication::eBroadcastBitReadThreadDidExit)
667 {
668 // Our read thread exited on us so just fall through and return zero...
669 }
670 }
671 return 0;
672}
673
674void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000675GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
676 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000677{
678 // Put the packet data into the buffer in a thread safe fashion
679 Mutex::Locker locker(m_bytes_mutex);
680 m_bytes.append ((const char *)src, src_len);
681
682 // Parse up the packets into gdb remote packets
683 while (!m_bytes.empty())
684 {
685 // end_idx must be one past the last valid packet byte. Start
686 // it off with an invalid value that is the same as the current
687 // index.
688 size_t end_idx = 0;
689
690 switch (m_bytes[0])
691 {
692 case '+': // Look for ack
693 case '-': // Look for cancel
694 case '\x03': // ^C to halt target
695 end_idx = 1; // The command is one byte long...
696 break;
697
698 case '$':
699 // Look for a standard gdb packet?
700 end_idx = m_bytes.find('#');
701 if (end_idx != std::string::npos)
702 {
703 if (end_idx + 2 < m_bytes.size())
704 {
705 end_idx += 3;
706 }
707 else
708 {
709 // Checksum bytes aren't all here yet
710 end_idx = std::string::npos;
711 }
712 }
713 break;
714
715 default:
716 break;
717 }
718
719 if (end_idx == std::string::npos)
720 {
721 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
722 return;
723 }
724 else if (end_idx > 0)
725 {
726 // We have a valid packet...
727 assert (end_idx <= m_bytes.size());
728 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
729 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
730 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
731 m_bytes.erase(0, end_idx);
732 }
733 else
734 {
735 assert (1 <= m_bytes.size());
736 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
737 m_bytes.erase(0, 1);
738 }
739 }
740}
741
742lldb::pid_t
743GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
744{
745 StringExtractorGDBRemote response;
746 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
747 {
748 if (response.GetChar() == 'Q')
749 if (response.GetChar() == 'C')
750 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
751 }
752 return LLDB_INVALID_PROCESS_ID;
753}
754
755bool
756GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
757{
758 error_str.clear();
759 StringExtractorGDBRemote response;
760 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
761 {
762 if (response.IsOKPacket())
763 return true;
764 if (response.GetChar() == 'E')
765 {
766 // A string the describes what failed when launching...
767 error_str = response.GetStringRef().substr(1);
768 }
769 else
770 {
771 error_str.assign ("unknown error occurred launching process");
772 }
773 }
774 else
775 {
776 error_str.assign ("failed to send the qLaunchSuccess packet");
777 }
778 return false;
779}
780
781int
782GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
783{
784 if (argv && argv[0])
785 {
786 StreamString packet;
787 packet.PutChar('A');
788 const char *arg;
789 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
790 {
791 const int arg_len = strlen(arg);
792 if (i > 0)
793 packet.PutChar(',');
794 packet.Printf("%i,%i,", arg_len * 2, i);
Greg Claytoncd548032011-02-01 01:31:41 +0000795 packet.PutBytesAsRawHex8(arg, arg_len, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000796 }
797
798 StringExtractorGDBRemote response;
799 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
800 {
801 if (response.IsOKPacket())
802 return 0;
803 uint8_t error = response.GetError();
804 if (error)
805 return error;
806 }
807 }
808 return -1;
809}
810
811int
812GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
813{
814 if (name_equal_value && name_equal_value[0])
815 {
816 StreamString packet;
817 packet.Printf("QEnvironment:%s", name_equal_value);
818 StringExtractorGDBRemote response;
819 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
820 {
821 if (response.IsOKPacket())
822 return 0;
823 uint8_t error = response.GetError();
824 if (error)
825 return error;
826 }
827 }
828 return -1;
829}
830
831bool
832GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds)
833{
834 m_arch.Clear();
835 m_os.Clear();
836 m_vendor.Clear();
Greg Claytoncd548032011-02-01 01:31:41 +0000837 m_byte_order = lldb::endian::InlHostByteOrder();
Chris Lattner24943d22010-06-08 16:52:24 +0000838 m_pointer_byte_size = 0;
839
840 StringExtractorGDBRemote response;
841 if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false))
842 {
843 if (response.IsUnsupportedPacket())
844 return false;
845
846
847 std::string name;
848 std::string value;
Greg Claytone71e2582011-02-04 01:58:07 +0000849 uint32_t cpu = LLDB_INVALID_CPUTYPE;
850 uint32_t sub = 0;
851
Chris Lattner24943d22010-06-08 16:52:24 +0000852 while (response.GetNameColonValue(name, value))
853 {
854 if (name.compare("cputype") == 0)
855 {
856 // exception type in big endian hex
Greg Claytone71e2582011-02-04 01:58:07 +0000857 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000858 }
859 else if (name.compare("cpusubtype") == 0)
860 {
861 // exception count in big endian hex
Greg Claytone71e2582011-02-04 01:58:07 +0000862 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000863 }
864 else if (name.compare("ostype") == 0)
865 {
866 // exception data in big endian hex
867 m_os.SetCString(value.c_str());
868 }
869 else if (name.compare("vendor") == 0)
870 {
871 m_vendor.SetCString(value.c_str());
872 }
873 else if (name.compare("endian") == 0)
874 {
875 if (value.compare("little") == 0)
876 m_byte_order = eByteOrderLittle;
877 else if (value.compare("big") == 0)
878 m_byte_order = eByteOrderBig;
879 else if (value.compare("pdp") == 0)
880 m_byte_order = eByteOrderPDP;
881 }
882 else if (name.compare("ptrsize") == 0)
883 {
884 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
885 }
886 }
Greg Claytone71e2582011-02-04 01:58:07 +0000887
888 if (cpu != LLDB_INVALID_CPUTYPE)
889 m_arch.SetMachOArch (cpu, sub);
Chris Lattner24943d22010-06-08 16:52:24 +0000890 }
891 return HostInfoIsValid();
892}
893
894int
895GDBRemoteCommunication::SendAttach
896(
897 lldb::pid_t pid,
898 uint32_t timeout_seconds,
899 StringExtractorGDBRemote& response
900)
901{
902 if (pid != LLDB_INVALID_PROCESS_ID)
903 {
904 StreamString packet;
905 packet.Printf("vAttach;%x", pid);
906
907 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
908 {
909 if (response.IsErrorPacket())
910 return response.GetError();
911 return 0;
912 }
913 }
914 return -1;
915}
916
917const lldb_private::ArchSpec &
918GDBRemoteCommunication::GetHostArchitecture ()
919{
920 if (!HostInfoIsValid ())
921 GetHostInfo (1);
922 return m_arch;
923}
924
925const lldb_private::ConstString &
926GDBRemoteCommunication::GetOSString ()
927{
928 if (!HostInfoIsValid ())
929 GetHostInfo (1);
930 return m_os;
931}
932
933const lldb_private::ConstString &
934GDBRemoteCommunication::GetVendorString()
935{
936 if (!HostInfoIsValid ())
937 GetHostInfo (1);
938 return m_vendor;
939}
940
941lldb::ByteOrder
942GDBRemoteCommunication::GetByteOrder ()
943{
944 if (!HostInfoIsValid ())
945 GetHostInfo (1);
946 return m_byte_order;
947}
948
949uint32_t
950GDBRemoteCommunication::GetAddressByteSize ()
951{
952 if (!HostInfoIsValid ())
953 GetHostInfo (1);
954 return m_pointer_byte_size;
955}
956
957addr_t
958GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
959{
960 char packet[64];
961 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
962 permissions & lldb::ePermissionsReadable ? "r" : "",
963 permissions & lldb::ePermissionsWritable ? "w" : "",
964 permissions & lldb::ePermissionsExecutable ? "x" : "");
965 StringExtractorGDBRemote response;
966 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
967 {
968 if (!response.IsErrorPacket())
969 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
970 }
971 return LLDB_INVALID_ADDRESS;
972}
973
974bool
975GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
976{
977 char packet[64];
978 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
979 StringExtractorGDBRemote response;
980 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
981 {
Sean Callanan6a925532011-01-13 08:53:35 +0000982 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +0000983 return true;
984 }
985 return false;
986}
Jim Ingham3ae449a2010-11-17 02:32:00 +0000987