blob: a2c6a696cbf2b241bb11b9e050e7a3a84cb65156 [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 Claytonc97bfdb2011-03-10 02:26:48 +000038 m_packet_timeout (1),
Greg Claytonc1f45872011-02-12 06:28:37 +000039 m_supports_not_sending_acks (eLazyBoolCalculate),
40 m_supports_thread_suffix (eLazyBoolCalculate),
41 m_supports_qHostInfo (eLazyBoolCalculate),
42 m_supports_vCont_all (eLazyBoolCalculate),
43 m_supports_vCont_any (eLazyBoolCalculate),
44 m_supports_vCont_c (eLazyBoolCalculate),
45 m_supports_vCont_C (eLazyBoolCalculate),
46 m_supports_vCont_s (eLazyBoolCalculate),
47 m_supports_vCont_S (eLazyBoolCalculate),
Chris Lattner24943d22010-06-08 16:52:24 +000048 m_rx_packet_listener ("gdbremote.rx_packet"),
49 m_sequence_mutex (Mutex::eMutexTypeRecursive),
Greg Claytoncecf3482011-01-20 07:53:45 +000050 m_public_is_running (false),
51 m_private_is_running (false),
Chris Lattner24943d22010-06-08 16:52:24 +000052 m_async_mutex (Mutex::eMutexTypeRecursive),
53 m_async_packet_predicate (false),
54 m_async_packet (),
55 m_async_response (),
Chris Lattner24943d22010-06-08 16:52:24 +000056 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;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000127 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
Greg Claytonc1f45872011-02-12 06:28:37 +0000128 {
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;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000161 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
Greg Claytonc1f45872011-02-12 06:28:37 +0000162 {
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;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000181 if (SendPacketAndWaitForResponse("vCont?", response, false))
Greg Claytonc1f45872011-02-12 06:28:37 +0000182 {
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,
Chris Lattner24943d22010-06-08 16:52:24 +0000233 bool send_async
234)
235{
236 return SendPacketAndWaitForResponse (payload,
237 ::strlen (payload),
238 response,
Chris Lattner24943d22010-06-08 16:52:24 +0000239 send_async);
240}
241
242size_t
243GDBRemoteCommunication::SendPacketAndWaitForResponse
244(
245 const char *payload,
246 size_t payload_length,
247 StringExtractorGDBRemote &response,
Chris Lattner24943d22010-06-08 16:52:24 +0000248 bool send_async
249)
250{
251 Mutex::Locker locker;
252 TimeValue timeout_time;
253 timeout_time = TimeValue::Now();
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000254 timeout_time.OffsetWithSeconds (m_packet_timeout);
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);
Chris Lattner24943d22010-06-08 16:52:24 +0000268 m_async_packet_predicate.SetValue (true, eBroadcastNever);
269
Greg Claytondb2bab42011-01-27 09:02:32 +0000270 if (log)
271 log->Printf ("async: async packet = %s", m_async_packet.c_str());
272
Chris Lattner24943d22010-06-08 16:52:24 +0000273 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000274 bool sent_interrupt = false;
Greg Clayton68ca8232011-01-25 02:58:48 +0000275 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000276 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000277 if (sent_interrupt)
Chris Lattner24943d22010-06-08 16:52:24 +0000278 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000279 if (log)
280 log->Printf ("async: sent interrupt");
281 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
282 {
283 if (log)
284 log->Printf ("async: got response");
285 response = m_async_response;
286 return response.GetStringRef().size();
287 }
288 else
289 {
290 if (log)
291 log->Printf ("async: timed out waiting for response");
292 }
293
294 // Make sure we wait until the continue packet has been sent again...
295 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
296 {
297 if (log)
298 log->Printf ("async: timed out waiting for process to resume");
299 }
300 }
301 else
302 {
303 // We had a racy condition where we went to send the interrupt
304 // yet we were able to get the loc
Chris Lattner24943d22010-06-08 16:52:24 +0000305 }
306 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000307 else
308 {
309 if (log)
310 log->Printf ("async: failed to interrupt");
311 }
Chris Lattner24943d22010-06-08 16:52:24 +0000312 }
313 else
314 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000315 if (log)
316 log->Printf ("mutex taken and send_async == false, aborting packet");
Chris Lattner24943d22010-06-08 16:52:24 +0000317 }
318 }
319 return 0;
320}
321
322//template<typename _Tp>
323//class ScopedValueChanger
324//{
325//public:
Greg Clayton5d187e52011-01-08 20:28:42 +0000326// // Take a value reference and the value to assign it to when this class
Chris Lattner24943d22010-06-08 16:52:24 +0000327// // instance goes out of scope.
328// ScopedValueChanger (_Tp &value_ref, _Tp value) :
329// m_value_ref (value_ref),
330// m_value (value)
331// {
332// }
333//
334// // This object is going out of scope, change the value pointed to by
335// // m_value_ref to the value we got during construction which was stored in
336// // m_value;
337// ~ScopedValueChanger ()
338// {
339// m_value_ref = m_value;
340// }
341//protected:
Greg Clayton5d187e52011-01-08 20:28:42 +0000342// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
Chris Lattner24943d22010-06-08 16:52:24 +0000343// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
344//};
345
346StateType
347GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
348(
349 ProcessGDBRemote *process,
350 const char *payload,
351 size_t packet_length,
352 StringExtractorGDBRemote &response
353)
354{
Greg Claytone005f2c2010-11-06 01:53:30 +0000355 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000356 if (log)
357 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
358
359 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000360 StateType state = eStateRunning;
361
Greg Claytonb749a262010-12-03 06:02:24 +0000362 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Greg Claytoncecf3482011-01-20 07:53:45 +0000363 m_public_is_running.SetValue (true, eBroadcastNever);
Greg Claytondb2bab42011-01-27 09:02:32 +0000364 // Set the starting continue packet into "continue_packet". This packet
365 // make change if we are interrupted and we continue after an async packet...
366 std::string continue_packet(payload, packet_length);
367
Chris Lattner24943d22010-06-08 16:52:24 +0000368 while (state == eStateRunning)
369 {
370 if (log)
Greg Claytondb2bab42011-01-27 09:02:32 +0000371 log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
372 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
373 state = eStateInvalid;
374
375 m_private_is_running.SetValue (true, eBroadcastNever);
376
377 if (log)
378 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000379
380 if (WaitForPacket (response, (TimeValue*)NULL))
381 {
382 if (response.Empty())
383 state = eStateInvalid;
384 else
385 {
386 const char stop_type = response.GetChar();
387 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000388 log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000389 switch (stop_type)
390 {
391 case 'T':
392 case 'S':
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000393 if (process->GetStopID() == 0)
394 {
395 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
396 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000397 lldb::pid_t pid = GetCurrentProcessID ();
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000398 if (pid != LLDB_INVALID_PROCESS_ID)
399 process->SetID (pid);
400 }
401 process->BuildDynamicRegisterInfo (true);
402 }
403
Greg Claytoncecf3482011-01-20 07:53:45 +0000404 // Privately notify any internal threads that we have stopped
405 // in case we wanted to interrupt our process, yet we might
406 // send a packet and continue without returning control to the
407 // user.
408 m_private_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000409 if (m_async_signal != -1)
410 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000411 if (log)
412 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000413
Chris Lattner24943d22010-06-08 16:52:24 +0000414 // Save off the async signal we are supposed to send
415 const int async_signal = m_async_signal;
416 // Clear the async signal member so we don't end up
417 // sending the signal multiple times...
418 m_async_signal = -1;
419 // Check which signal we stopped with
420 uint8_t signo = response.GetHexU8(255);
421 if (signo == async_signal)
422 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000423 if (log)
424 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
Greg Claytonb4d1d332010-09-03 21:14:27 +0000425
Chris Lattner24943d22010-06-08 16:52:24 +0000426 // We already stopped with a signal that we wanted
427 // to stop with, so we are done
428 response.SetFilePos (0);
429 }
430 else
431 {
432 // We stopped with a different signal that the one
433 // we wanted to stop with, so now we must resume
434 // with the signal we want
435 char signal_packet[32];
436 int signal_packet_len = 0;
437 signal_packet_len = ::snprintf (signal_packet,
438 sizeof (signal_packet),
439 "C%2.2x",
440 async_signal);
441
Greg Clayton68ca8232011-01-25 02:58:48 +0000442 if (log)
443 log->Printf ("async: stopped with signal %s, resume with %s",
Greg Claytonb4d1d332010-09-03 21:14:27 +0000444 Host::GetSignalAsCString (signo),
445 Host::GetSignalAsCString (async_signal));
446
Greg Claytondb2bab42011-01-27 09:02:32 +0000447 // Set the continue packet to resume...
448 continue_packet.assign(signal_packet, signal_packet_len);
449 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000450 }
451 }
452 else if (m_async_packet_predicate.GetValue())
453 {
454 // We are supposed to send an asynchronous packet while
455 // we are running.
456 m_async_response.Clear();
Greg Claytondb2bab42011-01-27 09:02:32 +0000457 if (m_async_packet.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000458 {
Greg Claytondb2bab42011-01-27 09:02:32 +0000459 if (log)
460 log->Printf ("async: error: empty async packet");
461
462 }
463 else
464 {
465 if (log)
466 log->Printf ("async: sending packet: %s",
467 m_async_packet.c_str());
468
Greg Clayton53d68e72010-07-20 22:52:08 +0000469 SendPacketAndWaitForResponse (&m_async_packet[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000470 m_async_packet.size(),
471 m_async_response,
Chris Lattner24943d22010-06-08 16:52:24 +0000472 false);
473 }
474 // Let the other thread that was trying to send the async
Greg Claytondb2bab42011-01-27 09:02:32 +0000475 // packet know that the packet has been sent and response is
476 // ready...
Chris Lattner24943d22010-06-08 16:52:24 +0000477 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
478
Greg Claytondb2bab42011-01-27 09:02:32 +0000479 // Set the continue packet to resume...
480 continue_packet.assign (1, 'c');
481 continue;
Chris Lattner24943d22010-06-08 16:52:24 +0000482 }
483 // Stop with signal and thread info
484 state = eStateStopped;
485 break;
486
487 case 'W':
Greg Clayton68ca8232011-01-25 02:58:48 +0000488 case 'X':
Chris Lattner24943d22010-06-08 16:52:24 +0000489 // process exited
490 state = eStateExited;
491 break;
492
493 case 'O':
494 // STDOUT
495 {
496 std::string inferior_stdout;
497 inferior_stdout.reserve(response.GetBytesLeft () / 2);
498 char ch;
499 while ((ch = response.GetHexU8()) != '\0')
500 inferior_stdout.append(1, ch);
501 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
502 }
503 break;
504
505 case 'E':
506 // ERROR
507 state = eStateInvalid;
508 break;
509
510 default:
511 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +0000512 log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
Greg Claytona2f74232011-02-24 22:24:29 +0000513 state = eStateInvalid;
Chris Lattner24943d22010-06-08 16:52:24 +0000514 break;
515 }
516 }
517 }
518 else
519 {
520 if (log)
521 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
522 state = eStateInvalid;
523 }
524 }
525 if (log)
526 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
527 response.SetFilePos(0);
Greg Claytoncecf3482011-01-20 07:53:45 +0000528 m_private_is_running.SetValue (false, eBroadcastAlways);
529 m_public_is_running.SetValue (false, eBroadcastAlways);
Chris Lattner24943d22010-06-08 16:52:24 +0000530 return state;
531}
532
533size_t
534GDBRemoteCommunication::SendPacket (const char *payload)
535{
536 Mutex::Locker locker(m_sequence_mutex);
537 return SendPacketNoLock (payload, ::strlen (payload));
538}
539
540size_t
541GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
542{
543 Mutex::Locker locker(m_sequence_mutex);
544 return SendPacketNoLock (payload, payload_length);
545}
546
547size_t
548GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
549{
550 if (IsConnected())
551 {
552 StreamString packet(0, 4, eByteOrderBig);
553
554 packet.PutChar('$');
555 packet.Write (payload, payload_length);
556 packet.PutChar('#');
557 packet.PutHex8(CalculcateChecksum (payload, payload_length));
558
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000559 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
560 if (log)
561 log->Printf ("send packet: %s", packet.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000562 ConnectionStatus status = eConnectionStatusSuccess;
563 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
564 if (bytes_written == packet.GetSize())
565 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000566 if (GetSendAcks ())
Greg Clayton54e7afa2010-07-09 20:39:50 +0000567 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000568 if (GetAck () != '+')
Greg Clayton54e7afa2010-07-09 20:39:50 +0000569 return 0;
570 }
Chris Lattner24943d22010-06-08 16:52:24 +0000571 }
Johnny Chen515ea542010-09-14 22:10:43 +0000572 else
573 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000574 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
575 if (log)
576 log->Printf ("error: failed to send packet: %s", packet.GetData());
Johnny Chen515ea542010-09-14 22:10:43 +0000577 }
Chris Lattner24943d22010-06-08 16:52:24 +0000578 return bytes_written;
Greg Claytoneea26402010-09-14 23:36:40 +0000579 }
Chris Lattner24943d22010-06-08 16:52:24 +0000580 return 0;
581}
582
583char
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000584GDBRemoteCommunication::GetAck ()
Chris Lattner24943d22010-06-08 16:52:24 +0000585{
586 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000587 if (WaitForPacket (response, m_packet_timeout) == 1)
Chris Lattner24943d22010-06-08 16:52:24 +0000588 return response.GetChar();
589 return 0;
590}
591
592bool
593GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
594{
595 return locker.TryLock (m_sequence_mutex.GetMutex());
596}
597
598bool
599GDBRemoteCommunication::SendAsyncSignal (int signo)
600{
601 m_async_signal = signo;
602 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +0000603 bool sent_interrupt = false;
Greg Clayton1a679462010-09-03 19:15:43 +0000604 Mutex::Locker locker;
Greg Claytona4881d02011-01-22 07:12:45 +0000605 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
Chris Lattner24943d22010-06-08 16:52:24 +0000606 return true;
607 m_async_signal = -1;
608 return false;
609}
610
Greg Clayton1a679462010-09-03 19:15:43 +0000611// This function takes a mutex locker as a parameter in case the GetSequenceMutex
612// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
613// (the expected result), then it will send the halt packet. If it does succeed
614// then the caller that requested the interrupt will want to keep the sequence
615// locked down so that no one else can send packets while the caller has control.
616// This function usually gets called when we are running and need to stop the
617// target. It can also be used when we are running and and we need to do something
618// else (like read/write memory), so we need to interrupt the running process
619// (gdb remote protocol requires this), and do what we need to do, then resume.
620
Chris Lattner24943d22010-06-08 16:52:24 +0000621bool
Greg Claytona4881d02011-01-22 07:12:45 +0000622GDBRemoteCommunication::SendInterrupt
623(
624 Mutex::Locker& locker,
625 uint32_t seconds_to_wait_for_stop,
626 bool &sent_interrupt,
627 bool &timed_out
628)
Chris Lattner24943d22010-06-08 16:52:24 +0000629{
Greg Claytona4881d02011-01-22 07:12:45 +0000630 sent_interrupt = false;
631 timed_out = false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000632 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +0000633
Greg Claytondb2bab42011-01-27 09:02:32 +0000634 if (IsRunning())
Chris Lattner24943d22010-06-08 16:52:24 +0000635 {
636 // Only send an interrupt if our debugserver is running...
Greg Clayton1a679462010-09-03 19:15:43 +0000637 if (GetSequenceMutex (locker) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000638 {
639 // Someone has the mutex locked waiting for a response or for the
640 // inferior to stop, so send the interrupt on the down low...
641 char ctrl_c = '\x03';
642 ConnectionStatus status = eConnectionStatusSuccess;
643 TimeValue timeout;
644 if (seconds_to_wait_for_stop)
645 {
646 timeout = TimeValue::Now();
647 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
648 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000649 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton68ca8232011-01-25 02:58:48 +0000650 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
Greg Claytondb2bab42011-01-27 09:02:32 +0000651 if (bytes_written > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000652 {
Greg Claytona4881d02011-01-22 07:12:45 +0000653 sent_interrupt = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000654 if (seconds_to_wait_for_stop)
Greg Claytondb2bab42011-01-27 09:02:32 +0000655 {
Greg Clayton1c2aa462011-02-03 01:07:45 +0000656 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
657 {
658 if (log)
659 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
660 return true;
661 }
662 else
663 {
664 if (log)
665 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
666 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000667 }
668 else
669 {
670 if (log)
671 log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
Greg Clayton1c2aa462011-02-03 01:07:45 +0000672 return true;
Greg Claytondb2bab42011-01-27 09:02:32 +0000673 }
Chris Lattner24943d22010-06-08 16:52:24 +0000674 }
Greg Claytondb2bab42011-01-27 09:02:32 +0000675 else
676 {
677 if (log)
678 log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
679 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000680 return false;
Greg Claytondb2bab42011-01-27 09:02:32 +0000681 }
682 else
683 {
684 if (log)
685 log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
Chris Lattner24943d22010-06-08 16:52:24 +0000686 }
687 }
Greg Clayton1c2aa462011-02-03 01:07:45 +0000688 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000689}
690
Greg Clayton72e1c782011-01-22 23:43:18 +0000691bool
Greg Clayton72e1c782011-01-22 23:43:18 +0000692GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
693{
694 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
695}
696
Chris Lattner24943d22010-06-08 16:52:24 +0000697size_t
698GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
699{
Greg Claytoncecf3482011-01-20 07:53:45 +0000700 Mutex::Locker locker(m_sequence_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000701 TimeValue timeout_time;
702 timeout_time = TimeValue::Now();
703 timeout_time.OffsetWithSeconds (timeout_seconds);
704 return WaitForPacketNoLock (response, &timeout_time);
705}
706
707size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000708GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000709{
710 Mutex::Locker locker(m_sequence_mutex);
711 return WaitForPacketNoLock (response, timeout_time_ptr);
712}
713
714size_t
Greg Clayton72e1c782011-01-22 23:43:18 +0000715GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000716{
717 bool checksum_error = false;
718 response.Clear ();
719
720 EventSP event_sp;
721
722 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp))
723 {
724 const uint32_t event_type = event_sp->GetType();
725 if (event_type | Communication::eBroadcastBitPacketAvailable)
726 {
727 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get());
728 if (event_bytes)
729 {
730 const char * packet_data = (const char *)event_bytes->GetBytes();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000731 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
732 if (log)
733 log->Printf ("read packet: %s", packet_data);
Chris Lattner24943d22010-06-08 16:52:24 +0000734 const size_t packet_size = event_bytes->GetByteSize();
735 if (packet_data && packet_size > 0)
736 {
737 std::string &response_str = response.GetStringRef();
738 if (packet_data[0] == '$')
739 {
Greg Clayton4862fa22011-01-08 03:17:57 +0000740 bool success = false;
741 if (packet_size < 4)
742 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data);
743 else if (packet_data[packet_size-3] != '#' ||
744 !::isxdigit (packet_data[packet_size-2]) ||
745 !::isxdigit (packet_data[packet_size-1]))
746 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data);
747 else
748 success = true;
749
750 if (success)
751 response_str.assign (packet_data + 1, packet_size - 4);
Greg Claytonc1f45872011-02-12 06:28:37 +0000752 if (GetSendAcks ())
Chris Lattner24943d22010-06-08 16:52:24 +0000753 {
754 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
Greg Clayton53d68e72010-07-20 22:52:08 +0000755 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000756 checksum_error = packet_checksum != actual_checksum;
757 // Send the ack or nack if needed
Greg Clayton4862fa22011-01-08 03:17:57 +0000758 if (checksum_error || !success)
Greg Claytona4881d02011-01-22 07:12:45 +0000759 SendNack();
Chris Lattner24943d22010-06-08 16:52:24 +0000760 else
Greg Claytona4881d02011-01-22 07:12:45 +0000761 SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000762 }
763 }
764 else
765 {
766 response_str.assign (packet_data, packet_size);
767 }
768 return response_str.size();
769 }
770 }
771 }
772 else if (Communication::eBroadcastBitReadThreadDidExit)
773 {
774 // Our read thread exited on us so just fall through and return zero...
775 }
776 }
777 return 0;
778}
779
780void
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000781GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast,
782 ConnectionStatus status)
Chris Lattner24943d22010-06-08 16:52:24 +0000783{
784 // Put the packet data into the buffer in a thread safe fashion
785 Mutex::Locker locker(m_bytes_mutex);
786 m_bytes.append ((const char *)src, src_len);
787
788 // Parse up the packets into gdb remote packets
789 while (!m_bytes.empty())
790 {
791 // end_idx must be one past the last valid packet byte. Start
792 // it off with an invalid value that is the same as the current
793 // index.
794 size_t end_idx = 0;
795
796 switch (m_bytes[0])
797 {
798 case '+': // Look for ack
799 case '-': // Look for cancel
800 case '\x03': // ^C to halt target
801 end_idx = 1; // The command is one byte long...
802 break;
803
804 case '$':
805 // Look for a standard gdb packet?
806 end_idx = m_bytes.find('#');
807 if (end_idx != std::string::npos)
808 {
809 if (end_idx + 2 < m_bytes.size())
810 {
811 end_idx += 3;
812 }
813 else
814 {
815 // Checksum bytes aren't all here yet
816 end_idx = std::string::npos;
817 }
818 }
819 break;
820
821 default:
822 break;
823 }
824
825 if (end_idx == std::string::npos)
826 {
827 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str());
828 return;
829 }
830 else if (end_idx > 0)
831 {
832 // We have a valid packet...
833 assert (end_idx <= m_bytes.size());
834 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx));
835 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes());
836 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release());
837 m_bytes.erase(0, end_idx);
838 }
839 else
840 {
841 assert (1 <= m_bytes.size());
842 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]);
843 m_bytes.erase(0, 1);
844 }
845 }
846}
847
848lldb::pid_t
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000849GDBRemoteCommunication::GetCurrentProcessID ()
Chris Lattner24943d22010-06-08 16:52:24 +0000850{
851 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000852 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000853 {
854 if (response.GetChar() == 'Q')
855 if (response.GetChar() == 'C')
856 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
857 }
858 return LLDB_INVALID_PROCESS_ID;
859}
860
861bool
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000862GDBRemoteCommunication::GetLaunchSuccess (std::string &error_str)
Chris Lattner24943d22010-06-08 16:52:24 +0000863{
864 error_str.clear();
865 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000866 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000867 {
868 if (response.IsOKPacket())
869 return true;
870 if (response.GetChar() == 'E')
871 {
872 // A string the describes what failed when launching...
873 error_str = response.GetStringRef().substr(1);
874 }
875 else
876 {
877 error_str.assign ("unknown error occurred launching process");
878 }
879 }
880 else
881 {
882 error_str.assign ("failed to send the qLaunchSuccess packet");
883 }
884 return false;
885}
886
887int
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000888GDBRemoteCommunication::SendArgumentsPacket (char const *argv[])
Chris Lattner24943d22010-06-08 16:52:24 +0000889{
890 if (argv && argv[0])
891 {
892 StreamString packet;
893 packet.PutChar('A');
894 const char *arg;
895 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
896 {
897 const int arg_len = strlen(arg);
898 if (i > 0)
899 packet.PutChar(',');
900 packet.Printf("%i,%i,", arg_len * 2, i);
Greg Claytona2f74232011-02-24 22:24:29 +0000901 packet.PutBytesAsRawHex8 (arg, arg_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000902 }
903
904 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000905 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000906 {
907 if (response.IsOKPacket())
908 return 0;
909 uint8_t error = response.GetError();
910 if (error)
911 return error;
912 }
913 }
914 return -1;
915}
916
917int
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000918GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value)
Chris Lattner24943d22010-06-08 16:52:24 +0000919{
920 if (name_equal_value && name_equal_value[0])
921 {
922 StreamString packet;
923 packet.Printf("QEnvironment:%s", name_equal_value);
924 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000925 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000926 {
927 if (response.IsOKPacket())
928 return 0;
929 uint8_t error = response.GetError();
930 if (error)
931 return error;
932 }
933 }
934 return -1;
935}
936
937bool
Greg Claytonc1f45872011-02-12 06:28:37 +0000938GDBRemoteCommunication::GetHostInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +0000939{
Greg Claytonc1f45872011-02-12 06:28:37 +0000940 if (m_supports_qHostInfo == eLazyBoolCalculate)
Chris Lattner24943d22010-06-08 16:52:24 +0000941 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000942 m_supports_qHostInfo = eLazyBoolNo;
Chris Lattner24943d22010-06-08 16:52:24 +0000943
Greg Claytonc1f45872011-02-12 06:28:37 +0000944 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000945 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000946 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000947 if (response.IsUnsupportedPacket())
948 return false;
949
950 m_supports_qHostInfo = eLazyBoolYes;
951
952 std::string name;
953 std::string value;
954 uint32_t cpu = LLDB_INVALID_CPUTYPE;
955 uint32_t sub = 0;
Greg Claytone71e2582011-02-04 01:58:07 +0000956
Greg Claytonc1f45872011-02-12 06:28:37 +0000957 while (response.GetNameColonValue(name, value))
958 {
959 if (name.compare("cputype") == 0)
960 {
961 // exception type in big endian hex
962 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
963 }
964 else if (name.compare("cpusubtype") == 0)
965 {
966 // exception count in big endian hex
967 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
968 }
969 else if (name.compare("ostype") == 0)
970 {
971 // exception data in big endian hex
972 m_os.SetCString(value.c_str());
973 }
974 else if (name.compare("vendor") == 0)
975 {
976 m_vendor.SetCString(value.c_str());
977 }
978 else if (name.compare("endian") == 0)
979 {
980 if (value.compare("little") == 0)
981 m_byte_order = eByteOrderLittle;
982 else if (value.compare("big") == 0)
983 m_byte_order = eByteOrderBig;
984 else if (value.compare("pdp") == 0)
985 m_byte_order = eByteOrderPDP;
986 }
987 else if (name.compare("ptrsize") == 0)
988 {
989 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
990 }
991 }
992
993 if (cpu != LLDB_INVALID_CPUTYPE)
Greg Clayton940b1032011-02-23 00:35:02 +0000994 m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
Greg Claytonc1f45872011-02-12 06:28:37 +0000995 }
Chris Lattner24943d22010-06-08 16:52:24 +0000996 }
Greg Claytonc1f45872011-02-12 06:28:37 +0000997 return m_supports_qHostInfo == eLazyBoolYes;
Chris Lattner24943d22010-06-08 16:52:24 +0000998}
999
1000int
1001GDBRemoteCommunication::SendAttach
1002(
1003 lldb::pid_t pid,
Chris Lattner24943d22010-06-08 16:52:24 +00001004 StringExtractorGDBRemote& response
1005)
1006{
1007 if (pid != LLDB_INVALID_PROCESS_ID)
1008 {
1009 StreamString packet;
1010 packet.Printf("vAttach;%x", pid);
1011
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001012 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00001013 {
1014 if (response.IsErrorPacket())
1015 return response.GetError();
1016 return 0;
1017 }
1018 }
1019 return -1;
1020}
1021
1022const lldb_private::ArchSpec &
1023GDBRemoteCommunication::GetHostArchitecture ()
1024{
1025 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001026 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001027 return m_arch;
1028}
1029
1030const lldb_private::ConstString &
1031GDBRemoteCommunication::GetOSString ()
1032{
1033 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001034 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001035 return m_os;
1036}
1037
1038const lldb_private::ConstString &
1039GDBRemoteCommunication::GetVendorString()
1040{
1041 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001042 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001043 return m_vendor;
1044}
1045
1046lldb::ByteOrder
1047GDBRemoteCommunication::GetByteOrder ()
1048{
1049 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001050 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001051 return m_byte_order;
1052}
1053
1054uint32_t
1055GDBRemoteCommunication::GetAddressByteSize ()
1056{
1057 if (!HostInfoIsValid ())
Greg Claytonc1f45872011-02-12 06:28:37 +00001058 GetHostInfo ();
Chris Lattner24943d22010-06-08 16:52:24 +00001059 return m_pointer_byte_size;
1060}
1061
1062addr_t
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001063GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions)
Chris Lattner24943d22010-06-08 16:52:24 +00001064{
1065 char packet[64];
1066 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1067 permissions & lldb::ePermissionsReadable ? "r" : "",
1068 permissions & lldb::ePermissionsWritable ? "w" : "",
1069 permissions & lldb::ePermissionsExecutable ? "x" : "");
1070 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001071 if (SendPacketAndWaitForResponse (packet, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00001072 {
1073 if (!response.IsErrorPacket())
1074 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1075 }
1076 return LLDB_INVALID_ADDRESS;
1077}
1078
1079bool
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001080GDBRemoteCommunication::DeallocateMemory (addr_t addr)
Chris Lattner24943d22010-06-08 16:52:24 +00001081{
1082 char packet[64];
1083 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1084 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001085 if (SendPacketAndWaitForResponse (packet, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00001086 {
Sean Callanan6a925532011-01-13 08:53:35 +00001087 if (response.IsOKPacket())
Chris Lattner24943d22010-06-08 16:52:24 +00001088 return true;
1089 }
1090 return false;
1091}
Jim Ingham3ae449a2010-11-17 02:32:00 +00001092
Greg Claytona2f74232011-02-24 22:24:29 +00001093int
1094GDBRemoteCommunication::SetSTDIN (char const *path)
1095{
1096 if (path && path[0])
1097 {
1098 StreamString packet;
1099 packet.PutCString("QSetSTDIN:");
1100 packet.PutBytesAsRawHex8(path, strlen(path));
1101
1102 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001103 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Greg Claytona2f74232011-02-24 22:24:29 +00001104 {
1105 if (response.IsOKPacket())
1106 return 0;
1107 uint8_t error = response.GetError();
1108 if (error)
1109 return error;
1110 }
1111 }
1112 return -1;
1113}
1114
1115int
1116GDBRemoteCommunication::SetSTDOUT (char const *path)
1117{
1118 if (path && path[0])
1119 {
1120 StreamString packet;
1121 packet.PutCString("QSetSTDOUT:");
1122 packet.PutBytesAsRawHex8(path, strlen(path));
1123
1124 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001125 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Greg Claytona2f74232011-02-24 22:24:29 +00001126 {
1127 if (response.IsOKPacket())
1128 return 0;
1129 uint8_t error = response.GetError();
1130 if (error)
1131 return error;
1132 }
1133 }
1134 return -1;
1135}
1136
1137int
1138GDBRemoteCommunication::SetSTDERR (char const *path)
1139{
1140 if (path && path[0])
1141 {
1142 StreamString packet;
1143 packet.PutCString("QSetSTDERR:");
1144 packet.PutBytesAsRawHex8(path, strlen(path));
1145
1146 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001147 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Greg Claytona2f74232011-02-24 22:24:29 +00001148 {
1149 if (response.IsOKPacket())
1150 return 0;
1151 uint8_t error = response.GetError();
1152 if (error)
1153 return error;
1154 }
1155 }
1156 return -1;
1157}
1158
1159int
1160GDBRemoteCommunication::SetWorkingDir (char const *path)
1161{
1162 if (path && path[0])
1163 {
1164 StreamString packet;
1165 packet.PutCString("QSetWorkingDir:");
1166 packet.PutBytesAsRawHex8(path, strlen(path));
1167
1168 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001169 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Greg Claytona2f74232011-02-24 22:24:29 +00001170 {
1171 if (response.IsOKPacket())
1172 return 0;
1173 uint8_t error = response.GetError();
1174 if (error)
1175 return error;
1176 }
1177 }
1178 return -1;
1179}
1180
1181int
1182GDBRemoteCommunication::SetDisableASLR (bool enable)
1183{
1184 StreamString packet;
1185 packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
1186
1187 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001188 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
Greg Claytona2f74232011-02-24 22:24:29 +00001189 {
1190 if (response.IsOKPacket())
1191 return 0;
1192 uint8_t error = response.GetError();
1193 if (error)
1194 return error;
1195 }
1196 return -1;
1197}