blob: 5e685e000c7678e41e6896d5629e2a980506555b [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 Clayton989816b2011-05-14 01:50:35 +000048 m_supports__m (eLazyBoolCalculate),
49 m_supports__M (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{
72 m_rx_packet_listener.StartListeningForEvents(this,
73 Communication::eBroadcastBitPacketAvailable |
74 Communication::eBroadcastBitReadThreadDidExit);
75}
76
77//----------------------------------------------------------------------
78// Destructor
79//----------------------------------------------------------------------
80GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
81{
82 m_rx_packet_listener.StopListeningForEvents(this,
83 Communication::eBroadcastBitPacketAvailable |
84 Communication::eBroadcastBitReadThreadDidExit);
85 if (IsConnected())
86 {
87 StopReadThread();
88 Disconnect();
89 }
90}
91
92bool
Greg Clayton58e26e02011-03-24 04:28:38 +000093GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
94{
95 // Start the read thread after we send the handshake ack since if we
96 // fail to send the handshake ack, there is no reason to continue...
97 if (SendAck())
98 return StartReadThread (error_ptr);
99
100 if (error_ptr)
101 error_ptr->SetErrorString("failed to send the handshake ack");
102 return false;
103}
104
105void
106GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton61d043b2011-03-22 04:00:09 +0000107{
108 if (m_supports_not_sending_acks == eLazyBoolCalculate)
109 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000110 m_send_acks = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000111 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton58e26e02011-03-24 04:28:38 +0000112
113 StringExtractorGDBRemote response;
Greg Clayton61d043b2011-03-22 04:00:09 +0000114 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
115 {
116 if (response.IsOKResponse())
Greg Clayton58e26e02011-03-24 04:28:38 +0000117 {
118 m_send_acks = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000119 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton58e26e02011-03-24 04:28:38 +0000120 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000121 }
122 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000123}
124
125void
126GDBRemoteCommunicationClient::ResetDiscoverableSettings()
127{
128 m_supports_not_sending_acks = eLazyBoolCalculate;
129 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton61d043b2011-03-22 04:00:09 +0000130 m_supports_vCont_c = eLazyBoolCalculate;
131 m_supports_vCont_C = eLazyBoolCalculate;
132 m_supports_vCont_s = eLazyBoolCalculate;
133 m_supports_vCont_S = eLazyBoolCalculate;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000134 m_qHostInfo_is_valid = eLazyBoolCalculate;
Greg Clayton989816b2011-05-14 01:50:35 +0000135 m_supports__m = eLazyBoolCalculate;
136 m_supports__M = eLazyBoolCalculate;
137
Greg Clayton24bc5d92011-03-30 18:16:51 +0000138 m_supports_qProcessInfoPID = true;
139 m_supports_qfProcessInfo = true;
140 m_supports_qUserName = true;
141 m_supports_qGroupName = true;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000142 m_supports_qThreadStopInfo = true;
143 m_supports_z0 = true;
144 m_supports_z1 = true;
145 m_supports_z2 = true;
146 m_supports_z3 = true;
147 m_supports_z4 = true;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000148 m_host_arch.Clear();
Greg Clayton61d043b2011-03-22 04:00:09 +0000149}
150
151
152bool
153GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
154{
155 if (m_supports_thread_suffix == eLazyBoolCalculate)
156 {
157 StringExtractorGDBRemote response;
158 m_supports_thread_suffix = eLazyBoolNo;
159 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
160 {
161 if (response.IsOKResponse())
162 m_supports_thread_suffix = eLazyBoolYes;
163 }
164 }
165 return m_supports_thread_suffix;
166}
167bool
168GDBRemoteCommunicationClient::GetVContSupported (char flavor)
169{
170 if (m_supports_vCont_c == eLazyBoolCalculate)
171 {
172 StringExtractorGDBRemote response;
173 m_supports_vCont_any = eLazyBoolNo;
174 m_supports_vCont_all = eLazyBoolNo;
175 m_supports_vCont_c = eLazyBoolNo;
176 m_supports_vCont_C = eLazyBoolNo;
177 m_supports_vCont_s = eLazyBoolNo;
178 m_supports_vCont_S = eLazyBoolNo;
179 if (SendPacketAndWaitForResponse("vCont?", response, false))
180 {
181 const char *response_cstr = response.GetStringRef().c_str();
182 if (::strstr (response_cstr, ";c"))
183 m_supports_vCont_c = eLazyBoolYes;
184
185 if (::strstr (response_cstr, ";C"))
186 m_supports_vCont_C = eLazyBoolYes;
187
188 if (::strstr (response_cstr, ";s"))
189 m_supports_vCont_s = eLazyBoolYes;
190
191 if (::strstr (response_cstr, ";S"))
192 m_supports_vCont_S = eLazyBoolYes;
193
194 if (m_supports_vCont_c == eLazyBoolYes &&
195 m_supports_vCont_C == eLazyBoolYes &&
196 m_supports_vCont_s == eLazyBoolYes &&
197 m_supports_vCont_S == eLazyBoolYes)
198 {
199 m_supports_vCont_all = eLazyBoolYes;
200 }
201
202 if (m_supports_vCont_c == eLazyBoolYes ||
203 m_supports_vCont_C == eLazyBoolYes ||
204 m_supports_vCont_s == eLazyBoolYes ||
205 m_supports_vCont_S == eLazyBoolYes)
206 {
207 m_supports_vCont_any = eLazyBoolYes;
208 }
209 }
210 }
211
212 switch (flavor)
213 {
214 case 'a': return m_supports_vCont_any;
215 case 'A': return m_supports_vCont_all;
216 case 'c': return m_supports_vCont_c;
217 case 'C': return m_supports_vCont_C;
218 case 's': return m_supports_vCont_s;
219 case 'S': return m_supports_vCont_S;
220 default: break;
221 }
222 return false;
223}
224
225
226size_t
227GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
228(
229 const char *payload,
230 StringExtractorGDBRemote &response,
231 bool send_async
232)
233{
234 return SendPacketAndWaitForResponse (payload,
235 ::strlen (payload),
236 response,
237 send_async);
238}
239
240size_t
241GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
242(
243 const char *payload,
244 size_t payload_length,
245 StringExtractorGDBRemote &response,
246 bool send_async
247)
248{
249 Mutex::Locker locker;
250 TimeValue timeout_time;
251 timeout_time = TimeValue::Now();
252 timeout_time.OffsetWithSeconds (m_packet_timeout);
253 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
254
255 if (GetSequenceMutex (locker))
256 {
257 if (SendPacketNoLock (payload, strlen(payload)))
258 return WaitForPacketNoLock (response, &timeout_time);
259 }
260 else
261 {
262 if (send_async)
263 {
264 Mutex::Locker async_locker (m_async_mutex);
265 m_async_packet.assign(payload, payload_length);
266 m_async_packet_predicate.SetValue (true, eBroadcastNever);
267
268 if (log)
269 log->Printf ("async: async packet = %s", m_async_packet.c_str());
270
271 bool timed_out = false;
272 bool sent_interrupt = false;
273 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
274 {
275 if (sent_interrupt)
276 {
277 if (log)
278 log->Printf ("async: sent interrupt");
279 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
280 {
281 if (log)
282 log->Printf ("async: got response");
283 response = m_async_response;
284 return response.GetStringRef().size();
285 }
286 else
287 {
288 if (log)
289 log->Printf ("async: timed out waiting for response");
290 }
291
292 // Make sure we wait until the continue packet has been sent again...
293 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
294 {
295 if (log)
296 log->Printf ("async: timed out waiting for process to resume");
297 }
298 }
299 else
300 {
301 // We had a racy condition where we went to send the interrupt
302 // yet we were able to get the loc
303 }
304 }
305 else
306 {
307 if (log)
308 log->Printf ("async: failed to interrupt");
309 }
310 }
311 else
312 {
313 if (log)
314 log->Printf ("mutex taken and send_async == false, aborting packet");
315 }
316 }
317 return 0;
318}
319
320//template<typename _Tp>
321//class ScopedValueChanger
322//{
323//public:
324// // Take a value reference and the value to assign it to when this class
325// // instance goes out of scope.
326// ScopedValueChanger (_Tp &value_ref, _Tp value) :
327// m_value_ref (value_ref),
328// m_value (value)
329// {
330// }
331//
332// // This object is going out of scope, change the value pointed to by
333// // m_value_ref to the value we got during construction which was stored in
334// // m_value;
335// ~ScopedValueChanger ()
336// {
337// m_value_ref = m_value;
338// }
339//protected:
340// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
341// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
342//};
343
344StateType
345GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
346(
347 ProcessGDBRemote *process,
348 const char *payload,
349 size_t packet_length,
350 StringExtractorGDBRemote &response
351)
352{
353 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
354 if (log)
355 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
356
357 Mutex::Locker locker(m_sequence_mutex);
358 StateType state = eStateRunning;
359
360 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
361 m_public_is_running.SetValue (true, eBroadcastNever);
362 // Set the starting continue packet into "continue_packet". This packet
363 // make change if we are interrupted and we continue after an async packet...
364 std::string continue_packet(payload, packet_length);
365
366 while (state == eStateRunning)
367 {
368 if (log)
369 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
370 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
371 state = eStateInvalid;
372
373 m_private_is_running.SetValue (true, eBroadcastNever);
374
375 if (log)
376 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__);
377
378 if (WaitForPacket (response, (TimeValue*)NULL))
379 {
380 if (response.Empty())
381 state = eStateInvalid;
382 else
383 {
384 const char stop_type = response.GetChar();
385 if (log)
386 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
387 switch (stop_type)
388 {
389 case 'T':
390 case 'S':
391 if (process->GetStopID() == 0)
392 {
393 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
394 {
395 lldb::pid_t pid = GetCurrentProcessID ();
396 if (pid != LLDB_INVALID_PROCESS_ID)
397 process->SetID (pid);
398 }
399 process->BuildDynamicRegisterInfo (true);
400 }
401
402 // Privately notify any internal threads that we have stopped
403 // in case we wanted to interrupt our process, yet we might
404 // send a packet and continue without returning control to the
405 // user.
406 m_private_is_running.SetValue (false, eBroadcastAlways);
407 if (m_async_signal != -1)
408 {
409 if (log)
410 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
411
412 // Save off the async signal we are supposed to send
413 const int async_signal = m_async_signal;
414 // Clear the async signal member so we don't end up
415 // sending the signal multiple times...
416 m_async_signal = -1;
417 // Check which signal we stopped with
418 uint8_t signo = response.GetHexU8(255);
419 if (signo == async_signal)
420 {
421 if (log)
422 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
423
424 // We already stopped with a signal that we wanted
425 // to stop with, so we are done
426 response.SetFilePos (0);
427 }
428 else
429 {
430 // We stopped with a different signal that the one
431 // we wanted to stop with, so now we must resume
432 // with the signal we want
433 char signal_packet[32];
434 int signal_packet_len = 0;
435 signal_packet_len = ::snprintf (signal_packet,
436 sizeof (signal_packet),
437 "C%2.2x",
438 async_signal);
439
440 if (log)
441 log->Printf ("async: stopped with signal %s, resume with %s",
442 Host::GetSignalAsCString (signo),
443 Host::GetSignalAsCString (async_signal));
444
445 // Set the continue packet to resume...
446 continue_packet.assign(signal_packet, signal_packet_len);
447 continue;
448 }
449 }
450 else if (m_async_packet_predicate.GetValue())
451 {
452 // We are supposed to send an asynchronous packet while
453 // we are running.
454 m_async_response.Clear();
455 if (m_async_packet.empty())
456 {
457 if (log)
458 log->Printf ("async: error: empty async packet");
459
460 }
461 else
462 {
463 if (log)
464 log->Printf ("async: sending packet: %s",
465 m_async_packet.c_str());
466
467 SendPacketAndWaitForResponse (&m_async_packet[0],
468 m_async_packet.size(),
469 m_async_response,
470 false);
471 }
472 // Let the other thread that was trying to send the async
473 // packet know that the packet has been sent and response is
474 // ready...
475 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
476
477 // Set the continue packet to resume...
478 continue_packet.assign (1, 'c');
479 continue;
480 }
481 // Stop with signal and thread info
482 state = eStateStopped;
483 break;
484
485 case 'W':
486 case 'X':
487 // process exited
488 state = eStateExited;
489 break;
490
491 case 'O':
492 // STDOUT
493 {
494 std::string inferior_stdout;
495 inferior_stdout.reserve(response.GetBytesLeft () / 2);
496 char ch;
497 while ((ch = response.GetHexU8()) != '\0')
498 inferior_stdout.append(1, ch);
499 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
500 }
501 break;
502
503 case 'E':
504 // ERROR
505 state = eStateInvalid;
506 break;
507
508 default:
509 if (log)
510 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
511 state = eStateInvalid;
512 break;
513 }
514 }
515 }
516 else
517 {
518 if (log)
519 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
520 state = eStateInvalid;
521 }
522 }
523 if (log)
524 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
525 response.SetFilePos(0);
526 m_private_is_running.SetValue (false, eBroadcastAlways);
527 m_public_is_running.SetValue (false, eBroadcastAlways);
528 return state;
529}
530
531bool
532GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
533{
534 m_async_signal = signo;
535 bool timed_out = false;
536 bool sent_interrupt = false;
537 Mutex::Locker locker;
538 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
539 return true;
540 m_async_signal = -1;
541 return false;
542}
543
544// This function takes a mutex locker as a parameter in case the GetSequenceMutex
545// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
546// (the expected result), then it will send the halt packet. If it does succeed
547// then the caller that requested the interrupt will want to keep the sequence
548// locked down so that no one else can send packets while the caller has control.
549// This function usually gets called when we are running and need to stop the
550// target. It can also be used when we are running and and we need to do something
551// else (like read/write memory), so we need to interrupt the running process
552// (gdb remote protocol requires this), and do what we need to do, then resume.
553
554bool
555GDBRemoteCommunicationClient::SendInterrupt
556(
557 Mutex::Locker& locker,
558 uint32_t seconds_to_wait_for_stop,
559 bool &sent_interrupt,
560 bool &timed_out
561)
562{
563 sent_interrupt = false;
564 timed_out = false;
565 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
566
567 if (IsRunning())
568 {
569 // Only send an interrupt if our debugserver is running...
570 if (GetSequenceMutex (locker) == false)
571 {
572 // Someone has the mutex locked waiting for a response or for the
573 // inferior to stop, so send the interrupt on the down low...
574 char ctrl_c = '\x03';
575 ConnectionStatus status = eConnectionStatusSuccess;
576 TimeValue timeout;
577 if (seconds_to_wait_for_stop)
578 {
579 timeout = TimeValue::Now();
580 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
581 }
582 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
583 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
584 if (bytes_written > 0)
585 {
586 sent_interrupt = true;
587 if (seconds_to_wait_for_stop)
588 {
589 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
590 {
591 if (log)
592 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__);
593 return true;
594 }
595 else
596 {
597 if (log)
598 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
599 }
600 }
601 else
602 {
603 if (log)
604 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
605 return true;
606 }
607 }
608 else
609 {
610 if (log)
611 log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__);
612 }
613 return false;
614 }
615 else
616 {
617 if (log)
618 log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
619 }
620 }
621 return true;
622}
623
624lldb::pid_t
625GDBRemoteCommunicationClient::GetCurrentProcessID ()
626{
627 StringExtractorGDBRemote response;
628 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
629 {
630 if (response.GetChar() == 'Q')
631 if (response.GetChar() == 'C')
632 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
633 }
634 return LLDB_INVALID_PROCESS_ID;
635}
636
637bool
638GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
639{
640 error_str.clear();
641 StringExtractorGDBRemote response;
642 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
643 {
644 if (response.IsOKResponse())
645 return true;
646 if (response.GetChar() == 'E')
647 {
648 // A string the describes what failed when launching...
649 error_str = response.GetStringRef().substr(1);
650 }
651 else
652 {
653 error_str.assign ("unknown error occurred launching process");
654 }
655 }
656 else
657 {
658 error_str.assign ("failed to send the qLaunchSuccess packet");
659 }
660 return false;
661}
662
663int
664GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
665{
666 if (argv && argv[0])
667 {
668 StreamString packet;
669 packet.PutChar('A');
670 const char *arg;
671 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
672 {
673 const int arg_len = strlen(arg);
674 if (i > 0)
675 packet.PutChar(',');
676 packet.Printf("%i,%i,", arg_len * 2, i);
677 packet.PutBytesAsRawHex8 (arg, arg_len);
678 }
679
680 StringExtractorGDBRemote response;
681 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
682 {
683 if (response.IsOKResponse())
684 return 0;
685 uint8_t error = response.GetError();
686 if (error)
687 return error;
688 }
689 }
690 return -1;
691}
692
693int
694GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
695{
696 if (name_equal_value && name_equal_value[0])
697 {
698 StreamString packet;
699 packet.Printf("QEnvironment:%s", name_equal_value);
700 StringExtractorGDBRemote response;
701 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
702 {
703 if (response.IsOKResponse())
704 return 0;
705 uint8_t error = response.GetError();
706 if (error)
707 return error;
708 }
709 }
710 return -1;
711}
712
Greg Claytona4582402011-05-08 04:53:50 +0000713int
714GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
715{
716 if (arch && arch[0])
717 {
718 StreamString packet;
719 packet.Printf("QLaunchArch:%s", arch);
720 StringExtractorGDBRemote response;
721 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
722 {
723 if (response.IsOKResponse())
724 return 0;
725 uint8_t error = response.GetError();
726 if (error)
727 return error;
728 }
729 }
730 return -1;
731}
732
Greg Clayton61d043b2011-03-22 04:00:09 +0000733bool
Greg Clayton58e26e02011-03-24 04:28:38 +0000734GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
735 uint32_t &minor,
736 uint32_t &update)
737{
738 if (GetHostInfo ())
739 {
740 if (m_os_version_major != UINT32_MAX)
741 {
742 major = m_os_version_major;
743 minor = m_os_version_minor;
744 update = m_os_version_update;
745 return true;
746 }
747 }
748 return false;
749}
750
751bool
752GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
753{
754 if (GetHostInfo ())
755 {
756 if (!m_os_build.empty())
757 {
758 s = m_os_build;
759 return true;
760 }
761 }
762 s.clear();
763 return false;
764}
765
766
767bool
768GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
769{
770 if (GetHostInfo ())
771 {
772 if (!m_os_kernel.empty())
773 {
774 s = m_os_kernel;
775 return true;
776 }
777 }
778 s.clear();
779 return false;
780}
781
782bool
783GDBRemoteCommunicationClient::GetHostname (std::string &s)
784{
785 if (GetHostInfo ())
786 {
787 if (!m_hostname.empty())
788 {
789 s = m_hostname;
790 return true;
791 }
792 }
793 s.clear();
794 return false;
795}
796
797ArchSpec
798GDBRemoteCommunicationClient::GetSystemArchitecture ()
799{
800 if (GetHostInfo ())
801 return m_host_arch;
802 return ArchSpec();
803}
804
805
806bool
Greg Clayton06d7cc82011-04-04 18:18:57 +0000807GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton61d043b2011-03-22 04:00:09 +0000808{
Greg Clayton06d7cc82011-04-04 18:18:57 +0000809 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +0000810 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000811 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton61d043b2011-03-22 04:00:09 +0000812 StringExtractorGDBRemote response;
813 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
814 {
815 if (response.IsUnsupportedResponse())
Greg Clayton24bc5d92011-03-30 18:16:51 +0000816 {
Greg Clayton61d043b2011-03-22 04:00:09 +0000817 return false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000818 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000819 else if (response.IsNormalResponse())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000820 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000821 std::string name;
822 std::string value;
823 uint32_t cpu = LLDB_INVALID_CPUTYPE;
824 uint32_t sub = 0;
825 std::string arch_name;
826 std::string os_name;
827 std::string vendor_name;
828 std::string triple;
829 uint32_t pointer_byte_size = 0;
830 StringExtractor extractor;
831 ByteOrder byte_order = eByteOrderInvalid;
832 uint32_t num_keys_decoded = 0;
833 while (response.GetNameColonValue(name, value))
Greg Claytoncb8977d2011-03-23 00:09:55 +0000834 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000835 if (name.compare("cputype") == 0)
Greg Clayton58e26e02011-03-24 04:28:38 +0000836 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000837 // exception type in big endian hex
838 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
839 if (cpu != LLDB_INVALID_CPUTYPE)
840 ++num_keys_decoded;
841 }
842 else if (name.compare("cpusubtype") == 0)
843 {
844 // exception count in big endian hex
845 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
846 if (sub != 0)
847 ++num_keys_decoded;
848 }
849 else if (name.compare("arch") == 0)
850 {
851 arch_name.swap (value);
852 ++num_keys_decoded;
853 }
854 else if (name.compare("triple") == 0)
855 {
856 // The triple comes as ASCII hex bytes since it contains '-' chars
857 extractor.GetStringRef().swap(value);
858 extractor.SetFilePos(0);
859 extractor.GetHexByteString (triple);
860 ++num_keys_decoded;
861 }
862 else if (name.compare("os_build") == 0)
863 {
864 extractor.GetStringRef().swap(value);
865 extractor.SetFilePos(0);
866 extractor.GetHexByteString (m_os_build);
867 ++num_keys_decoded;
868 }
869 else if (name.compare("hostname") == 0)
870 {
871 extractor.GetStringRef().swap(value);
872 extractor.SetFilePos(0);
873 extractor.GetHexByteString (m_hostname);
874 ++num_keys_decoded;
875 }
876 else if (name.compare("os_kernel") == 0)
877 {
878 extractor.GetStringRef().swap(value);
879 extractor.SetFilePos(0);
880 extractor.GetHexByteString (m_os_kernel);
881 ++num_keys_decoded;
882 }
883 else if (name.compare("ostype") == 0)
884 {
885 os_name.swap (value);
886 ++num_keys_decoded;
887 }
888 else if (name.compare("vendor") == 0)
889 {
890 vendor_name.swap(value);
891 ++num_keys_decoded;
892 }
893 else if (name.compare("endian") == 0)
894 {
895 ++num_keys_decoded;
896 if (value.compare("little") == 0)
897 byte_order = eByteOrderLittle;
898 else if (value.compare("big") == 0)
899 byte_order = eByteOrderBig;
900 else if (value.compare("pdp") == 0)
901 byte_order = eByteOrderPDP;
902 else
903 --num_keys_decoded;
904 }
905 else if (name.compare("ptrsize") == 0)
906 {
907 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
908 if (pointer_byte_size != 0)
909 ++num_keys_decoded;
910 }
911 else if (name.compare("os_version") == 0)
912 {
913 Args::StringToVersion (value.c_str(),
914 m_os_version_major,
915 m_os_version_minor,
916 m_os_version_update);
917 if (m_os_version_major != UINT32_MAX)
918 ++num_keys_decoded;
919 }
920 }
921
922 if (num_keys_decoded > 0)
923 m_qHostInfo_is_valid = eLazyBoolYes;
924
925 if (triple.empty())
926 {
927 if (arch_name.empty())
928 {
929 if (cpu != LLDB_INVALID_CPUTYPE)
930 {
931 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
932 if (pointer_byte_size)
933 {
934 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
935 }
936 if (byte_order != eByteOrderInvalid)
937 {
938 assert (byte_order == m_host_arch.GetByteOrder());
939 }
940 if (!vendor_name.empty())
941 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
942 if (!os_name.empty())
943 m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
944
945 }
946 }
947 else
948 {
949 std::string triple;
950 triple += arch_name;
951 triple += '-';
952 if (vendor_name.empty())
953 triple += "unknown";
954 else
955 triple += vendor_name;
956 triple += '-';
957 if (os_name.empty())
958 triple += "unknown";
959 else
960 triple += os_name;
Greg Claytonf15996e2011-04-07 22:46:35 +0000961 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Clayton58e26e02011-03-24 04:28:38 +0000962 if (pointer_byte_size)
963 {
964 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
965 }
966 if (byte_order != eByteOrderInvalid)
967 {
968 assert (byte_order == m_host_arch.GetByteOrder());
969 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000970
Greg Clayton58e26e02011-03-24 04:28:38 +0000971 }
972 }
973 else
974 {
Greg Claytonf15996e2011-04-07 22:46:35 +0000975 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000976 if (pointer_byte_size)
977 {
978 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
979 }
980 if (byte_order != eByteOrderInvalid)
981 {
982 assert (byte_order == m_host_arch.GetByteOrder());
983 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000984 }
Greg Claytoncb8977d2011-03-23 00:09:55 +0000985 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000986 }
987 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000988 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton61d043b2011-03-22 04:00:09 +0000989}
990
991int
992GDBRemoteCommunicationClient::SendAttach
993(
994 lldb::pid_t pid,
995 StringExtractorGDBRemote& response
996)
997{
998 if (pid != LLDB_INVALID_PROCESS_ID)
999 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001000 char packet[64];
1001 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid);
1002 assert (packet_len < sizeof(packet));
1003 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001004 {
1005 if (response.IsErrorResponse())
1006 return response.GetError();
1007 return 0;
1008 }
1009 }
1010 return -1;
1011}
1012
1013const lldb_private::ArchSpec &
1014GDBRemoteCommunicationClient::GetHostArchitecture ()
1015{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001016 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +00001017 GetHostInfo ();
Greg Claytoncb8977d2011-03-23 00:09:55 +00001018 return m_host_arch;
Greg Clayton61d043b2011-03-22 04:00:09 +00001019}
1020
1021addr_t
1022GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1023{
Greg Clayton989816b2011-05-14 01:50:35 +00001024 if (m_supports__M != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001025 {
Greg Clayton989816b2011-05-14 01:50:35 +00001026 m_supports__M = eLazyBoolYes;
1027 char packet[64];
1028 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1029 permissions & lldb::ePermissionsReadable ? "r" : "",
1030 permissions & lldb::ePermissionsWritable ? "w" : "",
1031 permissions & lldb::ePermissionsExecutable ? "x" : "");
1032 assert (packet_len < sizeof(packet));
1033 StringExtractorGDBRemote response;
1034 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1035 {
1036 if (response.IsUnsupportedResponse())
1037 m_supports__M = eLazyBoolNo;
1038 else if (!response.IsErrorResponse())
1039 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1040 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001041 }
1042 return LLDB_INVALID_ADDRESS;
1043}
1044
1045bool
1046GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1047{
Greg Clayton989816b2011-05-14 01:50:35 +00001048 if (m_supports__m != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001049 {
Greg Clayton989816b2011-05-14 01:50:35 +00001050 m_supports__m = eLazyBoolYes;
1051 char packet[64];
1052 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1053 assert (packet_len < sizeof(packet));
1054 StringExtractorGDBRemote response;
1055 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1056 {
1057 if (response.IsOKResponse())
1058 return true;
1059 else if (response.IsUnsupportedResponse())
1060 m_supports__m = eLazyBoolNo;
1061 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001062 }
1063 return false;
1064}
1065
1066int
1067GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1068{
1069 if (path && path[0])
1070 {
1071 StreamString packet;
1072 packet.PutCString("QSetSTDIN:");
1073 packet.PutBytesAsRawHex8(path, strlen(path));
1074
1075 StringExtractorGDBRemote response;
1076 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1077 {
1078 if (response.IsOKResponse())
1079 return 0;
1080 uint8_t error = response.GetError();
1081 if (error)
1082 return error;
1083 }
1084 }
1085 return -1;
1086}
1087
1088int
1089GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1090{
1091 if (path && path[0])
1092 {
1093 StreamString packet;
1094 packet.PutCString("QSetSTDOUT:");
1095 packet.PutBytesAsRawHex8(path, strlen(path));
1096
1097 StringExtractorGDBRemote response;
1098 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1099 {
1100 if (response.IsOKResponse())
1101 return 0;
1102 uint8_t error = response.GetError();
1103 if (error)
1104 return error;
1105 }
1106 }
1107 return -1;
1108}
1109
1110int
1111GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1112{
1113 if (path && path[0])
1114 {
1115 StreamString packet;
1116 packet.PutCString("QSetSTDERR:");
1117 packet.PutBytesAsRawHex8(path, strlen(path));
1118
1119 StringExtractorGDBRemote response;
1120 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1121 {
1122 if (response.IsOKResponse())
1123 return 0;
1124 uint8_t error = response.GetError();
1125 if (error)
1126 return error;
1127 }
1128 }
1129 return -1;
1130}
1131
1132int
1133GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1134{
1135 if (path && path[0])
1136 {
1137 StreamString packet;
1138 packet.PutCString("QSetWorkingDir:");
1139 packet.PutBytesAsRawHex8(path, strlen(path));
1140
1141 StringExtractorGDBRemote response;
1142 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1143 {
1144 if (response.IsOKResponse())
1145 return 0;
1146 uint8_t error = response.GetError();
1147 if (error)
1148 return error;
1149 }
1150 }
1151 return -1;
1152}
1153
1154int
1155GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1156{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001157 char packet[32];
1158 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1159 assert (packet_len < sizeof(packet));
Greg Clayton61d043b2011-03-22 04:00:09 +00001160 StringExtractorGDBRemote response;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001161 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001162 {
1163 if (response.IsOKResponse())
1164 return 0;
1165 uint8_t error = response.GetError();
1166 if (error)
1167 return error;
1168 }
1169 return -1;
1170}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001171
1172bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001173GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001174{
1175 if (response.IsNormalResponse())
1176 {
1177 std::string name;
1178 std::string value;
1179 StringExtractor extractor;
1180
1181 while (response.GetNameColonValue(name, value))
1182 {
1183 if (name.compare("pid") == 0)
1184 {
1185 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1186 }
1187 else if (name.compare("ppid") == 0)
1188 {
1189 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1190 }
1191 else if (name.compare("uid") == 0)
1192 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001193 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001194 }
1195 else if (name.compare("euid") == 0)
1196 {
1197 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1198 }
1199 else if (name.compare("gid") == 0)
1200 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001201 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001202 }
1203 else if (name.compare("egid") == 0)
1204 {
1205 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1206 }
1207 else if (name.compare("triple") == 0)
1208 {
1209 // The triple comes as ASCII hex bytes since it contains '-' chars
1210 extractor.GetStringRef().swap(value);
1211 extractor.SetFilePos(0);
1212 extractor.GetHexByteString (value);
Greg Claytonf15996e2011-04-07 22:46:35 +00001213 process_info.GetArchitecture ().SetTriple (value.c_str(), NULL);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001214 }
1215 else if (name.compare("name") == 0)
1216 {
1217 StringExtractor extractor;
1218 // The the process name from ASCII hex bytes since we can't
1219 // control the characters in a process name
1220 extractor.GetStringRef().swap(value);
1221 extractor.SetFilePos(0);
1222 extractor.GetHexByteString (value);
Greg Claytonff39f742011-04-01 00:29:43 +00001223 process_info.SetName (value.c_str());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001224 }
1225 }
1226
1227 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1228 return true;
1229 }
1230 return false;
1231}
1232
1233bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001234GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001235{
1236 process_info.Clear();
1237
1238 if (m_supports_qProcessInfoPID)
1239 {
1240 char packet[32];
1241 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%i", pid);
1242 assert (packet_len < sizeof(packet));
1243 StringExtractorGDBRemote response;
1244 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1245 {
1246 if (response.IsUnsupportedResponse())
1247 {
1248 m_supports_qProcessInfoPID = false;
1249 return false;
1250 }
1251
1252 return DecodeProcessInfoResponse (response, process_info);
1253 }
1254 }
1255 return false;
1256}
1257
1258uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +00001259GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1260 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001261{
1262 process_infos.Clear();
1263
1264 if (m_supports_qfProcessInfo)
1265 {
1266 StreamString packet;
1267 packet.PutCString ("qfProcessInfo");
1268 if (!match_info.MatchAllProcesses())
1269 {
1270 packet.PutChar (':');
1271 const char *name = match_info.GetProcessInfo().GetName();
1272 bool has_name_match = false;
1273 if (name && name[0])
1274 {
1275 has_name_match = true;
1276 NameMatchType name_match_type = match_info.GetNameMatchType();
1277 switch (name_match_type)
1278 {
1279 case eNameMatchIgnore:
1280 has_name_match = false;
1281 break;
1282
1283 case eNameMatchEquals:
1284 packet.PutCString ("name_match:equals;");
1285 break;
1286
1287 case eNameMatchContains:
1288 packet.PutCString ("name_match:contains;");
1289 break;
1290
1291 case eNameMatchStartsWith:
1292 packet.PutCString ("name_match:starts_with;");
1293 break;
1294
1295 case eNameMatchEndsWith:
1296 packet.PutCString ("name_match:ends_with;");
1297 break;
1298
1299 case eNameMatchRegularExpression:
1300 packet.PutCString ("name_match:regex;");
1301 break;
1302 }
1303 if (has_name_match)
1304 {
1305 packet.PutCString ("name:");
1306 packet.PutBytesAsRawHex8(name, ::strlen(name));
1307 packet.PutChar (';');
1308 }
1309 }
1310
1311 if (match_info.GetProcessInfo().ProcessIDIsValid())
1312 packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
1313 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
1314 packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
Greg Claytonb72d0f02011-04-12 05:54:46 +00001315 if (match_info.GetProcessInfo().UserIDIsValid())
1316 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
1317 if (match_info.GetProcessInfo().GroupIDIsValid())
1318 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001319 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
1320 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
1321 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1322 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
1323 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1324 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
1325 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
1326 {
1327 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
1328 const llvm::Triple &triple = match_arch.GetTriple();
1329 packet.PutCString("triple:");
1330 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
1331 packet.PutChar (';');
1332 }
1333 }
1334 StringExtractorGDBRemote response;
1335 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1336 {
1337 if (response.IsUnsupportedResponse())
1338 {
1339 m_supports_qfProcessInfo = false;
1340 return 0;
1341 }
1342
1343 do
1344 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001345 ProcessInstanceInfo process_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001346 if (!DecodeProcessInfoResponse (response, process_info))
1347 break;
1348 process_infos.Append(process_info);
1349 response.GetStringRef().clear();
1350 response.SetFilePos(0);
1351 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
1352 }
1353 }
1354 return process_infos.GetSize();
1355
1356}
1357
1358bool
1359GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
1360{
1361 if (m_supports_qUserName)
1362 {
1363 char packet[32];
1364 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
1365 assert (packet_len < sizeof(packet));
1366 StringExtractorGDBRemote response;
1367 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1368 {
1369 if (response.IsUnsupportedResponse())
1370 {
1371 m_supports_qUserName = false;
1372 return false;
1373 }
1374
1375 if (response.IsNormalResponse())
1376 {
1377 // Make sure we parsed the right number of characters. The response is
1378 // the hex encoded user name and should make up the entire packet.
1379 // If there are any non-hex ASCII bytes, the length won't match below..
1380 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1381 return true;
1382 }
1383 }
1384 }
1385 return false;
1386
1387}
1388
1389bool
1390GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
1391{
1392 if (m_supports_qGroupName)
1393 {
1394 char packet[32];
1395 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
1396 assert (packet_len < sizeof(packet));
1397 StringExtractorGDBRemote response;
1398 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1399 {
1400 if (response.IsUnsupportedResponse())
1401 {
1402 m_supports_qGroupName = false;
1403 return false;
1404 }
1405
1406 if (response.IsNormalResponse())
1407 {
1408 // Make sure we parsed the right number of characters. The response is
1409 // the hex encoded group name and should make up the entire packet.
1410 // If there are any non-hex ASCII bytes, the length won't match below..
1411 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1412 return true;
1413 }
1414 }
1415 }
1416 return false;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001417}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001418
Greg Clayton06d7cc82011-04-04 18:18:57 +00001419void
1420GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
1421{
1422 uint32_t i;
1423 TimeValue start_time, end_time;
1424 uint64_t total_time_nsec;
1425 float packets_per_second;
1426 if (SendSpeedTestPacket (0, 0))
1427 {
1428 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
1429 {
1430 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
1431 {
1432 start_time = TimeValue::Now();
1433 for (i=0; i<num_packets; ++i)
1434 {
1435 SendSpeedTestPacket (send_size, recv_size);
1436 }
1437 end_time = TimeValue::Now();
1438 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001439 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001440 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%09.9llu sec for %f packets/sec.\n",
1441 num_packets,
1442 send_size,
1443 recv_size,
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001444 total_time_nsec / TimeValue::NanoSecondPerSecond,
1445 total_time_nsec % TimeValue::NanoSecondPerSecond,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001446 packets_per_second);
1447 if (recv_size == 0)
1448 recv_size = 32;
1449 }
1450 if (send_size == 0)
1451 send_size = 32;
1452 }
1453 }
1454 else
1455 {
1456 start_time = TimeValue::Now();
1457 for (i=0; i<num_packets; ++i)
1458 {
1459 GetCurrentProcessID ();
1460 }
1461 end_time = TimeValue::Now();
1462 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001463 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001464 printf ("%u 'qC' packets packets in 0x%llu%09.9llu sec for %f packets/sec.\n",
1465 num_packets,
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001466 total_time_nsec / TimeValue::NanoSecondPerSecond,
1467 total_time_nsec % TimeValue::NanoSecondPerSecond,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001468 packets_per_second);
1469 }
1470}
1471
1472bool
1473GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
1474{
1475 StreamString packet;
1476 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
1477 uint32_t bytes_left = send_size;
1478 while (bytes_left > 0)
1479 {
1480 if (bytes_left >= 26)
1481 {
1482 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
1483 bytes_left -= 26;
1484 }
1485 else
1486 {
1487 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
1488 bytes_left = 0;
1489 }
1490 }
1491
1492 StringExtractorGDBRemote response;
1493 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1494 {
1495 if (response.IsUnsupportedResponse())
1496 return false;
1497 return true;
1498 }
1499 return false;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001500}
Greg Claytonb72d0f02011-04-12 05:54:46 +00001501
1502uint16_t
1503GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
1504{
1505 StringExtractorGDBRemote response;
1506 if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
1507 {
1508 std::string name;
1509 std::string value;
1510 uint16_t port = 0;
1511 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1512 while (response.GetNameColonValue(name, value))
1513 {
1514 if (name.size() == 4 && name.compare("port") == 0)
1515 port = Args::StringToUInt32(value.c_str(), 0, 0);
1516 if (name.size() == 3 && name.compare("pid") == 0)
1517 pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
1518 }
1519 return port;
1520 }
1521 return 0;
1522}
1523
1524bool
1525GDBRemoteCommunicationClient::SetCurrentThread (int tid)
1526{
1527 if (m_curr_tid == tid)
1528 return true;
1529
1530 char packet[32];
1531 int packet_len;
1532 if (tid <= 0)
1533 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
1534 else
1535 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
1536 assert (packet_len + 1 < sizeof(packet));
1537 StringExtractorGDBRemote response;
1538 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1539 {
1540 if (response.IsOKResponse())
1541 {
1542 m_curr_tid = tid;
1543 return true;
1544 }
1545 }
1546 return false;
1547}
1548
1549bool
1550GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
1551{
1552 if (m_curr_tid_run == tid)
1553 return true;
1554
1555 char packet[32];
1556 int packet_len;
1557 if (tid <= 0)
1558 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
1559 else
1560 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
1561
1562 assert (packet_len + 1 < sizeof(packet));
1563 StringExtractorGDBRemote response;
1564 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1565 {
1566 if (response.IsOKResponse())
1567 {
1568 m_curr_tid_run = tid;
1569 return true;
1570 }
1571 }
1572 return false;
1573}
1574
1575bool
1576GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
1577{
1578 if (SendPacketAndWaitForResponse("?", 1, response, false))
1579 return response.IsNormalResponse();
1580 return false;
1581}
1582
1583bool
1584GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
1585{
1586 if (m_supports_qThreadStopInfo)
1587 {
1588 char packet[256];
1589 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
1590 assert (packet_len < sizeof(packet));
1591 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1592 {
1593 if (response.IsUnsupportedResponse())
1594 m_supports_qThreadStopInfo = false;
1595 else if (response.IsNormalResponse())
1596 return true;
1597 else
1598 return false;
1599 }
1600 }
1601 if (SetCurrentThread (tid))
1602 return GetStopReply (response);
1603 return false;
1604}
1605
1606
1607uint8_t
1608GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
1609{
1610 switch (type)
1611 {
1612 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
1613 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
1614 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
1615 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
1616 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
1617 default: return UINT8_MAX;
1618 }
1619
1620 char packet[64];
1621 const int packet_len = ::snprintf (packet,
1622 sizeof(packet),
1623 "%c%i,%llx,%x",
1624 insert ? 'Z' : 'z',
1625 type,
1626 addr,
1627 length);
1628
1629 assert (packet_len + 1 < sizeof(packet));
1630 StringExtractorGDBRemote response;
1631 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
1632 {
1633 if (response.IsOKResponse())
1634 return 0;
1635 if (response.IsUnsupportedResponse())
1636 {
1637 switch (type)
1638 {
1639 case eBreakpointSoftware: m_supports_z0 = false; break;
1640 case eBreakpointHardware: m_supports_z1 = false; break;
1641 case eWatchpointWrite: m_supports_z2 = false; break;
1642 case eWatchpointRead: m_supports_z3 = false; break;
1643 case eWatchpointReadWrite: m_supports_z4 = false; break;
1644 default: break;
1645 }
1646 }
1647 else if (response.IsErrorResponse())
1648 return response.GetError();
1649 }
1650 return UINT8_MAX;
1651}