blob: 9ebb143a150c7457c58883c9d551d1324eece30b [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"),
Greg Claytonc1f45872011-02-12 06:28:37 +000037 m_supports_not_sending_acks (eLazyBoolCalculate),
38 m_supports_thread_suffix (eLazyBoolCalculate),
39 m_supports_qHostInfo (eLazyBoolCalculate),
40 m_supports_vCont_all (eLazyBoolCalculate),
41 m_supports_vCont_any (eLazyBoolCalculate),
42 m_supports_vCont_c (eLazyBoolCalculate),
43 m_supports_vCont_C (eLazyBoolCalculate),
44 m_supports_vCont_s (eLazyBoolCalculate),
45 m_supports_vCont_S (eLazyBoolCalculate),
Chris Lattner24943d22010-06-08 16:52:24 +000046 m_rx_packet_listener ("gdbremote.rx_packet"),
47 m_sequence_mutex (Mutex::eMutexTypeRecursive),
Greg Claytoncecf3482011-01-20 07:53:45 +000048 m_public_is_running (false),
49 m_private_is_running (false),
Chris Lattner24943d22010-06-08 16:52:24 +000050 m_async_mutex (Mutex::eMutexTypeRecursive),
51 m_async_packet_predicate (false),
52 m_async_packet (),
53 m_async_response (),
54 m_async_timeout (UINT32_MAX),
55 m_async_signal (-1),
56 m_arch(),
57 m_os(),
58 m_vendor(),
Greg Claytoncd548032011-02-01 01:31:41 +000059 m_byte_order(lldb::endian::InlHostByteOrder()),
Chris Lattner24943d22010-06-08 16:52:24 +000060 m_pointer_byte_size(0)
61{
62 m_rx_packet_listener.StartListeningForEvents(this,
63 Communication::eBroadcastBitPacketAvailable |
64 Communication::eBroadcastBitReadThreadDidExit);
65}
66
67//----------------------------------------------------------------------
68// Destructor
69//----------------------------------------------------------------------
70GDBRemoteCommunication::~GDBRemoteCommunication()
71{
72 m_rx_packet_listener.StopListeningForEvents(this,
73 Communication::eBroadcastBitPacketAvailable |
74 Communication::eBroadcastBitReadThreadDidExit);
75 if (IsConnected())
76 {
77 StopReadThread();
78 Disconnect();
79 }
80}
81
82
83char
84GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
85{
86 int checksum = 0;
87
88 // We only need to compute the checksum if we are sending acks
Greg Claytonc1f45872011-02-12 06:28:37 +000089 if (GetSendAcks ())
Chris Lattner24943d22010-06-08 16:52:24 +000090 {
Greg Clayton54e7afa2010-07-09 20:39:50 +000091 for (size_t i = 0; i < payload_length; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +000092 checksum += payload[i];
93 }
94 return checksum & 255;
95}
96
97size_t
Greg Claytona4881d02011-01-22 07:12:45 +000098GDBRemoteCommunication::SendAck ()
Chris Lattner24943d22010-06-08 16:52:24 +000099{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000100 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
101 if (log)
102 log->Printf ("send packet: +");
Chris Lattner24943d22010-06-08 16:52:24 +0000103 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytona4881d02011-01-22 07:12:45 +0000104 char ack_char = '+';
Chris Lattner24943d22010-06-08 16:52:24 +0000105 return Write (&ack_char, 1, status, NULL) == 1;
106}
107
108size_t
Greg Claytona4881d02011-01-22 07:12:45 +0000109GDBRemoteCommunication::SendNack ()
110{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000111 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
112 if (log)
113 log->Printf ("send packet: -");
Greg Claytona4881d02011-01-22 07:12:45 +0000114 ConnectionStatus status = eConnectionStatusSuccess;
115 char nack_char = '-';
116 return Write (&nack_char, 1, status, NULL) == 1;
117}
118
Greg Claytonc1f45872011-02-12 06:28:37 +0000119bool
120GDBRemoteCommunication::GetSendAcks ()
121{
122 if (m_supports_not_sending_acks == eLazyBoolCalculate)
123 {
124 StringExtractorGDBRemote response;
125 m_supports_not_sending_acks = eLazyBoolNo;
126 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
127 {
128 if (response.IsOKPacket())
129 m_supports_not_sending_acks = eLazyBoolYes;
130 }
131 }
132 return m_supports_not_sending_acks != eLazyBoolYes;
133}
134
135void
136GDBRemoteCommunication::ResetDiscoverableSettings()
137{
138 m_supports_not_sending_acks = eLazyBoolCalculate;
139 m_supports_thread_suffix = eLazyBoolCalculate;
140 m_supports_qHostInfo = eLazyBoolCalculate;
141 m_supports_vCont_c = eLazyBoolCalculate;
142 m_supports_vCont_C = eLazyBoolCalculate;
143 m_supports_vCont_s = eLazyBoolCalculate;
144 m_supports_vCont_S = eLazyBoolCalculate;
145 m_arch.Clear();
146 m_os.Clear();
147 m_vendor.Clear();
148 m_byte_order = lldb::endian::InlHostByteOrder();
149 m_pointer_byte_size = 0;
150}
151
152
153bool
154GDBRemoteCommunication::GetThreadSuffixSupported ()
155{
156 if (m_supports_thread_suffix == eLazyBoolCalculate)
157 {
158 StringExtractorGDBRemote response;
159 m_supports_thread_suffix = eLazyBoolNo;
160 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false))
161 {
162 if (response.IsOKPacket())
163 m_supports_thread_suffix = eLazyBoolYes;
164 }
165 }
166 return m_supports_thread_suffix;
167}
168bool
169GDBRemoteCommunication::GetVContSupported (char flavor)
170{
171 if (m_supports_vCont_c == eLazyBoolCalculate)
172 {
173 StringExtractorGDBRemote response;
174 m_supports_vCont_c = eLazyBoolNo;
175 m_supports_vCont_C = eLazyBoolNo;
176 m_supports_vCont_s = eLazyBoolNo;
177 m_supports_vCont_S = eLazyBoolNo;
178 if (SendPacketAndWaitForResponse("vCont?", response, 1, false))
179 {
180 const char *response_cstr = response.GetStringRef().c_str();
181 if (::strstr (response_cstr, ";c"))
182 m_supports_vCont_c = eLazyBoolYes;
183
184 if (::strstr (response_cstr, ";C"))
185 m_supports_vCont_C = eLazyBoolYes;
186
187 if (::strstr (response_cstr, ";s"))
188 m_supports_vCont_s = eLazyBoolYes;
189
190 if (::strstr (response_cstr, ";S"))
191 m_supports_vCont_S = eLazyBoolYes;
192
193 if (m_supports_vCont_c == eLazyBoolYes &&
194 m_supports_vCont_C == eLazyBoolYes &&
195 m_supports_vCont_s == eLazyBoolYes &&
196 m_supports_vCont_S == eLazyBoolYes)
197 {
198 m_supports_vCont_all = eLazyBoolYes;
199 }
200
201 if (m_supports_vCont_c == eLazyBoolYes ||
202 m_supports_vCont_C == eLazyBoolYes ||
203 m_supports_vCont_s == eLazyBoolYes ||
204 m_supports_vCont_S == eLazyBoolYes)
205 {
206 m_supports_vCont_any = eLazyBoolYes;
207 }
208 }
209 }
210
211 switch (flavor)
212 {
213 case 'a': return m_supports_vCont_any;
214 case 'A': return m_supports_vCont_all;
215 case 'c': return m_supports_vCont_c;
216 case 'C': return m_supports_vCont_C;
217 case 's': return m_supports_vCont_s;
218 case 'S': return m_supports_vCont_S;
219 default: break;
220 }
221 return false;
222}
223
224
Greg Claytona4881d02011-01-22 07:12:45 +0000225size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000226GDBRemoteCommunication::SendPacketAndWaitForResponse
227(
228 const char *payload,
229 StringExtractorGDBRemote &response,
230 uint32_t timeout_seconds,
231 bool send_async
232)
233{
234 return SendPacketAndWaitForResponse (payload,
235 ::strlen (payload),
236 response,
237 timeout_seconds,
238 send_async);
239}
240
241size_t
242GDBRemoteCommunication::SendPacketAndWaitForResponse
243(
244 const char *payload,
245 size_t payload_length,
246 StringExtractorGDBRemote &response,
247 uint32_t timeout_seconds,
248 bool send_async
249)
250{
251 Mutex::Locker locker;
252 TimeValue timeout_time;
253 timeout_time = TimeValue::Now();
254 timeout_time.OffsetWithSeconds (timeout_seconds);
Greg Claytondb2bab42011-01-27 09:02:32 +0000255 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000256
Greg Clayton1a679462010-09-03 19:15:43 +0000257 if (GetSequenceMutex (locker))
Chris Lattner24943d22010-06-08 16:52:24 +0000258 {
259 if (SendPacketNoLock (payload, strlen(payload)))
260 return WaitForPacketNoLock (response, &timeout_time);
261 }
262 else
263 {
264 if (send_async)
265 {
266 Mutex::Locker async_locker (m_async_mutex);
267 m_async_packet.assign(payload, payload_length);
268 m_async_timeout = timeout_seconds;
269 m_async_packet_predicate.SetValue (true, eBroadcastNever);
270
Greg Claytondb2bab42011-01-27 09:02:32 +0000271 if (log)
272 log->Printf ("async: async packet = %s", m_async_packet.c_str());
273
Chris Lattner24943d22010-06-08 16:52:24 +0000274 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000275 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000276 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000277 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000278 if (sent_interrupt)
Chris Lattner24943d22010-06-08 16:52:24 +0000279 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000280 if (log)
281 log->Printf ("async: sent interrupt");
282 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
283 {
284 if (log)
285 log->Printf ("async: got response");
286 response = m_async_response;
287 return response.GetStringRef().size();
288 }
289 else
290 {
291 if (log)
292 log->Printf ("async: timed out waiting for response");
293 }
294
295 // Make sure we wait until the continue packet has been sent again...
296 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
297 {
298 if (log)
299 log->Printf ("async: timed out waiting for process to resume");
300 }
301 }
302 else
303 {
304 // We had a racy condition where we went to send the interrupt
305 // yet we were able to get the loc
Chris Lattner24943d22010-06-08 16:52:24 +0000306 }
307 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000308 else
309 {
310 if (log)
311 log->Printf ("async: failed to interrupt");
312 }
Chris Lattner24943d22010-06-08 16:52:24 +0000313 }
314 else
315 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000316 if (log)
317 log->Printf ("mutex taken and send_async == false, aborting packet");
Chris Lattner24943d22010-06-08 16:52:24 +0000318 }
319 }
320 return 0;
321}
322
323//template<typename _Tp>
324//class ScopedValueChanger
325//{
326//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000327// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000328// // instance goes out of scope.
329// ScopedValueChanger (_Tp &value_ref, _Tp value) :
330// m_value_ref (value_ref),
331// m_value (value)
332// {
333// }
334//
335// // This object is going out of scope, change the value pointed to by
336// // m_value_ref to the value we got during construction which was stored in
337// // m_value;
338// ~ScopedValueChanger ()
339// {
340// m_value_ref = m_value;
341// }
342//protected:
Greg Clayton5d187e52011-01-08 20:28:42 +0000343// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000344// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
345//};
346
347StateType
348GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
349(
350 ProcessGDBRemote *process,
351 const char *payload,
352 size_t packet_length,
353 StringExtractorGDBRemote &response
354)
355{
Greg Claytone005f2c2010-11-06 01:53:30 +0000356 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000357 if (log)
358 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
359
360 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000361 StateType state = eStateRunning;
362
Greg Claytonb749a262010-12-03 06:02:24 +0000363 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000364 m_public_is_running.SetValue (true, eBroadcastNever);
Greg Claytondb2bab42011-01-27 09:02:32 +0000365 // Set the starting continue packet into "continue_packet". This packet
366 // make change if we are interrupted and we continue after an async packet...
367 std::string continue_packet(payload, packet_length);
368
Chris Lattner24943d22010-06-08 16:52:24 +0000369 while (state == eStateRunning)
370 {
371 if (log)
Greg Claytondb2bab42011-01-27 09:02:32 +0000372 log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
373 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
374 state = eStateInvalid;
375
376 m_private_is_running.SetValue (true, eBroadcastNever);
377
378 if (log)
379 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000380
381 if (WaitForPacket (response, (TimeValue*)NULL))
382 {
383 if (response.Empty())
384 state = eStateInvalid;
385 else
386 {
387 const char stop_type = response.GetChar();
388 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000389 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000390 switch (stop_type)
391 {
392 case 'T':
393 case 'S':
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000394 if (process->GetStopID() == 0)
395 {
396 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
397 {
398 lldb::pid_t pid = GetCurrentProcessID (1);
399 if (pid != LLDB_INVALID_PROCESS_ID)
400 process->SetID (pid);
401 }
402 process->BuildDynamicRegisterInfo (true);
403 }
404
Greg Claytoncecf3482011-01-20 07:53:45 +0000405 // Privately notify any internal threads that we have stopped
406 // in case we wanted to interrupt our process, yet we might
407 // send a packet and continue without returning control to the
408 // user.
409 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000410 if (m_async_signal != -1)
411 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000412 if (log)
413 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000414
Chris Lattner24943d22010-06-08 16:52:24 +0000415 // Save off the async signal we are supposed to send
416 const int async_signal = m_async_signal;
417 // Clear the async signal member so we don't end up
418 // sending the signal multiple times...
419 m_async_signal = -1;
420 // Check which signal we stopped with
421 uint8_t signo = response.GetHexU8(255);
422 if (signo == async_signal)
423 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000424 if (log)
425 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000426
Chris Lattner24943d22010-06-08 16:52:24 +0000427 // We already stopped with a signal that we wanted
428 // to stop with, so we are done
429 response.SetFilePos (0);
430 }
431 else
432 {
433 // We stopped with a different signal that the one
434 // we wanted to stop with, so now we must resume
435 // with the signal we want
436 char signal_packet[32];
437 int signal_packet_len = 0;
438 signal_packet_len = ::snprintf (signal_packet,
439 sizeof (signal_packet),
440 "C%2.2x",
441 async_signal);
442
Greg Clayton68ca8232011-01-25 02:58:48 +0000443 if (log)
444 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000445 Host::GetSignalAsCString (signo),
446 Host::GetSignalAsCString (async_signal));
447
Greg Claytondb2bab42011-01-27 09:02:32 +0000448 // Set the continue packet to resume...
449 continue_packet.assign(signal_packet, signal_packet_len);
450 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000451 }
452 }
453 else if (m_async_packet_predicate.GetValue())
454 {
455 // We are supposed to send an asynchronous packet while
456 // we are running.
457 m_async_response.Clear();
Greg Claytondb2bab42011-01-27 09:02:32 +0000458 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000459 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000460 if (log)
461 log->Printf ("async: error: empty async packet");
462
463 }
464 else
465 {
466 if (log)
467 log->Printf ("async: sending packet: %s",
468 m_async_packet.c_str());
469
Greg Clayton53d68e72010-07-20 22:52:08 +0000470 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000471 m_async_packet.size(),
472 m_async_response,
473 m_async_timeout,
474 false);
475 }
476 // Let the other thread that was trying to send the async
Greg Claytondb2bab42011-01-27 09:02:32 +0000477 // packet know that the packet has been sent and response is
478 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000479 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
480
Greg Claytondb2bab42011-01-27 09:02:32 +0000481 // Set the continue packet to resume...
482 continue_packet.assign (1, 'c');
483 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000484 }
485 // Stop with signal and thread info
486 state = eStateStopped;
487 break;
488
489 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000490 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000491 // process exited
492 state = eStateExited;
493 break;
494
495 case 'O':
496 // STDOUT
497 {
498 std::string inferior_stdout;
499 inferior_stdout.reserve(response.GetBytesLeft () / 2);
500 char ch;
501 while ((ch = response.GetHexU8()) != '\0')
502 inferior_stdout.append(1, ch);
503 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
504 }
505 break;
506
507 case 'E':
508 // ERROR
509 state = eStateInvalid;
510 break;
511
512 default:
513 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000514 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000515 break;
516 }
517 }
518 }
519 else
520 {
521 if (log)
522 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
523 state = eStateInvalid;
524 }
525 }
526 if (log)
527 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
528 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000529 m_private_is_running.SetValue (false, eBroadcastAlways);
530 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000531 return state;
532}
533
534size_t
535GDBRemoteCommunication::SendPacket (const char *payload)
536{
537 Mutex::Locker locker(m_sequence_mutex);
538 return SendPacketNoLock (payload, ::strlen (payload));
539}
540
541size_t
542GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
543{
544 Mutex::Locker locker(m_sequence_mutex);
545 return SendPacketNoLock (payload, payload_length);
546}
547
548size_t
549GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
550{
551 if (IsConnected())
552 {
553 StreamString packet(0, 4, eByteOrderBig);
554
555 packet.PutChar('$');
556 packet.Write (payload, payload_length);
557 packet.PutChar('#');
558 packet.PutHex8(CalculcateChecksum (payload, payload_length));
559
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000560 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
561 if (log)
562 log->Printf ("send packet: %s", packet.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000563 ConnectionStatus status = eConnectionStatusSuccess;
564 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
565 if (bytes_written == packet.GetSize())
566 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000567 if (GetSendAcks ())
Greg Clayton54e7afa2010-07-09 20:39:50 +0000568 {
569 if (GetAck (1) != '+')
570 return 0;
571 }
Chris Lattner24943d22010-06-08 16:52:24 +0000572 }
Johnny Chen515ea542010-09-14 22:10:43 +0000573 else
574 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000575 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
576 if (log)
577 log->Printf ("error: failed to send packet: %s", packet.GetData());
Johnny Chen515ea542010-09-14 22:10:43 +0000578 }
Chris Lattner24943d22010-06-08 16:52:24 +0000579 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000580 }
Chris Lattner24943d22010-06-08 16:52:24 +0000581 return 0;
582}
583
584char
585GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
586{
587 StringExtractorGDBRemote response;
588 if (WaitForPacket (response, timeout_seconds) == 1)
589 return response.GetChar();
590 return 0;
591}
592
593bool
594GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
595{
596 return locker.TryLock (m_sequence_mutex.GetMutex());
597}
598
599bool
600GDBRemoteCommunication::SendAsyncSignal (int signo)
601{
602 m_async_signal = signo;
603 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000604 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000605 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000606 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000607 return true;
608 m_async_signal = -1;
609 return false;
610}
611
Greg Clayton1a679462010-09-03 19:15:43 +0000612// This function takes a mutex locker as a parameter in case the GetSequenceMutex
613// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
614// (the expected result), then it will send the halt packet. If it does succeed
615// then the caller that requested the interrupt will want to keep the sequence
616// locked down so that no one else can send packets while the caller has control.
617// This function usually gets called when we are running and need to stop the
618// target. It can also be used when we are running and and we need to do something
619// else (like read/write memory), so we need to interrupt the running process
620// (gdb remote protocol requires this), and do what we need to do, then resume.
621
Chris Lattner24943d22010-06-08 16:52:24 +0000622bool
Greg Claytona4881d02011-01-22 07:12:45 +0000623GDBRemoteCommunication::SendInterrupt
624(
625 Mutex::Locker& locker,
626 uint32_t seconds_to_wait_for_stop,
627 bool &sent_interrupt,
628 bool &timed_out
629)
Chris Lattner24943d22010-06-08 16:52:24 +0000630{
Greg Claytona4881d02011-01-22 07:12:45 +0000631 sent_interrupt = false;
632 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000633 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000634
Greg Claytondb2bab42011-01-27 09:02:32 +0000635 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000636 {
637 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000638 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000639 {
640 // Someone has the mutex locked waiting for a response or for the
641 // inferior to stop, so send the interrupt on the down low...
642 char ctrl_c = '\x03';
643 ConnectionStatus status = eConnectionStatusSuccess;
644 TimeValue timeout;
645 if (seconds_to_wait_for_stop)
646 {
647 timeout = TimeValue::Now();
648 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
649 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000650 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000651 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000652 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000653 {
Greg Claytona4881d02011-01-22 07:12:45 +0000654 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000655 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000656 {
Greg Clayton1c2aa462011-02-03 01:07:45 +0000657 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
658 {
659 if (log)
660 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
661 return true;
662 }
663 else
664 {
665 if (log)
666 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
667 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000668 }
669 else
670 {
671 if (log)
672 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
Greg Clayton1c2aa462011-02-03 01:07:45 +0000673 return true;
Greg Claytondb2bab42011-01-27 09:02:32 +0000674 }
Chris Lattner24943d22010-06-08 16:52:24 +0000675 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000676 else
677 {
678 if (log)
679 log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
680 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000681 return false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000682 }
683 else
684 {
685 if (log)
686 log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000687 }
688 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000689 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000690}
691
Greg Clayton72e1c782011-01-22 23:43:18 +0000692bool
693GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
694{
695 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
696}
697
698bool
699GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
700{
701 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
702}
703
Chris Lattner24943d22010-06-08 16:52:24 +0000704size_t
705GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
706{
Greg Claytoncecf3482011-01-20 07:53:45 +0000707 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000708 TimeValue timeout_time;
709 timeout_time = TimeValue::Now();
710 timeout_time.OffsetWithSeconds (timeout_seconds);
711 return WaitForPacketNoLock (response, &timeout_time);
712}
713
714size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000715GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000716{
717 Mutex::Locker locker(m_sequence_mutex);
718 return WaitForPacketNoLock (response, timeout_time_ptr);
719}
720
721size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000722GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000723{
724 bool checksum_error = false;
725 response.Clear ();
726
727 EventSP event_sp;
728
729 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
730 {
731 const uint32_t event_type = event_sp->GetType();
732 if (event_type | Communication::eBroadcastBitPacketAvailable)
733 {
734 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
735 if (event_bytes)
736 {
737 const char * packet_data = (const char *)event_bytes->GetBytes();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000738 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
739 if (log)
740 log->Printf ("read packet: %s", packet_data);
Chris Lattner24943d22010-06-08 16:52:24 +0000741 const size_t packet_size = event_bytes->GetByteSize();
742 if (packet_data && packet_size > 0)
743 {
744 std::string &response_str = response.GetStringRef();
745 if (packet_data[0] == '$')
746 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000747 bool success = false;
748 if (packet_size < 4)
749 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
750 else if (packet_data[packet_size-3] != '#' ||
751 !::isxdigit (packet_data[packet_size-2]) ||
752 !::isxdigit (packet_data[packet_size-1]))
753 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
754 else
755 success = true;
756
757 if (success)
758 response_str.assign (packet_data + 1, packet_size - 4);
Greg Claytonc1f45872011-02-12 06:28:37 +0000759 if (GetSendAcks ())
Chris Lattner24943d22010-06-08 16:52:24 +0000760 {
761 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000762 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000763 checksum_error = packet_checksum != actual_checksum;
764 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000765 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000766 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000767 else
Greg Claytona4881d02011-01-22 07:12:45 +0000768 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000769 }
770 }
771 else
772 {
773 response_str.assign (packet_data, packet_size);
774 }
775 return response_str.size();
776 }
777 }
778 }
779 else if (Communication::eBroadcastBitReadThreadDidExit)
780 {
781 // Our read thread exited on us so just fall through and return zero...
782 }
783 }
784 return 0;
785}
786
787void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000788GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
789 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000790{
791 // Put the packet data into the buffer in a thread safe fashion
792 Mutex::Locker locker(m_bytes_mutex);
793 m_bytes.append ((const char *)src, src_len);
794
795 // Parse up the packets into gdb remote packets
796 while (!m_bytes.empty())
797 {
798 // end_idx must be one past the last valid packet byte. Start
799 // it off with an invalid value that is the same as the current
800 // index.
801 size_t end_idx = 0;
802
803 switch (m_bytes[0])
804 {
805 case '+': // Look for ack
806 case '-': // Look for cancel
807 case '\x03': // ^C to halt target
808 end_idx = 1; // The command is one byte long...
809 break;
810
811 case '$':
812 // Look for a standard gdb packet?
813 end_idx = m_bytes.find('#');
814 if (end_idx != std::string::npos)
815 {
816 if (end_idx + 2 < m_bytes.size())
817 {
818 end_idx += 3;
819 }
820 else
821 {
822 // Checksum bytes aren't all here yet
823 end_idx = std::string::npos;
824 }
825 }
826 break;
827
828 default:
829 break;
830 }
831
832 if (end_idx == std::string::npos)
833 {
834 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
835 return;
836 }
837 else if (end_idx > 0)
838 {
839 // We have a valid packet...
840 assert (end_idx <= m_bytes.size());
841 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
842 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
843 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
844 m_bytes.erase(0, end_idx);
845 }
846 else
847 {
848 assert (1 <= m_bytes.size());
849 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
850 m_bytes.erase(0, 1);
851 }
852 }
853}
854
855lldb::pid_t
856GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
857{
858 StringExtractorGDBRemote response;
859 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
860 {
861 if (response.GetChar() == 'Q')
862 if (response.GetChar() == 'C')
863 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
864 }
865 return LLDB_INVALID_PROCESS_ID;
866}
867
868bool
869GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
870{
871 error_str.clear();
872 StringExtractorGDBRemote response;
873 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
874 {
875 if (response.IsOKPacket())
876 return true;
877 if (response.GetChar() == 'E')
878 {
879 // A string the describes what failed when launching...
880 error_str = response.GetStringRef().substr(1);
881 }
882 else
883 {
884 error_str.assign ("unknown error occurred launching process");
885 }
886 }
887 else
888 {
889 error_str.assign ("failed to send the qLaunchSuccess packet");
890 }
891 return false;
892}
893
894int
895GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
896{
897 if (argv && argv[0])
898 {
899 StreamString packet;
900 packet.PutChar('A');
901 const char *arg;
902 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
903 {
904 const int arg_len = strlen(arg);
905 if (i > 0)
906 packet.PutChar(',');
907 packet.Printf("%i,%i,", arg_len * 2, i);
Greg Claytoncd548032011-02-01 01:31:41 +0000908 packet.PutBytesAsRawHex8(arg, arg_len, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000909 }
910
911 StringExtractorGDBRemote response;
912 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
913 {
914 if (response.IsOKPacket())
915 return 0;
916 uint8_t error = response.GetError();
917 if (error)
918 return error;
919 }
920 }
921 return -1;
922}
923
924int
925GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
926{
927 if (name_equal_value && name_equal_value[0])
928 {
929 StreamString packet;
930 packet.Printf("QEnvironment:%s", name_equal_value);
931 StringExtractorGDBRemote response;
932 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
933 {
934 if (response.IsOKPacket())
935 return 0;
936 uint8_t error = response.GetError();
937 if (error)
938 return error;
939 }
940 }
941 return -1;
942}
943
944bool
Greg Claytonc1f45872011-02-12 06:28:37 +0000945GDBRemoteCommunication::GetHostInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +0000946{
Greg Claytonc1f45872011-02-12 06:28:37 +0000947 if (m_supports_qHostInfo == eLazyBoolCalculate)
Chris Lattner24943d22010-06-08 16:52:24 +0000948 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000949 m_supports_qHostInfo = eLazyBoolNo;
Chris Lattner24943d22010-06-08 16:52:24 +0000950
Greg Claytonc1f45872011-02-12 06:28:37 +0000951 StringExtractorGDBRemote response;
952 if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000953 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000954 if (response.IsUnsupportedPacket())
955 return false;
956
957 m_supports_qHostInfo = eLazyBoolYes;
958
959 std::string name;
960 std::string value;
961 uint32_t cpu = LLDB_INVALID_CPUTYPE;
962 uint32_t sub = 0;
Greg Claytone71e2582011-02-04 01:58:07 +0000963
Greg Claytonc1f45872011-02-12 06:28:37 +0000964 while (response.GetNameColonValue(name, value))
965 {
966 if (name.compare("cputype") == 0)
967 {
968 // exception type in big endian hex
969 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
970 }
971 else if (name.compare("cpusubtype") == 0)
972 {
973 // exception count in big endian hex
974 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
975 }
976 else if (name.compare("ostype") == 0)
977 {
978 // exception data in big endian hex
979 m_os.SetCString(value.c_str());
980 }
981 else if (name.compare("vendor") == 0)
982 {
983 m_vendor.SetCString(value.c_str());
984 }
985 else if (name.compare("endian") == 0)
986 {
987 if (value.compare("little") == 0)
988 m_byte_order = eByteOrderLittle;
989 else if (value.compare("big") == 0)
990 m_byte_order = eByteOrderBig;
991 else if (value.compare("pdp") == 0)
992 m_byte_order = eByteOrderPDP;
993 }
994 else if (name.compare("ptrsize") == 0)
995 {
996 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
997 }
998 }
999
1000 if (cpu != LLDB_INVALID_CPUTYPE)
1001 m_arch.SetMachOArch (cpu, sub);
1002 }
Chris Lattner24943d22010-06-08 16:52:24 +00001003 }
Greg Claytonc1f45872011-02-12 06:28:37 +00001004 return m_supports_qHostInfo == eLazyBoolYes;
Chris Lattner24943d22010-06-08 16:52:24 +00001005}
1006
1007int
1008GDBRemoteCommunication::SendAttach
1009(
1010 lldb::pid_t pid,
1011 uint32_t timeout_seconds,
1012 StringExtractorGDBRemote& response
1013)
1014{
1015 if (pid != LLDB_INVALID_PROCESS_ID)
1016 {
1017 StreamString packet;
1018 packet.Printf("vAttach;%x", pid);
1019
1020 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
1021 {
1022 if (response.IsErrorPacket())
1023 return response.GetError();
1024 return 0;
1025 }
1026 }
1027 return -1;
1028}
1029
1030const lldb_private::ArchSpec &
1031GDBRemoteCommunication::GetHostArchitecture ()
1032{
1033 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001034 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001035 return m_arch;
1036}
1037
1038const lldb_private::ConstString &
1039GDBRemoteCommunication::GetOSString ()
1040{
1041 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001042 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001043 return m_os;
1044}
1045
1046const lldb_private::ConstString &
1047GDBRemoteCommunication::GetVendorString()
1048{
1049 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001050 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001051 return m_vendor;
1052}
1053
1054lldb::ByteOrder
1055GDBRemoteCommunication::GetByteOrder ()
1056{
1057 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001058 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001059 return m_byte_order;
1060}
1061
1062uint32_t
1063GDBRemoteCommunication::GetAddressByteSize ()
1064{
1065 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001066 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001067 return m_pointer_byte_size;
1068}
1069
1070addr_t
1071GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
1072{
1073 char packet[64];
1074 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1075 permissions & lldb::ePermissionsReadable ? "r" : "",
1076 permissions & lldb::ePermissionsWritable ? "w" : "",
1077 permissions & lldb::ePermissionsExecutable ? "x" : "");
1078 StringExtractorGDBRemote response;
1079 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1080 {
1081 if (!response.IsErrorPacket())
1082 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1083 }
1084 return LLDB_INVALID_ADDRESS;
1085}
1086
1087bool
1088GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
1089{
1090 char packet[64];
1091 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1092 StringExtractorGDBRemote response;
1093 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1094 {
Sean Callanan6a925532011-01-13 08:53:35 +00001095 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +00001096 return true;
1097 }
1098 return false;
1099}
Jim Ingham3ae449a2010-11-17 02:32:00 +00001100