blob: 1f14a6e99456f6c79f7d1e056e201ec4aba60688 [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;
175 m_supports_vCont_c = eLazyBoolNo;
176 m_supports_vCont_C = eLazyBoolNo;
177 m_supports_vCont_s = eLazyBoolNo;
178 m_supports_vCont_S = eLazyBoolNo;
179 if (SendPacketAndWaitForResponse("vCont?", response, 1, false))
180 {
181 const char *response_cstr = response.GetStringRef().c_str();
182 if (::strstr (response_cstr, ";c"))
183 m_supports_vCont_c = eLazyBoolYes;
184
185 if (::strstr (response_cstr, ";C"))
186 m_supports_vCont_C = eLazyBoolYes;
187
188 if (::strstr (response_cstr, ";s"))
189 m_supports_vCont_s = eLazyBoolYes;
190
191 if (::strstr (response_cstr, ";S"))
192 m_supports_vCont_S = eLazyBoolYes;
193
194 if (m_supports_vCont_c == eLazyBoolYes &&
195 m_supports_vCont_C == eLazyBoolYes &&
196 m_supports_vCont_s == eLazyBoolYes &&
197 m_supports_vCont_S == eLazyBoolYes)
198 {
199 m_supports_vCont_all = eLazyBoolYes;
200 }
201
202 if (m_supports_vCont_c == eLazyBoolYes ||
203 m_supports_vCont_C == eLazyBoolYes ||
204 m_supports_vCont_s == eLazyBoolYes ||
205 m_supports_vCont_S == eLazyBoolYes)
206 {
207 m_supports_vCont_any = eLazyBoolYes;
208 }
209 }
210 }
211
212 switch (flavor)
213 {
214 case 'a': return m_supports_vCont_any;
215 case 'A': return m_supports_vCont_all;
216 case 'c': return m_supports_vCont_c;
217 case 'C': return m_supports_vCont_C;
218 case 's': return m_supports_vCont_s;
219 case 'S': return m_supports_vCont_S;
220 default: break;
221 }
222 return false;
223}
224
225
Greg Claytona4881d02011-01-22 07:12:45 +0000226size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000227GDBRemoteCommunication::SendPacketAndWaitForResponse
228(
229 const char *payload,
230 StringExtractorGDBRemote &response,
231 uint32_t timeout_seconds,
232 bool send_async
233)
234{
235 return SendPacketAndWaitForResponse (payload,
236 ::strlen (payload),
237 response,
238 timeout_seconds,
239 send_async);
240}
241
242size_t
243GDBRemoteCommunication::SendPacketAndWaitForResponse
244(
245 const char *payload,
246 size_t payload_length,
247 StringExtractorGDBRemote &response,
248 uint32_t timeout_seconds,
249 bool send_async
250)
251{
252 Mutex::Locker locker;
253 TimeValue timeout_time;
254 timeout_time = TimeValue::Now();
255 timeout_time.OffsetWithSeconds (timeout_seconds);
Greg Claytondb2bab42011-01-27 09:02:32 +0000256 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000257
Greg Clayton1a679462010-09-03 19:15:43 +0000258 if (GetSequenceMutex (locker))
Chris Lattner24943d22010-06-08 16:52:24 +0000259 {
260 if (SendPacketNoLock (payload, strlen(payload)))
261 return WaitForPacketNoLock (response, &timeout_time);
262 }
263 else
264 {
265 if (send_async)
266 {
267 Mutex::Locker async_locker (m_async_mutex);
268 m_async_packet.assign(payload, payload_length);
269 m_async_timeout = timeout_seconds;
270 m_async_packet_predicate.SetValue (true, eBroadcastNever);
271
Greg Claytondb2bab42011-01-27 09:02:32 +0000272 if (log)
273 log->Printf ("async: async packet = %s", m_async_packet.c_str());
274
Chris Lattner24943d22010-06-08 16:52:24 +0000275 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000276 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000277 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000278 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000279 if (sent_interrupt)
Chris Lattner24943d22010-06-08 16:52:24 +0000280 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000281 if (log)
282 log->Printf ("async: sent interrupt");
283 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
284 {
285 if (log)
286 log->Printf ("async: got response");
287 response = m_async_response;
288 return response.GetStringRef().size();
289 }
290 else
291 {
292 if (log)
293 log->Printf ("async: timed out waiting for response");
294 }
295
296 // Make sure we wait until the continue packet has been sent again...
297 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
298 {
299 if (log)
300 log->Printf ("async: timed out waiting for process to resume");
301 }
302 }
303 else
304 {
305 // We had a racy condition where we went to send the interrupt
306 // yet we were able to get the loc
Chris Lattner24943d22010-06-08 16:52:24 +0000307 }
308 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000309 else
310 {
311 if (log)
312 log->Printf ("async: failed to interrupt");
313 }
Chris Lattner24943d22010-06-08 16:52:24 +0000314 }
315 else
316 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000317 if (log)
318 log->Printf ("mutex taken and send_async == false, aborting packet");
Chris Lattner24943d22010-06-08 16:52:24 +0000319 }
320 }
321 return 0;
322}
323
324//template<typename _Tp>
325//class ScopedValueChanger
326//{
327//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000328// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000329// // instance goes out of scope.
330// ScopedValueChanger (_Tp &value_ref, _Tp value) :
331// m_value_ref (value_ref),
332// m_value (value)
333// {
334// }
335//
336// // This object is going out of scope, change the value pointed to by
337// // m_value_ref to the value we got during construction which was stored in
338// // m_value;
339// ~ScopedValueChanger ()
340// {
341// m_value_ref = m_value;
342// }
343//protected:
Greg Clayton5d187e52011-01-08 20:28:42 +0000344// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000345// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
346//};
347
348StateType
349GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
350(
351 ProcessGDBRemote *process,
352 const char *payload,
353 size_t packet_length,
354 StringExtractorGDBRemote &response
355)
356{
Greg Claytone005f2c2010-11-06 01:53:30 +0000357 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000358 if (log)
359 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
360
361 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000362 StateType state = eStateRunning;
363
Greg Claytonb749a262010-12-03 06:02:24 +0000364 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000365 m_public_is_running.SetValue (true, eBroadcastNever);
Greg Claytondb2bab42011-01-27 09:02:32 +0000366 // Set the starting continue packet into "continue_packet". This packet
367 // make change if we are interrupted and we continue after an async packet...
368 std::string continue_packet(payload, packet_length);
369
Chris Lattner24943d22010-06-08 16:52:24 +0000370 while (state == eStateRunning)
371 {
372 if (log)
Greg Claytondb2bab42011-01-27 09:02:32 +0000373 log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
374 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
375 state = eStateInvalid;
376
377 m_private_is_running.SetValue (true, eBroadcastNever);
378
379 if (log)
380 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000381
382 if (WaitForPacket (response, (TimeValue*)NULL))
383 {
384 if (response.Empty())
385 state = eStateInvalid;
386 else
387 {
388 const char stop_type = response.GetChar();
389 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000390 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000391 switch (stop_type)
392 {
393 case 'T':
394 case 'S':
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000395 if (process->GetStopID() == 0)
396 {
397 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
398 {
399 lldb::pid_t pid = GetCurrentProcessID (1);
400 if (pid != LLDB_INVALID_PROCESS_ID)
401 process->SetID (pid);
402 }
403 process->BuildDynamicRegisterInfo (true);
404 }
405
Greg Claytoncecf3482011-01-20 07:53:45 +0000406 // Privately notify any internal threads that we have stopped
407 // in case we wanted to interrupt our process, yet we might
408 // send a packet and continue without returning control to the
409 // user.
410 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000411 if (m_async_signal != -1)
412 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000413 if (log)
414 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000415
Chris Lattner24943d22010-06-08 16:52:24 +0000416 // Save off the async signal we are supposed to send
417 const int async_signal = m_async_signal;
418 // Clear the async signal member so we don't end up
419 // sending the signal multiple times...
420 m_async_signal = -1;
421 // Check which signal we stopped with
422 uint8_t signo = response.GetHexU8(255);
423 if (signo == async_signal)
424 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000425 if (log)
426 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000427
Chris Lattner24943d22010-06-08 16:52:24 +0000428 // We already stopped with a signal that we wanted
429 // to stop with, so we are done
430 response.SetFilePos (0);
431 }
432 else
433 {
434 // We stopped with a different signal that the one
435 // we wanted to stop with, so now we must resume
436 // with the signal we want
437 char signal_packet[32];
438 int signal_packet_len = 0;
439 signal_packet_len = ::snprintf (signal_packet,
440 sizeof (signal_packet),
441 "C%2.2x",
442 async_signal);
443
Greg Clayton68ca8232011-01-25 02:58:48 +0000444 if (log)
445 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000446 Host::GetSignalAsCString (signo),
447 Host::GetSignalAsCString (async_signal));
448
Greg Claytondb2bab42011-01-27 09:02:32 +0000449 // Set the continue packet to resume...
450 continue_packet.assign(signal_packet, signal_packet_len);
451 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000452 }
453 }
454 else if (m_async_packet_predicate.GetValue())
455 {
456 // We are supposed to send an asynchronous packet while
457 // we are running.
458 m_async_response.Clear();
Greg Claytondb2bab42011-01-27 09:02:32 +0000459 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000460 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000461 if (log)
462 log->Printf ("async: error: empty async packet");
463
464 }
465 else
466 {
467 if (log)
468 log->Printf ("async: sending packet: %s",
469 m_async_packet.c_str());
470
Greg Clayton53d68e72010-07-20 22:52:08 +0000471 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000472 m_async_packet.size(),
473 m_async_response,
474 m_async_timeout,
475 false);
476 }
477 // Let the other thread that was trying to send the async
Greg Claytondb2bab42011-01-27 09:02:32 +0000478 // packet know that the packet has been sent and response is
479 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000480 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
481
Greg Claytondb2bab42011-01-27 09:02:32 +0000482 // Set the continue packet to resume...
483 continue_packet.assign (1, 'c');
484 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000485 }
486 // Stop with signal and thread info
487 state = eStateStopped;
488 break;
489
490 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000491 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000492 // process exited
493 state = eStateExited;
494 break;
495
496 case 'O':
497 // STDOUT
498 {
499 std::string inferior_stdout;
500 inferior_stdout.reserve(response.GetBytesLeft () / 2);
501 char ch;
502 while ((ch = response.GetHexU8()) != '\0')
503 inferior_stdout.append(1, ch);
504 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
505 }
506 break;
507
508 case 'E':
509 // ERROR
510 state = eStateInvalid;
511 break;
512
513 default:
514 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000515 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000516 break;
517 }
518 }
519 }
520 else
521 {
522 if (log)
523 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
524 state = eStateInvalid;
525 }
526 }
527 if (log)
528 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
529 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000530 m_private_is_running.SetValue (false, eBroadcastAlways);
531 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000532 return state;
533}
534
535size_t
536GDBRemoteCommunication::SendPacket (const char *payload)
537{
538 Mutex::Locker locker(m_sequence_mutex);
539 return SendPacketNoLock (payload, ::strlen (payload));
540}
541
542size_t
543GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
544{
545 Mutex::Locker locker(m_sequence_mutex);
546 return SendPacketNoLock (payload, payload_length);
547}
548
549size_t
550GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
551{
552 if (IsConnected())
553 {
554 StreamString packet(0, 4, eByteOrderBig);
555
556 packet.PutChar('$');
557 packet.Write (payload, payload_length);
558 packet.PutChar('#');
559 packet.PutHex8(CalculcateChecksum (payload, payload_length));
560
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000561 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
562 if (log)
563 log->Printf ("send packet: %s", packet.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000564 ConnectionStatus status = eConnectionStatusSuccess;
565 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
566 if (bytes_written == packet.GetSize())
567 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000568 if (GetSendAcks ())
Greg Clayton54e7afa2010-07-09 20:39:50 +0000569 {
570 if (GetAck (1) != '+')
571 return 0;
572 }
Chris Lattner24943d22010-06-08 16:52:24 +0000573 }
Johnny Chen515ea542010-09-14 22:10:43 +0000574 else
575 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000576 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
577 if (log)
578 log->Printf ("error: failed to send packet: %s", packet.GetData());
Johnny Chen515ea542010-09-14 22:10:43 +0000579 }
Chris Lattner24943d22010-06-08 16:52:24 +0000580 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000581 }
Chris Lattner24943d22010-06-08 16:52:24 +0000582 return 0;
583}
584
585char
586GDBRemoteCommunication::GetAck (uint32_t timeout_seconds)
587{
588 StringExtractorGDBRemote response;
589 if (WaitForPacket (response, timeout_seconds) == 1)
590 return response.GetChar();
591 return 0;
592}
593
594bool
595GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
596{
597 return locker.TryLock (m_sequence_mutex.GetMutex());
598}
599
600bool
601GDBRemoteCommunication::SendAsyncSignal (int signo)
602{
603 m_async_signal = signo;
604 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000605 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000606 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000607 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000608 return true;
609 m_async_signal = -1;
610 return false;
611}
612
Greg Clayton1a679462010-09-03 19:15:43 +0000613// This function takes a mutex locker as a parameter in case the GetSequenceMutex
614// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
615// (the expected result), then it will send the halt packet. If it does succeed
616// then the caller that requested the interrupt will want to keep the sequence
617// locked down so that no one else can send packets while the caller has control.
618// This function usually gets called when we are running and need to stop the
619// target. It can also be used when we are running and and we need to do something
620// else (like read/write memory), so we need to interrupt the running process
621// (gdb remote protocol requires this), and do what we need to do, then resume.
622
Chris Lattner24943d22010-06-08 16:52:24 +0000623bool
Greg Claytona4881d02011-01-22 07:12:45 +0000624GDBRemoteCommunication::SendInterrupt
625(
626 Mutex::Locker& locker,
627 uint32_t seconds_to_wait_for_stop,
628 bool &sent_interrupt,
629 bool &timed_out
630)
Chris Lattner24943d22010-06-08 16:52:24 +0000631{
Greg Claytona4881d02011-01-22 07:12:45 +0000632 sent_interrupt = false;
633 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000634 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000635
Greg Claytondb2bab42011-01-27 09:02:32 +0000636 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000637 {
638 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000639 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000640 {
641 // Someone has the mutex locked waiting for a response or for the
642 // inferior to stop, so send the interrupt on the down low...
643 char ctrl_c = '\x03';
644 ConnectionStatus status = eConnectionStatusSuccess;
645 TimeValue timeout;
646 if (seconds_to_wait_for_stop)
647 {
648 timeout = TimeValue::Now();
649 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
650 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000651 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000652 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000653 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000654 {
Greg Claytona4881d02011-01-22 07:12:45 +0000655 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000656 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000657 {
Greg Clayton1c2aa462011-02-03 01:07:45 +0000658 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
659 {
660 if (log)
661 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
662 return true;
663 }
664 else
665 {
666 if (log)
667 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
668 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000669 }
670 else
671 {
672 if (log)
673 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
Greg Clayton1c2aa462011-02-03 01:07:45 +0000674 return true;
Greg Claytondb2bab42011-01-27 09:02:32 +0000675 }
Chris Lattner24943d22010-06-08 16:52:24 +0000676 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000677 else
678 {
679 if (log)
680 log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
681 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000682 return false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000683 }
684 else
685 {
686 if (log)
687 log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000688 }
689 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000690 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000691}
692
Greg Clayton72e1c782011-01-22 23:43:18 +0000693bool
694GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
695{
696 return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
697}
698
699bool
700GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
701{
702 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
703}
704
Chris Lattner24943d22010-06-08 16:52:24 +0000705size_t
706GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
707{
Greg Claytoncecf3482011-01-20 07:53:45 +0000708 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000709 TimeValue timeout_time;
710 timeout_time = TimeValue::Now();
711 timeout_time.OffsetWithSeconds (timeout_seconds);
712 return WaitForPacketNoLock (response, &timeout_time);
713}
714
715size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000716GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000717{
718 Mutex::Locker locker(m_sequence_mutex);
719 return WaitForPacketNoLock (response, timeout_time_ptr);
720}
721
722size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000723GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000724{
725 bool checksum_error = false;
726 response.Clear ();
727
728 EventSP event_sp;
729
730 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
731 {
732 const uint32_t event_type = event_sp->GetType();
733 if (event_type | Communication::eBroadcastBitPacketAvailable)
734 {
735 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
736 if (event_bytes)
737 {
738 const char * packet_data = (const char *)event_bytes->GetBytes();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000739 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
740 if (log)
741 log->Printf ("read packet: %s", packet_data);
Chris Lattner24943d22010-06-08 16:52:24 +0000742 const size_t packet_size = event_bytes->GetByteSize();
743 if (packet_data && packet_size > 0)
744 {
745 std::string &response_str = response.GetStringRef();
746 if (packet_data[0] == '$')
747 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000748 bool success = false;
749 if (packet_size < 4)
750 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
751 else if (packet_data[packet_size-3] != '#' ||
752 !::isxdigit (packet_data[packet_size-2]) ||
753 !::isxdigit (packet_data[packet_size-1]))
754 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
755 else
756 success = true;
757
758 if (success)
759 response_str.assign (packet_data + 1, packet_size - 4);
Greg Claytonc1f45872011-02-12 06:28:37 +0000760 if (GetSendAcks ())
Chris Lattner24943d22010-06-08 16:52:24 +0000761 {
762 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000763 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000764 checksum_error = packet_checksum != actual_checksum;
765 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000766 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000767 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000768 else
Greg Claytona4881d02011-01-22 07:12:45 +0000769 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000770 }
771 }
772 else
773 {
774 response_str.assign (packet_data, packet_size);
775 }
776 return response_str.size();
777 }
778 }
779 }
780 else if (Communication::eBroadcastBitReadThreadDidExit)
781 {
782 // Our read thread exited on us so just fall through and return zero...
783 }
784 }
785 return 0;
786}
787
788void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000789GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
790 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000791{
792 // Put the packet data into the buffer in a thread safe fashion
793 Mutex::Locker locker(m_bytes_mutex);
794 m_bytes.append ((const char *)src, src_len);
795
796 // Parse up the packets into gdb remote packets
797 while (!m_bytes.empty())
798 {
799 // end_idx must be one past the last valid packet byte. Start
800 // it off with an invalid value that is the same as the current
801 // index.
802 size_t end_idx = 0;
803
804 switch (m_bytes[0])
805 {
806 case '+': // Look for ack
807 case '-': // Look for cancel
808 case '\x03': // ^C to halt target
809 end_idx = 1; // The command is one byte long...
810 break;
811
812 case '$':
813 // Look for a standard gdb packet?
814 end_idx = m_bytes.find('#');
815 if (end_idx != std::string::npos)
816 {
817 if (end_idx + 2 < m_bytes.size())
818 {
819 end_idx += 3;
820 }
821 else
822 {
823 // Checksum bytes aren't all here yet
824 end_idx = std::string::npos;
825 }
826 }
827 break;
828
829 default:
830 break;
831 }
832
833 if (end_idx == std::string::npos)
834 {
835 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
836 return;
837 }
838 else if (end_idx > 0)
839 {
840 // We have a valid packet...
841 assert (end_idx <= m_bytes.size());
842 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
843 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
844 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
845 m_bytes.erase(0, end_idx);
846 }
847 else
848 {
849 assert (1 <= m_bytes.size());
850 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
851 m_bytes.erase(0, 1);
852 }
853 }
854}
855
856lldb::pid_t
857GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds)
858{
859 StringExtractorGDBRemote response;
860 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false))
861 {
862 if (response.GetChar() == 'Q')
863 if (response.GetChar() == 'C')
864 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
865 }
866 return LLDB_INVALID_PROCESS_ID;
867}
868
869bool
870GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str)
871{
872 error_str.clear();
873 StringExtractorGDBRemote response;
874 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false))
875 {
876 if (response.IsOKPacket())
877 return true;
878 if (response.GetChar() == 'E')
879 {
880 // A string the describes what failed when launching...
881 error_str = response.GetStringRef().substr(1);
882 }
883 else
884 {
885 error_str.assign ("unknown error occurred launching process");
886 }
887 }
888 else
889 {
890 error_str.assign ("failed to send the qLaunchSuccess packet");
891 }
892 return false;
893}
894
895int
896GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds)
897{
898 if (argv && argv[0])
899 {
900 StreamString packet;
901 packet.PutChar('A');
902 const char *arg;
903 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
904 {
905 const int arg_len = strlen(arg);
906 if (i > 0)
907 packet.PutChar(',');
908 packet.Printf("%i,%i,", arg_len * 2, i);
Greg Claytoncd548032011-02-01 01:31:41 +0000909 packet.PutBytesAsRawHex8(arg, arg_len, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000910 }
911
912 StringExtractorGDBRemote response;
913 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
914 {
915 if (response.IsOKPacket())
916 return 0;
917 uint8_t error = response.GetError();
918 if (error)
919 return error;
920 }
921 }
922 return -1;
923}
924
925int
926GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds)
927{
928 if (name_equal_value && name_equal_value[0])
929 {
930 StreamString packet;
931 packet.Printf("QEnvironment:%s", name_equal_value);
932 StringExtractorGDBRemote response;
933 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
934 {
935 if (response.IsOKPacket())
936 return 0;
937 uint8_t error = response.GetError();
938 if (error)
939 return error;
940 }
941 }
942 return -1;
943}
944
945bool
Greg Claytonc1f45872011-02-12 06:28:37 +0000946GDBRemoteCommunication::GetHostInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +0000947{
Greg Claytonc1f45872011-02-12 06:28:37 +0000948 if (m_supports_qHostInfo == eLazyBoolCalculate)
Chris Lattner24943d22010-06-08 16:52:24 +0000949 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000950 m_supports_qHostInfo = eLazyBoolNo;
Chris Lattner24943d22010-06-08 16:52:24 +0000951
Greg Claytonc1f45872011-02-12 06:28:37 +0000952 StringExtractorGDBRemote response;
953 if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000954 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000955 if (response.IsUnsupportedPacket())
956 return false;
957
958 m_supports_qHostInfo = eLazyBoolYes;
959
960 std::string name;
961 std::string value;
962 uint32_t cpu = LLDB_INVALID_CPUTYPE;
963 uint32_t sub = 0;
Greg Claytone71e2582011-02-04 01:58:07 +0000964
Greg Claytonc1f45872011-02-12 06:28:37 +0000965 while (response.GetNameColonValue(name, value))
966 {
967 if (name.compare("cputype") == 0)
968 {
969 // exception type in big endian hex
970 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
971 }
972 else if (name.compare("cpusubtype") == 0)
973 {
974 // exception count in big endian hex
975 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
976 }
977 else if (name.compare("ostype") == 0)
978 {
979 // exception data in big endian hex
980 m_os.SetCString(value.c_str());
981 }
982 else if (name.compare("vendor") == 0)
983 {
984 m_vendor.SetCString(value.c_str());
985 }
986 else if (name.compare("endian") == 0)
987 {
988 if (value.compare("little") == 0)
989 m_byte_order = eByteOrderLittle;
990 else if (value.compare("big") == 0)
991 m_byte_order = eByteOrderBig;
992 else if (value.compare("pdp") == 0)
993 m_byte_order = eByteOrderPDP;
994 }
995 else if (name.compare("ptrsize") == 0)
996 {
997 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
998 }
999 }
1000
1001 if (cpu != LLDB_INVALID_CPUTYPE)
1002 m_arch.SetMachOArch (cpu, sub);
1003 }
Chris Lattner24943d22010-06-08 16:52:24 +00001004 }
Greg Claytonc1f45872011-02-12 06:28:37 +00001005 return m_supports_qHostInfo == eLazyBoolYes;
Chris Lattner24943d22010-06-08 16:52:24 +00001006}
1007
1008int
1009GDBRemoteCommunication::SendAttach
1010(
1011 lldb::pid_t pid,
1012 uint32_t timeout_seconds,
1013 StringExtractorGDBRemote& response
1014)
1015{
1016 if (pid != LLDB_INVALID_PROCESS_ID)
1017 {
1018 StreamString packet;
1019 packet.Printf("vAttach;%x", pid);
1020
1021 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false))
1022 {
1023 if (response.IsErrorPacket())
1024 return response.GetError();
1025 return 0;
1026 }
1027 }
1028 return -1;
1029}
1030
1031const lldb_private::ArchSpec &
1032GDBRemoteCommunication::GetHostArchitecture ()
1033{
1034 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001035 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001036 return m_arch;
1037}
1038
1039const lldb_private::ConstString &
1040GDBRemoteCommunication::GetOSString ()
1041{
1042 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001043 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001044 return m_os;
1045}
1046
1047const lldb_private::ConstString &
1048GDBRemoteCommunication::GetVendorString()
1049{
1050 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001051 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001052 return m_vendor;
1053}
1054
1055lldb::ByteOrder
1056GDBRemoteCommunication::GetByteOrder ()
1057{
1058 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001059 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001060 return m_byte_order;
1061}
1062
1063uint32_t
1064GDBRemoteCommunication::GetAddressByteSize ()
1065{
1066 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001067 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001068 return m_pointer_byte_size;
1069}
1070
1071addr_t
1072GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds)
1073{
1074 char packet[64];
1075 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1076 permissions & lldb::ePermissionsReadable ? "r" : "",
1077 permissions & lldb::ePermissionsWritable ? "w" : "",
1078 permissions & lldb::ePermissionsExecutable ? "x" : "");
1079 StringExtractorGDBRemote response;
1080 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1081 {
1082 if (!response.IsErrorPacket())
1083 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1084 }
1085 return LLDB_INVALID_ADDRESS;
1086}
1087
1088bool
1089GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
1090{
1091 char packet[64];
1092 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1093 StringExtractorGDBRemote response;
1094 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false))
1095 {
Sean Callanan6a925532011-01-13 08:53:35 +00001096 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +00001097 return true;
1098 }
1099 return false;
1100}
Jim Ingham3ae449a2010-11-17 02:32:00 +00001101