blob: e23be430b2efb246804c6b32afb5d26d22c71fd4 [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
Greg Clayton395fc332011-02-15 21:59:32 +000016#include "llvm/ADT/Triple.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000017#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/ConnectionFileDescriptor.h"
19#include "lldb/Core/Log.h"
20#include "lldb/Core/State.h"
21#include "lldb/Core/StreamString.h"
Greg Claytoncd548032011-02-01 01:31:41 +000022#include "lldb/Host/Host.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Host/TimeValue.h"
24
25// Project includes
Greg Clayton54e7afa2010-07-09 20:39:50 +000026#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "ProcessGDBRemote.h"
28#include "ProcessGDBRemoteLog.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33//----------------------------------------------------------------------
34// GDBRemoteCommunication constructor
35//----------------------------------------------------------------------
36GDBRemoteCommunication::GDBRemoteCommunication() :
Greg Claytoneecb0f32010-12-04 02:39:47 +000037 Communication("gdb-remote.packets"),
Greg Claytonc1f45872011-02-12 06:28:37 +000038 m_supports_not_sending_acks (eLazyBoolCalculate),
39 m_supports_thread_suffix (eLazyBoolCalculate),
40 m_supports_qHostInfo (eLazyBoolCalculate),
41 m_supports_vCont_all (eLazyBoolCalculate),
42 m_supports_vCont_any (eLazyBoolCalculate),
43 m_supports_vCont_c (eLazyBoolCalculate),
44 m_supports_vCont_C (eLazyBoolCalculate),
45 m_supports_vCont_s (eLazyBoolCalculate),
46 m_supports_vCont_S (eLazyBoolCalculate),
Chris Lattner24943d22010-06-08 16:52:24 +000047 m_rx_packet_listener ("gdbremote.rx_packet"),
48 m_sequence_mutex (Mutex::eMutexTypeRecursive),
Greg Claytoncecf3482011-01-20 07:53:45 +000049 m_public_is_running (false),
50 m_private_is_running (false),
Chris Lattner24943d22010-06-08 16:52:24 +000051 m_async_mutex (Mutex::eMutexTypeRecursive),
52 m_async_packet_predicate (false),
53 m_async_packet (),
54 m_async_response (),
55 m_async_timeout (UINT32_MAX),
56 m_async_signal (-1),
57 m_arch(),
58 m_os(),
59 m_vendor(),
Greg Claytoncd548032011-02-01 01:31:41 +000060 m_byte_order(lldb::endian::InlHostByteOrder()),
Chris Lattner24943d22010-06-08 16:52:24 +000061 m_pointer_byte_size(0)
62{
63 m_rx_packet_listener.StartListeningForEvents(this,
64 Communication::eBroadcastBitPacketAvailable |
65 Communication::eBroadcastBitReadThreadDidExit);
66}
67
68//----------------------------------------------------------------------
69// Destructor
70//----------------------------------------------------------------------
71GDBRemoteCommunication::~GDBRemoteCommunication()
72{
73 m_rx_packet_listener.StopListeningForEvents(this,
74 Communication::eBroadcastBitPacketAvailable |
75 Communication::eBroadcastBitReadThreadDidExit);
76 if (IsConnected())
77 {
78 StopReadThread();
79 Disconnect();
80 }
81}
82
83
84char
85GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
86{
87 int checksum = 0;
88
89 // We only need to compute the checksum if we are sending acks
Greg Claytonc1f45872011-02-12 06:28:37 +000090 if (GetSendAcks ())
Chris Lattner24943d22010-06-08 16:52:24 +000091 {
Greg Clayton54e7afa2010-07-09 20:39:50 +000092 for (size_t i = 0; i < payload_length; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +000093 checksum += payload[i];
94 }
95 return checksum & 255;
96}
97
98size_t
Greg Claytona4881d02011-01-22 07:12:45 +000099GDBRemoteCommunication::SendAck ()
Chris Lattner24943d22010-06-08 16:52:24 +0000100{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000101 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
102 if (log)
103 log->Printf ("send packet: +");
Chris Lattner24943d22010-06-08 16:52:24 +0000104 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytona4881d02011-01-22 07:12:45 +0000105 char ack_char = '+';
Chris Lattner24943d22010-06-08 16:52:24 +0000106 return Write (&ack_char, 1, status, NULL) == 1;
107}
108
109size_t
Greg Claytona4881d02011-01-22 07:12:45 +0000110GDBRemoteCommunication::SendNack ()
111{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000112 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
113 if (log)
114 log->Printf ("send packet: -");
Greg Claytona4881d02011-01-22 07:12:45 +0000115 ConnectionStatus status = eConnectionStatusSuccess;
116 char nack_char = '-';
117 return Write (&nack_char, 1, status, NULL) == 1;
118}
119
Greg Claytonc1f45872011-02-12 06:28:37 +0000120bool
121GDBRemoteCommunication::GetSendAcks ()
122{
123 if (m_supports_not_sending_acks == eLazyBoolCalculate)
124 {
125 StringExtractorGDBRemote response;
126 m_supports_not_sending_acks = eLazyBoolNo;
127 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
128 {
129 if (response.IsOKPacket())
130 m_supports_not_sending_acks = eLazyBoolYes;
131 }
132 }
133 return m_supports_not_sending_acks != eLazyBoolYes;
134}
135
136void
137GDBRemoteCommunication::ResetDiscoverableSettings()
138{
139 m_supports_not_sending_acks = eLazyBoolCalculate;
140 m_supports_thread_suffix = eLazyBoolCalculate;
141 m_supports_qHostInfo = eLazyBoolCalculate;
142 m_supports_vCont_c = eLazyBoolCalculate;
143 m_supports_vCont_C = eLazyBoolCalculate;
144 m_supports_vCont_s = eLazyBoolCalculate;
145 m_supports_vCont_S = eLazyBoolCalculate;
146 m_arch.Clear();
147 m_os.Clear();
148 m_vendor.Clear();
149 m_byte_order = lldb::endian::InlHostByteOrder();
150 m_pointer_byte_size = 0;
151}
152
153
154bool
155GDBRemoteCommunication::GetThreadSuffixSupported ()
156{
157 if (m_supports_thread_suffix == eLazyBoolCalculate)
158 {
159 StringExtractorGDBRemote response;
160 m_supports_thread_suffix = eLazyBoolNo;
161 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false))
162 {
163 if (response.IsOKPacket())
164 m_supports_thread_suffix = eLazyBoolYes;
165 }
166 }
167 return m_supports_thread_suffix;
168}
169bool
170GDBRemoteCommunication::GetVContSupported (char flavor)
171{
172 if (m_supports_vCont_c == eLazyBoolCalculate)
173 {
174 StringExtractorGDBRemote response;
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000175 m_supports_vCont_any = eLazyBoolNo;
176 m_supports_vCont_all = eLazyBoolNo;
Greg Claytonc1f45872011-02-12 06:28:37 +0000177 m_supports_vCont_c = eLazyBoolNo;
178 m_supports_vCont_C = eLazyBoolNo;
179 m_supports_vCont_s = eLazyBoolNo;
180 m_supports_vCont_S = eLazyBoolNo;
181 if (SendPacketAndWaitForResponse("vCont?", response, 1, false))
182 {
183 const char *response_cstr = response.GetStringRef().c_str();
184 if (::strstr (response_cstr, ";c"))
185 m_supports_vCont_c = eLazyBoolYes;
186
187 if (::strstr (response_cstr, ";C"))
188 m_supports_vCont_C = eLazyBoolYes;
189
190 if (::strstr (response_cstr, ";s"))
191 m_supports_vCont_s = eLazyBoolYes;
192
193 if (::strstr (response_cstr, ";S"))
194 m_supports_vCont_S = eLazyBoolYes;
195
196 if (m_supports_vCont_c == eLazyBoolYes &&
197 m_supports_vCont_C == eLazyBoolYes &&
198 m_supports_vCont_s == eLazyBoolYes &&
199 m_supports_vCont_S == eLazyBoolYes)
200 {
201 m_supports_vCont_all = eLazyBoolYes;
202 }
203
204 if (m_supports_vCont_c == eLazyBoolYes ||
205 m_supports_vCont_C == eLazyBoolYes ||
206 m_supports_vCont_s == eLazyBoolYes ||
207 m_supports_vCont_S == eLazyBoolYes)
208 {
209 m_supports_vCont_any = eLazyBoolYes;
210 }
211 }
212 }
213
214 switch (flavor)
215 {
216 case 'a': return m_supports_vCont_any;
217 case 'A': return m_supports_vCont_all;
218 case 'c': return m_supports_vCont_c;
219 case 'C': return m_supports_vCont_C;
220 case 's': return m_supports_vCont_s;
221 case 'S': return m_supports_vCont_S;
222 default: break;
223 }
224 return false;
225}
226
227
Greg Claytona4881d02011-01-22 07:12:45 +0000228size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000229GDBRemoteCommunication::SendPacketAndWaitForResponse
230(
231 const char *payload,
232 StringExtractorGDBRemote &response,
233 uint32_t timeout_seconds,
234 bool send_async
235)
236{
237 return SendPacketAndWaitForResponse (payload,
238 ::strlen (payload),
239 response,
240 timeout_seconds,
241 send_async);
242}
243
244size_t
245GDBRemoteCommunication::SendPacketAndWaitForResponse
246(
247 const char *payload,
248 size_t payload_length,
249 StringExtractorGDBRemote &response,
250 uint32_t timeout_seconds,
251 bool send_async
252)
253{
254 Mutex::Locker locker;
255 TimeValue timeout_time;
256 timeout_time = TimeValue::Now();
257 timeout_time.OffsetWithSeconds (timeout_seconds);
Greg Claytondb2bab42011-01-27 09:02:32 +0000258 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000259
Greg Clayton1a679462010-09-03 19:15:43 +0000260 if (GetSequenceMutex (locker))
Chris Lattner24943d22010-06-08 16:52:24 +0000261 {
262 if (SendPacketNoLock (payload, strlen(payload)))
263 return WaitForPacketNoLock (response, &timeout_time);
264 }
265 else
266 {
267 if (send_async)
268 {
269 Mutex::Locker async_locker (m_async_mutex);
270 m_async_packet.assign(payload, payload_length);
271 m_async_timeout = timeout_seconds;
272 m_async_packet_predicate.SetValue (true, eBroadcastNever);
273
Greg Claytondb2bab42011-01-27 09:02:32 +0000274 if (log)
275 log->Printf ("async: async packet = %s", m_async_packet.c_str());
276
Chris Lattner24943d22010-06-08 16:52:24 +0000277 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000278 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000279 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000280 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000281 if (sent_interrupt)
Chris Lattner24943d22010-06-08 16:52:24 +0000282 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000283 if (log)
284 log->Printf ("async: sent interrupt");
285 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
286 {
287 if (log)
288 log->Printf ("async: got response");
289 response = m_async_response;
290 return response.GetStringRef().size();
291 }
292 else
293 {
294 if (log)
295 log->Printf ("async: timed out waiting for response");
296 }
297
298 // Make sure we wait until the continue packet has been sent again...
299 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
300 {
301 if (log)
302 log->Printf ("async: timed out waiting for process to resume");
303 }
304 }
305 else
306 {
307 // We had a racy condition where we went to send the interrupt
308 // yet we were able to get the loc
Chris Lattner24943d22010-06-08 16:52:24 +0000309 }
310 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000311 else
312 {
313 if (log)
314 log->Printf ("async: failed to interrupt");
315 }
Chris Lattner24943d22010-06-08 16:52:24 +0000316 }
317 else
318 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000319 if (log)
320 log->Printf ("mutex taken and send_async == false, aborting packet");
Chris Lattner24943d22010-06-08 16:52:24 +0000321 }
322 }
323 return 0;
324}
325
326//template<typename _Tp>
327//class ScopedValueChanger
328//{
329//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000330// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000331// // instance goes out of scope.
332// ScopedValueChanger (_Tp &value_ref, _Tp value) :
333// m_value_ref (value_ref),
334// m_value (value)
335// {
336// }
337//
338// // This object is going out of scope, change the value pointed to by
339// // m_value_ref to the value we got during construction which was stored in
340// // m_value;
341// ~ScopedValueChanger ()
342// {
343// m_value_ref = m_value;
344// }
345//protected:
Greg Clayton5d187e52011-01-08 20:28:42 +0000346// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000347// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
348//};
349
350StateType
351GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
352(
353 ProcessGDBRemote *process,
354 const char *payload,
355 size_t packet_length,
356 StringExtractorGDBRemote &response
357)
358{
Greg Claytone005f2c2010-11-06 01:53:30 +0000359 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000360 if (log)
361 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
362
363 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000364 StateType state = eStateRunning;
365
Greg Claytonb749a262010-12-03 06:02:24 +0000366 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000367 m_public_is_running.SetValue (true, eBroadcastNever);
Greg Claytondb2bab42011-01-27 09:02:32 +0000368 // Set the starting continue packet into "continue_packet". This packet
369 // make change if we are interrupted and we continue after an async packet...
370 std::string continue_packet(payload, packet_length);
371
Chris Lattner24943d22010-06-08 16:52:24 +0000372 while (state == eStateRunning)
373 {
374 if (log)
Greg Claytondb2bab42011-01-27 09:02:32 +0000375 log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
376 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
377 state = eStateInvalid;
378
379 m_private_is_running.SetValue (true, eBroadcastNever);
380
381 if (log)
382 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000383
384 if (WaitForPacket (response, (TimeValue*)NULL))
385 {
386 if (response.Empty())
387 state = eStateInvalid;
388 else
389 {
390 const char stop_type = response.GetChar();
391 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000392 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000393 switch (stop_type)
394 {
395 case 'T':
396 case 'S':
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000397 if (process->GetStopID() == 0)
398 {
399 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
400 {
401 lldb::pid_t pid = GetCurrentProcessID (1);
402 if (pid != LLDB_INVALID_PROCESS_ID)
403 process->SetID (pid);
404 }
405 process->BuildDynamicRegisterInfo (true);
406 }
407
Greg Claytoncecf3482011-01-20 07:53:45 +0000408 // Privately notify any internal threads that we have stopped
409 // in case we wanted to interrupt our process, yet we might
410 // send a packet and continue without returning control to the
411 // user.
412 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000413 if (m_async_signal != -1)
414 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000415 if (log)
416 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000417
Chris Lattner24943d22010-06-08 16:52:24 +0000418 // Save off the async signal we are supposed to send
419 const int async_signal = m_async_signal;
420 // Clear the async signal member so we don't end up
421 // sending the signal multiple times...
422 m_async_signal = -1;
423 // Check which signal we stopped with
424 uint8_t signo = response.GetHexU8(255);
425 if (signo == async_signal)
426 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000427 if (log)
428 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000429
Chris Lattner24943d22010-06-08 16:52:24 +0000430 // We already stopped with a signal that we wanted
431 // to stop with, so we are done
432 response.SetFilePos (0);
433 }
434 else
435 {
436 // We stopped with a different signal that the one
437 // we wanted to stop with, so now we must resume
438 // with the signal we want
439 char signal_packet[32];
440 int signal_packet_len = 0;
441 signal_packet_len = ::snprintf (signal_packet,
442 sizeof (signal_packet),
443 "C%2.2x",
444 async_signal);
445
Greg Clayton68ca8232011-01-25 02:58:48 +0000446 if (log)
447 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000448 Host::GetSignalAsCString (signo),
449 Host::GetSignalAsCString (async_signal));
450
Greg Claytondb2bab42011-01-27 09:02:32 +0000451 // Set the continue packet to resume...
452 continue_packet.assign(signal_packet, signal_packet_len);
453 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000454 }
455 }
456 else if (m_async_packet_predicate.GetValue())
457 {
458 // We are supposed to send an asynchronous packet while
459 // we are running.
460 m_async_response.Clear();
Greg Claytondb2bab42011-01-27 09:02:32 +0000461 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000462 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000463 if (log)
464 log->Printf ("async: error: empty async packet");
465
466 }
467 else
468 {
469 if (log)
470 log->Printf ("async: sending packet: %s",
471 m_async_packet.c_str());
472
Greg Clayton53d68e72010-07-20 22:52:08 +0000473 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000474 m_async_packet.size(),
475 m_async_response,
476 m_async_timeout,
477 false);
478 }
479 // Let the other thread that was trying to send the async
Greg Claytondb2bab42011-01-27 09:02:32 +0000480 // packet know that the packet has been sent and response is
481 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000482 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
483
Greg Claytondb2bab42011-01-27 09:02:32 +0000484 // Set the continue packet to resume...
485 continue_packet.assign (1, 'c');
486 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000487 }
488 // Stop with signal and thread info
489 state = eStateStopped;
490 break;
491
492 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000493 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000494 // process exited
495 state = eStateExited;
496 break;
497
498 case 'O':
499 // STDOUT
500 {
501 std::string inferior_stdout;
502 inferior_stdout.reserve(response.GetBytesLeft () / 2);
503 char ch;
504 while ((ch = response.GetHexU8()) != '\0')
505 inferior_stdout.append(1, ch);
506 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
507 }
508 break;
509
510 case 'E':
511 // ERROR
512 state = eStateInvalid;
513 break;
514
515 default:
516 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000517 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000518 break;
519 }
520 }
521 }
522 else
523 {
524 if (log)
525 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
526 state = eStateInvalid;
527 }
528 }
529 if (log)
530 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
531 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000532 m_private_is_running.SetValue (false, eBroadcastAlways);
533 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000534 return state;
535}
536
537size_t
538GDBRemoteCommunication::SendPacket (const char *payload)
539{
540 Mutex::Locker locker(m_sequence_mutex);
541 return SendPacketNoLock (payload, ::strlen (payload));
542}
543
544size_t
545GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
546{
547 Mutex::Locker locker(m_sequence_mutex);
548 return SendPacketNoLock (payload, payload_length);
549}
550
551size_t
552GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
553{
554 if (IsConnected())
555 {
556 StreamString packet(0, 4, eByteOrderBig);
557
558 packet.PutChar('$');
559 packet.Write (payload, payload_length);
560 packet.PutChar('#');
561 packet.PutHex8(CalculcateChecksum (payload, payload_length));
562
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000563 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
564 if (log)
565 log->Printf ("send packet: %s", packet.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000566 ConnectionStatus status = eConnectionStatusSuccess;
567 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
568 if (bytes_written == packet.GetSize())
569 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000570 if (GetSendAcks ())
Greg Clayton54e7afa2010-07-09 20:39:50 +0000571 {
572 if (GetAck (1) != '+')
573 return 0;
574 }
Chris Lattner24943d22010-06-08 16:52:24 +0000575 }
Johnny Chen515ea542010-09-14 22:10:43 +0000576 else
577 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000578 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
579 if (log)
580 log->Printf ("error: failed to send packet: %s", packet.GetData());
Johnny Chen515ea542010-09-14 22:10:43 +0000581 }
Chris Lattner24943d22010-06-08 16:52:24 +0000582 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000583 }
Chris Lattner24943d22010-06-08 16:52:24 +0000584 return 0;
585}
586
587char
588GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
589{
590 StringExtractorGDBRemote response;
591 if (WaitForPacket (response, timeout_seconds) == 1)
592 return response.GetChar();
593 return 0;
594}
595
596bool
597GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
598{
599 return locker.TryLock (m_sequence_mutex.GetMutex());
600}
601
602bool
603GDBRemoteCommunication::SendAsyncSignal (int signo)
604{
605 m_async_signal = signo;
606 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000607 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000608 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000609 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000610 return true;
611 m_async_signal = -1;
612 return false;
613}
614
Greg Clayton1a679462010-09-03 19:15:43 +0000615// This function takes a mutex locker as a parameter in case the GetSequenceMutex
616// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
617// (the expected result), then it will send the halt packet. If it does succeed
618// then the caller that requested the interrupt will want to keep the sequence
619// locked down so that no one else can send packets while the caller has control.
620// This function usually gets called when we are running and need to stop the
621// target. It can also be used when we are running and and we need to do something
622// else (like read/write memory), so we need to interrupt the running process
623// (gdb remote protocol requires this), and do what we need to do, then resume.
624
Chris Lattner24943d22010-06-08 16:52:24 +0000625bool
Greg Claytona4881d02011-01-22 07:12:45 +0000626GDBRemoteCommunication::SendInterrupt
627(
628 Mutex::Locker& locker,
629 uint32_t seconds_to_wait_for_stop,
630 bool &sent_interrupt,
631 bool &timed_out
632)
Chris Lattner24943d22010-06-08 16:52:24 +0000633{
Greg Claytona4881d02011-01-22 07:12:45 +0000634 sent_interrupt = false;
635 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000636 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000637
Greg Claytondb2bab42011-01-27 09:02:32 +0000638 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000639 {
640 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000641 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000642 {
643 // Someone has the mutex locked waiting for a response or for the
644 // inferior to stop, so send the interrupt on the down low...
645 char ctrl_c = '\x03';
646 ConnectionStatus status = eConnectionStatusSuccess;
647 TimeValue timeout;
648 if (seconds_to_wait_for_stop)
649 {
650 timeout = TimeValue::Now();
651 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
652 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000653 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000654 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000655 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000656 {
Greg Claytona4881d02011-01-22 07:12:45 +0000657 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000658 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000659 {
Greg Clayton1c2aa462011-02-03 01:07:45 +0000660 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
661 {
662 if (log)
663 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
664 return true;
665 }
666 else
667 {
668 if (log)
669 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
670 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000671 }
672 else
673 {
674 if (log)
675 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
Greg Clayton1c2aa462011-02-03 01:07:45 +0000676 return true;
Greg Claytondb2bab42011-01-27 09:02:32 +0000677 }
Chris Lattner24943d22010-06-08 16:52:24 +0000678 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000679 else
680 {
681 if (log)
682 log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
683 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000684 return false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000685 }
686 else
687 {
688 if (log)
689 log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000690 }
691 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000692 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000693}
694
Greg Clayton72e1c782011-01-22 23:43:18 +0000695bool
696GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
697{
698 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
699}
700
701bool
702GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
703{
704 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
705}
706
Chris Lattner24943d22010-06-08 16:52:24 +0000707size_t
708GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
709{
Greg Claytoncecf3482011-01-20 07:53:45 +0000710 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000711 TimeValue timeout_time;
712 timeout_time = TimeValue::Now();
713 timeout_time.OffsetWithSeconds (timeout_seconds);
714 return WaitForPacketNoLock (response, &timeout_time);
715}
716
717size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000718GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000719{
720 Mutex::Locker locker(m_sequence_mutex);
721 return WaitForPacketNoLock (response, timeout_time_ptr);
722}
723
724size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000725GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000726{
727 bool checksum_error = false;
728 response.Clear ();
729
730 EventSP event_sp;
731
732 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
733 {
734 const uint32_t event_type = event_sp->GetType();
735 if (event_type | Communication::eBroadcastBitPacketAvailable)
736 {
737 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
738 if (event_bytes)
739 {
740 const char * packet_data = (const char *)event_bytes->GetBytes();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000741 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
742 if (log)
743 log->Printf ("read packet: %s", packet_data);
Chris Lattner24943d22010-06-08 16:52:24 +0000744 const size_t packet_size = event_bytes->GetByteSize();
745 if (packet_data && packet_size > 0)
746 {
747 std::string &response_str = response.GetStringRef();
748 if (packet_data[0] == '$')
749 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000750 bool success = false;
751 if (packet_size < 4)
752 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
753 else if (packet_data[packet_size-3] != '#' ||
754 !::isxdigit (packet_data[packet_size-2]) ||
755 !::isxdigit (packet_data[packet_size-1]))
756 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
757 else
758 success = true;
759
760 if (success)
761 response_str.assign (packet_data + 1, packet_size - 4);
Greg Claytonc1f45872011-02-12 06:28:37 +0000762 if (GetSendAcks ())
Chris Lattner24943d22010-06-08 16:52:24 +0000763 {
764 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000765 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000766 checksum_error = packet_checksum != actual_checksum;
767 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000768 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000769 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000770 else
Greg Claytona4881d02011-01-22 07:12:45 +0000771 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000772 }
773 }
774 else
775 {
776 response_str.assign (packet_data, packet_size);
777 }
778 return response_str.size();
779 }
780 }
781 }
782 else if (Communication::eBroadcastBitReadThreadDidExit)
783 {
784 // Our read thread exited on us so just fall through and return zero...
785 }
786 }
787 return 0;
788}
789
790void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000791GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
792 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000793{
794 // Put the packet data into the buffer in a thread safe fashion
795 Mutex::Locker locker(m_bytes_mutex);
796 m_bytes.append ((const char *)src, src_len);
797
798 // Parse up the packets into gdb remote packets
799 while (!m_bytes.empty())
800 {
801 // end_idx must be one past the last valid packet byte. Start
802 // it off with an invalid value that is the same as the current
803 // index.
804 size_t end_idx = 0;
805
806 switch (m_bytes[0])
807 {
808 case '+': // Look for ack
809 case '-': // Look for cancel
810 case '\x03': // ^C to halt target
811 end_idx = 1; // The command is one byte long...
812 break;
813
814 case '$':
815 // Look for a standard gdb packet?
816 end_idx = m_bytes.find('#');
817 if (end_idx != std::string::npos)
818 {
819 if (end_idx + 2 < m_bytes.size())
820 {
821 end_idx += 3;
822 }
823 else
824 {
825 // Checksum bytes aren't all here yet
826 end_idx = std::string::npos;
827 }
828 }
829 break;
830
831 default:
832 break;
833 }
834
835 if (end_idx == std::string::npos)
836 {
837 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
838 return;
839 }
840 else if (end_idx > 0)
841 {
842 // We have a valid packet...
843 assert (end_idx <= m_bytes.size());
844 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
845 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
846 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
847 m_bytes.erase(0, end_idx);
848 }
849 else
850 {
851 assert (1 <= m_bytes.size());
852 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
853 m_bytes.erase(0, 1);
854 }
855 }
856}
857
858lldb::pid_t
859GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
860{
861 StringExtractorGDBRemote response;
862 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
863 {
864 if (response.GetChar() == 'Q')
865 if (response.GetChar() == 'C')
866 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
867 }
868 return LLDB_INVALID_PROCESS_ID;
869}
870
871bool
872GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
873{
874 error_str.clear();
875 StringExtractorGDBRemote response;
876 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
877 {
878 if (response.IsOKPacket())
879 return true;
880 if (response.GetChar() == 'E')
881 {
882 // A string the describes what failed when launching...
883 error_str = response.GetStringRef().substr(1);
884 }
885 else
886 {
887 error_str.assign ("unknown error occurred launching process");
888 }
889 }
890 else
891 {
892 error_str.assign ("failed to send the qLaunchSuccess packet");
893 }
894 return false;
895}
896
897int
898GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
899{
900 if (argv && argv[0])
901 {
902 StreamString packet;
903 packet.PutChar('A');
904 const char *arg;
905 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
906 {
907 const int arg_len = strlen(arg);
908 if (i > 0)
909 packet.PutChar(',');
910 packet.Printf("%i,%i,", arg_len * 2, i);
Greg Claytoncd548032011-02-01 01:31:41 +0000911 packet.PutBytesAsRawHex8(arg, arg_len, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000912 }
913
914 StringExtractorGDBRemote response;
915 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
916 {
917 if (response.IsOKPacket())
918 return 0;
919 uint8_t error = response.GetError();
920 if (error)
921 return error;
922 }
923 }
924 return -1;
925}
926
927int
928GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
929{
930 if (name_equal_value && name_equal_value[0])
931 {
932 StreamString packet;
933 packet.Printf("QEnvironment:%s", name_equal_value);
934 StringExtractorGDBRemote response;
935 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
936 {
937 if (response.IsOKPacket())
938 return 0;
939 uint8_t error = response.GetError();
940 if (error)
941 return error;
942 }
943 }
944 return -1;
945}
946
947bool
Greg Claytonc1f45872011-02-12 06:28:37 +0000948GDBRemoteCommunication::GetHostInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +0000949{
Greg Claytonc1f45872011-02-12 06:28:37 +0000950 if (m_supports_qHostInfo == eLazyBoolCalculate)
Chris Lattner24943d22010-06-08 16:52:24 +0000951 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000952 m_supports_qHostInfo = eLazyBoolNo;
Chris Lattner24943d22010-06-08 16:52:24 +0000953
Greg Claytonc1f45872011-02-12 06:28:37 +0000954 StringExtractorGDBRemote response;
955 if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000956 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000957 if (response.IsUnsupportedPacket())
958 return false;
959
960 m_supports_qHostInfo = eLazyBoolYes;
961
962 std::string name;
963 std::string value;
964 uint32_t cpu = LLDB_INVALID_CPUTYPE;
965 uint32_t sub = 0;
Greg Claytone71e2582011-02-04 01:58:07 +0000966
Greg Claytonc1f45872011-02-12 06:28:37 +0000967 while (response.GetNameColonValue(name, value))
968 {
969 if (name.compare("cputype") == 0)
970 {
971 // exception type in big endian hex
972 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
973 }
974 else if (name.compare("cpusubtype") == 0)
975 {
976 // exception count in big endian hex
977 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
978 }
979 else if (name.compare("ostype") == 0)
980 {
981 // exception data in big endian hex
982 m_os.SetCString(value.c_str());
983 }
984 else if (name.compare("vendor") == 0)
985 {
986 m_vendor.SetCString(value.c_str());
987 }
988 else if (name.compare("endian") == 0)
989 {
990 if (value.compare("little") == 0)
991 m_byte_order = eByteOrderLittle;
992 else if (value.compare("big") == 0)
993 m_byte_order = eByteOrderBig;
994 else if (value.compare("pdp") == 0)
995 m_byte_order = eByteOrderPDP;
996 }
997 else if (name.compare("ptrsize") == 0)
998 {
999 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
1000 }
1001 }
1002
1003 if (cpu != LLDB_INVALID_CPUTYPE)
1004 m_arch.SetMachOArch (cpu, sub);
1005 }
Chris Lattner24943d22010-06-08 16:52:24 +00001006 }
Greg Claytonc1f45872011-02-12 06:28:37 +00001007 return m_supports_qHostInfo == eLazyBoolYes;
Chris Lattner24943d22010-06-08 16:52:24 +00001008}
1009
1010int
1011GDBRemoteCommunication::SendAttach
1012(
1013 lldb::pid_t pid,
1014 uint32_t timeout_seconds,
1015 StringExtractorGDBRemote& response
1016)
1017{
1018 if (pid != LLDB_INVALID_PROCESS_ID)
1019 {
1020 StreamString packet;
1021 packet.Printf("vAttach;%x", pid);
1022
1023 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
1024 {
1025 if (response.IsErrorPacket())
1026 return response.GetError();
1027 return 0;
1028 }
1029 }
1030 return -1;
1031}
1032
1033const lldb_private::ArchSpec &
1034GDBRemoteCommunication::GetHostArchitecture ()
1035{
1036 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001037 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001038 return m_arch;
1039}
1040
1041const lldb_private::ConstString &
1042GDBRemoteCommunication::GetOSString ()
1043{
1044 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001045 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001046 return m_os;
1047}
1048
1049const lldb_private::ConstString &
1050GDBRemoteCommunication::GetVendorString()
1051{
1052 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001053 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001054 return m_vendor;
1055}
1056
1057lldb::ByteOrder
1058GDBRemoteCommunication::GetByteOrder ()
1059{
1060 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001061 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001062 return m_byte_order;
1063}
1064
1065uint32_t
1066GDBRemoteCommunication::GetAddressByteSize ()
1067{
1068 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001069 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001070 return m_pointer_byte_size;
1071}
1072
1073addr_t
1074GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
1075{
1076 char packet[64];
1077 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1078 permissions & lldb::ePermissionsReadable ? "r" : "",
1079 permissions & lldb::ePermissionsWritable ? "w" : "",
1080 permissions & lldb::ePermissionsExecutable ? "x" : "");
1081 StringExtractorGDBRemote response;
1082 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1083 {
1084 if (!response.IsErrorPacket())
1085 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1086 }
1087 return LLDB_INVALID_ADDRESS;
1088}
1089
1090bool
1091GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
1092{
1093 char packet[64];
1094 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1095 StringExtractorGDBRemote response;
1096 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1097 {
Sean Callanan6a925532011-01-13 08:53:35 +00001098 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +00001099 return true;
1100 }
1101 return false;
1102}
Jim Ingham3ae449a2010-11-17 02:32:00 +00001103