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