blob: afe376a5f589f21cb3a57d03cbc9b760d96faaac [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{
Greg Clayton61d043b2011-03-22 04:00:09 +000071}
72
73//----------------------------------------------------------------------
74// Destructor
75//----------------------------------------------------------------------
76GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
77{
Greg Clayton61d043b2011-03-22 04:00:09 +000078 if (IsConnected())
Greg Clayton61d043b2011-03-22 04:00:09 +000079 Disconnect();
Greg Clayton61d043b2011-03-22 04:00:09 +000080}
81
82bool
Greg Clayton58e26e02011-03-24 04:28:38 +000083GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
84{
85 // Start the read thread after we send the handshake ack since if we
86 // fail to send the handshake ack, there is no reason to continue...
87 if (SendAck())
Greg Clayton63afdb02011-06-17 01:22:15 +000088 return true;
Greg Clayton58e26e02011-03-24 04:28:38 +000089
90 if (error_ptr)
91 error_ptr->SetErrorString("failed to send the handshake ack");
92 return false;
93}
94
95void
96GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton61d043b2011-03-22 04:00:09 +000097{
98 if (m_supports_not_sending_acks == eLazyBoolCalculate)
99 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000100 m_send_acks = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000101 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton58e26e02011-03-24 04:28:38 +0000102
103 StringExtractorGDBRemote response;
Greg Clayton61d043b2011-03-22 04:00:09 +0000104 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
105 {
106 if (response.IsOKResponse())
Greg Clayton58e26e02011-03-24 04:28:38 +0000107 {
108 m_send_acks = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000109 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton58e26e02011-03-24 04:28:38 +0000110 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000111 }
112 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000113}
114
115void
116GDBRemoteCommunicationClient::ResetDiscoverableSettings()
117{
118 m_supports_not_sending_acks = eLazyBoolCalculate;
119 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton61d043b2011-03-22 04:00:09 +0000120 m_supports_vCont_c = eLazyBoolCalculate;
121 m_supports_vCont_C = eLazyBoolCalculate;
122 m_supports_vCont_s = eLazyBoolCalculate;
123 m_supports_vCont_S = eLazyBoolCalculate;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000124 m_qHostInfo_is_valid = eLazyBoolCalculate;
Greg Clayton2f085c62011-05-15 01:25:55 +0000125 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
Greg Clayton989816b2011-05-14 01:50:35 +0000126
Greg Clayton24bc5d92011-03-30 18:16:51 +0000127 m_supports_qProcessInfoPID = true;
128 m_supports_qfProcessInfo = true;
129 m_supports_qUserName = true;
130 m_supports_qGroupName = true;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000131 m_supports_qThreadStopInfo = true;
132 m_supports_z0 = true;
133 m_supports_z1 = true;
134 m_supports_z2 = true;
135 m_supports_z3 = true;
136 m_supports_z4 = true;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000137 m_host_arch.Clear();
Greg Clayton61d043b2011-03-22 04:00:09 +0000138}
139
140
141bool
142GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
143{
144 if (m_supports_thread_suffix == eLazyBoolCalculate)
145 {
146 StringExtractorGDBRemote response;
147 m_supports_thread_suffix = eLazyBoolNo;
148 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
149 {
150 if (response.IsOKResponse())
151 m_supports_thread_suffix = eLazyBoolYes;
152 }
153 }
154 return m_supports_thread_suffix;
155}
156bool
157GDBRemoteCommunicationClient::GetVContSupported (char flavor)
158{
159 if (m_supports_vCont_c == eLazyBoolCalculate)
160 {
161 StringExtractorGDBRemote response;
162 m_supports_vCont_any = eLazyBoolNo;
163 m_supports_vCont_all = eLazyBoolNo;
164 m_supports_vCont_c = eLazyBoolNo;
165 m_supports_vCont_C = eLazyBoolNo;
166 m_supports_vCont_s = eLazyBoolNo;
167 m_supports_vCont_S = eLazyBoolNo;
168 if (SendPacketAndWaitForResponse("vCont?", response, false))
169 {
170 const char *response_cstr = response.GetStringRef().c_str();
171 if (::strstr (response_cstr, ";c"))
172 m_supports_vCont_c = eLazyBoolYes;
173
174 if (::strstr (response_cstr, ";C"))
175 m_supports_vCont_C = eLazyBoolYes;
176
177 if (::strstr (response_cstr, ";s"))
178 m_supports_vCont_s = eLazyBoolYes;
179
180 if (::strstr (response_cstr, ";S"))
181 m_supports_vCont_S = eLazyBoolYes;
182
183 if (m_supports_vCont_c == eLazyBoolYes &&
184 m_supports_vCont_C == eLazyBoolYes &&
185 m_supports_vCont_s == eLazyBoolYes &&
186 m_supports_vCont_S == eLazyBoolYes)
187 {
188 m_supports_vCont_all = eLazyBoolYes;
189 }
190
191 if (m_supports_vCont_c == eLazyBoolYes ||
192 m_supports_vCont_C == eLazyBoolYes ||
193 m_supports_vCont_s == eLazyBoolYes ||
194 m_supports_vCont_S == eLazyBoolYes)
195 {
196 m_supports_vCont_any = eLazyBoolYes;
197 }
198 }
199 }
200
201 switch (flavor)
202 {
203 case 'a': return m_supports_vCont_any;
204 case 'A': return m_supports_vCont_all;
205 case 'c': return m_supports_vCont_c;
206 case 'C': return m_supports_vCont_C;
207 case 's': return m_supports_vCont_s;
208 case 'S': return m_supports_vCont_S;
209 default: break;
210 }
211 return false;
212}
213
214
215size_t
216GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
217(
218 const char *payload,
219 StringExtractorGDBRemote &response,
220 bool send_async
221)
222{
223 return SendPacketAndWaitForResponse (payload,
224 ::strlen (payload),
225 response,
226 send_async);
227}
228
229size_t
230GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
231(
232 const char *payload,
233 size_t payload_length,
234 StringExtractorGDBRemote &response,
235 bool send_async
236)
237{
238 Mutex::Locker locker;
Greg Clayton61d043b2011-03-22 04:00:09 +0000239 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
240
241 if (GetSequenceMutex (locker))
242 {
Greg Clayton139da722011-05-20 03:15:54 +0000243 if (SendPacketNoLock (payload, payload_length))
Greg Clayton63afdb02011-06-17 01:22:15 +0000244 return WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
Greg Clayton61d043b2011-03-22 04:00:09 +0000245 }
246 else
247 {
248 if (send_async)
249 {
250 Mutex::Locker async_locker (m_async_mutex);
251 m_async_packet.assign(payload, payload_length);
252 m_async_packet_predicate.SetValue (true, eBroadcastNever);
253
254 if (log)
255 log->Printf ("async: async packet = %s", m_async_packet.c_str());
256
257 bool timed_out = false;
258 bool sent_interrupt = false;
259 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
260 {
261 if (sent_interrupt)
262 {
Greg Clayton63afdb02011-06-17 01:22:15 +0000263 TimeValue timeout_time;
264 timeout_time = TimeValue::Now();
265 timeout_time.OffsetWithSeconds (m_packet_timeout);
266
Greg Clayton61d043b2011-03-22 04:00:09 +0000267 if (log)
268 log->Printf ("async: sent interrupt");
269 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
270 {
271 if (log)
272 log->Printf ("async: got response");
273 response = m_async_response;
274 return response.GetStringRef().size();
275 }
276 else
277 {
278 if (log)
279 log->Printf ("async: timed out waiting for response");
280 }
281
282 // Make sure we wait until the continue packet has been sent again...
283 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
284 {
285 if (log)
286 log->Printf ("async: timed out waiting for process to resume");
287 }
288 }
289 else
290 {
291 // We had a racy condition where we went to send the interrupt
292 // yet we were able to get the loc
293 }
294 }
295 else
296 {
297 if (log)
298 log->Printf ("async: failed to interrupt");
299 }
300 }
301 else
302 {
303 if (log)
304 log->Printf ("mutex taken and send_async == false, aborting packet");
305 }
306 }
307 return 0;
308}
309
310//template<typename _Tp>
311//class ScopedValueChanger
312//{
313//public:
314// // Take a value reference and the value to assign it to when this class
315// // instance goes out of scope.
316// ScopedValueChanger (_Tp &value_ref, _Tp value) :
317// m_value_ref (value_ref),
318// m_value (value)
319// {
320// }
321//
322// // This object is going out of scope, change the value pointed to by
323// // m_value_ref to the value we got during construction which was stored in
324// // m_value;
325// ~ScopedValueChanger ()
326// {
327// m_value_ref = m_value;
328// }
329//protected:
330// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
331// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
332//};
333
334StateType
335GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
336(
337 ProcessGDBRemote *process,
338 const char *payload,
339 size_t packet_length,
340 StringExtractorGDBRemote &response
341)
342{
343 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
344 if (log)
345 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
346
347 Mutex::Locker locker(m_sequence_mutex);
348 StateType state = eStateRunning;
349
350 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
351 m_public_is_running.SetValue (true, eBroadcastNever);
352 // Set the starting continue packet into "continue_packet". This packet
353 // make change if we are interrupted and we continue after an async packet...
354 std::string continue_packet(payload, packet_length);
355
Greg Clayton628cead2011-05-19 03:54:16 +0000356 bool got_stdout = false;
357
Greg Clayton61d043b2011-03-22 04:00:09 +0000358 while (state == eStateRunning)
359 {
Greg Clayton628cead2011-05-19 03:54:16 +0000360 if (!got_stdout)
361 {
362 if (log)
363 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
364 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
365 state = eStateInvalid;
Greg Clayton61d043b2011-03-22 04:00:09 +0000366
Greg Clayton628cead2011-05-19 03:54:16 +0000367 m_private_is_running.SetValue (true, eBroadcastNever);
368 }
369
370 got_stdout = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000371
372 if (log)
373 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__);
374
Greg Clayton63afdb02011-06-17 01:22:15 +0000375 if (WaitForPacketWithTimeoutMicroSeconds (response, UINT32_MAX))
Greg Clayton61d043b2011-03-22 04:00:09 +0000376 {
377 if (response.Empty())
378 state = eStateInvalid;
379 else
380 {
381 const char stop_type = response.GetChar();
382 if (log)
383 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
384 switch (stop_type)
385 {
386 case 'T':
387 case 'S':
388 if (process->GetStopID() == 0)
389 {
390 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
391 {
392 lldb::pid_t pid = GetCurrentProcessID ();
393 if (pid != LLDB_INVALID_PROCESS_ID)
394 process->SetID (pid);
395 }
396 process->BuildDynamicRegisterInfo (true);
397 }
398
399 // Privately notify any internal threads that we have stopped
400 // in case we wanted to interrupt our process, yet we might
401 // send a packet and continue without returning control to the
402 // user.
403 m_private_is_running.SetValue (false, eBroadcastAlways);
404 if (m_async_signal != -1)
405 {
406 if (log)
407 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
408
409 // Save off the async signal we are supposed to send
410 const int async_signal = m_async_signal;
411 // Clear the async signal member so we don't end up
412 // sending the signal multiple times...
413 m_async_signal = -1;
414 // Check which signal we stopped with
415 uint8_t signo = response.GetHexU8(255);
416 if (signo == async_signal)
417 {
418 if (log)
419 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
420
421 // We already stopped with a signal that we wanted
422 // to stop with, so we are done
423 response.SetFilePos (0);
424 }
425 else
426 {
427 // We stopped with a different signal that the one
428 // we wanted to stop with, so now we must resume
429 // with the signal we want
430 char signal_packet[32];
431 int signal_packet_len = 0;
432 signal_packet_len = ::snprintf (signal_packet,
433 sizeof (signal_packet),
434 "C%2.2x",
435 async_signal);
436
437 if (log)
438 log->Printf ("async: stopped with signal %s, resume with %s",
439 Host::GetSignalAsCString (signo),
440 Host::GetSignalAsCString (async_signal));
441
442 // Set the continue packet to resume...
443 continue_packet.assign(signal_packet, signal_packet_len);
444 continue;
445 }
446 }
447 else if (m_async_packet_predicate.GetValue())
448 {
449 // We are supposed to send an asynchronous packet while
450 // we are running.
451 m_async_response.Clear();
452 if (m_async_packet.empty())
453 {
454 if (log)
455 log->Printf ("async: error: empty async packet");
456
457 }
458 else
459 {
460 if (log)
461 log->Printf ("async: sending packet: %s",
462 m_async_packet.c_str());
463
464 SendPacketAndWaitForResponse (&m_async_packet[0],
465 m_async_packet.size(),
466 m_async_response,
467 false);
468 }
469 // Let the other thread that was trying to send the async
470 // packet know that the packet has been sent and response is
471 // ready...
472 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
473
474 // Set the continue packet to resume...
475 continue_packet.assign (1, 'c');
476 continue;
477 }
478 // Stop with signal and thread info
479 state = eStateStopped;
480 break;
481
482 case 'W':
483 case 'X':
484 // process exited
485 state = eStateExited;
486 break;
487
488 case 'O':
489 // STDOUT
490 {
Greg Clayton628cead2011-05-19 03:54:16 +0000491 got_stdout = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000492 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 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +0000813 if (response.IsNormalResponse())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000814 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000815 std::string name;
816 std::string value;
817 uint32_t cpu = LLDB_INVALID_CPUTYPE;
818 uint32_t sub = 0;
819 std::string arch_name;
820 std::string os_name;
821 std::string vendor_name;
822 std::string triple;
823 uint32_t pointer_byte_size = 0;
824 StringExtractor extractor;
825 ByteOrder byte_order = eByteOrderInvalid;
826 uint32_t num_keys_decoded = 0;
827 while (response.GetNameColonValue(name, value))
Greg Claytoncb8977d2011-03-23 00:09:55 +0000828 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000829 if (name.compare("cputype") == 0)
Greg Clayton58e26e02011-03-24 04:28:38 +0000830 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000831 // exception type in big endian hex
832 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
833 if (cpu != LLDB_INVALID_CPUTYPE)
834 ++num_keys_decoded;
835 }
836 else if (name.compare("cpusubtype") == 0)
837 {
838 // exception count in big endian hex
839 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
840 if (sub != 0)
841 ++num_keys_decoded;
842 }
843 else if (name.compare("arch") == 0)
844 {
845 arch_name.swap (value);
846 ++num_keys_decoded;
847 }
848 else if (name.compare("triple") == 0)
849 {
850 // The triple comes as ASCII hex bytes since it contains '-' chars
851 extractor.GetStringRef().swap(value);
852 extractor.SetFilePos(0);
853 extractor.GetHexByteString (triple);
854 ++num_keys_decoded;
855 }
856 else if (name.compare("os_build") == 0)
857 {
858 extractor.GetStringRef().swap(value);
859 extractor.SetFilePos(0);
860 extractor.GetHexByteString (m_os_build);
861 ++num_keys_decoded;
862 }
863 else if (name.compare("hostname") == 0)
864 {
865 extractor.GetStringRef().swap(value);
866 extractor.SetFilePos(0);
867 extractor.GetHexByteString (m_hostname);
868 ++num_keys_decoded;
869 }
870 else if (name.compare("os_kernel") == 0)
871 {
872 extractor.GetStringRef().swap(value);
873 extractor.SetFilePos(0);
874 extractor.GetHexByteString (m_os_kernel);
875 ++num_keys_decoded;
876 }
877 else if (name.compare("ostype") == 0)
878 {
879 os_name.swap (value);
880 ++num_keys_decoded;
881 }
882 else if (name.compare("vendor") == 0)
883 {
884 vendor_name.swap(value);
885 ++num_keys_decoded;
886 }
887 else if (name.compare("endian") == 0)
888 {
889 ++num_keys_decoded;
890 if (value.compare("little") == 0)
891 byte_order = eByteOrderLittle;
892 else if (value.compare("big") == 0)
893 byte_order = eByteOrderBig;
894 else if (value.compare("pdp") == 0)
895 byte_order = eByteOrderPDP;
896 else
897 --num_keys_decoded;
898 }
899 else if (name.compare("ptrsize") == 0)
900 {
901 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
902 if (pointer_byte_size != 0)
903 ++num_keys_decoded;
904 }
905 else if (name.compare("os_version") == 0)
906 {
907 Args::StringToVersion (value.c_str(),
908 m_os_version_major,
909 m_os_version_minor,
910 m_os_version_update);
911 if (m_os_version_major != UINT32_MAX)
912 ++num_keys_decoded;
913 }
914 }
915
916 if (num_keys_decoded > 0)
917 m_qHostInfo_is_valid = eLazyBoolYes;
918
919 if (triple.empty())
920 {
921 if (arch_name.empty())
922 {
923 if (cpu != LLDB_INVALID_CPUTYPE)
924 {
925 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
926 if (pointer_byte_size)
927 {
928 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
929 }
930 if (byte_order != eByteOrderInvalid)
931 {
932 assert (byte_order == m_host_arch.GetByteOrder());
933 }
934 if (!vendor_name.empty())
935 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
936 if (!os_name.empty())
937 m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
938
939 }
940 }
941 else
942 {
943 std::string triple;
944 triple += arch_name;
945 triple += '-';
946 if (vendor_name.empty())
947 triple += "unknown";
948 else
949 triple += vendor_name;
950 triple += '-';
951 if (os_name.empty())
952 triple += "unknown";
953 else
954 triple += os_name;
Greg Claytonf15996e2011-04-07 22:46:35 +0000955 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Clayton58e26e02011-03-24 04:28:38 +0000956 if (pointer_byte_size)
957 {
958 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
959 }
960 if (byte_order != eByteOrderInvalid)
961 {
962 assert (byte_order == m_host_arch.GetByteOrder());
963 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000964
Greg Clayton58e26e02011-03-24 04:28:38 +0000965 }
966 }
967 else
968 {
Greg Claytonf15996e2011-04-07 22:46:35 +0000969 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000970 if (pointer_byte_size)
971 {
972 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
973 }
974 if (byte_order != eByteOrderInvalid)
975 {
976 assert (byte_order == m_host_arch.GetByteOrder());
977 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000978 }
Greg Claytoncb8977d2011-03-23 00:09:55 +0000979 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000980 }
981 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000982 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton61d043b2011-03-22 04:00:09 +0000983}
984
985int
986GDBRemoteCommunicationClient::SendAttach
987(
988 lldb::pid_t pid,
989 StringExtractorGDBRemote& response
990)
991{
992 if (pid != LLDB_INVALID_PROCESS_ID)
993 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000994 char packet[64];
995 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid);
996 assert (packet_len < sizeof(packet));
997 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +0000998 {
999 if (response.IsErrorResponse())
1000 return response.GetError();
1001 return 0;
1002 }
1003 }
1004 return -1;
1005}
1006
1007const lldb_private::ArchSpec &
1008GDBRemoteCommunicationClient::GetHostArchitecture ()
1009{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001010 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +00001011 GetHostInfo ();
Greg Claytoncb8977d2011-03-23 00:09:55 +00001012 return m_host_arch;
Greg Clayton61d043b2011-03-22 04:00:09 +00001013}
1014
1015addr_t
1016GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1017{
Greg Clayton2f085c62011-05-15 01:25:55 +00001018 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001019 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001020 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001021 char packet[64];
1022 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1023 permissions & lldb::ePermissionsReadable ? "r" : "",
1024 permissions & lldb::ePermissionsWritable ? "w" : "",
1025 permissions & lldb::ePermissionsExecutable ? "x" : "");
1026 assert (packet_len < sizeof(packet));
1027 StringExtractorGDBRemote response;
1028 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1029 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001030 if (!response.IsErrorResponse())
Greg Clayton989816b2011-05-14 01:50:35 +00001031 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1032 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001033 else
1034 {
1035 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1036 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001037 }
1038 return LLDB_INVALID_ADDRESS;
1039}
1040
1041bool
1042GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1043{
Greg Clayton2f085c62011-05-15 01:25:55 +00001044 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001045 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001046 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001047 char packet[64];
1048 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1049 assert (packet_len < sizeof(packet));
1050 StringExtractorGDBRemote response;
1051 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1052 {
1053 if (response.IsOKResponse())
1054 return true;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001055 }
1056 else
1057 {
1058 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 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001244 return DecodeProcessInfoResponse (response, process_info);
1245 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001246 else
1247 {
1248 m_supports_qProcessInfoPID = false;
1249 return false;
1250 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001251 }
1252 return false;
1253}
1254
1255uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +00001256GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1257 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001258{
1259 process_infos.Clear();
1260
1261 if (m_supports_qfProcessInfo)
1262 {
1263 StreamString packet;
1264 packet.PutCString ("qfProcessInfo");
1265 if (!match_info.MatchAllProcesses())
1266 {
1267 packet.PutChar (':');
1268 const char *name = match_info.GetProcessInfo().GetName();
1269 bool has_name_match = false;
1270 if (name && name[0])
1271 {
1272 has_name_match = true;
1273 NameMatchType name_match_type = match_info.GetNameMatchType();
1274 switch (name_match_type)
1275 {
1276 case eNameMatchIgnore:
1277 has_name_match = false;
1278 break;
1279
1280 case eNameMatchEquals:
1281 packet.PutCString ("name_match:equals;");
1282 break;
1283
1284 case eNameMatchContains:
1285 packet.PutCString ("name_match:contains;");
1286 break;
1287
1288 case eNameMatchStartsWith:
1289 packet.PutCString ("name_match:starts_with;");
1290 break;
1291
1292 case eNameMatchEndsWith:
1293 packet.PutCString ("name_match:ends_with;");
1294 break;
1295
1296 case eNameMatchRegularExpression:
1297 packet.PutCString ("name_match:regex;");
1298 break;
1299 }
1300 if (has_name_match)
1301 {
1302 packet.PutCString ("name:");
1303 packet.PutBytesAsRawHex8(name, ::strlen(name));
1304 packet.PutChar (';');
1305 }
1306 }
1307
1308 if (match_info.GetProcessInfo().ProcessIDIsValid())
1309 packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
1310 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
1311 packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
Greg Claytonb72d0f02011-04-12 05:54:46 +00001312 if (match_info.GetProcessInfo().UserIDIsValid())
1313 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
1314 if (match_info.GetProcessInfo().GroupIDIsValid())
1315 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001316 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
1317 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
1318 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1319 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
1320 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1321 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
1322 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
1323 {
1324 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
1325 const llvm::Triple &triple = match_arch.GetTriple();
1326 packet.PutCString("triple:");
1327 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
1328 packet.PutChar (';');
1329 }
1330 }
1331 StringExtractorGDBRemote response;
1332 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1333 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001334 do
1335 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001336 ProcessInstanceInfo process_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001337 if (!DecodeProcessInfoResponse (response, process_info))
1338 break;
1339 process_infos.Append(process_info);
1340 response.GetStringRef().clear();
1341 response.SetFilePos(0);
1342 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
1343 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001344 else
1345 {
1346 m_supports_qfProcessInfo = false;
1347 return 0;
1348 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001349 }
1350 return process_infos.GetSize();
1351
1352}
1353
1354bool
1355GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
1356{
1357 if (m_supports_qUserName)
1358 {
1359 char packet[32];
1360 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
1361 assert (packet_len < sizeof(packet));
1362 StringExtractorGDBRemote response;
1363 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1364 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001365 if (response.IsNormalResponse())
1366 {
1367 // Make sure we parsed the right number of characters. The response is
1368 // the hex encoded user name and should make up the entire packet.
1369 // If there are any non-hex ASCII bytes, the length won't match below..
1370 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1371 return true;
1372 }
1373 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001374 else
1375 {
1376 m_supports_qUserName = false;
1377 return false;
1378 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001379 }
1380 return false;
1381
1382}
1383
1384bool
1385GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
1386{
1387 if (m_supports_qGroupName)
1388 {
1389 char packet[32];
1390 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
1391 assert (packet_len < sizeof(packet));
1392 StringExtractorGDBRemote response;
1393 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1394 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001395 if (response.IsNormalResponse())
1396 {
1397 // Make sure we parsed the right number of characters. The response is
1398 // the hex encoded group name and should make up the entire packet.
1399 // If there are any non-hex ASCII bytes, the length won't match below..
1400 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1401 return true;
1402 }
1403 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001404 else
1405 {
1406 m_supports_qGroupName = false;
1407 return false;
1408 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001409 }
1410 return false;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001411}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001412
Greg Clayton06d7cc82011-04-04 18:18:57 +00001413void
1414GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
1415{
1416 uint32_t i;
1417 TimeValue start_time, end_time;
1418 uint64_t total_time_nsec;
1419 float packets_per_second;
1420 if (SendSpeedTestPacket (0, 0))
1421 {
1422 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
1423 {
1424 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
1425 {
1426 start_time = TimeValue::Now();
1427 for (i=0; i<num_packets; ++i)
1428 {
1429 SendSpeedTestPacket (send_size, recv_size);
1430 }
1431 end_time = TimeValue::Now();
1432 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001433 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001434 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%09.9llu sec for %f packets/sec.\n",
1435 num_packets,
1436 send_size,
1437 recv_size,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001438 total_time_nsec / TimeValue::NanoSecPerSec,
1439 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001440 packets_per_second);
1441 if (recv_size == 0)
1442 recv_size = 32;
1443 }
1444 if (send_size == 0)
1445 send_size = 32;
1446 }
1447 }
1448 else
1449 {
1450 start_time = TimeValue::Now();
1451 for (i=0; i<num_packets; ++i)
1452 {
1453 GetCurrentProcessID ();
1454 }
1455 end_time = TimeValue::Now();
1456 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001457 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001458 printf ("%u 'qC' packets packets in 0x%llu%09.9llu sec for %f packets/sec.\n",
1459 num_packets,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001460 total_time_nsec / TimeValue::NanoSecPerSec,
1461 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001462 packets_per_second);
1463 }
1464}
1465
1466bool
1467GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
1468{
1469 StreamString packet;
1470 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
1471 uint32_t bytes_left = send_size;
1472 while (bytes_left > 0)
1473 {
1474 if (bytes_left >= 26)
1475 {
1476 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
1477 bytes_left -= 26;
1478 }
1479 else
1480 {
1481 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
1482 bytes_left = 0;
1483 }
1484 }
1485
1486 StringExtractorGDBRemote response;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001487 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001488 return false;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001489}
Greg Claytonb72d0f02011-04-12 05:54:46 +00001490
1491uint16_t
1492GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
1493{
1494 StringExtractorGDBRemote response;
1495 if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
1496 {
1497 std::string name;
1498 std::string value;
1499 uint16_t port = 0;
1500 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1501 while (response.GetNameColonValue(name, value))
1502 {
1503 if (name.size() == 4 && name.compare("port") == 0)
1504 port = Args::StringToUInt32(value.c_str(), 0, 0);
1505 if (name.size() == 3 && name.compare("pid") == 0)
1506 pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
1507 }
1508 return port;
1509 }
1510 return 0;
1511}
1512
1513bool
1514GDBRemoteCommunicationClient::SetCurrentThread (int tid)
1515{
1516 if (m_curr_tid == tid)
1517 return true;
1518
1519 char packet[32];
1520 int packet_len;
1521 if (tid <= 0)
1522 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
1523 else
1524 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
1525 assert (packet_len + 1 < sizeof(packet));
1526 StringExtractorGDBRemote response;
1527 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1528 {
1529 if (response.IsOKResponse())
1530 {
1531 m_curr_tid = tid;
1532 return true;
1533 }
1534 }
1535 return false;
1536}
1537
1538bool
1539GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
1540{
1541 if (m_curr_tid_run == tid)
1542 return true;
1543
1544 char packet[32];
1545 int packet_len;
1546 if (tid <= 0)
1547 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
1548 else
1549 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
1550
1551 assert (packet_len + 1 < sizeof(packet));
1552 StringExtractorGDBRemote response;
1553 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1554 {
1555 if (response.IsOKResponse())
1556 {
1557 m_curr_tid_run = tid;
1558 return true;
1559 }
1560 }
1561 return false;
1562}
1563
1564bool
1565GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
1566{
1567 if (SendPacketAndWaitForResponse("?", 1, response, false))
1568 return response.IsNormalResponse();
1569 return false;
1570}
1571
1572bool
1573GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
1574{
1575 if (m_supports_qThreadStopInfo)
1576 {
1577 char packet[256];
1578 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
1579 assert (packet_len < sizeof(packet));
1580 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1581 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001582 if (response.IsNormalResponse())
Greg Claytonb72d0f02011-04-12 05:54:46 +00001583 return true;
1584 else
1585 return false;
1586 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001587 else
1588 {
1589 m_supports_qThreadStopInfo = false;
1590 }
Greg Claytonb72d0f02011-04-12 05:54:46 +00001591 }
Greg Clayton139da722011-05-20 03:15:54 +00001592// if (SetCurrentThread (tid))
1593// return GetStopReply (response);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001594 return false;
1595}
1596
1597
1598uint8_t
1599GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
1600{
1601 switch (type)
1602 {
1603 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
1604 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
1605 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
1606 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
1607 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
1608 default: return UINT8_MAX;
1609 }
1610
1611 char packet[64];
1612 const int packet_len = ::snprintf (packet,
1613 sizeof(packet),
1614 "%c%i,%llx,%x",
1615 insert ? 'Z' : 'z',
1616 type,
1617 addr,
1618 length);
1619
1620 assert (packet_len + 1 < sizeof(packet));
1621 StringExtractorGDBRemote response;
1622 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
1623 {
1624 if (response.IsOKResponse())
1625 return 0;
Greg Claytonb72d0f02011-04-12 05:54:46 +00001626 else if (response.IsErrorResponse())
1627 return response.GetError();
1628 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001629 else
1630 {
1631 switch (type)
1632 {
1633 case eBreakpointSoftware: m_supports_z0 = false; break;
1634 case eBreakpointHardware: m_supports_z1 = false; break;
1635 case eWatchpointWrite: m_supports_z2 = false; break;
1636 case eWatchpointRead: m_supports_z3 = false; break;
1637 case eWatchpointReadWrite: m_supports_z4 = false; break;
1638 default: break;
1639 }
1640 }
1641
Greg Claytonb72d0f02011-04-12 05:54:46 +00001642 return UINT8_MAX;
1643}
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001644
1645size_t
1646GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
1647 bool &sequence_mutex_unavailable)
1648{
1649 Mutex::Locker locker;
1650 thread_ids.clear();
1651
1652 if (GetSequenceMutex (locker))
1653 {
1654 sequence_mutex_unavailable = false;
1655 StringExtractorGDBRemote response;
1656
Greg Clayton63afdb02011-06-17 01:22:15 +00001657 for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001658 response.IsNormalResponse();
Greg Clayton63afdb02011-06-17 01:22:15 +00001659 SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()))
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001660 {
1661 char ch = response.GetChar();
1662 if (ch == 'l')
1663 break;
1664 if (ch == 'm')
1665 {
1666 do
1667 {
1668 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1669
1670 if (tid != LLDB_INVALID_THREAD_ID)
1671 {
1672 thread_ids.push_back (tid);
1673 }
1674 ch = response.GetChar(); // Skip the command separator
1675 } while (ch == ','); // Make sure we got a comma separator
1676 }
1677 }
1678 }
1679 else
1680 {
1681 sequence_mutex_unavailable = true;
1682 }
1683 return thread_ids.size();
1684}