blob: 54382ff1240f49154e5c7de76d6947eb10528e53 [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 Clayton7e2f91c2011-01-29 07:10:55 +0000276 if (process->GetStopID() == 0)
277 {
278 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
279 {
280 lldb::pid_t pid = GetCurrentProcessID (1);
281 if (pid != LLDB_INVALID_PROCESS_ID)
282 process->SetID (pid);
283 }
284 process->BuildDynamicRegisterInfo (true);
285 }
286
Greg Claytoncecf3482011-01-20 07:53:45 +0000287 // Privately notify any internal threads that we have stopped
288 // in case we wanted to interrupt our process, yet we might
289 // send a packet and continue without returning control to the
290 // user.
291 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000292 if (m_async_signal != -1)
293 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000294 if (log)
295 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000296
Chris Lattner24943d22010-06-08 16:52:24 +0000297 // Save off the async signal we are supposed to send
298 const int async_signal = m_async_signal;
299 // Clear the async signal member so we don't end up
300 // sending the signal multiple times...
301 m_async_signal = -1;
302 // Check which signal we stopped with
303 uint8_t signo = response.GetHexU8(255);
304 if (signo == async_signal)
305 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000306 if (log)
307 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000308
Chris Lattner24943d22010-06-08 16:52:24 +0000309 // We already stopped with a signal that we wanted
310 // to stop with, so we are done
311 response.SetFilePos (0);
312 }
313 else
314 {
315 // We stopped with a different signal that the one
316 // we wanted to stop with, so now we must resume
317 // with the signal we want
318 char signal_packet[32];
319 int signal_packet_len = 0;
320 signal_packet_len = ::snprintf (signal_packet,
321 sizeof (signal_packet),
322 "C%2.2x",
323 async_signal);
324
Greg Clayton68ca8232011-01-25 02:58:48 +0000325 if (log)
326 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000327 Host::GetSignalAsCString (signo),
328 Host::GetSignalAsCString (async_signal));
329
Greg Claytondb2bab42011-01-27 09:02:32 +0000330 // Set the continue packet to resume...
331 continue_packet.assign(signal_packet, signal_packet_len);
332 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000333 }
334 }
335 else if (m_async_packet_predicate.GetValue())
336 {
337 // We are supposed to send an asynchronous packet while
338 // we are running.
339 m_async_response.Clear();
Greg Claytondb2bab42011-01-27 09:02:32 +0000340 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000341 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000342 if (log)
343 log->Printf ("async: error: empty async packet");
344
345 }
346 else
347 {
348 if (log)
349 log->Printf ("async: sending packet: %s",
350 m_async_packet.c_str());
351
Greg Clayton53d68e72010-07-20 22:52:08 +0000352 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000353 m_async_packet.size(),
354 m_async_response,
355 m_async_timeout,
356 false);
357 }
358 // Let the other thread that was trying to send the async
Greg Claytondb2bab42011-01-27 09:02:32 +0000359 // packet know that the packet has been sent and response is
360 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000361 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
362
Greg Claytondb2bab42011-01-27 09:02:32 +0000363 // Set the continue packet to resume...
364 continue_packet.assign (1, 'c');
365 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000366 }
367 // Stop with signal and thread info
368 state = eStateStopped;
369 break;
370
371 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000372 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000373 // process exited
374 state = eStateExited;
375 break;
376
377 case 'O':
378 // STDOUT
379 {
380 std::string inferior_stdout;
381 inferior_stdout.reserve(response.GetBytesLeft () / 2);
382 char ch;
383 while ((ch = response.GetHexU8()) != '\0')
384 inferior_stdout.append(1, ch);
385 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
386 }
387 break;
388
389 case 'E':
390 // ERROR
391 state = eStateInvalid;
392 break;
393
394 default:
395 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000396 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000397 break;
398 }
399 }
400 }
401 else
402 {
403 if (log)
404 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
405 state = eStateInvalid;
406 }
407 }
408 if (log)
409 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
410 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000411 m_private_is_running.SetValue (false, eBroadcastAlways);
412 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000413 return state;
414}
415
416size_t
417GDBRemoteCommunication::SendPacket (const char *payload)
418{
419 Mutex::Locker locker(m_sequence_mutex);
420 return SendPacketNoLock (payload, ::strlen (payload));
421}
422
423size_t
424GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
425{
426 Mutex::Locker locker(m_sequence_mutex);
427 return SendPacketNoLock (payload, payload_length);
428}
429
430size_t
431GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
432{
433 if (IsConnected())
434 {
435 StreamString packet(0, 4, eByteOrderBig);
436
437 packet.PutChar('$');
438 packet.Write (payload, payload_length);
439 packet.PutChar('#');
440 packet.PutHex8(CalculcateChecksum (payload, payload_length));
441
442 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %s", packet.GetData());
443 ConnectionStatus status = eConnectionStatusSuccess;
444 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
445 if (bytes_written == packet.GetSize())
446 {
447 if (m_send_acks)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000448 {
449 if (GetAck (1) != '+')
450 return 0;
451 }
Chris Lattner24943d22010-06-08 16:52:24 +0000452 }
Johnny Chen515ea542010-09-14 22:10:43 +0000453 else
454 {
455 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "error: failed to send packet: %s", packet.GetData());
456 }
Chris Lattner24943d22010-06-08 16:52:24 +0000457 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000458 }
Chris Lattner24943d22010-06-08 16:52:24 +0000459 return 0;
460}
461
462char
463GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
464{
465 StringExtractorGDBRemote response;
466 if (WaitForPacket (response, timeout_seconds) == 1)
467 return response.GetChar();
468 return 0;
469}
470
471bool
472GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
473{
474 return locker.TryLock (m_sequence_mutex.GetMutex());
475}
476
477bool
478GDBRemoteCommunication::SendAsyncSignal (int signo)
479{
480 m_async_signal = signo;
481 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000482 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000483 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000484 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000485 return true;
486 m_async_signal = -1;
487 return false;
488}
489
Greg Clayton1a679462010-09-03 19:15:43 +0000490// This function takes a mutex locker as a parameter in case the GetSequenceMutex
491// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
492// (the expected result), then it will send the halt packet. If it does succeed
493// then the caller that requested the interrupt will want to keep the sequence
494// locked down so that no one else can send packets while the caller has control.
495// This function usually gets called when we are running and need to stop the
496// target. It can also be used when we are running and and we need to do something
497// else (like read/write memory), so we need to interrupt the running process
498// (gdb remote protocol requires this), and do what we need to do, then resume.
499
Chris Lattner24943d22010-06-08 16:52:24 +0000500bool
Greg Claytona4881d02011-01-22 07:12:45 +0000501GDBRemoteCommunication::SendInterrupt
502(
503 Mutex::Locker& locker,
504 uint32_t seconds_to_wait_for_stop,
505 bool &sent_interrupt,
506 bool &timed_out
507)
Chris Lattner24943d22010-06-08 16:52:24 +0000508{
Greg Claytona4881d02011-01-22 07:12:45 +0000509 sent_interrupt = false;
510 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000511 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000512
Greg Claytondb2bab42011-01-27 09:02:32 +0000513 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000514 {
515 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000516 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000517 {
518 // Someone has the mutex locked waiting for a response or for the
519 // inferior to stop, so send the interrupt on the down low...
520 char ctrl_c = '\x03';
521 ConnectionStatus status = eConnectionStatusSuccess;
522 TimeValue timeout;
523 if (seconds_to_wait_for_stop)
524 {
525 timeout = TimeValue::Now();
526 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
527 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000528 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000529 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000530 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000531 {
Greg Claytona4881d02011-01-22 07:12:45 +0000532 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000533 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000534 {
Greg Claytona4881d02011-01-22 07:12:45 +0000535 m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out);
Greg Claytondb2bab42011-01-27 09:02:32 +0000536 if (log)
537 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
538
539 }
540 else
541 {
542 if (log)
543 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
544 }
Chris Lattner24943d22010-06-08 16:52:24 +0000545 return true;
546 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000547 else
548 {
549 if (log)
550 log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
551 }
552 }
553 else
554 {
555 if (log)
556 log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000557 }
558 }
559 return false;
560}
561
Greg Clayton72e1c782011-01-22 23:43:18 +0000562bool
563GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
564{
565 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
566}
567
568bool
569GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
570{
571 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
572}
573
Chris Lattner24943d22010-06-08 16:52:24 +0000574size_t
575GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
576{
Greg Claytoncecf3482011-01-20 07:53:45 +0000577 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000578 TimeValue timeout_time;
579 timeout_time = TimeValue::Now();
580 timeout_time.OffsetWithSeconds (timeout_seconds);
581 return WaitForPacketNoLock (response, &timeout_time);
582}
583
584size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000585GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000586{
587 Mutex::Locker locker(m_sequence_mutex);
588 return WaitForPacketNoLock (response, timeout_time_ptr);
589}
590
591size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000592GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000593{
594 bool checksum_error = false;
595 response.Clear ();
596
597 EventSP event_sp;
598
599 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
600 {
601 const uint32_t event_type = event_sp->GetType();
602 if (event_type | Communication::eBroadcastBitPacketAvailable)
603 {
604 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
605 if (event_bytes)
606 {
607 const char * packet_data = (const char *)event_bytes->GetBytes();
608 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "read packet: %s", packet_data);
609 const size_t packet_size = event_bytes->GetByteSize();
610 if (packet_data && packet_size > 0)
611 {
612 std::string &response_str = response.GetStringRef();
613 if (packet_data[0] == '$')
614 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000615 bool success = false;
616 if (packet_size < 4)
617 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
618 else if (packet_data[packet_size-3] != '#' ||
619 !::isxdigit (packet_data[packet_size-2]) ||
620 !::isxdigit (packet_data[packet_size-1]))
621 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
622 else
623 success = true;
624
625 if (success)
626 response_str.assign (packet_data + 1, packet_size - 4);
Chris Lattner24943d22010-06-08 16:52:24 +0000627 if (m_send_acks)
628 {
629 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000630 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000631 checksum_error = packet_checksum != actual_checksum;
632 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000633 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000634 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000635 else
Greg Claytona4881d02011-01-22 07:12:45 +0000636 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000637 }
638 }
639 else
640 {
641 response_str.assign (packet_data, packet_size);
642 }
643 return response_str.size();
644 }
645 }
646 }
647 else if (Communication::eBroadcastBitReadThreadDidExit)
648 {
649 // Our read thread exited on us so just fall through and return zero...
650 }
651 }
652 return 0;
653}
654
655void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000656GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
657 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000658{
659 // Put the packet data into the buffer in a thread safe fashion
660 Mutex::Locker locker(m_bytes_mutex);
661 m_bytes.append ((const char *)src, src_len);
662
663 // Parse up the packets into gdb remote packets
664 while (!m_bytes.empty())
665 {
666 // end_idx must be one past the last valid packet byte. Start
667 // it off with an invalid value that is the same as the current
668 // index.
669 size_t end_idx = 0;
670
671 switch (m_bytes[0])
672 {
673 case '+': // Look for ack
674 case '-': // Look for cancel
675 case '\x03': // ^C to halt target
676 end_idx = 1; // The command is one byte long...
677 break;
678
679 case '$':
680 // Look for a standard gdb packet?
681 end_idx = m_bytes.find('#');
682 if (end_idx != std::string::npos)
683 {
684 if (end_idx + 2 < m_bytes.size())
685 {
686 end_idx += 3;
687 }
688 else
689 {
690 // Checksum bytes aren't all here yet
691 end_idx = std::string::npos;
692 }
693 }
694 break;
695
696 default:
697 break;
698 }
699
700 if (end_idx == std::string::npos)
701 {
702 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
703 return;
704 }
705 else if (end_idx > 0)
706 {
707 // We have a valid packet...
708 assert (end_idx <= m_bytes.size());
709 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
710 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
711 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
712 m_bytes.erase(0, end_idx);
713 }
714 else
715 {
716 assert (1 <= m_bytes.size());
717 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
718 m_bytes.erase(0, 1);
719 }
720 }
721}
722
723lldb::pid_t
724GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
725{
726 StringExtractorGDBRemote response;
727 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
728 {
729 if (response.GetChar() == 'Q')
730 if (response.GetChar() == 'C')
731 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
732 }
733 return LLDB_INVALID_PROCESS_ID;
734}
735
736bool
737GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
738{
739 error_str.clear();
740 StringExtractorGDBRemote response;
741 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
742 {
743 if (response.IsOKPacket())
744 return true;
745 if (response.GetChar() == 'E')
746 {
747 // A string the describes what failed when launching...
748 error_str = response.GetStringRef().substr(1);
749 }
750 else
751 {
752 error_str.assign ("unknown error occurred launching process");
753 }
754 }
755 else
756 {
757 error_str.assign ("failed to send the qLaunchSuccess packet");
758 }
759 return false;
760}
761
762int
763GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
764{
765 if (argv && argv[0])
766 {
767 StreamString packet;
768 packet.PutChar('A');
769 const char *arg;
770 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
771 {
772 const int arg_len = strlen(arg);
773 if (i > 0)
774 packet.PutChar(',');
775 packet.Printf("%i,%i,", arg_len * 2, i);
776 packet.PutBytesAsRawHex8(arg, arg_len, eByteOrderHost, eByteOrderHost);
777 }
778
779 StringExtractorGDBRemote response;
780 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
781 {
782 if (response.IsOKPacket())
783 return 0;
784 uint8_t error = response.GetError();
785 if (error)
786 return error;
787 }
788 }
789 return -1;
790}
791
792int
793GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
794{
795 if (name_equal_value && name_equal_value[0])
796 {
797 StreamString packet;
798 packet.Printf("QEnvironment:%s", name_equal_value);
799 StringExtractorGDBRemote response;
800 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
801 {
802 if (response.IsOKPacket())
803 return 0;
804 uint8_t error = response.GetError();
805 if (error)
806 return error;
807 }
808 }
809 return -1;
810}
811
812bool
813GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds)
814{
815 m_arch.Clear();
816 m_os.Clear();
817 m_vendor.Clear();
818 m_byte_order = eByteOrderHost;
819 m_pointer_byte_size = 0;
820
821 StringExtractorGDBRemote response;
822 if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false))
823 {
824 if (response.IsUnsupportedPacket())
825 return false;
826
827
828 std::string name;
829 std::string value;
830 while (response.GetNameColonValue(name, value))
831 {
832 if (name.compare("cputype") == 0)
833 {
834 // exception type in big endian hex
835 m_arch.SetCPUType(Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0));
836 }
837 else if (name.compare("cpusubtype") == 0)
838 {
839 // exception count in big endian hex
840 m_arch.SetCPUSubtype(Args::StringToUInt32 (value.c_str(), 0, 0));
841 }
842 else if (name.compare("ostype") == 0)
843 {
844 // exception data in big endian hex
845 m_os.SetCString(value.c_str());
846 }
847 else if (name.compare("vendor") == 0)
848 {
849 m_vendor.SetCString(value.c_str());
850 }
851 else if (name.compare("endian") == 0)
852 {
853 if (value.compare("little") == 0)
854 m_byte_order = eByteOrderLittle;
855 else if (value.compare("big") == 0)
856 m_byte_order = eByteOrderBig;
857 else if (value.compare("pdp") == 0)
858 m_byte_order = eByteOrderPDP;
859 }
860 else if (name.compare("ptrsize") == 0)
861 {
862 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
863 }
864 }
865 }
866 return HostInfoIsValid();
867}
868
869int
870GDBRemoteCommunication::SendAttach
871(
872 lldb::pid_t pid,
873 uint32_t timeout_seconds,
874 StringExtractorGDBRemote& response
875)
876{
877 if (pid != LLDB_INVALID_PROCESS_ID)
878 {
879 StreamString packet;
880 packet.Printf("vAttach;%x", pid);
881
882 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
883 {
884 if (response.IsErrorPacket())
885 return response.GetError();
886 return 0;
887 }
888 }
889 return -1;
890}
891
892const lldb_private::ArchSpec &
893GDBRemoteCommunication::GetHostArchitecture ()
894{
895 if (!HostInfoIsValid ())
896 GetHostInfo (1);
897 return m_arch;
898}
899
900const lldb_private::ConstString &
901GDBRemoteCommunication::GetOSString ()
902{
903 if (!HostInfoIsValid ())
904 GetHostInfo (1);
905 return m_os;
906}
907
908const lldb_private::ConstString &
909GDBRemoteCommunication::GetVendorString()
910{
911 if (!HostInfoIsValid ())
912 GetHostInfo (1);
913 return m_vendor;
914}
915
916lldb::ByteOrder
917GDBRemoteCommunication::GetByteOrder ()
918{
919 if (!HostInfoIsValid ())
920 GetHostInfo (1);
921 return m_byte_order;
922}
923
924uint32_t
925GDBRemoteCommunication::GetAddressByteSize ()
926{
927 if (!HostInfoIsValid ())
928 GetHostInfo (1);
929 return m_pointer_byte_size;
930}
931
932addr_t
933GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
934{
935 char packet[64];
936 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
937 permissions & lldb::ePermissionsReadable ? "r" : "",
938 permissions & lldb::ePermissionsWritable ? "w" : "",
939 permissions & lldb::ePermissionsExecutable ? "x" : "");
940 StringExtractorGDBRemote response;
941 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
942 {
943 if (!response.IsErrorPacket())
944 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
945 }
946 return LLDB_INVALID_ADDRESS;
947}
948
949bool
950GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
951{
952 char packet[64];
953 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
954 StringExtractorGDBRemote response;
955 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
956 {
Sean Callanan6a925532011-01-13 08:53:35 +0000957 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +0000958 return true;
959 }
960 return false;
961}
Jim Ingham3ae449a2010-11-17 02:32:00 +0000962