blob: d1c51eca638df33c44700ba045ad8e0dcfdbc533 [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 {
Greg Clayton139da722011-05-20 03:15:54 +0000255 if (SendPacketNoLock (payload, payload_length))
Greg Clayton61d043b2011-03-22 04:00:09 +0000256 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
Greg Clayton628cead2011-05-19 03:54:16 +0000364 bool got_stdout = false;
365
Greg Clayton61d043b2011-03-22 04:00:09 +0000366 while (state == eStateRunning)
367 {
Greg Clayton628cead2011-05-19 03:54:16 +0000368 if (!got_stdout)
369 {
370 if (log)
371 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
372 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
373 state = eStateInvalid;
Greg Clayton61d043b2011-03-22 04:00:09 +0000374
Greg Clayton628cead2011-05-19 03:54:16 +0000375 m_private_is_running.SetValue (true, eBroadcastNever);
376 }
377
378 got_stdout = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000379
380 if (log)
381 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__);
382
383 if (WaitForPacket (response, (TimeValue*)NULL))
384 {
385 if (response.Empty())
386 state = eStateInvalid;
387 else
388 {
389 const char stop_type = response.GetChar();
390 if (log)
391 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
392 switch (stop_type)
393 {
394 case 'T':
395 case 'S':
396 if (process->GetStopID() == 0)
397 {
398 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
399 {
400 lldb::pid_t pid = GetCurrentProcessID ();
401 if (pid != LLDB_INVALID_PROCESS_ID)
402 process->SetID (pid);
403 }
404 process->BuildDynamicRegisterInfo (true);
405 }
406
407 // Privately notify any internal threads that we have stopped
408 // in case we wanted to interrupt our process, yet we might
409 // send a packet and continue without returning control to the
410 // user.
411 m_private_is_running.SetValue (false, eBroadcastAlways);
412 if (m_async_signal != -1)
413 {
414 if (log)
415 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
416
417 // Save off the async signal we are supposed to send
418 const int async_signal = m_async_signal;
419 // Clear the async signal member so we don't end up
420 // sending the signal multiple times...
421 m_async_signal = -1;
422 // Check which signal we stopped with
423 uint8_t signo = response.GetHexU8(255);
424 if (signo == async_signal)
425 {
426 if (log)
427 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
428
429 // We already stopped with a signal that we wanted
430 // to stop with, so we are done
431 response.SetFilePos (0);
432 }
433 else
434 {
435 // We stopped with a different signal that the one
436 // we wanted to stop with, so now we must resume
437 // with the signal we want
438 char signal_packet[32];
439 int signal_packet_len = 0;
440 signal_packet_len = ::snprintf (signal_packet,
441 sizeof (signal_packet),
442 "C%2.2x",
443 async_signal);
444
445 if (log)
446 log->Printf ("async: stopped with signal %s, resume with %s",
447 Host::GetSignalAsCString (signo),
448 Host::GetSignalAsCString (async_signal));
449
450 // Set the continue packet to resume...
451 continue_packet.assign(signal_packet, signal_packet_len);
452 continue;
453 }
454 }
455 else if (m_async_packet_predicate.GetValue())
456 {
457 // We are supposed to send an asynchronous packet while
458 // we are running.
459 m_async_response.Clear();
460 if (m_async_packet.empty())
461 {
462 if (log)
463 log->Printf ("async: error: empty async packet");
464
465 }
466 else
467 {
468 if (log)
469 log->Printf ("async: sending packet: %s",
470 m_async_packet.c_str());
471
472 SendPacketAndWaitForResponse (&m_async_packet[0],
473 m_async_packet.size(),
474 m_async_response,
475 false);
476 }
477 // Let the other thread that was trying to send the async
478 // packet know that the packet has been sent and response is
479 // ready...
480 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
481
482 // Set the continue packet to resume...
483 continue_packet.assign (1, 'c');
484 continue;
485 }
486 // Stop with signal and thread info
487 state = eStateStopped;
488 break;
489
490 case 'W':
491 case 'X':
492 // process exited
493 state = eStateExited;
494 break;
495
496 case 'O':
497 // STDOUT
498 {
Greg Clayton628cead2011-05-19 03:54:16 +0000499 got_stdout = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000500 std::string inferior_stdout;
501 inferior_stdout.reserve(response.GetBytesLeft () / 2);
502 char ch;
503 while ((ch = response.GetHexU8()) != '\0')
504 inferior_stdout.append(1, ch);
505 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
506 }
507 break;
508
509 case 'E':
510 // ERROR
511 state = eStateInvalid;
512 break;
513
514 default:
515 if (log)
516 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
517 state = eStateInvalid;
518 break;
519 }
520 }
521 }
522 else
523 {
524 if (log)
525 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
526 state = eStateInvalid;
527 }
528 }
529 if (log)
530 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
531 response.SetFilePos(0);
532 m_private_is_running.SetValue (false, eBroadcastAlways);
533 m_public_is_running.SetValue (false, eBroadcastAlways);
534 return state;
535}
536
537bool
538GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
539{
540 m_async_signal = signo;
541 bool timed_out = false;
542 bool sent_interrupt = false;
543 Mutex::Locker locker;
544 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
545 return true;
546 m_async_signal = -1;
547 return false;
548}
549
550// This function takes a mutex locker as a parameter in case the GetSequenceMutex
551// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
552// (the expected result), then it will send the halt packet. If it does succeed
553// then the caller that requested the interrupt will want to keep the sequence
554// locked down so that no one else can send packets while the caller has control.
555// This function usually gets called when we are running and need to stop the
556// target. It can also be used when we are running and and we need to do something
557// else (like read/write memory), so we need to interrupt the running process
558// (gdb remote protocol requires this), and do what we need to do, then resume.
559
560bool
561GDBRemoteCommunicationClient::SendInterrupt
562(
563 Mutex::Locker& locker,
564 uint32_t seconds_to_wait_for_stop,
565 bool &sent_interrupt,
566 bool &timed_out
567)
568{
569 sent_interrupt = false;
570 timed_out = false;
571 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
572
573 if (IsRunning())
574 {
575 // Only send an interrupt if our debugserver is running...
576 if (GetSequenceMutex (locker) == false)
577 {
578 // Someone has the mutex locked waiting for a response or for the
579 // inferior to stop, so send the interrupt on the down low...
580 char ctrl_c = '\x03';
581 ConnectionStatus status = eConnectionStatusSuccess;
582 TimeValue timeout;
583 if (seconds_to_wait_for_stop)
584 {
585 timeout = TimeValue::Now();
586 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
587 }
588 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
589 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
590 if (bytes_written > 0)
591 {
592 sent_interrupt = true;
593 if (seconds_to_wait_for_stop)
594 {
595 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
596 {
597 if (log)
598 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__);
599 return true;
600 }
601 else
602 {
603 if (log)
604 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
605 }
606 }
607 else
608 {
609 if (log)
610 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
611 return true;
612 }
613 }
614 else
615 {
616 if (log)
617 log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__);
618 }
619 return false;
620 }
621 else
622 {
623 if (log)
624 log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
625 }
626 }
627 return true;
628}
629
630lldb::pid_t
631GDBRemoteCommunicationClient::GetCurrentProcessID ()
632{
633 StringExtractorGDBRemote response;
634 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
635 {
636 if (response.GetChar() == 'Q')
637 if (response.GetChar() == 'C')
638 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
639 }
640 return LLDB_INVALID_PROCESS_ID;
641}
642
643bool
644GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
645{
646 error_str.clear();
647 StringExtractorGDBRemote response;
648 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
649 {
650 if (response.IsOKResponse())
651 return true;
652 if (response.GetChar() == 'E')
653 {
654 // A string the describes what failed when launching...
655 error_str = response.GetStringRef().substr(1);
656 }
657 else
658 {
659 error_str.assign ("unknown error occurred launching process");
660 }
661 }
662 else
663 {
664 error_str.assign ("failed to send the qLaunchSuccess packet");
665 }
666 return false;
667}
668
669int
670GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
671{
672 if (argv && argv[0])
673 {
674 StreamString packet;
675 packet.PutChar('A');
676 const char *arg;
677 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
678 {
679 const int arg_len = strlen(arg);
680 if (i > 0)
681 packet.PutChar(',');
682 packet.Printf("%i,%i,", arg_len * 2, i);
683 packet.PutBytesAsRawHex8 (arg, arg_len);
684 }
685
686 StringExtractorGDBRemote response;
687 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
688 {
689 if (response.IsOKResponse())
690 return 0;
691 uint8_t error = response.GetError();
692 if (error)
693 return error;
694 }
695 }
696 return -1;
697}
698
699int
700GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
701{
702 if (name_equal_value && name_equal_value[0])
703 {
704 StreamString packet;
705 packet.Printf("QEnvironment:%s", name_equal_value);
706 StringExtractorGDBRemote response;
707 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
708 {
709 if (response.IsOKResponse())
710 return 0;
711 uint8_t error = response.GetError();
712 if (error)
713 return error;
714 }
715 }
716 return -1;
717}
718
Greg Claytona4582402011-05-08 04:53:50 +0000719int
720GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
721{
722 if (arch && arch[0])
723 {
724 StreamString packet;
725 packet.Printf("QLaunchArch:%s", arch);
726 StringExtractorGDBRemote response;
727 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
728 {
729 if (response.IsOKResponse())
730 return 0;
731 uint8_t error = response.GetError();
732 if (error)
733 return error;
734 }
735 }
736 return -1;
737}
738
Greg Clayton61d043b2011-03-22 04:00:09 +0000739bool
Greg Clayton58e26e02011-03-24 04:28:38 +0000740GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
741 uint32_t &minor,
742 uint32_t &update)
743{
744 if (GetHostInfo ())
745 {
746 if (m_os_version_major != UINT32_MAX)
747 {
748 major = m_os_version_major;
749 minor = m_os_version_minor;
750 update = m_os_version_update;
751 return true;
752 }
753 }
754 return false;
755}
756
757bool
758GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
759{
760 if (GetHostInfo ())
761 {
762 if (!m_os_build.empty())
763 {
764 s = m_os_build;
765 return true;
766 }
767 }
768 s.clear();
769 return false;
770}
771
772
773bool
774GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
775{
776 if (GetHostInfo ())
777 {
778 if (!m_os_kernel.empty())
779 {
780 s = m_os_kernel;
781 return true;
782 }
783 }
784 s.clear();
785 return false;
786}
787
788bool
789GDBRemoteCommunicationClient::GetHostname (std::string &s)
790{
791 if (GetHostInfo ())
792 {
793 if (!m_hostname.empty())
794 {
795 s = m_hostname;
796 return true;
797 }
798 }
799 s.clear();
800 return false;
801}
802
803ArchSpec
804GDBRemoteCommunicationClient::GetSystemArchitecture ()
805{
806 if (GetHostInfo ())
807 return m_host_arch;
808 return ArchSpec();
809}
810
811
812bool
Greg Clayton06d7cc82011-04-04 18:18:57 +0000813GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton61d043b2011-03-22 04:00:09 +0000814{
Greg Clayton06d7cc82011-04-04 18:18:57 +0000815 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +0000816 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000817 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton61d043b2011-03-22 04:00:09 +0000818 StringExtractorGDBRemote response;
819 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
820 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +0000821 if (response.IsNormalResponse())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000822 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000823 std::string name;
824 std::string value;
825 uint32_t cpu = LLDB_INVALID_CPUTYPE;
826 uint32_t sub = 0;
827 std::string arch_name;
828 std::string os_name;
829 std::string vendor_name;
830 std::string triple;
831 uint32_t pointer_byte_size = 0;
832 StringExtractor extractor;
833 ByteOrder byte_order = eByteOrderInvalid;
834 uint32_t num_keys_decoded = 0;
835 while (response.GetNameColonValue(name, value))
Greg Claytoncb8977d2011-03-23 00:09:55 +0000836 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000837 if (name.compare("cputype") == 0)
Greg Clayton58e26e02011-03-24 04:28:38 +0000838 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000839 // exception type in big endian hex
840 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
841 if (cpu != LLDB_INVALID_CPUTYPE)
842 ++num_keys_decoded;
843 }
844 else if (name.compare("cpusubtype") == 0)
845 {
846 // exception count in big endian hex
847 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
848 if (sub != 0)
849 ++num_keys_decoded;
850 }
851 else if (name.compare("arch") == 0)
852 {
853 arch_name.swap (value);
854 ++num_keys_decoded;
855 }
856 else if (name.compare("triple") == 0)
857 {
858 // The triple comes as ASCII hex bytes since it contains '-' chars
859 extractor.GetStringRef().swap(value);
860 extractor.SetFilePos(0);
861 extractor.GetHexByteString (triple);
862 ++num_keys_decoded;
863 }
864 else if (name.compare("os_build") == 0)
865 {
866 extractor.GetStringRef().swap(value);
867 extractor.SetFilePos(0);
868 extractor.GetHexByteString (m_os_build);
869 ++num_keys_decoded;
870 }
871 else if (name.compare("hostname") == 0)
872 {
873 extractor.GetStringRef().swap(value);
874 extractor.SetFilePos(0);
875 extractor.GetHexByteString (m_hostname);
876 ++num_keys_decoded;
877 }
878 else if (name.compare("os_kernel") == 0)
879 {
880 extractor.GetStringRef().swap(value);
881 extractor.SetFilePos(0);
882 extractor.GetHexByteString (m_os_kernel);
883 ++num_keys_decoded;
884 }
885 else if (name.compare("ostype") == 0)
886 {
887 os_name.swap (value);
888 ++num_keys_decoded;
889 }
890 else if (name.compare("vendor") == 0)
891 {
892 vendor_name.swap(value);
893 ++num_keys_decoded;
894 }
895 else if (name.compare("endian") == 0)
896 {
897 ++num_keys_decoded;
898 if (value.compare("little") == 0)
899 byte_order = eByteOrderLittle;
900 else if (value.compare("big") == 0)
901 byte_order = eByteOrderBig;
902 else if (value.compare("pdp") == 0)
903 byte_order = eByteOrderPDP;
904 else
905 --num_keys_decoded;
906 }
907 else if (name.compare("ptrsize") == 0)
908 {
909 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
910 if (pointer_byte_size != 0)
911 ++num_keys_decoded;
912 }
913 else if (name.compare("os_version") == 0)
914 {
915 Args::StringToVersion (value.c_str(),
916 m_os_version_major,
917 m_os_version_minor,
918 m_os_version_update);
919 if (m_os_version_major != UINT32_MAX)
920 ++num_keys_decoded;
921 }
922 }
923
924 if (num_keys_decoded > 0)
925 m_qHostInfo_is_valid = eLazyBoolYes;
926
927 if (triple.empty())
928 {
929 if (arch_name.empty())
930 {
931 if (cpu != LLDB_INVALID_CPUTYPE)
932 {
933 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
934 if (pointer_byte_size)
935 {
936 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
937 }
938 if (byte_order != eByteOrderInvalid)
939 {
940 assert (byte_order == m_host_arch.GetByteOrder());
941 }
942 if (!vendor_name.empty())
943 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
944 if (!os_name.empty())
945 m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
946
947 }
948 }
949 else
950 {
951 std::string triple;
952 triple += arch_name;
953 triple += '-';
954 if (vendor_name.empty())
955 triple += "unknown";
956 else
957 triple += vendor_name;
958 triple += '-';
959 if (os_name.empty())
960 triple += "unknown";
961 else
962 triple += os_name;
Greg Claytonf15996e2011-04-07 22:46:35 +0000963 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Clayton58e26e02011-03-24 04:28:38 +0000964 if (pointer_byte_size)
965 {
966 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
967 }
968 if (byte_order != eByteOrderInvalid)
969 {
970 assert (byte_order == m_host_arch.GetByteOrder());
971 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000972
Greg Clayton58e26e02011-03-24 04:28:38 +0000973 }
974 }
975 else
976 {
Greg Claytonf15996e2011-04-07 22:46:35 +0000977 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000978 if (pointer_byte_size)
979 {
980 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
981 }
982 if (byte_order != eByteOrderInvalid)
983 {
984 assert (byte_order == m_host_arch.GetByteOrder());
985 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000986 }
Greg Claytoncb8977d2011-03-23 00:09:55 +0000987 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000988 }
989 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000990 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton61d043b2011-03-22 04:00:09 +0000991}
992
993int
994GDBRemoteCommunicationClient::SendAttach
995(
996 lldb::pid_t pid,
997 StringExtractorGDBRemote& response
998)
999{
1000 if (pid != LLDB_INVALID_PROCESS_ID)
1001 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001002 char packet[64];
1003 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid);
1004 assert (packet_len < sizeof(packet));
1005 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001006 {
1007 if (response.IsErrorResponse())
1008 return response.GetError();
1009 return 0;
1010 }
1011 }
1012 return -1;
1013}
1014
1015const lldb_private::ArchSpec &
1016GDBRemoteCommunicationClient::GetHostArchitecture ()
1017{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001018 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +00001019 GetHostInfo ();
Greg Claytoncb8977d2011-03-23 00:09:55 +00001020 return m_host_arch;
Greg Clayton61d043b2011-03-22 04:00:09 +00001021}
1022
1023addr_t
1024GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1025{
Greg Clayton2f085c62011-05-15 01:25:55 +00001026 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001027 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001028 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001029 char packet[64];
1030 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1031 permissions & lldb::ePermissionsReadable ? "r" : "",
1032 permissions & lldb::ePermissionsWritable ? "w" : "",
1033 permissions & lldb::ePermissionsExecutable ? "x" : "");
1034 assert (packet_len < sizeof(packet));
1035 StringExtractorGDBRemote response;
1036 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1037 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001038 if (!response.IsErrorResponse())
Greg Clayton989816b2011-05-14 01:50:35 +00001039 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1040 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001041 else
1042 {
1043 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1044 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001045 }
1046 return LLDB_INVALID_ADDRESS;
1047}
1048
1049bool
1050GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1051{
Greg Clayton2f085c62011-05-15 01:25:55 +00001052 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001053 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001054 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001055 char packet[64];
1056 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1057 assert (packet_len < sizeof(packet));
1058 StringExtractorGDBRemote response;
1059 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1060 {
1061 if (response.IsOKResponse())
1062 return true;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001063 }
1064 else
1065 {
1066 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton989816b2011-05-14 01:50:35 +00001067 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001068 }
1069 return false;
1070}
1071
1072int
1073GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1074{
1075 if (path && path[0])
1076 {
1077 StreamString packet;
1078 packet.PutCString("QSetSTDIN:");
1079 packet.PutBytesAsRawHex8(path, strlen(path));
1080
1081 StringExtractorGDBRemote response;
1082 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1083 {
1084 if (response.IsOKResponse())
1085 return 0;
1086 uint8_t error = response.GetError();
1087 if (error)
1088 return error;
1089 }
1090 }
1091 return -1;
1092}
1093
1094int
1095GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1096{
1097 if (path && path[0])
1098 {
1099 StreamString packet;
1100 packet.PutCString("QSetSTDOUT:");
1101 packet.PutBytesAsRawHex8(path, strlen(path));
1102
1103 StringExtractorGDBRemote response;
1104 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1105 {
1106 if (response.IsOKResponse())
1107 return 0;
1108 uint8_t error = response.GetError();
1109 if (error)
1110 return error;
1111 }
1112 }
1113 return -1;
1114}
1115
1116int
1117GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1118{
1119 if (path && path[0])
1120 {
1121 StreamString packet;
1122 packet.PutCString("QSetSTDERR:");
1123 packet.PutBytesAsRawHex8(path, strlen(path));
1124
1125 StringExtractorGDBRemote response;
1126 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1127 {
1128 if (response.IsOKResponse())
1129 return 0;
1130 uint8_t error = response.GetError();
1131 if (error)
1132 return error;
1133 }
1134 }
1135 return -1;
1136}
1137
1138int
1139GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1140{
1141 if (path && path[0])
1142 {
1143 StreamString packet;
1144 packet.PutCString("QSetWorkingDir:");
1145 packet.PutBytesAsRawHex8(path, strlen(path));
1146
1147 StringExtractorGDBRemote response;
1148 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1149 {
1150 if (response.IsOKResponse())
1151 return 0;
1152 uint8_t error = response.GetError();
1153 if (error)
1154 return error;
1155 }
1156 }
1157 return -1;
1158}
1159
1160int
1161GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1162{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001163 char packet[32];
1164 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1165 assert (packet_len < sizeof(packet));
Greg Clayton61d043b2011-03-22 04:00:09 +00001166 StringExtractorGDBRemote response;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001167 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001168 {
1169 if (response.IsOKResponse())
1170 return 0;
1171 uint8_t error = response.GetError();
1172 if (error)
1173 return error;
1174 }
1175 return -1;
1176}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001177
1178bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001179GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001180{
1181 if (response.IsNormalResponse())
1182 {
1183 std::string name;
1184 std::string value;
1185 StringExtractor extractor;
1186
1187 while (response.GetNameColonValue(name, value))
1188 {
1189 if (name.compare("pid") == 0)
1190 {
1191 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1192 }
1193 else if (name.compare("ppid") == 0)
1194 {
1195 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1196 }
1197 else if (name.compare("uid") == 0)
1198 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001199 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001200 }
1201 else if (name.compare("euid") == 0)
1202 {
1203 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1204 }
1205 else if (name.compare("gid") == 0)
1206 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001207 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001208 }
1209 else if (name.compare("egid") == 0)
1210 {
1211 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1212 }
1213 else if (name.compare("triple") == 0)
1214 {
1215 // The triple comes as ASCII hex bytes since it contains '-' chars
1216 extractor.GetStringRef().swap(value);
1217 extractor.SetFilePos(0);
1218 extractor.GetHexByteString (value);
Greg Claytonf15996e2011-04-07 22:46:35 +00001219 process_info.GetArchitecture ().SetTriple (value.c_str(), NULL);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001220 }
1221 else if (name.compare("name") == 0)
1222 {
1223 StringExtractor extractor;
1224 // The the process name from ASCII hex bytes since we can't
1225 // control the characters in a process name
1226 extractor.GetStringRef().swap(value);
1227 extractor.SetFilePos(0);
1228 extractor.GetHexByteString (value);
Greg Claytonff39f742011-04-01 00:29:43 +00001229 process_info.SetName (value.c_str());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001230 }
1231 }
1232
1233 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1234 return true;
1235 }
1236 return false;
1237}
1238
1239bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001240GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001241{
1242 process_info.Clear();
1243
1244 if (m_supports_qProcessInfoPID)
1245 {
1246 char packet[32];
1247 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%i", pid);
1248 assert (packet_len < sizeof(packet));
1249 StringExtractorGDBRemote response;
1250 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1251 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001252 return DecodeProcessInfoResponse (response, process_info);
1253 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001254 else
1255 {
1256 m_supports_qProcessInfoPID = false;
1257 return false;
1258 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001259 }
1260 return false;
1261}
1262
1263uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +00001264GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1265 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001266{
1267 process_infos.Clear();
1268
1269 if (m_supports_qfProcessInfo)
1270 {
1271 StreamString packet;
1272 packet.PutCString ("qfProcessInfo");
1273 if (!match_info.MatchAllProcesses())
1274 {
1275 packet.PutChar (':');
1276 const char *name = match_info.GetProcessInfo().GetName();
1277 bool has_name_match = false;
1278 if (name && name[0])
1279 {
1280 has_name_match = true;
1281 NameMatchType name_match_type = match_info.GetNameMatchType();
1282 switch (name_match_type)
1283 {
1284 case eNameMatchIgnore:
1285 has_name_match = false;
1286 break;
1287
1288 case eNameMatchEquals:
1289 packet.PutCString ("name_match:equals;");
1290 break;
1291
1292 case eNameMatchContains:
1293 packet.PutCString ("name_match:contains;");
1294 break;
1295
1296 case eNameMatchStartsWith:
1297 packet.PutCString ("name_match:starts_with;");
1298 break;
1299
1300 case eNameMatchEndsWith:
1301 packet.PutCString ("name_match:ends_with;");
1302 break;
1303
1304 case eNameMatchRegularExpression:
1305 packet.PutCString ("name_match:regex;");
1306 break;
1307 }
1308 if (has_name_match)
1309 {
1310 packet.PutCString ("name:");
1311 packet.PutBytesAsRawHex8(name, ::strlen(name));
1312 packet.PutChar (';');
1313 }
1314 }
1315
1316 if (match_info.GetProcessInfo().ProcessIDIsValid())
1317 packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
1318 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
1319 packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
Greg Claytonb72d0f02011-04-12 05:54:46 +00001320 if (match_info.GetProcessInfo().UserIDIsValid())
1321 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
1322 if (match_info.GetProcessInfo().GroupIDIsValid())
1323 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001324 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
1325 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
1326 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1327 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
1328 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1329 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
1330 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
1331 {
1332 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
1333 const llvm::Triple &triple = match_arch.GetTriple();
1334 packet.PutCString("triple:");
1335 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
1336 packet.PutChar (';');
1337 }
1338 }
1339 StringExtractorGDBRemote response;
1340 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1341 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001342 do
1343 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001344 ProcessInstanceInfo process_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001345 if (!DecodeProcessInfoResponse (response, process_info))
1346 break;
1347 process_infos.Append(process_info);
1348 response.GetStringRef().clear();
1349 response.SetFilePos(0);
1350 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
1351 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001352 else
1353 {
1354 m_supports_qfProcessInfo = false;
1355 return 0;
1356 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001357 }
1358 return process_infos.GetSize();
1359
1360}
1361
1362bool
1363GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
1364{
1365 if (m_supports_qUserName)
1366 {
1367 char packet[32];
1368 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
1369 assert (packet_len < sizeof(packet));
1370 StringExtractorGDBRemote response;
1371 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1372 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001373 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 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001382 else
1383 {
1384 m_supports_qUserName = false;
1385 return false;
1386 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001387 }
1388 return false;
1389
1390}
1391
1392bool
1393GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
1394{
1395 if (m_supports_qGroupName)
1396 {
1397 char packet[32];
1398 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
1399 assert (packet_len < sizeof(packet));
1400 StringExtractorGDBRemote response;
1401 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1402 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001403 if (response.IsNormalResponse())
1404 {
1405 // Make sure we parsed the right number of characters. The response is
1406 // the hex encoded group name and should make up the entire packet.
1407 // If there are any non-hex ASCII bytes, the length won't match below..
1408 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1409 return true;
1410 }
1411 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001412 else
1413 {
1414 m_supports_qGroupName = false;
1415 return false;
1416 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001417 }
1418 return false;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001419}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001420
Greg Clayton06d7cc82011-04-04 18:18:57 +00001421void
1422GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
1423{
1424 uint32_t i;
1425 TimeValue start_time, end_time;
1426 uint64_t total_time_nsec;
1427 float packets_per_second;
1428 if (SendSpeedTestPacket (0, 0))
1429 {
1430 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
1431 {
1432 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
1433 {
1434 start_time = TimeValue::Now();
1435 for (i=0; i<num_packets; ++i)
1436 {
1437 SendSpeedTestPacket (send_size, recv_size);
1438 }
1439 end_time = TimeValue::Now();
1440 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001441 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001442 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%09.9llu sec for %f packets/sec.\n",
1443 num_packets,
1444 send_size,
1445 recv_size,
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001446 total_time_nsec / TimeValue::NanoSecondPerSecond,
1447 total_time_nsec % TimeValue::NanoSecondPerSecond,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001448 packets_per_second);
1449 if (recv_size == 0)
1450 recv_size = 32;
1451 }
1452 if (send_size == 0)
1453 send_size = 32;
1454 }
1455 }
1456 else
1457 {
1458 start_time = TimeValue::Now();
1459 for (i=0; i<num_packets; ++i)
1460 {
1461 GetCurrentProcessID ();
1462 }
1463 end_time = TimeValue::Now();
1464 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001465 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001466 printf ("%u 'qC' packets packets in 0x%llu%09.9llu sec for %f packets/sec.\n",
1467 num_packets,
Stephen Wilsonbaf01e02011-04-07 10:27:22 +00001468 total_time_nsec / TimeValue::NanoSecondPerSecond,
1469 total_time_nsec % TimeValue::NanoSecondPerSecond,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001470 packets_per_second);
1471 }
1472}
1473
1474bool
1475GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
1476{
1477 StreamString packet;
1478 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
1479 uint32_t bytes_left = send_size;
1480 while (bytes_left > 0)
1481 {
1482 if (bytes_left >= 26)
1483 {
1484 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
1485 bytes_left -= 26;
1486 }
1487 else
1488 {
1489 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
1490 bytes_left = 0;
1491 }
1492 }
1493
1494 StringExtractorGDBRemote response;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001495 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001496 return false;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001497}
Greg Claytonb72d0f02011-04-12 05:54:46 +00001498
1499uint16_t
1500GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
1501{
1502 StringExtractorGDBRemote response;
1503 if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
1504 {
1505 std::string name;
1506 std::string value;
1507 uint16_t port = 0;
1508 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1509 while (response.GetNameColonValue(name, value))
1510 {
1511 if (name.size() == 4 && name.compare("port") == 0)
1512 port = Args::StringToUInt32(value.c_str(), 0, 0);
1513 if (name.size() == 3 && name.compare("pid") == 0)
1514 pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
1515 }
1516 return port;
1517 }
1518 return 0;
1519}
1520
1521bool
1522GDBRemoteCommunicationClient::SetCurrentThread (int tid)
1523{
1524 if (m_curr_tid == tid)
1525 return true;
1526
1527 char packet[32];
1528 int packet_len;
1529 if (tid <= 0)
1530 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
1531 else
1532 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
1533 assert (packet_len + 1 < sizeof(packet));
1534 StringExtractorGDBRemote response;
1535 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1536 {
1537 if (response.IsOKResponse())
1538 {
1539 m_curr_tid = tid;
1540 return true;
1541 }
1542 }
1543 return false;
1544}
1545
1546bool
1547GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
1548{
1549 if (m_curr_tid_run == tid)
1550 return true;
1551
1552 char packet[32];
1553 int packet_len;
1554 if (tid <= 0)
1555 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
1556 else
1557 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
1558
1559 assert (packet_len + 1 < sizeof(packet));
1560 StringExtractorGDBRemote response;
1561 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1562 {
1563 if (response.IsOKResponse())
1564 {
1565 m_curr_tid_run = tid;
1566 return true;
1567 }
1568 }
1569 return false;
1570}
1571
1572bool
1573GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
1574{
1575 if (SendPacketAndWaitForResponse("?", 1, response, false))
1576 return response.IsNormalResponse();
1577 return false;
1578}
1579
1580bool
1581GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
1582{
1583 if (m_supports_qThreadStopInfo)
1584 {
1585 char packet[256];
1586 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
1587 assert (packet_len < sizeof(packet));
1588 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1589 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001590 if (response.IsNormalResponse())
Greg Claytonb72d0f02011-04-12 05:54:46 +00001591 return true;
1592 else
1593 return false;
1594 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001595 else
1596 {
1597 m_supports_qThreadStopInfo = false;
1598 }
Greg Claytonb72d0f02011-04-12 05:54:46 +00001599 }
Greg Clayton139da722011-05-20 03:15:54 +00001600// if (SetCurrentThread (tid))
1601// return GetStopReply (response);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001602 return false;
1603}
1604
1605
1606uint8_t
1607GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
1608{
1609 switch (type)
1610 {
1611 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
1612 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
1613 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
1614 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
1615 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
1616 default: return UINT8_MAX;
1617 }
1618
1619 char packet[64];
1620 const int packet_len = ::snprintf (packet,
1621 sizeof(packet),
1622 "%c%i,%llx,%x",
1623 insert ? 'Z' : 'z',
1624 type,
1625 addr,
1626 length);
1627
1628 assert (packet_len + 1 < sizeof(packet));
1629 StringExtractorGDBRemote response;
1630 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
1631 {
1632 if (response.IsOKResponse())
1633 return 0;
Greg Claytonb72d0f02011-04-12 05:54:46 +00001634 else if (response.IsErrorResponse())
1635 return response.GetError();
1636 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001637 else
1638 {
1639 switch (type)
1640 {
1641 case eBreakpointSoftware: m_supports_z0 = false; break;
1642 case eBreakpointHardware: m_supports_z1 = false; break;
1643 case eWatchpointWrite: m_supports_z2 = false; break;
1644 case eWatchpointRead: m_supports_z3 = false; break;
1645 case eWatchpointReadWrite: m_supports_z4 = false; break;
1646 default: break;
1647 }
1648 }
1649
Greg Claytonb72d0f02011-04-12 05:54:46 +00001650 return UINT8_MAX;
1651}
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001652
1653size_t
1654GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
1655 bool &sequence_mutex_unavailable)
1656{
1657 Mutex::Locker locker;
1658 thread_ids.clear();
1659
1660 if (GetSequenceMutex (locker))
1661 {
1662 sequence_mutex_unavailable = false;
1663 StringExtractorGDBRemote response;
1664
1665 TimeValue timeout_time;
1666 timeout_time = TimeValue::Now();
1667 timeout_time.OffsetWithSeconds (m_packet_timeout*2); // We will always send at least two packets here...
1668
1669 for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketNoLock (response, &timeout_time);
1670 response.IsNormalResponse();
1671 SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketNoLock (response, &timeout_time))
1672 {
1673 char ch = response.GetChar();
1674 if (ch == 'l')
1675 break;
1676 if (ch == 'm')
1677 {
1678 do
1679 {
1680 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1681
1682 if (tid != LLDB_INVALID_THREAD_ID)
1683 {
1684 thread_ids.push_back (tid);
1685 }
1686 ch = response.GetChar(); // Skip the command separator
1687 } while (ch == ','); // Make sure we got a comma separator
1688 }
1689 }
1690 }
1691 else
1692 {
1693 sequence_mutex_unavailable = true;
1694 }
1695 return thread_ids.size();
1696}