blob: e308f915d1ccfdd1b3f659a00a0a83b578060797 [file] [log] [blame]
Greg Clayton61d043b2011-03-22 04:00:09 +00001//===-- GDBRemoteCommunicationClient.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 "GDBRemoteCommunicationClient.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16#include "llvm/ADT/Triple.h"
17#include "lldb/Interpreter/Args.h"
18#include "lldb/Core/ConnectionFileDescriptor.h"
19#include "lldb/Core/Log.h"
20#include "lldb/Core/State.h"
21#include "lldb/Core/StreamString.h"
22#include "lldb/Host/Endian.h"
23#include "lldb/Host/Host.h"
24#include "lldb/Host/TimeValue.h"
25
26// Project includes
27#include "Utility/StringExtractorGDBRemote.h"
28#include "ProcessGDBRemote.h"
29#include "ProcessGDBRemoteLog.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34//----------------------------------------------------------------------
35// GDBRemoteCommunicationClient constructor
36//----------------------------------------------------------------------
Greg Claytonb72d0f02011-04-12 05:54:46 +000037GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
38 GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
Greg Clayton61d043b2011-03-22 04:00:09 +000039 m_supports_not_sending_acks (eLazyBoolCalculate),
40 m_supports_thread_suffix (eLazyBoolCalculate),
Greg Clayton61d043b2011-03-22 04:00:09 +000041 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),
Greg Clayton24bc5d92011-03-30 18:16:51 +000047 m_qHostInfo_is_valid (eLazyBoolCalculate),
Greg Clayton2f085c62011-05-15 01:25:55 +000048 m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
Greg Claytona9385532011-11-18 07:03:08 +000049 m_supports_memory_region_info (eLazyBoolCalculate),
Greg Clayton24bc5d92011-03-30 18:16:51 +000050 m_supports_qProcessInfoPID (true),
51 m_supports_qfProcessInfo (true),
52 m_supports_qUserName (true),
53 m_supports_qGroupName (true),
Greg Claytonb72d0f02011-04-12 05:54:46 +000054 m_supports_qThreadStopInfo (true),
55 m_supports_z0 (true),
56 m_supports_z1 (true),
57 m_supports_z2 (true),
58 m_supports_z3 (true),
59 m_supports_z4 (true),
60 m_curr_tid (LLDB_INVALID_THREAD_ID),
61 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Greg Clayton61d043b2011-03-22 04:00:09 +000062 m_async_mutex (Mutex::eMutexTypeRecursive),
63 m_async_packet_predicate (false),
64 m_async_packet (),
65 m_async_response (),
66 m_async_signal (-1),
Greg Clayton58e26e02011-03-24 04:28:38 +000067 m_host_arch(),
68 m_os_version_major (UINT32_MAX),
69 m_os_version_minor (UINT32_MAX),
70 m_os_version_update (UINT32_MAX)
Greg Clayton61d043b2011-03-22 04:00:09 +000071{
Greg Clayton61d043b2011-03-22 04:00:09 +000072}
73
74//----------------------------------------------------------------------
75// Destructor
76//----------------------------------------------------------------------
77GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
78{
Greg Clayton61d043b2011-03-22 04:00:09 +000079 if (IsConnected())
Greg Clayton61d043b2011-03-22 04:00:09 +000080 Disconnect();
Greg Clayton61d043b2011-03-22 04:00:09 +000081}
82
83bool
Greg Clayton58e26e02011-03-24 04:28:38 +000084GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
85{
86 // Start the read thread after we send the handshake ack since if we
87 // fail to send the handshake ack, there is no reason to continue...
88 if (SendAck())
Greg Clayton63afdb02011-06-17 01:22:15 +000089 return true;
Greg Clayton58e26e02011-03-24 04:28:38 +000090
91 if (error_ptr)
92 error_ptr->SetErrorString("failed to send the handshake ack");
93 return false;
94}
95
96void
97GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton61d043b2011-03-22 04:00:09 +000098{
99 if (m_supports_not_sending_acks == eLazyBoolCalculate)
100 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000101 m_send_acks = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000102 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton58e26e02011-03-24 04:28:38 +0000103
104 StringExtractorGDBRemote response;
Greg Clayton61d043b2011-03-22 04:00:09 +0000105 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
106 {
107 if (response.IsOKResponse())
Greg Clayton58e26e02011-03-24 04:28:38 +0000108 {
109 m_send_acks = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000110 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton58e26e02011-03-24 04:28:38 +0000111 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000112 }
113 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000114}
115
116void
117GDBRemoteCommunicationClient::ResetDiscoverableSettings()
118{
119 m_supports_not_sending_acks = eLazyBoolCalculate;
120 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton61d043b2011-03-22 04:00:09 +0000121 m_supports_vCont_c = eLazyBoolCalculate;
122 m_supports_vCont_C = eLazyBoolCalculate;
123 m_supports_vCont_s = eLazyBoolCalculate;
124 m_supports_vCont_S = eLazyBoolCalculate;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000125 m_qHostInfo_is_valid = eLazyBoolCalculate;
Greg Clayton2f085c62011-05-15 01:25:55 +0000126 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
Greg Claytona9385532011-11-18 07:03:08 +0000127 m_supports_memory_region_info = eLazyBoolCalculate;
Greg Clayton989816b2011-05-14 01:50:35 +0000128
Greg Clayton24bc5d92011-03-30 18:16:51 +0000129 m_supports_qProcessInfoPID = true;
130 m_supports_qfProcessInfo = true;
131 m_supports_qUserName = true;
132 m_supports_qGroupName = true;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000133 m_supports_qThreadStopInfo = true;
134 m_supports_z0 = true;
135 m_supports_z1 = true;
136 m_supports_z2 = true;
137 m_supports_z3 = true;
138 m_supports_z4 = true;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000139 m_host_arch.Clear();
Greg Clayton61d043b2011-03-22 04:00:09 +0000140}
141
142
143bool
144GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
145{
146 if (m_supports_thread_suffix == eLazyBoolCalculate)
147 {
148 StringExtractorGDBRemote response;
149 m_supports_thread_suffix = eLazyBoolNo;
150 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
151 {
152 if (response.IsOKResponse())
153 m_supports_thread_suffix = eLazyBoolYes;
154 }
155 }
156 return m_supports_thread_suffix;
157}
158bool
159GDBRemoteCommunicationClient::GetVContSupported (char flavor)
160{
161 if (m_supports_vCont_c == eLazyBoolCalculate)
162 {
163 StringExtractorGDBRemote response;
164 m_supports_vCont_any = eLazyBoolNo;
165 m_supports_vCont_all = eLazyBoolNo;
166 m_supports_vCont_c = eLazyBoolNo;
167 m_supports_vCont_C = eLazyBoolNo;
168 m_supports_vCont_s = eLazyBoolNo;
169 m_supports_vCont_S = eLazyBoolNo;
170 if (SendPacketAndWaitForResponse("vCont?", response, false))
171 {
172 const char *response_cstr = response.GetStringRef().c_str();
173 if (::strstr (response_cstr, ";c"))
174 m_supports_vCont_c = eLazyBoolYes;
175
176 if (::strstr (response_cstr, ";C"))
177 m_supports_vCont_C = eLazyBoolYes;
178
179 if (::strstr (response_cstr, ";s"))
180 m_supports_vCont_s = eLazyBoolYes;
181
182 if (::strstr (response_cstr, ";S"))
183 m_supports_vCont_S = eLazyBoolYes;
184
185 if (m_supports_vCont_c == eLazyBoolYes &&
186 m_supports_vCont_C == eLazyBoolYes &&
187 m_supports_vCont_s == eLazyBoolYes &&
188 m_supports_vCont_S == eLazyBoolYes)
189 {
190 m_supports_vCont_all = eLazyBoolYes;
191 }
192
193 if (m_supports_vCont_c == eLazyBoolYes ||
194 m_supports_vCont_C == eLazyBoolYes ||
195 m_supports_vCont_s == eLazyBoolYes ||
196 m_supports_vCont_S == eLazyBoolYes)
197 {
198 m_supports_vCont_any = eLazyBoolYes;
199 }
200 }
201 }
202
203 switch (flavor)
204 {
205 case 'a': return m_supports_vCont_any;
206 case 'A': return m_supports_vCont_all;
207 case 'c': return m_supports_vCont_c;
208 case 'C': return m_supports_vCont_C;
209 case 's': return m_supports_vCont_s;
210 case 'S': return m_supports_vCont_S;
211 default: break;
212 }
213 return false;
214}
215
216
217size_t
218GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
219(
220 const char *payload,
221 StringExtractorGDBRemote &response,
222 bool send_async
223)
224{
225 return SendPacketAndWaitForResponse (payload,
226 ::strlen (payload),
227 response,
228 send_async);
229}
230
231size_t
232GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
233(
234 const char *payload,
235 size_t payload_length,
236 StringExtractorGDBRemote &response,
237 bool send_async
238)
239{
240 Mutex::Locker locker;
Greg Clayton61d043b2011-03-22 04:00:09 +0000241 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton801417e2011-07-07 01:59:51 +0000242 size_t response_len = 0;
Greg Clayton61d043b2011-03-22 04:00:09 +0000243 if (GetSequenceMutex (locker))
244 {
Greg Clayton139da722011-05-20 03:15:54 +0000245 if (SendPacketNoLock (payload, payload_length))
Greg Clayton801417e2011-07-07 01:59:51 +0000246 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
247 else
248 {
249 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000250 log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
Greg Clayton801417e2011-07-07 01:59:51 +0000251 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000252 }
253 else
254 {
255 if (send_async)
256 {
257 Mutex::Locker async_locker (m_async_mutex);
258 m_async_packet.assign(payload, payload_length);
259 m_async_packet_predicate.SetValue (true, eBroadcastNever);
260
261 if (log)
262 log->Printf ("async: async packet = %s", m_async_packet.c_str());
263
264 bool timed_out = false;
Greg Clayton05e4d972012-03-29 01:55:41 +0000265 if (SendInterrupt(locker, 2, timed_out))
Greg Clayton61d043b2011-03-22 04:00:09 +0000266 {
Greg Clayton05e4d972012-03-29 01:55:41 +0000267 if (m_interrupt_sent)
Greg Clayton61d043b2011-03-22 04:00:09 +0000268 {
Greg Clayton63afdb02011-06-17 01:22:15 +0000269 TimeValue timeout_time;
270 timeout_time = TimeValue::Now();
271 timeout_time.OffsetWithSeconds (m_packet_timeout);
272
Greg Clayton61d043b2011-03-22 04:00:09 +0000273 if (log)
274 log->Printf ("async: sent interrupt");
Greg Clayton801417e2011-07-07 01:59:51 +0000275
Greg Clayton61d043b2011-03-22 04:00:09 +0000276 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
277 {
278 if (log)
279 log->Printf ("async: got response");
Greg Clayton801417e2011-07-07 01:59:51 +0000280
281 // Swap the response buffer to avoid malloc and string copy
282 response.GetStringRef().swap (m_async_response.GetStringRef());
283 response_len = response.GetStringRef().size();
Greg Clayton61d043b2011-03-22 04:00:09 +0000284 }
285 else
286 {
287 if (log)
288 log->Printf ("async: timed out waiting for response");
289 }
290
291 // Make sure we wait until the continue packet has been sent again...
292 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
293 {
Greg Claytonb7669b32011-10-27 22:04:16 +0000294 if (log)
295 {
296 if (timed_out)
297 log->Printf ("async: timed out waiting for process to resume, but process was resumed");
298 else
299 log->Printf ("async: async packet sent");
300 }
301 }
302 else
303 {
Greg Clayton61d043b2011-03-22 04:00:09 +0000304 if (log)
305 log->Printf ("async: timed out waiting for process to resume");
306 }
307 }
308 else
309 {
310 // We had a racy condition where we went to send the interrupt
Greg Clayton05e4d972012-03-29 01:55:41 +0000311 // yet we were able to get the lock, so the process must have
312 // just stopped?
Greg Clayton801417e2011-07-07 01:59:51 +0000313 if (log)
Greg Clayton05e4d972012-03-29 01:55:41 +0000314 log->Printf ("async: got lock without sending interrupt");
315 // Send the packet normally since we got the lock
316 if (SendPacketNoLock (payload, payload_length))
317 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
318 else
319 {
320 if (log)
321 log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
322 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000323 }
324 }
325 else
326 {
327 if (log)
328 log->Printf ("async: failed to interrupt");
329 }
330 }
331 else
332 {
333 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000334 log->Printf("error: packet mutex taken and send_async == false, not sending packet '%*s'", (int) payload_length, payload);
Greg Clayton61d043b2011-03-22 04:00:09 +0000335 }
336 }
Greg Clayton801417e2011-07-07 01:59:51 +0000337 if (response_len == 0)
338 {
339 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000340 log->Printf("error: failed to get response for '%*s'", (int) payload_length, payload);
Greg Clayton801417e2011-07-07 01:59:51 +0000341 }
342 return response_len;
Greg Clayton61d043b2011-03-22 04:00:09 +0000343}
344
345//template<typename _Tp>
346//class ScopedValueChanger
347//{
348//public:
349// // Take a value reference and the value to assign it to when this class
350// // instance goes out of scope.
351// ScopedValueChanger (_Tp &value_ref, _Tp value) :
352// m_value_ref (value_ref),
353// m_value (value)
354// {
355// }
356//
357// // This object is going out of scope, change the value pointed to by
358// // m_value_ref to the value we got during construction which was stored in
359// // m_value;
360// ~ScopedValueChanger ()
361// {
362// m_value_ref = m_value;
363// }
364//protected:
365// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
366// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
367//};
368
369StateType
370GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
371(
372 ProcessGDBRemote *process,
373 const char *payload,
374 size_t packet_length,
375 StringExtractorGDBRemote &response
376)
377{
378 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
379 if (log)
380 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
381
382 Mutex::Locker locker(m_sequence_mutex);
383 StateType state = eStateRunning;
384
385 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
386 m_public_is_running.SetValue (true, eBroadcastNever);
387 // Set the starting continue packet into "continue_packet". This packet
388 // make change if we are interrupted and we continue after an async packet...
389 std::string continue_packet(payload, packet_length);
390
Greg Clayton628cead2011-05-19 03:54:16 +0000391 bool got_stdout = false;
392
Greg Clayton61d043b2011-03-22 04:00:09 +0000393 while (state == eStateRunning)
394 {
Greg Clayton628cead2011-05-19 03:54:16 +0000395 if (!got_stdout)
396 {
397 if (log)
398 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
399 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
400 state = eStateInvalid;
Greg Clayton61d043b2011-03-22 04:00:09 +0000401
Greg Claytonb7669b32011-10-27 22:04:16 +0000402 m_private_is_running.SetValue (true, eBroadcastAlways);
Greg Clayton628cead2011-05-19 03:54:16 +0000403 }
404
405 got_stdout = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000406
407 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000408 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
Greg Clayton61d043b2011-03-22 04:00:09 +0000409
Greg Clayton63afdb02011-06-17 01:22:15 +0000410 if (WaitForPacketWithTimeoutMicroSeconds (response, UINT32_MAX))
Greg Clayton61d043b2011-03-22 04:00:09 +0000411 {
412 if (response.Empty())
413 state = eStateInvalid;
414 else
415 {
416 const char stop_type = response.GetChar();
417 if (log)
418 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
419 switch (stop_type)
420 {
421 case 'T':
422 case 'S':
Greg Clayton61d043b2011-03-22 04:00:09 +0000423 {
Greg Clayton05e4d972012-03-29 01:55:41 +0000424 if (process->GetStopID() == 0)
Greg Clayton61d043b2011-03-22 04:00:09 +0000425 {
Greg Clayton05e4d972012-03-29 01:55:41 +0000426 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
427 {
428 lldb::pid_t pid = GetCurrentProcessID ();
429 if (pid != LLDB_INVALID_PROCESS_ID)
430 process->SetID (pid);
431 }
432 process->BuildDynamicRegisterInfo (true);
Greg Clayton61d043b2011-03-22 04:00:09 +0000433 }
Greg Clayton05e4d972012-03-29 01:55:41 +0000434
435 // Privately notify any internal threads that we have stopped
436 // in case we wanted to interrupt our process, yet we might
437 // send a packet and continue without returning control to the
438 // user.
439 m_private_is_running.SetValue (false, eBroadcastAlways);
440
441 const uint8_t signo = response.GetHexU8 (UINT8_MAX);
442
443 bool continue_after_aync = false;
444 if (m_async_signal != -1 || m_async_packet_predicate.GetValue())
445 {
446 continue_after_aync = true;
447 // We sent an interrupt packet to stop the inferior process
448 // for an async signal or to send an async packet while running
449 // but we might have been single stepping and received the
450 // stop packet for the step instead of for the interrupt packet.
451 // Typically when an interrupt is sent a SIGINT or SIGSTOP
452 // is used, so if we get anything else, we need to try and
453 // get another stop reply packet that may have been sent
454 // due to sending the interrupt when the target is stopped
455 // which will just re-send a copy of the last stop reply
456 // packet. If we don't do this, then the reply for our
457 // async packet will be the repeat stop reply packet and cause
458 // a lot of trouble for us!
459 if (signo != SIGINT && signo != SIGSTOP)
460 {
461 continue_after_aync = false;
462
463 // We didn't get a a SIGINT or SIGSTOP, so try for a
464 // very brief time (1 ms) to get another stop reply
465 // packet to make sure it doesn't get in the way
466 StringExtractorGDBRemote extra_stop_reply_packet;
467 uint32_t timeout_usec = 1000;
468 if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec))
469 {
470 switch (extra_stop_reply_packet.GetChar())
471 {
472 case 'T':
473 case 'S':
474 // We did get an extra stop reply, which means
475 // our interrupt didn't stop the target so we
476 // shouldn't continue after the async signal
477 // or packet is sent...
478 continue_after_aync = false;
479 break;
480 }
481 }
482 }
483 }
484
485 if (m_async_signal != -1)
486 {
487 if (log)
488 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
489
490 // Save off the async signal we are supposed to send
491 const int async_signal = m_async_signal;
492 // Clear the async signal member so we don't end up
493 // sending the signal multiple times...
494 m_async_signal = -1;
495 // Check which signal we stopped with
496 if (signo == async_signal)
497 {
498 if (log)
499 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
500
501 // We already stopped with a signal that we wanted
502 // to stop with, so we are done
503 }
504 else
505 {
506 // We stopped with a different signal that the one
507 // we wanted to stop with, so now we must resume
508 // with the signal we want
509 char signal_packet[32];
510 int signal_packet_len = 0;
511 signal_packet_len = ::snprintf (signal_packet,
512 sizeof (signal_packet),
513 "C%2.2x",
514 async_signal);
515
516 if (log)
517 log->Printf ("async: stopped with signal %s, resume with %s",
518 Host::GetSignalAsCString (signo),
519 Host::GetSignalAsCString (async_signal));
520
521 // Set the continue packet to resume even if the
522 // interrupt didn't cause our stop (ignore continue_after_aync)
523 continue_packet.assign(signal_packet, signal_packet_len);
524 continue;
525 }
526 }
527 else if (m_async_packet_predicate.GetValue())
528 {
529 LogSP packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
530
531 // We are supposed to send an asynchronous packet while
532 // we are running.
533 m_async_response.Clear();
534 if (m_async_packet.empty())
535 {
536 if (packet_log)
537 packet_log->Printf ("async: error: empty async packet");
538
539 }
540 else
541 {
542 if (packet_log)
543 packet_log->Printf ("async: sending packet");
544
545 SendPacketAndWaitForResponse (&m_async_packet[0],
546 m_async_packet.size(),
547 m_async_response,
548 false);
549 }
550 // Let the other thread that was trying to send the async
551 // packet know that the packet has been sent and response is
552 // ready...
553 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
554
555 if (packet_log)
556 packet_log->Printf ("async: sent packet, continue_after_aync = %i", continue_after_aync);
557
558 // Set the continue packet to resume if our interrupt
559 // for the async packet did cause the stop
560 if (continue_after_aync)
561 {
562 continue_packet.assign (1, 'c');
563 continue;
564 }
565 }
566 // Stop with signal and thread info
567 state = eStateStopped;
Greg Clayton61d043b2011-03-22 04:00:09 +0000568 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000569 break;
570
571 case 'W':
572 case 'X':
573 // process exited
574 state = eStateExited;
575 break;
576
577 case 'O':
578 // STDOUT
579 {
Greg Clayton628cead2011-05-19 03:54:16 +0000580 got_stdout = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000581 std::string inferior_stdout;
582 inferior_stdout.reserve(response.GetBytesLeft () / 2);
583 char ch;
584 while ((ch = response.GetHexU8()) != '\0')
585 inferior_stdout.append(1, ch);
586 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
587 }
588 break;
589
590 case 'E':
591 // ERROR
592 state = eStateInvalid;
593 break;
594
595 default:
596 if (log)
597 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
598 state = eStateInvalid;
599 break;
600 }
601 }
602 }
603 else
604 {
605 if (log)
606 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
607 state = eStateInvalid;
608 }
609 }
610 if (log)
611 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
612 response.SetFilePos(0);
613 m_private_is_running.SetValue (false, eBroadcastAlways);
614 m_public_is_running.SetValue (false, eBroadcastAlways);
615 return state;
616}
617
618bool
619GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
620{
Greg Clayton05e4d972012-03-29 01:55:41 +0000621 Mutex::Locker async_locker (m_async_mutex);
Greg Clayton61d043b2011-03-22 04:00:09 +0000622 m_async_signal = signo;
623 bool timed_out = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000624 Mutex::Locker locker;
Greg Clayton05e4d972012-03-29 01:55:41 +0000625 if (SendInterrupt (locker, 1, timed_out))
Greg Clayton61d043b2011-03-22 04:00:09 +0000626 return true;
627 m_async_signal = -1;
628 return false;
629}
630
631// This function takes a mutex locker as a parameter in case the GetSequenceMutex
632// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
633// (the expected result), then it will send the halt packet. If it does succeed
634// then the caller that requested the interrupt will want to keep the sequence
635// locked down so that no one else can send packets while the caller has control.
636// This function usually gets called when we are running and need to stop the
637// target. It can also be used when we are running and and we need to do something
638// else (like read/write memory), so we need to interrupt the running process
639// (gdb remote protocol requires this), and do what we need to do, then resume.
640
641bool
Greg Clayton05e4d972012-03-29 01:55:41 +0000642GDBRemoteCommunicationClient::SendInterrupt
Greg Clayton61d043b2011-03-22 04:00:09 +0000643(
644 Mutex::Locker& locker,
645 uint32_t seconds_to_wait_for_stop,
Greg Clayton61d043b2011-03-22 04:00:09 +0000646 bool &timed_out
647)
648{
Greg Clayton05e4d972012-03-29 01:55:41 +0000649 m_interrupt_sent = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000650 timed_out = false;
Greg Clayton05e4d972012-03-29 01:55:41 +0000651 LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Clayton61d043b2011-03-22 04:00:09 +0000652
653 if (IsRunning())
654 {
655 // Only send an interrupt if our debugserver is running...
656 if (GetSequenceMutex (locker) == false)
657 {
658 // Someone has the mutex locked waiting for a response or for the
659 // inferior to stop, so send the interrupt on the down low...
660 char ctrl_c = '\x03';
661 ConnectionStatus status = eConnectionStatusSuccess;
Greg Clayton61d043b2011-03-22 04:00:09 +0000662 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton05e4d972012-03-29 01:55:41 +0000663 if (log)
664 log->PutCString("send packet: \\x03");
Greg Clayton61d043b2011-03-22 04:00:09 +0000665 if (bytes_written > 0)
666 {
Greg Clayton05e4d972012-03-29 01:55:41 +0000667 m_interrupt_sent = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000668 if (seconds_to_wait_for_stop)
669 {
Greg Clayton05e4d972012-03-29 01:55:41 +0000670 TimeValue timeout;
671 if (seconds_to_wait_for_stop)
672 {
673 timeout = TimeValue::Now();
674 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
675 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000676 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
677 {
678 if (log)
Greg Clayton05e4d972012-03-29 01:55:41 +0000679 log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
Greg Clayton61d043b2011-03-22 04:00:09 +0000680 return true;
681 }
682 else
683 {
684 if (log)
Greg Clayton05e4d972012-03-29 01:55:41 +0000685 log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
Greg Clayton61d043b2011-03-22 04:00:09 +0000686 }
687 }
688 else
689 {
690 if (log)
Greg Clayton05e4d972012-03-29 01:55:41 +0000691 log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
Greg Clayton61d043b2011-03-22 04:00:09 +0000692 return true;
693 }
694 }
695 else
696 {
697 if (log)
Greg Clayton05e4d972012-03-29 01:55:41 +0000698 log->Printf ("SendInterrupt () - failed to write interrupt");
Greg Clayton61d043b2011-03-22 04:00:09 +0000699 }
700 return false;
701 }
702 else
703 {
704 if (log)
Greg Clayton05e4d972012-03-29 01:55:41 +0000705 log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
Greg Clayton61d043b2011-03-22 04:00:09 +0000706 }
707 }
Greg Clayton05e4d972012-03-29 01:55:41 +0000708 else
709 {
710 if (log)
711 log->Printf ("SendInterrupt () - not running");
712 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000713 return true;
714}
715
716lldb::pid_t
717GDBRemoteCommunicationClient::GetCurrentProcessID ()
718{
719 StringExtractorGDBRemote response;
720 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
721 {
722 if (response.GetChar() == 'Q')
723 if (response.GetChar() == 'C')
724 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
725 }
726 return LLDB_INVALID_PROCESS_ID;
727}
728
729bool
730GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
731{
732 error_str.clear();
733 StringExtractorGDBRemote response;
734 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
735 {
736 if (response.IsOKResponse())
737 return true;
738 if (response.GetChar() == 'E')
739 {
740 // A string the describes what failed when launching...
741 error_str = response.GetStringRef().substr(1);
742 }
743 else
744 {
745 error_str.assign ("unknown error occurred launching process");
746 }
747 }
748 else
749 {
750 error_str.assign ("failed to send the qLaunchSuccess packet");
751 }
752 return false;
753}
754
755int
756GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
757{
758 if (argv && argv[0])
759 {
760 StreamString packet;
761 packet.PutChar('A');
762 const char *arg;
763 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
764 {
765 const int arg_len = strlen(arg);
766 if (i > 0)
767 packet.PutChar(',');
768 packet.Printf("%i,%i,", arg_len * 2, i);
769 packet.PutBytesAsRawHex8 (arg, arg_len);
770 }
771
772 StringExtractorGDBRemote response;
773 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
774 {
775 if (response.IsOKResponse())
776 return 0;
777 uint8_t error = response.GetError();
778 if (error)
779 return error;
780 }
781 }
782 return -1;
783}
784
785int
786GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
787{
788 if (name_equal_value && name_equal_value[0])
789 {
790 StreamString packet;
791 packet.Printf("QEnvironment:%s", name_equal_value);
792 StringExtractorGDBRemote response;
793 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
794 {
795 if (response.IsOKResponse())
796 return 0;
797 uint8_t error = response.GetError();
798 if (error)
799 return error;
800 }
801 }
802 return -1;
803}
804
Greg Claytona4582402011-05-08 04:53:50 +0000805int
806GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
807{
808 if (arch && arch[0])
809 {
810 StreamString packet;
811 packet.Printf("QLaunchArch:%s", arch);
812 StringExtractorGDBRemote response;
813 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
814 {
815 if (response.IsOKResponse())
816 return 0;
817 uint8_t error = response.GetError();
818 if (error)
819 return error;
820 }
821 }
822 return -1;
823}
824
Greg Clayton61d043b2011-03-22 04:00:09 +0000825bool
Greg Clayton58e26e02011-03-24 04:28:38 +0000826GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
827 uint32_t &minor,
828 uint32_t &update)
829{
830 if (GetHostInfo ())
831 {
832 if (m_os_version_major != UINT32_MAX)
833 {
834 major = m_os_version_major;
835 minor = m_os_version_minor;
836 update = m_os_version_update;
837 return true;
838 }
839 }
840 return false;
841}
842
843bool
844GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
845{
846 if (GetHostInfo ())
847 {
848 if (!m_os_build.empty())
849 {
850 s = m_os_build;
851 return true;
852 }
853 }
854 s.clear();
855 return false;
856}
857
858
859bool
860GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
861{
862 if (GetHostInfo ())
863 {
864 if (!m_os_kernel.empty())
865 {
866 s = m_os_kernel;
867 return true;
868 }
869 }
870 s.clear();
871 return false;
872}
873
874bool
875GDBRemoteCommunicationClient::GetHostname (std::string &s)
876{
877 if (GetHostInfo ())
878 {
879 if (!m_hostname.empty())
880 {
881 s = m_hostname;
882 return true;
883 }
884 }
885 s.clear();
886 return false;
887}
888
889ArchSpec
890GDBRemoteCommunicationClient::GetSystemArchitecture ()
891{
892 if (GetHostInfo ())
893 return m_host_arch;
894 return ArchSpec();
895}
896
897
898bool
Greg Clayton06d7cc82011-04-04 18:18:57 +0000899GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton61d043b2011-03-22 04:00:09 +0000900{
Greg Clayton06d7cc82011-04-04 18:18:57 +0000901 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +0000902 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000903 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton61d043b2011-03-22 04:00:09 +0000904 StringExtractorGDBRemote response;
905 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
906 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +0000907 if (response.IsNormalResponse())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000908 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000909 std::string name;
910 std::string value;
911 uint32_t cpu = LLDB_INVALID_CPUTYPE;
912 uint32_t sub = 0;
913 std::string arch_name;
914 std::string os_name;
915 std::string vendor_name;
916 std::string triple;
917 uint32_t pointer_byte_size = 0;
918 StringExtractor extractor;
919 ByteOrder byte_order = eByteOrderInvalid;
920 uint32_t num_keys_decoded = 0;
921 while (response.GetNameColonValue(name, value))
Greg Claytoncb8977d2011-03-23 00:09:55 +0000922 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000923 if (name.compare("cputype") == 0)
Greg Clayton58e26e02011-03-24 04:28:38 +0000924 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000925 // exception type in big endian hex
926 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
927 if (cpu != LLDB_INVALID_CPUTYPE)
928 ++num_keys_decoded;
929 }
930 else if (name.compare("cpusubtype") == 0)
931 {
932 // exception count in big endian hex
933 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
934 if (sub != 0)
935 ++num_keys_decoded;
936 }
937 else if (name.compare("arch") == 0)
938 {
939 arch_name.swap (value);
940 ++num_keys_decoded;
941 }
942 else if (name.compare("triple") == 0)
943 {
944 // The triple comes as ASCII hex bytes since it contains '-' chars
945 extractor.GetStringRef().swap(value);
946 extractor.SetFilePos(0);
947 extractor.GetHexByteString (triple);
948 ++num_keys_decoded;
949 }
950 else if (name.compare("os_build") == 0)
951 {
952 extractor.GetStringRef().swap(value);
953 extractor.SetFilePos(0);
954 extractor.GetHexByteString (m_os_build);
955 ++num_keys_decoded;
956 }
957 else if (name.compare("hostname") == 0)
958 {
959 extractor.GetStringRef().swap(value);
960 extractor.SetFilePos(0);
961 extractor.GetHexByteString (m_hostname);
962 ++num_keys_decoded;
963 }
964 else if (name.compare("os_kernel") == 0)
965 {
966 extractor.GetStringRef().swap(value);
967 extractor.SetFilePos(0);
968 extractor.GetHexByteString (m_os_kernel);
969 ++num_keys_decoded;
970 }
971 else if (name.compare("ostype") == 0)
972 {
973 os_name.swap (value);
974 ++num_keys_decoded;
975 }
976 else if (name.compare("vendor") == 0)
977 {
978 vendor_name.swap(value);
979 ++num_keys_decoded;
980 }
981 else if (name.compare("endian") == 0)
982 {
983 ++num_keys_decoded;
984 if (value.compare("little") == 0)
985 byte_order = eByteOrderLittle;
986 else if (value.compare("big") == 0)
987 byte_order = eByteOrderBig;
988 else if (value.compare("pdp") == 0)
989 byte_order = eByteOrderPDP;
990 else
991 --num_keys_decoded;
992 }
993 else if (name.compare("ptrsize") == 0)
994 {
995 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
996 if (pointer_byte_size != 0)
997 ++num_keys_decoded;
998 }
999 else if (name.compare("os_version") == 0)
1000 {
1001 Args::StringToVersion (value.c_str(),
1002 m_os_version_major,
1003 m_os_version_minor,
1004 m_os_version_update);
1005 if (m_os_version_major != UINT32_MAX)
1006 ++num_keys_decoded;
1007 }
1008 }
1009
1010 if (num_keys_decoded > 0)
1011 m_qHostInfo_is_valid = eLazyBoolYes;
1012
1013 if (triple.empty())
1014 {
1015 if (arch_name.empty())
1016 {
1017 if (cpu != LLDB_INVALID_CPUTYPE)
1018 {
1019 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
1020 if (pointer_byte_size)
1021 {
1022 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1023 }
1024 if (byte_order != eByteOrderInvalid)
1025 {
1026 assert (byte_order == m_host_arch.GetByteOrder());
1027 }
1028 if (!vendor_name.empty())
1029 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
1030 if (!os_name.empty())
Greg Clayton89798cc2011-09-15 00:21:03 +00001031 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001032
1033 }
1034 }
1035 else
1036 {
1037 std::string triple;
1038 triple += arch_name;
1039 triple += '-';
1040 if (vendor_name.empty())
1041 triple += "unknown";
1042 else
1043 triple += vendor_name;
1044 triple += '-';
1045 if (os_name.empty())
1046 triple += "unknown";
1047 else
1048 triple += os_name;
Greg Claytonf15996e2011-04-07 22:46:35 +00001049 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Clayton58e26e02011-03-24 04:28:38 +00001050 if (pointer_byte_size)
1051 {
1052 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1053 }
1054 if (byte_order != eByteOrderInvalid)
1055 {
1056 assert (byte_order == m_host_arch.GetByteOrder());
1057 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001058
Greg Clayton58e26e02011-03-24 04:28:38 +00001059 }
1060 }
1061 else
1062 {
Greg Claytonf15996e2011-04-07 22:46:35 +00001063 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Claytoncb8977d2011-03-23 00:09:55 +00001064 if (pointer_byte_size)
1065 {
1066 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1067 }
1068 if (byte_order != eByteOrderInvalid)
1069 {
1070 assert (byte_order == m_host_arch.GetByteOrder());
1071 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001072 }
Greg Claytoncb8977d2011-03-23 00:09:55 +00001073 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001074 }
1075 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001076 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton61d043b2011-03-22 04:00:09 +00001077}
1078
1079int
1080GDBRemoteCommunicationClient::SendAttach
1081(
1082 lldb::pid_t pid,
1083 StringExtractorGDBRemote& response
1084)
1085{
1086 if (pid != LLDB_INVALID_PROCESS_ID)
1087 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001088 char packet[64];
Greg Claytond9919d32011-12-01 23:28:38 +00001089 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%llx", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001090 assert (packet_len < sizeof(packet));
1091 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001092 {
1093 if (response.IsErrorResponse())
1094 return response.GetError();
1095 return 0;
1096 }
1097 }
1098 return -1;
1099}
1100
1101const lldb_private::ArchSpec &
1102GDBRemoteCommunicationClient::GetHostArchitecture ()
1103{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001104 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +00001105 GetHostInfo ();
Greg Claytoncb8977d2011-03-23 00:09:55 +00001106 return m_host_arch;
Greg Clayton61d043b2011-03-22 04:00:09 +00001107}
1108
1109addr_t
1110GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1111{
Greg Clayton2f085c62011-05-15 01:25:55 +00001112 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001113 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001114 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001115 char packet[64];
1116 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1117 permissions & lldb::ePermissionsReadable ? "r" : "",
1118 permissions & lldb::ePermissionsWritable ? "w" : "",
1119 permissions & lldb::ePermissionsExecutable ? "x" : "");
1120 assert (packet_len < sizeof(packet));
1121 StringExtractorGDBRemote response;
1122 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1123 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001124 if (!response.IsErrorResponse())
Greg Clayton989816b2011-05-14 01:50:35 +00001125 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1126 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001127 else
1128 {
1129 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1130 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001131 }
1132 return LLDB_INVALID_ADDRESS;
1133}
1134
1135bool
1136GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1137{
Greg Clayton2f085c62011-05-15 01:25:55 +00001138 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001139 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001140 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001141 char packet[64];
1142 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1143 assert (packet_len < sizeof(packet));
1144 StringExtractorGDBRemote response;
1145 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1146 {
1147 if (response.IsOKResponse())
1148 return true;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001149 }
1150 else
1151 {
1152 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton989816b2011-05-14 01:50:35 +00001153 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001154 }
1155 return false;
1156}
1157
Greg Claytona9385532011-11-18 07:03:08 +00001158Error
1159GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
1160 lldb_private::MemoryRegionInfo &region_info)
1161{
1162 Error error;
1163 region_info.Clear();
1164
1165 if (m_supports_memory_region_info != eLazyBoolNo)
1166 {
1167 m_supports_memory_region_info = eLazyBoolYes;
1168 char packet[64];
1169 const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%llx", (uint64_t)addr);
1170 assert (packet_len < sizeof(packet));
1171 StringExtractorGDBRemote response;
1172 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1173 {
1174 std::string name;
1175 std::string value;
1176 addr_t addr_value;
1177 bool success = true;
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001178 bool saw_permissions = false;
Greg Claytona9385532011-11-18 07:03:08 +00001179 while (success && response.GetNameColonValue(name, value))
1180 {
1181 if (name.compare ("start") == 0)
1182 {
1183 addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
1184 if (success)
1185 region_info.GetRange().SetRangeBase(addr_value);
1186 }
1187 else if (name.compare ("size") == 0)
1188 {
1189 addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
1190 if (success)
1191 region_info.GetRange().SetByteSize (addr_value);
1192 }
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001193 else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
Greg Claytona9385532011-11-18 07:03:08 +00001194 {
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001195 saw_permissions = true;
1196 if (region_info.GetRange().Contains (addr))
1197 {
1198 if (value.find('r') != std::string::npos)
1199 region_info.SetReadable (MemoryRegionInfo::eYes);
1200 else
1201 region_info.SetReadable (MemoryRegionInfo::eNo);
1202
1203 if (value.find('w') != std::string::npos)
1204 region_info.SetWritable (MemoryRegionInfo::eYes);
1205 else
1206 region_info.SetWritable (MemoryRegionInfo::eNo);
1207
1208 if (value.find('x') != std::string::npos)
1209 region_info.SetExecutable (MemoryRegionInfo::eYes);
1210 else
1211 region_info.SetExecutable (MemoryRegionInfo::eNo);
1212 }
1213 else
1214 {
1215 // The reported region does not contain this address -- we're looking at an unmapped page
1216 region_info.SetReadable (MemoryRegionInfo::eNo);
1217 region_info.SetWritable (MemoryRegionInfo::eNo);
1218 region_info.SetExecutable (MemoryRegionInfo::eNo);
1219 }
Greg Claytona9385532011-11-18 07:03:08 +00001220 }
1221 else if (name.compare ("error") == 0)
1222 {
1223 StringExtractorGDBRemote name_extractor;
1224 // Swap "value" over into "name_extractor"
1225 name_extractor.GetStringRef().swap(value);
1226 // Now convert the HEX bytes into a string value
1227 name_extractor.GetHexByteString (value);
1228 error.SetErrorString(value.c_str());
1229 }
1230 }
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001231
1232 // We got a valid address range back but no permissions -- which means this is an unmapped page
1233 if (region_info.GetRange().IsValid() && saw_permissions == false)
1234 {
1235 region_info.SetReadable (MemoryRegionInfo::eNo);
1236 region_info.SetWritable (MemoryRegionInfo::eNo);
1237 region_info.SetExecutable (MemoryRegionInfo::eNo);
1238 }
Greg Claytona9385532011-11-18 07:03:08 +00001239 }
1240 else
1241 {
1242 m_supports_memory_region_info = eLazyBoolNo;
1243 }
1244 }
1245
1246 if (m_supports_memory_region_info == eLazyBoolNo)
1247 {
1248 error.SetErrorString("qMemoryRegionInfo is not supported");
1249 }
1250 if (error.Fail())
1251 region_info.Clear();
1252 return error;
1253
1254}
1255
1256
Greg Clayton61d043b2011-03-22 04:00:09 +00001257int
1258GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1259{
1260 if (path && path[0])
1261 {
1262 StreamString packet;
1263 packet.PutCString("QSetSTDIN:");
1264 packet.PutBytesAsRawHex8(path, strlen(path));
1265
1266 StringExtractorGDBRemote response;
1267 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1268 {
1269 if (response.IsOKResponse())
1270 return 0;
1271 uint8_t error = response.GetError();
1272 if (error)
1273 return error;
1274 }
1275 }
1276 return -1;
1277}
1278
1279int
1280GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1281{
1282 if (path && path[0])
1283 {
1284 StreamString packet;
1285 packet.PutCString("QSetSTDOUT:");
1286 packet.PutBytesAsRawHex8(path, strlen(path));
1287
1288 StringExtractorGDBRemote response;
1289 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1290 {
1291 if (response.IsOKResponse())
1292 return 0;
1293 uint8_t error = response.GetError();
1294 if (error)
1295 return error;
1296 }
1297 }
1298 return -1;
1299}
1300
1301int
1302GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1303{
1304 if (path && path[0])
1305 {
1306 StreamString packet;
1307 packet.PutCString("QSetSTDERR:");
1308 packet.PutBytesAsRawHex8(path, strlen(path));
1309
1310 StringExtractorGDBRemote response;
1311 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1312 {
1313 if (response.IsOKResponse())
1314 return 0;
1315 uint8_t error = response.GetError();
1316 if (error)
1317 return error;
1318 }
1319 }
1320 return -1;
1321}
1322
1323int
1324GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1325{
1326 if (path && path[0])
1327 {
1328 StreamString packet;
1329 packet.PutCString("QSetWorkingDir:");
1330 packet.PutBytesAsRawHex8(path, strlen(path));
1331
1332 StringExtractorGDBRemote response;
1333 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1334 {
1335 if (response.IsOKResponse())
1336 return 0;
1337 uint8_t error = response.GetError();
1338 if (error)
1339 return error;
1340 }
1341 }
1342 return -1;
1343}
1344
1345int
1346GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1347{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001348 char packet[32];
1349 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1350 assert (packet_len < sizeof(packet));
Greg Clayton61d043b2011-03-22 04:00:09 +00001351 StringExtractorGDBRemote response;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001352 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001353 {
1354 if (response.IsOKResponse())
1355 return 0;
1356 uint8_t error = response.GetError();
1357 if (error)
1358 return error;
1359 }
1360 return -1;
1361}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001362
1363bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001364GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001365{
1366 if (response.IsNormalResponse())
1367 {
1368 std::string name;
1369 std::string value;
1370 StringExtractor extractor;
1371
1372 while (response.GetNameColonValue(name, value))
1373 {
1374 if (name.compare("pid") == 0)
1375 {
1376 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1377 }
1378 else if (name.compare("ppid") == 0)
1379 {
1380 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1381 }
1382 else if (name.compare("uid") == 0)
1383 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001384 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001385 }
1386 else if (name.compare("euid") == 0)
1387 {
1388 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1389 }
1390 else if (name.compare("gid") == 0)
1391 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001392 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001393 }
1394 else if (name.compare("egid") == 0)
1395 {
1396 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1397 }
1398 else if (name.compare("triple") == 0)
1399 {
1400 // The triple comes as ASCII hex bytes since it contains '-' chars
1401 extractor.GetStringRef().swap(value);
1402 extractor.SetFilePos(0);
1403 extractor.GetHexByteString (value);
Greg Claytonf15996e2011-04-07 22:46:35 +00001404 process_info.GetArchitecture ().SetTriple (value.c_str(), NULL);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001405 }
1406 else if (name.compare("name") == 0)
1407 {
1408 StringExtractor extractor;
1409 // The the process name from ASCII hex bytes since we can't
1410 // control the characters in a process name
1411 extractor.GetStringRef().swap(value);
1412 extractor.SetFilePos(0);
1413 extractor.GetHexByteString (value);
Greg Clayton527154d2011-11-15 03:53:30 +00001414 process_info.GetExecutableFile().SetFile (value.c_str(), false);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001415 }
1416 }
1417
1418 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1419 return true;
1420 }
1421 return false;
1422}
1423
1424bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001425GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001426{
1427 process_info.Clear();
1428
1429 if (m_supports_qProcessInfoPID)
1430 {
1431 char packet[32];
Greg Claytond9919d32011-12-01 23:28:38 +00001432 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%llu", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001433 assert (packet_len < sizeof(packet));
1434 StringExtractorGDBRemote response;
1435 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1436 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001437 return DecodeProcessInfoResponse (response, process_info);
1438 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001439 else
1440 {
1441 m_supports_qProcessInfoPID = false;
1442 return false;
1443 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001444 }
1445 return false;
1446}
1447
1448uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +00001449GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1450 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001451{
1452 process_infos.Clear();
1453
1454 if (m_supports_qfProcessInfo)
1455 {
1456 StreamString packet;
1457 packet.PutCString ("qfProcessInfo");
1458 if (!match_info.MatchAllProcesses())
1459 {
1460 packet.PutChar (':');
1461 const char *name = match_info.GetProcessInfo().GetName();
1462 bool has_name_match = false;
1463 if (name && name[0])
1464 {
1465 has_name_match = true;
1466 NameMatchType name_match_type = match_info.GetNameMatchType();
1467 switch (name_match_type)
1468 {
1469 case eNameMatchIgnore:
1470 has_name_match = false;
1471 break;
1472
1473 case eNameMatchEquals:
1474 packet.PutCString ("name_match:equals;");
1475 break;
1476
1477 case eNameMatchContains:
1478 packet.PutCString ("name_match:contains;");
1479 break;
1480
1481 case eNameMatchStartsWith:
1482 packet.PutCString ("name_match:starts_with;");
1483 break;
1484
1485 case eNameMatchEndsWith:
1486 packet.PutCString ("name_match:ends_with;");
1487 break;
1488
1489 case eNameMatchRegularExpression:
1490 packet.PutCString ("name_match:regex;");
1491 break;
1492 }
1493 if (has_name_match)
1494 {
1495 packet.PutCString ("name:");
1496 packet.PutBytesAsRawHex8(name, ::strlen(name));
1497 packet.PutChar (';');
1498 }
1499 }
1500
1501 if (match_info.GetProcessInfo().ProcessIDIsValid())
Greg Claytond9919d32011-12-01 23:28:38 +00001502 packet.Printf("pid:%llu;",match_info.GetProcessInfo().GetProcessID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001503 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
Greg Claytond9919d32011-12-01 23:28:38 +00001504 packet.Printf("parent_pid:%llu;",match_info.GetProcessInfo().GetParentProcessID());
Greg Claytonb72d0f02011-04-12 05:54:46 +00001505 if (match_info.GetProcessInfo().UserIDIsValid())
1506 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
1507 if (match_info.GetProcessInfo().GroupIDIsValid())
1508 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001509 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
1510 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
1511 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1512 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
1513 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1514 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
1515 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
1516 {
1517 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
1518 const llvm::Triple &triple = match_arch.GetTriple();
1519 packet.PutCString("triple:");
1520 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
1521 packet.PutChar (';');
1522 }
1523 }
1524 StringExtractorGDBRemote response;
1525 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1526 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001527 do
1528 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001529 ProcessInstanceInfo process_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001530 if (!DecodeProcessInfoResponse (response, process_info))
1531 break;
1532 process_infos.Append(process_info);
1533 response.GetStringRef().clear();
1534 response.SetFilePos(0);
1535 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
1536 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001537 else
1538 {
1539 m_supports_qfProcessInfo = false;
1540 return 0;
1541 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001542 }
1543 return process_infos.GetSize();
1544
1545}
1546
1547bool
1548GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
1549{
1550 if (m_supports_qUserName)
1551 {
1552 char packet[32];
1553 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
1554 assert (packet_len < sizeof(packet));
1555 StringExtractorGDBRemote response;
1556 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1557 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001558 if (response.IsNormalResponse())
1559 {
1560 // Make sure we parsed the right number of characters. The response is
1561 // the hex encoded user name and should make up the entire packet.
1562 // If there are any non-hex ASCII bytes, the length won't match below..
1563 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1564 return true;
1565 }
1566 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001567 else
1568 {
1569 m_supports_qUserName = false;
1570 return false;
1571 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001572 }
1573 return false;
1574
1575}
1576
1577bool
1578GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
1579{
1580 if (m_supports_qGroupName)
1581 {
1582 char packet[32];
1583 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
1584 assert (packet_len < sizeof(packet));
1585 StringExtractorGDBRemote response;
1586 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1587 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001588 if (response.IsNormalResponse())
1589 {
1590 // Make sure we parsed the right number of characters. The response is
1591 // the hex encoded group name and should make up the entire packet.
1592 // If there are any non-hex ASCII bytes, the length won't match below..
1593 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1594 return true;
1595 }
1596 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001597 else
1598 {
1599 m_supports_qGroupName = false;
1600 return false;
1601 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001602 }
1603 return false;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001604}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001605
Greg Clayton06d7cc82011-04-04 18:18:57 +00001606void
1607GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
1608{
1609 uint32_t i;
1610 TimeValue start_time, end_time;
1611 uint64_t total_time_nsec;
1612 float packets_per_second;
1613 if (SendSpeedTestPacket (0, 0))
1614 {
1615 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
1616 {
1617 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
1618 {
1619 start_time = TimeValue::Now();
1620 for (i=0; i<num_packets; ++i)
1621 {
1622 SendSpeedTestPacket (send_size, recv_size);
1623 }
1624 end_time = TimeValue::Now();
1625 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001626 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton153ccd72011-08-10 02:10:13 +00001627 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%9.9llu sec for %f packets/sec.\n",
Greg Clayton06d7cc82011-04-04 18:18:57 +00001628 num_packets,
1629 send_size,
1630 recv_size,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001631 total_time_nsec / TimeValue::NanoSecPerSec,
1632 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001633 packets_per_second);
1634 if (recv_size == 0)
1635 recv_size = 32;
1636 }
1637 if (send_size == 0)
1638 send_size = 32;
1639 }
1640 }
1641 else
1642 {
1643 start_time = TimeValue::Now();
1644 for (i=0; i<num_packets; ++i)
1645 {
1646 GetCurrentProcessID ();
1647 }
1648 end_time = TimeValue::Now();
1649 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001650 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton153ccd72011-08-10 02:10:13 +00001651 printf ("%u 'qC' packets packets in 0x%llu%9.9llu sec for %f packets/sec.\n",
Greg Clayton06d7cc82011-04-04 18:18:57 +00001652 num_packets,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001653 total_time_nsec / TimeValue::NanoSecPerSec,
1654 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001655 packets_per_second);
1656 }
1657}
1658
1659bool
1660GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
1661{
1662 StreamString packet;
1663 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
1664 uint32_t bytes_left = send_size;
1665 while (bytes_left > 0)
1666 {
1667 if (bytes_left >= 26)
1668 {
1669 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
1670 bytes_left -= 26;
1671 }
1672 else
1673 {
1674 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
1675 bytes_left = 0;
1676 }
1677 }
1678
1679 StringExtractorGDBRemote response;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001680 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001681 return false;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001682}
Greg Claytonb72d0f02011-04-12 05:54:46 +00001683
1684uint16_t
1685GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
1686{
1687 StringExtractorGDBRemote response;
1688 if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
1689 {
1690 std::string name;
1691 std::string value;
1692 uint16_t port = 0;
1693 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1694 while (response.GetNameColonValue(name, value))
1695 {
1696 if (name.size() == 4 && name.compare("port") == 0)
1697 port = Args::StringToUInt32(value.c_str(), 0, 0);
1698 if (name.size() == 3 && name.compare("pid") == 0)
1699 pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
1700 }
1701 return port;
1702 }
1703 return 0;
1704}
1705
1706bool
1707GDBRemoteCommunicationClient::SetCurrentThread (int tid)
1708{
1709 if (m_curr_tid == tid)
1710 return true;
1711
1712 char packet[32];
1713 int packet_len;
1714 if (tid <= 0)
1715 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
1716 else
1717 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
1718 assert (packet_len + 1 < sizeof(packet));
1719 StringExtractorGDBRemote response;
1720 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1721 {
1722 if (response.IsOKResponse())
1723 {
1724 m_curr_tid = tid;
1725 return true;
1726 }
1727 }
1728 return false;
1729}
1730
1731bool
1732GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
1733{
1734 if (m_curr_tid_run == tid)
1735 return true;
1736
1737 char packet[32];
1738 int packet_len;
1739 if (tid <= 0)
1740 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
1741 else
1742 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
1743
1744 assert (packet_len + 1 < sizeof(packet));
1745 StringExtractorGDBRemote response;
1746 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1747 {
1748 if (response.IsOKResponse())
1749 {
1750 m_curr_tid_run = tid;
1751 return true;
1752 }
1753 }
1754 return false;
1755}
1756
1757bool
1758GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
1759{
1760 if (SendPacketAndWaitForResponse("?", 1, response, false))
1761 return response.IsNormalResponse();
1762 return false;
1763}
1764
1765bool
1766GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
1767{
1768 if (m_supports_qThreadStopInfo)
1769 {
1770 char packet[256];
1771 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
1772 assert (packet_len < sizeof(packet));
1773 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1774 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001775 if (response.IsNormalResponse())
Greg Claytonb72d0f02011-04-12 05:54:46 +00001776 return true;
1777 else
1778 return false;
1779 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001780 else
1781 {
1782 m_supports_qThreadStopInfo = false;
1783 }
Greg Claytonb72d0f02011-04-12 05:54:46 +00001784 }
Greg Clayton139da722011-05-20 03:15:54 +00001785// if (SetCurrentThread (tid))
1786// return GetStopReply (response);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001787 return false;
1788}
1789
1790
1791uint8_t
1792GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
1793{
1794 switch (type)
1795 {
1796 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
1797 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
1798 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
1799 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
1800 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
1801 default: return UINT8_MAX;
1802 }
1803
1804 char packet[64];
1805 const int packet_len = ::snprintf (packet,
1806 sizeof(packet),
1807 "%c%i,%llx,%x",
1808 insert ? 'Z' : 'z',
1809 type,
1810 addr,
1811 length);
1812
1813 assert (packet_len + 1 < sizeof(packet));
1814 StringExtractorGDBRemote response;
1815 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
1816 {
1817 if (response.IsOKResponse())
1818 return 0;
Greg Claytonb72d0f02011-04-12 05:54:46 +00001819 else if (response.IsErrorResponse())
1820 return response.GetError();
1821 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001822 else
1823 {
1824 switch (type)
1825 {
1826 case eBreakpointSoftware: m_supports_z0 = false; break;
1827 case eBreakpointHardware: m_supports_z1 = false; break;
1828 case eWatchpointWrite: m_supports_z2 = false; break;
1829 case eWatchpointRead: m_supports_z3 = false; break;
1830 case eWatchpointReadWrite: m_supports_z4 = false; break;
1831 default: break;
1832 }
1833 }
1834
Greg Claytonb72d0f02011-04-12 05:54:46 +00001835 return UINT8_MAX;
1836}
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001837
1838size_t
1839GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
1840 bool &sequence_mutex_unavailable)
1841{
1842 Mutex::Locker locker;
1843 thread_ids.clear();
1844
1845 if (GetSequenceMutex (locker))
1846 {
1847 sequence_mutex_unavailable = false;
1848 StringExtractorGDBRemote response;
1849
Greg Clayton63afdb02011-06-17 01:22:15 +00001850 for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001851 response.IsNormalResponse();
Greg Clayton63afdb02011-06-17 01:22:15 +00001852 SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()))
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001853 {
1854 char ch = response.GetChar();
1855 if (ch == 'l')
1856 break;
1857 if (ch == 'm')
1858 {
1859 do
1860 {
1861 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1862
1863 if (tid != LLDB_INVALID_THREAD_ID)
1864 {
1865 thread_ids.push_back (tid);
1866 }
1867 ch = response.GetChar(); // Skip the command separator
1868 } while (ch == ','); // Make sure we got a comma separator
1869 }
1870 }
1871 }
1872 else
1873 {
1874 sequence_mutex_unavailable = true;
1875 }
1876 return thread_ids.size();
1877}