blob: 7cd77e58f526cfce19a8a3636ed046c358843b92 [file] [log] [blame]
Greg Clayton576d8832011-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
Daniel Maleab89d0492013-08-28 16:06:16 +000014#include <sys/stat.h>
15
Greg Clayton576d8832011-03-22 04:00:09 +000016// C++ Includes
Han Ming Ong4b6459f2013-01-18 23:11:53 +000017#include <sstream>
18
Greg Clayton576d8832011-03-22 04:00:09 +000019// Other libraries and framework includes
20#include "llvm/ADT/Triple.h"
21#include "lldb/Interpreter/Args.h"
22#include "lldb/Core/ConnectionFileDescriptor.h"
23#include "lldb/Core/Log.h"
24#include "lldb/Core/State.h"
Daniel Maleae0f8f572013-08-26 23:57:52 +000025#include "lldb/Core/StreamGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000026#include "lldb/Core/StreamString.h"
27#include "lldb/Host/Endian.h"
28#include "lldb/Host/Host.h"
29#include "lldb/Host/TimeValue.h"
30
31// Project includes
32#include "Utility/StringExtractorGDBRemote.h"
33#include "ProcessGDBRemote.h"
34#include "ProcessGDBRemoteLog.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000035#include "lldb/Host/Config.h"
Greg Clayton576d8832011-03-22 04:00:09 +000036
37using namespace lldb;
38using namespace lldb_private;
39
Virgile Bellob2f1fb22013-08-23 12:44:05 +000040#ifdef LLDB_DISABLE_POSIX
41#define SIGSTOP 17
42#endif
43
Greg Clayton576d8832011-03-22 04:00:09 +000044//----------------------------------------------------------------------
45// GDBRemoteCommunicationClient constructor
46//----------------------------------------------------------------------
Greg Clayton8b82f082011-04-12 05:54:46 +000047GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
48 GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
Greg Clayton576d8832011-03-22 04:00:09 +000049 m_supports_not_sending_acks (eLazyBoolCalculate),
50 m_supports_thread_suffix (eLazyBoolCalculate),
Greg Clayton44633992012-04-10 03:22:03 +000051 m_supports_threads_in_stop_reply (eLazyBoolCalculate),
Greg Clayton576d8832011-03-22 04:00:09 +000052 m_supports_vCont_all (eLazyBoolCalculate),
53 m_supports_vCont_any (eLazyBoolCalculate),
54 m_supports_vCont_c (eLazyBoolCalculate),
55 m_supports_vCont_C (eLazyBoolCalculate),
56 m_supports_vCont_s (eLazyBoolCalculate),
57 m_supports_vCont_S (eLazyBoolCalculate),
Greg Clayton32e0a752011-03-30 18:16:51 +000058 m_qHostInfo_is_valid (eLazyBoolCalculate),
Jason Molendaf17b5ac2012-12-19 02:54:03 +000059 m_qProcessInfo_is_valid (eLazyBoolCalculate),
Greg Clayton70b57652011-05-15 01:25:55 +000060 m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
Greg Clayton46fb5582011-11-18 07:03:08 +000061 m_supports_memory_region_info (eLazyBoolCalculate),
Johnny Chen64637202012-05-23 21:09:52 +000062 m_supports_watchpoint_support_info (eLazyBoolCalculate),
Jim Inghamacff8952013-05-02 00:27:30 +000063 m_supports_detach_stay_stopped (eLazyBoolCalculate),
Enrico Granataf04a2192012-07-13 23:18:48 +000064 m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
Jim Inghamcd16df92012-07-20 21:37:13 +000065 m_attach_or_wait_reply(eLazyBoolCalculate),
Jim Ingham279ceec2012-07-25 21:12:43 +000066 m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
Eric Christopher2490f5c2013-08-30 17:50:57 +000067 m_supports_p (eLazyBoolCalculate),
Greg Claytonf74cf862013-11-13 23:28:31 +000068 m_supports_QSaveRegisterState (eLazyBoolCalculate),
Greg Clayton32e0a752011-03-30 18:16:51 +000069 m_supports_qProcessInfoPID (true),
70 m_supports_qfProcessInfo (true),
71 m_supports_qUserName (true),
72 m_supports_qGroupName (true),
Greg Clayton8b82f082011-04-12 05:54:46 +000073 m_supports_qThreadStopInfo (true),
74 m_supports_z0 (true),
75 m_supports_z1 (true),
76 m_supports_z2 (true),
77 m_supports_z3 (true),
78 m_supports_z4 (true),
Greg Clayton89600582013-10-10 17:53:50 +000079 m_supports_QEnvironment (true),
80 m_supports_QEnvironmentHexEncoded (true),
Greg Clayton8b82f082011-04-12 05:54:46 +000081 m_curr_tid (LLDB_INVALID_THREAD_ID),
82 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Johnny Chen64637202012-05-23 21:09:52 +000083 m_num_supported_hardware_watchpoints (0),
Greg Clayton576d8832011-03-22 04:00:09 +000084 m_async_mutex (Mutex::eMutexTypeRecursive),
85 m_async_packet_predicate (false),
86 m_async_packet (),
87 m_async_response (),
88 m_async_signal (-1),
Han Ming Ong4b6459f2013-01-18 23:11:53 +000089 m_thread_id_to_used_usec_map (),
Greg Clayton1cb64962011-03-24 04:28:38 +000090 m_host_arch(),
Jason Molendaf17b5ac2012-12-19 02:54:03 +000091 m_process_arch(),
Greg Clayton1cb64962011-03-24 04:28:38 +000092 m_os_version_major (UINT32_MAX),
93 m_os_version_minor (UINT32_MAX),
Greg Clayton9ac6d2d2013-10-25 18:13:17 +000094 m_os_version_update (UINT32_MAX),
95 m_os_build (),
96 m_os_kernel (),
97 m_hostname (),
98 m_default_packet_timeout (0)
Greg Clayton576d8832011-03-22 04:00:09 +000099{
Greg Clayton576d8832011-03-22 04:00:09 +0000100}
101
102//----------------------------------------------------------------------
103// Destructor
104//----------------------------------------------------------------------
105GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
106{
Greg Clayton576d8832011-03-22 04:00:09 +0000107 if (IsConnected())
Greg Clayton576d8832011-03-22 04:00:09 +0000108 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000109}
110
111bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000112GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
113{
114 // Start the read thread after we send the handshake ack since if we
115 // fail to send the handshake ack, there is no reason to continue...
116 if (SendAck())
Greg Clayton73bf5db2011-06-17 01:22:15 +0000117 return true;
Greg Clayton1cb64962011-03-24 04:28:38 +0000118
119 if (error_ptr)
120 error_ptr->SetErrorString("failed to send the handshake ack");
121 return false;
122}
123
124void
125GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton576d8832011-03-22 04:00:09 +0000126{
127 if (m_supports_not_sending_acks == eLazyBoolCalculate)
128 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000129 m_send_acks = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000130 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000131
132 StringExtractorGDBRemote response;
Greg Clayton576d8832011-03-22 04:00:09 +0000133 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
134 {
135 if (response.IsOKResponse())
Greg Clayton1cb64962011-03-24 04:28:38 +0000136 {
137 m_send_acks = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000138 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton1cb64962011-03-24 04:28:38 +0000139 }
Greg Clayton576d8832011-03-22 04:00:09 +0000140 }
141 }
Greg Clayton576d8832011-03-22 04:00:09 +0000142}
143
144void
Greg Clayton44633992012-04-10 03:22:03 +0000145GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
146{
147 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
148 {
149 m_supports_threads_in_stop_reply = eLazyBoolNo;
150
151 StringExtractorGDBRemote response;
152 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false))
153 {
154 if (response.IsOKResponse())
155 m_supports_threads_in_stop_reply = eLazyBoolYes;
156 }
157 }
158}
159
Jim Inghamcd16df92012-07-20 21:37:13 +0000160bool
161GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
162{
163 if (m_attach_or_wait_reply == eLazyBoolCalculate)
164 {
165 m_attach_or_wait_reply = eLazyBoolNo;
166
167 StringExtractorGDBRemote response;
168 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false))
169 {
170 if (response.IsOKResponse())
171 m_attach_or_wait_reply = eLazyBoolYes;
172 }
173 }
174 if (m_attach_or_wait_reply == eLazyBoolYes)
175 return true;
176 else
177 return false;
178}
179
Jim Ingham279ceec2012-07-25 21:12:43 +0000180bool
181GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
182{
183 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
184 {
185 m_prepare_for_reg_writing_reply = eLazyBoolNo;
186
187 StringExtractorGDBRemote response;
188 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false))
189 {
190 if (response.IsOKResponse())
191 m_prepare_for_reg_writing_reply = eLazyBoolYes;
192 }
193 }
194 if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
195 return true;
196 else
197 return false;
198}
199
Greg Clayton44633992012-04-10 03:22:03 +0000200
201void
Greg Clayton576d8832011-03-22 04:00:09 +0000202GDBRemoteCommunicationClient::ResetDiscoverableSettings()
203{
204 m_supports_not_sending_acks = eLazyBoolCalculate;
205 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton44633992012-04-10 03:22:03 +0000206 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
Greg Clayton576d8832011-03-22 04:00:09 +0000207 m_supports_vCont_c = eLazyBoolCalculate;
208 m_supports_vCont_C = eLazyBoolCalculate;
209 m_supports_vCont_s = eLazyBoolCalculate;
210 m_supports_vCont_S = eLazyBoolCalculate;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000211 m_supports_p = eLazyBoolCalculate;
Greg Claytonf74cf862013-11-13 23:28:31 +0000212 m_supports_QSaveRegisterState = eLazyBoolCalculate;
Greg Clayton32e0a752011-03-30 18:16:51 +0000213 m_qHostInfo_is_valid = eLazyBoolCalculate;
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000214 m_qProcessInfo_is_valid = eLazyBoolCalculate;
Greg Clayton70b57652011-05-15 01:25:55 +0000215 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
Greg Clayton46fb5582011-11-18 07:03:08 +0000216 m_supports_memory_region_info = eLazyBoolCalculate;
Jim Ingham279ceec2012-07-25 21:12:43 +0000217 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
218 m_attach_or_wait_reply = eLazyBoolCalculate;
Greg Clayton2a48f522011-05-14 01:50:35 +0000219
Greg Clayton32e0a752011-03-30 18:16:51 +0000220 m_supports_qProcessInfoPID = true;
221 m_supports_qfProcessInfo = true;
222 m_supports_qUserName = true;
223 m_supports_qGroupName = true;
Greg Clayton8b82f082011-04-12 05:54:46 +0000224 m_supports_qThreadStopInfo = true;
225 m_supports_z0 = true;
226 m_supports_z1 = true;
227 m_supports_z2 = true;
228 m_supports_z3 = true;
229 m_supports_z4 = true;
Greg Clayton89600582013-10-10 17:53:50 +0000230 m_supports_QEnvironment = true;
231 m_supports_QEnvironmentHexEncoded = true;
Greg Claytond314e812011-03-23 00:09:55 +0000232 m_host_arch.Clear();
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000233 m_process_arch.Clear();
Greg Clayton576d8832011-03-22 04:00:09 +0000234}
235
236
237bool
238GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
239{
240 if (m_supports_thread_suffix == eLazyBoolCalculate)
241 {
242 StringExtractorGDBRemote response;
243 m_supports_thread_suffix = eLazyBoolNo;
244 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
245 {
246 if (response.IsOKResponse())
247 m_supports_thread_suffix = eLazyBoolYes;
248 }
249 }
250 return m_supports_thread_suffix;
251}
252bool
253GDBRemoteCommunicationClient::GetVContSupported (char flavor)
254{
255 if (m_supports_vCont_c == eLazyBoolCalculate)
256 {
257 StringExtractorGDBRemote response;
258 m_supports_vCont_any = eLazyBoolNo;
259 m_supports_vCont_all = eLazyBoolNo;
260 m_supports_vCont_c = eLazyBoolNo;
261 m_supports_vCont_C = eLazyBoolNo;
262 m_supports_vCont_s = eLazyBoolNo;
263 m_supports_vCont_S = eLazyBoolNo;
264 if (SendPacketAndWaitForResponse("vCont?", response, false))
265 {
266 const char *response_cstr = response.GetStringRef().c_str();
267 if (::strstr (response_cstr, ";c"))
268 m_supports_vCont_c = eLazyBoolYes;
269
270 if (::strstr (response_cstr, ";C"))
271 m_supports_vCont_C = eLazyBoolYes;
272
273 if (::strstr (response_cstr, ";s"))
274 m_supports_vCont_s = eLazyBoolYes;
275
276 if (::strstr (response_cstr, ";S"))
277 m_supports_vCont_S = eLazyBoolYes;
278
279 if (m_supports_vCont_c == eLazyBoolYes &&
280 m_supports_vCont_C == eLazyBoolYes &&
281 m_supports_vCont_s == eLazyBoolYes &&
282 m_supports_vCont_S == eLazyBoolYes)
283 {
284 m_supports_vCont_all = eLazyBoolYes;
285 }
286
287 if (m_supports_vCont_c == eLazyBoolYes ||
288 m_supports_vCont_C == eLazyBoolYes ||
289 m_supports_vCont_s == eLazyBoolYes ||
290 m_supports_vCont_S == eLazyBoolYes)
291 {
292 m_supports_vCont_any = eLazyBoolYes;
293 }
294 }
295 }
296
297 switch (flavor)
298 {
299 case 'a': return m_supports_vCont_any;
300 case 'A': return m_supports_vCont_all;
301 case 'c': return m_supports_vCont_c;
302 case 'C': return m_supports_vCont_C;
303 case 's': return m_supports_vCont_s;
304 case 'S': return m_supports_vCont_S;
305 default: break;
306 }
307 return false;
308}
309
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000310// Check if the target supports 'p' packet. It sends out a 'p'
311// packet and checks the response. A normal packet will tell us
312// that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000313//
314// Takes a valid thread ID because p needs to apply to a thread.
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000315bool
Sean Callananb1de1142013-09-04 23:24:15 +0000316GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000317{
318 if (m_supports_p == eLazyBoolCalculate)
319 {
320 StringExtractorGDBRemote response;
321 m_supports_p = eLazyBoolNo;
Sean Callananb1de1142013-09-04 23:24:15 +0000322 char packet[256];
323 if (GetThreadSuffixSupported())
324 snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
325 else
326 snprintf(packet, sizeof(packet), "p0");
327
328 if (SendPacketAndWaitForResponse(packet, response, false))
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000329 {
330 if (response.IsNormalResponse())
331 m_supports_p = eLazyBoolYes;
332 }
333 }
334 return m_supports_p;
335}
Greg Clayton576d8832011-03-22 04:00:09 +0000336
337size_t
338GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
339(
340 const char *payload,
341 StringExtractorGDBRemote &response,
342 bool send_async
343)
344{
345 return SendPacketAndWaitForResponse (payload,
346 ::strlen (payload),
347 response,
348 send_async);
349}
350
351size_t
352GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
353(
354 const char *payload,
355 size_t payload_length,
356 StringExtractorGDBRemote &response,
357 bool send_async
358)
359{
360 Mutex::Locker locker;
Greg Clayton5160ce52013-03-27 23:08:40 +0000361 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton644247c2011-07-07 01:59:51 +0000362 size_t response_len = 0;
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000363 if (GetSequenceMutex (locker))
Greg Clayton576d8832011-03-22 04:00:09 +0000364 {
Greg Clayton5fe15d22011-05-20 03:15:54 +0000365 if (SendPacketNoLock (payload, payload_length))
Greg Clayton644247c2011-07-07 01:59:51 +0000366 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
367 else
368 {
369 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000370 log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
Greg Clayton644247c2011-07-07 01:59:51 +0000371 }
Greg Clayton576d8832011-03-22 04:00:09 +0000372 }
373 else
374 {
375 if (send_async)
376 {
Greg Claytond3544052012-05-31 21:24:20 +0000377 if (IsRunning())
Greg Clayton576d8832011-03-22 04:00:09 +0000378 {
Greg Claytond3544052012-05-31 21:24:20 +0000379 Mutex::Locker async_locker (m_async_mutex);
380 m_async_packet.assign(payload, payload_length);
381 m_async_packet_predicate.SetValue (true, eBroadcastNever);
382
383 if (log)
384 log->Printf ("async: async packet = %s", m_async_packet.c_str());
385
386 bool timed_out = false;
387 if (SendInterrupt(locker, 2, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +0000388 {
Greg Claytond3544052012-05-31 21:24:20 +0000389 if (m_interrupt_sent)
Greg Clayton576d8832011-03-22 04:00:09 +0000390 {
Jim Inghambabfc382012-06-06 00:32:39 +0000391 m_interrupt_sent = false;
Greg Claytond3544052012-05-31 21:24:20 +0000392 TimeValue timeout_time;
393 timeout_time = TimeValue::Now();
394 timeout_time.OffsetWithSeconds (m_packet_timeout);
395
Greg Clayton576d8832011-03-22 04:00:09 +0000396 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000397 log->Printf ("async: sent interrupt");
Greg Clayton644247c2011-07-07 01:59:51 +0000398
Greg Claytond3544052012-05-31 21:24:20 +0000399 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
Greg Claytone889ad62011-10-27 22:04:16 +0000400 {
Greg Claytond3544052012-05-31 21:24:20 +0000401 if (log)
402 log->Printf ("async: got response");
403
404 // Swap the response buffer to avoid malloc and string copy
405 response.GetStringRef().swap (m_async_response.GetStringRef());
406 response_len = response.GetStringRef().size();
407 }
408 else
409 {
410 if (log)
411 log->Printf ("async: timed out waiting for response");
412 }
413
414 // Make sure we wait until the continue packet has been sent again...
415 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
416 {
417 if (log)
418 {
419 if (timed_out)
420 log->Printf ("async: timed out waiting for process to resume, but process was resumed");
421 else
422 log->Printf ("async: async packet sent");
423 }
424 }
425 else
426 {
427 if (log)
428 log->Printf ("async: timed out waiting for process to resume");
Greg Claytone889ad62011-10-27 22:04:16 +0000429 }
430 }
431 else
432 {
Greg Claytond3544052012-05-31 21:24:20 +0000433 // We had a racy condition where we went to send the interrupt
434 // yet we were able to get the lock, so the process must have
435 // just stopped?
Greg Clayton576d8832011-03-22 04:00:09 +0000436 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000437 log->Printf ("async: got lock without sending interrupt");
438 // Send the packet normally since we got the lock
439 if (SendPacketNoLock (payload, payload_length))
440 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
441 else
442 {
443 if (log)
444 log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
445 }
Greg Clayton576d8832011-03-22 04:00:09 +0000446 }
447 }
448 else
449 {
Greg Clayton644247c2011-07-07 01:59:51 +0000450 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000451 log->Printf ("async: failed to interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +0000452 }
453 }
454 else
455 {
456 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000457 log->Printf ("async: not running, async is ignored");
Greg Clayton576d8832011-03-22 04:00:09 +0000458 }
459 }
460 else
461 {
462 if (log)
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000463 log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
Greg Clayton576d8832011-03-22 04:00:09 +0000464 }
465 }
Greg Clayton644247c2011-07-07 01:59:51 +0000466 if (response_len == 0)
467 {
468 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000469 log->Printf("error: failed to get response for '%*s'", (int) payload_length, payload);
Greg Clayton644247c2011-07-07 01:59:51 +0000470 }
471 return response_len;
Greg Clayton576d8832011-03-22 04:00:09 +0000472}
473
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000474static const char *end_delimiter = "--end--;";
475static const int end_delimiter_len = 8;
476
477std::string
478GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
479( ProcessGDBRemote *process,
480 StringExtractorGDBRemote& profileDataExtractor
481)
482{
483 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
484 std::stringstream final_output;
485 std::string name, value;
486
487 // Going to assuming thread_used_usec comes first, else bail out.
488 while (profileDataExtractor.GetNameColonValue(name, value))
489 {
490 if (name.compare("thread_used_id") == 0)
491 {
492 StringExtractor threadIDHexExtractor(value.c_str());
493 uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
494
495 bool has_used_usec = false;
496 uint32_t curr_used_usec = 0;
497 std::string usec_name, usec_value;
498 uint32_t input_file_pos = profileDataExtractor.GetFilePos();
499 if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
500 {
501 if (usec_name.compare("thread_used_usec") == 0)
502 {
503 has_used_usec = true;
504 curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
505 }
506 else
507 {
508 // We didn't find what we want, it is probably
509 // an older version. Bail out.
510 profileDataExtractor.SetFilePos(input_file_pos);
511 }
512 }
513
514 if (has_used_usec)
515 {
516 uint32_t prev_used_usec = 0;
517 std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
518 if (iterator != m_thread_id_to_used_usec_map.end())
519 {
520 prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
521 }
522
523 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
524 // A good first time record is one that runs for at least 0.25 sec
525 bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
526 bool good_subsequent_time = (prev_used_usec > 0) &&
527 ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
528
529 if (good_first_time || good_subsequent_time)
530 {
531 // We try to avoid doing too many index id reservation,
532 // resulting in fast increase of index ids.
533
534 final_output << name << ":";
535 int32_t index_id = process->AssignIndexIDToThread(thread_id);
536 final_output << index_id << ";";
537
538 final_output << usec_name << ":" << usec_value << ";";
539 }
540 else
541 {
542 // Skip past 'thread_used_name'.
543 std::string local_name, local_value;
544 profileDataExtractor.GetNameColonValue(local_name, local_value);
545 }
546
547 // Store current time as previous time so that they can be compared later.
548 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
549 }
550 else
551 {
552 // Bail out and use old string.
553 final_output << name << ":" << value << ";";
554 }
555 }
556 else
557 {
558 final_output << name << ":" << value << ";";
559 }
560 }
561 final_output << end_delimiter;
562 m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
563
564 return final_output.str();
565}
566
Greg Clayton576d8832011-03-22 04:00:09 +0000567StateType
568GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
569(
570 ProcessGDBRemote *process,
571 const char *payload,
572 size_t packet_length,
573 StringExtractorGDBRemote &response
574)
575{
Greg Clayton1f5181a2012-07-02 22:05:25 +0000576 m_curr_tid = LLDB_INVALID_THREAD_ID;
Greg Clayton5160ce52013-03-27 23:08:40 +0000577 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton576d8832011-03-22 04:00:09 +0000578 if (log)
579 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
580
581 Mutex::Locker locker(m_sequence_mutex);
582 StateType state = eStateRunning;
583
584 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
585 m_public_is_running.SetValue (true, eBroadcastNever);
586 // Set the starting continue packet into "continue_packet". This packet
Jim Inghambabfc382012-06-06 00:32:39 +0000587 // may change if we are interrupted and we continue after an async packet...
Greg Clayton576d8832011-03-22 04:00:09 +0000588 std::string continue_packet(payload, packet_length);
589
Greg Clayton3f875c52013-02-22 22:23:55 +0000590 bool got_async_packet = false;
Greg Claytonaf247d72011-05-19 03:54:16 +0000591
Greg Clayton576d8832011-03-22 04:00:09 +0000592 while (state == eStateRunning)
593 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000594 if (!got_async_packet)
Greg Claytonaf247d72011-05-19 03:54:16 +0000595 {
596 if (log)
597 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
Greg Clayton37a0a242012-04-11 00:24:49 +0000598 if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) == 0)
Greg Claytonaf247d72011-05-19 03:54:16 +0000599 state = eStateInvalid;
Greg Clayton576d8832011-03-22 04:00:09 +0000600
Greg Claytone889ad62011-10-27 22:04:16 +0000601 m_private_is_running.SetValue (true, eBroadcastAlways);
Greg Claytonaf247d72011-05-19 03:54:16 +0000602 }
603
Greg Clayton3f875c52013-02-22 22:23:55 +0000604 got_async_packet = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000605
606 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000607 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
Greg Clayton576d8832011-03-22 04:00:09 +0000608
Greg Clayton37a0a242012-04-11 00:24:49 +0000609 if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX))
Greg Clayton576d8832011-03-22 04:00:09 +0000610 {
611 if (response.Empty())
612 state = eStateInvalid;
613 else
614 {
615 const char stop_type = response.GetChar();
616 if (log)
617 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
618 switch (stop_type)
619 {
620 case 'T':
621 case 'S':
Greg Clayton576d8832011-03-22 04:00:09 +0000622 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000623 if (process->GetStopID() == 0)
Greg Clayton576d8832011-03-22 04:00:09 +0000624 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000625 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
626 {
627 lldb::pid_t pid = GetCurrentProcessID ();
628 if (pid != LLDB_INVALID_PROCESS_ID)
629 process->SetID (pid);
630 }
631 process->BuildDynamicRegisterInfo (true);
Greg Clayton576d8832011-03-22 04:00:09 +0000632 }
Greg Clayton2687cd12012-03-29 01:55:41 +0000633
634 // Privately notify any internal threads that we have stopped
635 // in case we wanted to interrupt our process, yet we might
636 // send a packet and continue without returning control to the
637 // user.
638 m_private_is_running.SetValue (false, eBroadcastAlways);
639
640 const uint8_t signo = response.GetHexU8 (UINT8_MAX);
641
Jim Inghambabfc382012-06-06 00:32:39 +0000642 bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
643 if (continue_after_async || m_interrupt_sent)
Greg Clayton2687cd12012-03-29 01:55:41 +0000644 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000645 // We sent an interrupt packet to stop the inferior process
646 // for an async signal or to send an async packet while running
647 // but we might have been single stepping and received the
648 // stop packet for the step instead of for the interrupt packet.
649 // Typically when an interrupt is sent a SIGINT or SIGSTOP
650 // is used, so if we get anything else, we need to try and
651 // get another stop reply packet that may have been sent
652 // due to sending the interrupt when the target is stopped
653 // which will just re-send a copy of the last stop reply
654 // packet. If we don't do this, then the reply for our
655 // async packet will be the repeat stop reply packet and cause
656 // a lot of trouble for us!
657 if (signo != SIGINT && signo != SIGSTOP)
658 {
Greg Claytonfb72fde2012-05-15 02:50:49 +0000659 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +0000660
661 // We didn't get a a SIGINT or SIGSTOP, so try for a
662 // very brief time (1 ms) to get another stop reply
663 // packet to make sure it doesn't get in the way
664 StringExtractorGDBRemote extra_stop_reply_packet;
665 uint32_t timeout_usec = 1000;
666 if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec))
667 {
668 switch (extra_stop_reply_packet.GetChar())
669 {
670 case 'T':
671 case 'S':
672 // We did get an extra stop reply, which means
673 // our interrupt didn't stop the target so we
674 // shouldn't continue after the async signal
675 // or packet is sent...
Greg Claytonfb72fde2012-05-15 02:50:49 +0000676 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +0000677 break;
678 }
679 }
680 }
681 }
682
683 if (m_async_signal != -1)
684 {
685 if (log)
686 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
687
688 // Save off the async signal we are supposed to send
689 const int async_signal = m_async_signal;
690 // Clear the async signal member so we don't end up
691 // sending the signal multiple times...
692 m_async_signal = -1;
693 // Check which signal we stopped with
694 if (signo == async_signal)
695 {
696 if (log)
697 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
698
699 // We already stopped with a signal that we wanted
700 // to stop with, so we are done
701 }
702 else
703 {
704 // We stopped with a different signal that the one
705 // we wanted to stop with, so now we must resume
706 // with the signal we want
707 char signal_packet[32];
708 int signal_packet_len = 0;
709 signal_packet_len = ::snprintf (signal_packet,
710 sizeof (signal_packet),
711 "C%2.2x",
712 async_signal);
713
714 if (log)
715 log->Printf ("async: stopped with signal %s, resume with %s",
716 Host::GetSignalAsCString (signo),
717 Host::GetSignalAsCString (async_signal));
718
719 // Set the continue packet to resume even if the
Greg Claytonfb72fde2012-05-15 02:50:49 +0000720 // interrupt didn't cause our stop (ignore continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +0000721 continue_packet.assign(signal_packet, signal_packet_len);
722 continue;
723 }
724 }
725 else if (m_async_packet_predicate.GetValue())
726 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000727 Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton2687cd12012-03-29 01:55:41 +0000728
729 // We are supposed to send an asynchronous packet while
730 // we are running.
731 m_async_response.Clear();
732 if (m_async_packet.empty())
733 {
734 if (packet_log)
735 packet_log->Printf ("async: error: empty async packet");
736
737 }
738 else
739 {
740 if (packet_log)
741 packet_log->Printf ("async: sending packet");
742
743 SendPacketAndWaitForResponse (&m_async_packet[0],
744 m_async_packet.size(),
745 m_async_response,
746 false);
747 }
748 // Let the other thread that was trying to send the async
749 // packet know that the packet has been sent and response is
750 // ready...
751 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
752
753 if (packet_log)
Greg Claytonfb72fde2012-05-15 02:50:49 +0000754 packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);
Greg Clayton2687cd12012-03-29 01:55:41 +0000755
756 // Set the continue packet to resume if our interrupt
757 // for the async packet did cause the stop
Greg Claytonfb72fde2012-05-15 02:50:49 +0000758 if (continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +0000759 {
Greg Claytonf1186de2012-05-24 23:42:14 +0000760 // Reverting this for now as it is causing deadlocks
761 // in programs (<rdar://problem/11529853>). In the future
762 // we should check our thread list and "do the right thing"
763 // for new threads that show up while we stop and run async
764 // packets. Setting the packet to 'c' to continue all threads
765 // is the right thing to do 99.99% of the time because if a
766 // thread was single stepping, and we sent an interrupt, we
767 // will notice above that we didn't stop due to an interrupt
768 // but stopped due to stepping and we would _not_ continue.
769 continue_packet.assign (1, 'c');
Greg Clayton2687cd12012-03-29 01:55:41 +0000770 continue;
771 }
772 }
773 // Stop with signal and thread info
774 state = eStateStopped;
Greg Clayton576d8832011-03-22 04:00:09 +0000775 }
Greg Clayton576d8832011-03-22 04:00:09 +0000776 break;
777
778 case 'W':
779 case 'X':
780 // process exited
781 state = eStateExited;
782 break;
783
784 case 'O':
785 // STDOUT
786 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000787 got_async_packet = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000788 std::string inferior_stdout;
789 inferior_stdout.reserve(response.GetBytesLeft () / 2);
790 char ch;
791 while ((ch = response.GetHexU8()) != '\0')
792 inferior_stdout.append(1, ch);
793 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
794 }
795 break;
796
Han Ming Ongab3b8b22012-11-17 00:21:04 +0000797 case 'A':
798 // Async miscellaneous reply. Right now, only profile data is coming through this channel.
799 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000800 got_async_packet = true;
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000801 std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
802 if (m_partial_profile_data.length() > 0)
803 {
804 m_partial_profile_data.append(input);
805 input = m_partial_profile_data;
806 m_partial_profile_data.clear();
807 }
808
809 size_t found, pos = 0, len = input.length();
810 while ((found = input.find(end_delimiter, pos)) != std::string::npos)
811 {
812 StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
Han Ming Ong91ed6b82013-06-24 18:15:05 +0000813 std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
814 process->BroadcastAsyncProfileData (profile_data);
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000815
816 pos = found + end_delimiter_len;
817 }
818
819 if (pos < len)
820 {
821 // Last incomplete chunk.
822 m_partial_profile_data = input.substr(pos);
823 }
Han Ming Ongab3b8b22012-11-17 00:21:04 +0000824 }
825 break;
826
Greg Clayton576d8832011-03-22 04:00:09 +0000827 case 'E':
828 // ERROR
829 state = eStateInvalid;
830 break;
831
832 default:
833 if (log)
834 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
835 state = eStateInvalid;
836 break;
837 }
838 }
839 }
840 else
841 {
842 if (log)
843 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
844 state = eStateInvalid;
845 }
846 }
847 if (log)
848 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
849 response.SetFilePos(0);
850 m_private_is_running.SetValue (false, eBroadcastAlways);
851 m_public_is_running.SetValue (false, eBroadcastAlways);
852 return state;
853}
854
855bool
856GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
857{
Greg Clayton2687cd12012-03-29 01:55:41 +0000858 Mutex::Locker async_locker (m_async_mutex);
Greg Clayton576d8832011-03-22 04:00:09 +0000859 m_async_signal = signo;
860 bool timed_out = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000861 Mutex::Locker locker;
Greg Clayton2687cd12012-03-29 01:55:41 +0000862 if (SendInterrupt (locker, 1, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +0000863 return true;
864 m_async_signal = -1;
865 return false;
866}
867
Greg Clayton37a0a242012-04-11 00:24:49 +0000868// This function takes a mutex locker as a parameter in case the GetSequenceMutex
Greg Clayton576d8832011-03-22 04:00:09 +0000869// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
870// (the expected result), then it will send the halt packet. If it does succeed
871// then the caller that requested the interrupt will want to keep the sequence
872// locked down so that no one else can send packets while the caller has control.
873// This function usually gets called when we are running and need to stop the
874// target. It can also be used when we are running and and we need to do something
875// else (like read/write memory), so we need to interrupt the running process
876// (gdb remote protocol requires this), and do what we need to do, then resume.
877
878bool
Greg Clayton2687cd12012-03-29 01:55:41 +0000879GDBRemoteCommunicationClient::SendInterrupt
Greg Clayton576d8832011-03-22 04:00:09 +0000880(
881 Mutex::Locker& locker,
882 uint32_t seconds_to_wait_for_stop,
Greg Clayton576d8832011-03-22 04:00:09 +0000883 bool &timed_out
884)
885{
Greg Clayton576d8832011-03-22 04:00:09 +0000886 timed_out = false;
Greg Clayton5160ce52013-03-27 23:08:40 +0000887 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Clayton576d8832011-03-22 04:00:09 +0000888
889 if (IsRunning())
890 {
891 // Only send an interrupt if our debugserver is running...
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000892 if (GetSequenceMutex (locker))
Greg Clayton37a0a242012-04-11 00:24:49 +0000893 {
894 if (log)
895 log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
896 }
897 else
Greg Clayton576d8832011-03-22 04:00:09 +0000898 {
899 // Someone has the mutex locked waiting for a response or for the
900 // inferior to stop, so send the interrupt on the down low...
901 char ctrl_c = '\x03';
902 ConnectionStatus status = eConnectionStatusSuccess;
Greg Clayton576d8832011-03-22 04:00:09 +0000903 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton2687cd12012-03-29 01:55:41 +0000904 if (log)
905 log->PutCString("send packet: \\x03");
Greg Clayton576d8832011-03-22 04:00:09 +0000906 if (bytes_written > 0)
907 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000908 m_interrupt_sent = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000909 if (seconds_to_wait_for_stop)
910 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000911 TimeValue timeout;
912 if (seconds_to_wait_for_stop)
913 {
914 timeout = TimeValue::Now();
915 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
916 }
Greg Clayton576d8832011-03-22 04:00:09 +0000917 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
918 {
919 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000920 log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
Greg Clayton576d8832011-03-22 04:00:09 +0000921 return true;
922 }
923 else
924 {
925 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000926 log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
Greg Clayton576d8832011-03-22 04:00:09 +0000927 }
928 }
929 else
930 {
931 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000932 log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
Greg Clayton576d8832011-03-22 04:00:09 +0000933 return true;
934 }
935 }
936 else
937 {
938 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000939 log->Printf ("SendInterrupt () - failed to write interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +0000940 }
941 return false;
942 }
Greg Clayton576d8832011-03-22 04:00:09 +0000943 }
Greg Clayton2687cd12012-03-29 01:55:41 +0000944 else
945 {
946 if (log)
947 log->Printf ("SendInterrupt () - not running");
948 }
Greg Clayton576d8832011-03-22 04:00:09 +0000949 return true;
950}
951
952lldb::pid_t
953GDBRemoteCommunicationClient::GetCurrentProcessID ()
954{
955 StringExtractorGDBRemote response;
956 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
957 {
958 if (response.GetChar() == 'Q')
959 if (response.GetChar() == 'C')
960 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
961 }
962 return LLDB_INVALID_PROCESS_ID;
963}
964
965bool
966GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
967{
968 error_str.clear();
969 StringExtractorGDBRemote response;
970 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
971 {
972 if (response.IsOKResponse())
973 return true;
974 if (response.GetChar() == 'E')
975 {
976 // A string the describes what failed when launching...
977 error_str = response.GetStringRef().substr(1);
978 }
979 else
980 {
981 error_str.assign ("unknown error occurred launching process");
982 }
983 }
984 else
985 {
Jim Ingham98d6da52012-06-28 20:30:23 +0000986 error_str.assign ("timed out waiting for app to launch");
Greg Clayton576d8832011-03-22 04:00:09 +0000987 }
988 return false;
989}
990
991int
Greg Claytonfbb76342013-11-20 21:07:01 +0000992GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
Greg Clayton576d8832011-03-22 04:00:09 +0000993{
Greg Claytonfbb76342013-11-20 21:07:01 +0000994 // Since we don't get the send argv0 separate from the executable path, we need to
995 // make sure to use the actual exectuable path found in the launch_info...
996 std::vector<const char *> argv;
997 FileSpec exe_file = launch_info.GetExecutableFile();
998 std::string exe_path;
999 const char *arg = NULL;
1000 const Args &launch_args = launch_info.GetArguments();
1001 if (exe_file)
1002 exe_path = exe_file.GetPath();
1003 else
1004 {
1005 arg = launch_args.GetArgumentAtIndex(0);
1006 if (arg)
1007 exe_path = arg;
1008 }
1009 if (!exe_path.empty())
1010 {
1011 argv.push_back(exe_path.c_str());
1012 for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
1013 {
1014 if (arg)
1015 argv.push_back(arg);
1016 }
1017 }
1018 if (!argv.empty())
Greg Clayton576d8832011-03-22 04:00:09 +00001019 {
1020 StreamString packet;
1021 packet.PutChar('A');
Greg Claytonfbb76342013-11-20 21:07:01 +00001022 for (size_t i = 0, n = argv.size(); i < n; ++i)
Greg Clayton576d8832011-03-22 04:00:09 +00001023 {
Greg Claytonfbb76342013-11-20 21:07:01 +00001024 arg = argv[i];
Greg Clayton576d8832011-03-22 04:00:09 +00001025 const int arg_len = strlen(arg);
1026 if (i > 0)
1027 packet.PutChar(',');
Greg Claytonfbb76342013-11-20 21:07:01 +00001028 packet.Printf("%i,%i,", arg_len * 2, (int)i);
Greg Clayton576d8832011-03-22 04:00:09 +00001029 packet.PutBytesAsRawHex8 (arg, arg_len);
1030 }
1031
1032 StringExtractorGDBRemote response;
1033 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1034 {
1035 if (response.IsOKResponse())
1036 return 0;
1037 uint8_t error = response.GetError();
1038 if (error)
1039 return error;
1040 }
1041 }
1042 return -1;
1043}
1044
1045int
1046GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
1047{
1048 if (name_equal_value && name_equal_value[0])
1049 {
1050 StreamString packet;
Greg Clayton89600582013-10-10 17:53:50 +00001051 bool send_hex_encoding = false;
1052 for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p)
Greg Clayton576d8832011-03-22 04:00:09 +00001053 {
Greg Clayton89600582013-10-10 17:53:50 +00001054 if (isprint(*p))
1055 {
1056 switch (*p)
1057 {
1058 case '$':
1059 case '#':
1060 send_hex_encoding = true;
1061 break;
1062 default:
1063 break;
1064 }
1065 }
1066 else
1067 {
1068 // We have non printable characters, lets hex encode this...
1069 send_hex_encoding = true;
1070 }
1071 }
1072
1073 StringExtractorGDBRemote response;
1074 if (send_hex_encoding)
1075 {
1076 if (m_supports_QEnvironmentHexEncoded)
1077 {
1078 packet.PutCString("QEnvironmentHexEncoded:");
1079 packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
1080 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1081 {
1082 if (response.IsOKResponse())
1083 return 0;
1084 uint8_t error = response.GetError();
1085 if (error)
1086 return error;
1087 if (response.IsUnsupportedResponse())
1088 m_supports_QEnvironmentHexEncoded = false;
1089 }
1090 }
1091
1092 }
1093 else if (m_supports_QEnvironment)
1094 {
1095 packet.Printf("QEnvironment:%s", name_equal_value);
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 if (response.IsUnsupportedResponse())
1104 m_supports_QEnvironment = false;
1105 }
Greg Clayton576d8832011-03-22 04:00:09 +00001106 }
1107 }
1108 return -1;
1109}
1110
Greg Claytonc4103b32011-05-08 04:53:50 +00001111int
1112GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
1113{
1114 if (arch && arch[0])
1115 {
1116 StreamString packet;
1117 packet.Printf("QLaunchArch:%s", arch);
1118 StringExtractorGDBRemote response;
1119 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1120 {
1121 if (response.IsOKResponse())
1122 return 0;
1123 uint8_t error = response.GetError();
1124 if (error)
1125 return error;
1126 }
1127 }
1128 return -1;
1129}
1130
Greg Clayton576d8832011-03-22 04:00:09 +00001131bool
Greg Clayton1cb64962011-03-24 04:28:38 +00001132GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
1133 uint32_t &minor,
1134 uint32_t &update)
1135{
1136 if (GetHostInfo ())
1137 {
1138 if (m_os_version_major != UINT32_MAX)
1139 {
1140 major = m_os_version_major;
1141 minor = m_os_version_minor;
1142 update = m_os_version_update;
1143 return true;
1144 }
1145 }
1146 return false;
1147}
1148
1149bool
1150GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
1151{
1152 if (GetHostInfo ())
1153 {
1154 if (!m_os_build.empty())
1155 {
1156 s = m_os_build;
1157 return true;
1158 }
1159 }
1160 s.clear();
1161 return false;
1162}
1163
1164
1165bool
1166GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
1167{
1168 if (GetHostInfo ())
1169 {
1170 if (!m_os_kernel.empty())
1171 {
1172 s = m_os_kernel;
1173 return true;
1174 }
1175 }
1176 s.clear();
1177 return false;
1178}
1179
1180bool
1181GDBRemoteCommunicationClient::GetHostname (std::string &s)
1182{
1183 if (GetHostInfo ())
1184 {
1185 if (!m_hostname.empty())
1186 {
1187 s = m_hostname;
1188 return true;
1189 }
1190 }
1191 s.clear();
1192 return false;
1193}
1194
1195ArchSpec
1196GDBRemoteCommunicationClient::GetSystemArchitecture ()
1197{
1198 if (GetHostInfo ())
1199 return m_host_arch;
1200 return ArchSpec();
1201}
1202
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001203const lldb_private::ArchSpec &
1204GDBRemoteCommunicationClient::GetProcessArchitecture ()
1205{
1206 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1207 GetCurrentProcessInfo ();
1208 return m_process_arch;
1209}
1210
Greg Clayton1cb64962011-03-24 04:28:38 +00001211
1212bool
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001213GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton576d8832011-03-22 04:00:09 +00001214{
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001215 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001216 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001217 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +00001218 StringExtractorGDBRemote response;
1219 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
1220 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001221 if (response.IsNormalResponse())
Greg Claytond314e812011-03-23 00:09:55 +00001222 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001223 std::string name;
1224 std::string value;
1225 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1226 uint32_t sub = 0;
1227 std::string arch_name;
1228 std::string os_name;
1229 std::string vendor_name;
1230 std::string triple;
1231 uint32_t pointer_byte_size = 0;
1232 StringExtractor extractor;
1233 ByteOrder byte_order = eByteOrderInvalid;
1234 uint32_t num_keys_decoded = 0;
1235 while (response.GetNameColonValue(name, value))
Greg Claytond314e812011-03-23 00:09:55 +00001236 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001237 if (name.compare("cputype") == 0)
Greg Clayton1cb64962011-03-24 04:28:38 +00001238 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001239 // exception type in big endian hex
1240 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
1241 if (cpu != LLDB_INVALID_CPUTYPE)
1242 ++num_keys_decoded;
1243 }
1244 else if (name.compare("cpusubtype") == 0)
1245 {
1246 // exception count in big endian hex
1247 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
1248 if (sub != 0)
1249 ++num_keys_decoded;
1250 }
1251 else if (name.compare("arch") == 0)
1252 {
1253 arch_name.swap (value);
1254 ++num_keys_decoded;
1255 }
1256 else if (name.compare("triple") == 0)
1257 {
1258 // The triple comes as ASCII hex bytes since it contains '-' chars
1259 extractor.GetStringRef().swap(value);
1260 extractor.SetFilePos(0);
1261 extractor.GetHexByteString (triple);
1262 ++num_keys_decoded;
1263 }
1264 else if (name.compare("os_build") == 0)
1265 {
1266 extractor.GetStringRef().swap(value);
1267 extractor.SetFilePos(0);
1268 extractor.GetHexByteString (m_os_build);
1269 ++num_keys_decoded;
1270 }
1271 else if (name.compare("hostname") == 0)
1272 {
1273 extractor.GetStringRef().swap(value);
1274 extractor.SetFilePos(0);
1275 extractor.GetHexByteString (m_hostname);
1276 ++num_keys_decoded;
1277 }
1278 else if (name.compare("os_kernel") == 0)
1279 {
1280 extractor.GetStringRef().swap(value);
1281 extractor.SetFilePos(0);
1282 extractor.GetHexByteString (m_os_kernel);
1283 ++num_keys_decoded;
1284 }
1285 else if (name.compare("ostype") == 0)
1286 {
1287 os_name.swap (value);
1288 ++num_keys_decoded;
1289 }
1290 else if (name.compare("vendor") == 0)
1291 {
1292 vendor_name.swap(value);
1293 ++num_keys_decoded;
1294 }
1295 else if (name.compare("endian") == 0)
1296 {
1297 ++num_keys_decoded;
1298 if (value.compare("little") == 0)
1299 byte_order = eByteOrderLittle;
1300 else if (value.compare("big") == 0)
1301 byte_order = eByteOrderBig;
1302 else if (value.compare("pdp") == 0)
1303 byte_order = eByteOrderPDP;
1304 else
1305 --num_keys_decoded;
1306 }
1307 else if (name.compare("ptrsize") == 0)
1308 {
1309 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
1310 if (pointer_byte_size != 0)
1311 ++num_keys_decoded;
1312 }
1313 else if (name.compare("os_version") == 0)
1314 {
1315 Args::StringToVersion (value.c_str(),
1316 m_os_version_major,
1317 m_os_version_minor,
1318 m_os_version_update);
1319 if (m_os_version_major != UINT32_MAX)
1320 ++num_keys_decoded;
1321 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001322 else if (name.compare("watchpoint_exceptions_received") == 0)
1323 {
1324 ++num_keys_decoded;
1325 if (strcmp(value.c_str(),"before") == 0)
1326 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1327 else if (strcmp(value.c_str(),"after") == 0)
1328 m_watchpoints_trigger_after_instruction = eLazyBoolYes;
1329 else
1330 --num_keys_decoded;
1331 }
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00001332 else if (name.compare("default_packet_timeout") == 0)
1333 {
1334 m_default_packet_timeout = Args::StringToUInt32(value.c_str(), 0);
1335 if (m_default_packet_timeout > 0)
1336 {
1337 SetPacketTimeout(m_default_packet_timeout);
1338 ++num_keys_decoded;
1339 }
1340 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001341
Greg Clayton32e0a752011-03-30 18:16:51 +00001342 }
1343
1344 if (num_keys_decoded > 0)
1345 m_qHostInfo_is_valid = eLazyBoolYes;
1346
1347 if (triple.empty())
1348 {
1349 if (arch_name.empty())
1350 {
1351 if (cpu != LLDB_INVALID_CPUTYPE)
1352 {
1353 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
1354 if (pointer_byte_size)
1355 {
1356 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1357 }
1358 if (byte_order != eByteOrderInvalid)
1359 {
1360 assert (byte_order == m_host_arch.GetByteOrder());
1361 }
Greg Clayton70512312012-05-08 01:45:38 +00001362
1363 if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0)
1364 {
1365 switch (m_host_arch.GetMachine())
1366 {
1367 case llvm::Triple::arm:
1368 case llvm::Triple::thumb:
1369 os_name = "ios";
1370 break;
1371 default:
1372 os_name = "macosx";
1373 break;
1374 }
1375 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001376 if (!vendor_name.empty())
1377 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
1378 if (!os_name.empty())
Greg Claytone1dadb82011-09-15 00:21:03 +00001379 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Greg Clayton32e0a752011-03-30 18:16:51 +00001380
1381 }
1382 }
1383 else
1384 {
1385 std::string triple;
1386 triple += arch_name;
Greg Clayton70512312012-05-08 01:45:38 +00001387 if (!vendor_name.empty() || !os_name.empty())
1388 {
1389 triple += '-';
1390 if (vendor_name.empty())
1391 triple += "unknown";
1392 else
1393 triple += vendor_name;
1394 triple += '-';
1395 if (os_name.empty())
1396 triple += "unknown";
1397 else
1398 triple += os_name;
1399 }
1400 m_host_arch.SetTriple (triple.c_str());
1401
1402 llvm::Triple &host_triple = m_host_arch.GetTriple();
1403 if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
1404 {
1405 switch (m_host_arch.GetMachine())
1406 {
1407 case llvm::Triple::arm:
1408 case llvm::Triple::thumb:
1409 host_triple.setOS(llvm::Triple::IOS);
1410 break;
1411 default:
1412 host_triple.setOS(llvm::Triple::MacOSX);
1413 break;
1414 }
1415 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001416 if (pointer_byte_size)
1417 {
1418 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1419 }
1420 if (byte_order != eByteOrderInvalid)
1421 {
1422 assert (byte_order == m_host_arch.GetByteOrder());
1423 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001424
Greg Clayton1cb64962011-03-24 04:28:38 +00001425 }
1426 }
1427 else
1428 {
Greg Clayton70512312012-05-08 01:45:38 +00001429 m_host_arch.SetTriple (triple.c_str());
Greg Claytond314e812011-03-23 00:09:55 +00001430 if (pointer_byte_size)
1431 {
1432 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1433 }
1434 if (byte_order != eByteOrderInvalid)
1435 {
1436 assert (byte_order == m_host_arch.GetByteOrder());
1437 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001438 }
Greg Claytond314e812011-03-23 00:09:55 +00001439 }
Greg Clayton576d8832011-03-22 04:00:09 +00001440 }
1441 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001442 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001443}
1444
1445int
1446GDBRemoteCommunicationClient::SendAttach
1447(
1448 lldb::pid_t pid,
1449 StringExtractorGDBRemote& response
1450)
1451{
1452 if (pid != LLDB_INVALID_PROCESS_ID)
1453 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001454 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001455 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00001456 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00001457 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton576d8832011-03-22 04:00:09 +00001458 {
1459 if (response.IsErrorResponse())
1460 return response.GetError();
1461 return 0;
1462 }
1463 }
1464 return -1;
1465}
1466
1467const lldb_private::ArchSpec &
1468GDBRemoteCommunicationClient::GetHostArchitecture ()
1469{
Greg Clayton32e0a752011-03-30 18:16:51 +00001470 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001471 GetHostInfo ();
Greg Claytond314e812011-03-23 00:09:55 +00001472 return m_host_arch;
Greg Clayton576d8832011-03-22 04:00:09 +00001473}
1474
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00001475uint32_t
1476GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
1477{
1478 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1479 GetHostInfo ();
1480 return m_default_packet_timeout;
1481}
1482
Greg Clayton576d8832011-03-22 04:00:09 +00001483addr_t
1484GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1485{
Greg Clayton70b57652011-05-15 01:25:55 +00001486 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001487 {
Greg Clayton70b57652011-05-15 01:25:55 +00001488 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001489 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001490 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
Greg Clayton43e0af02012-09-18 18:04:04 +00001491 (uint64_t)size,
Greg Clayton2a48f522011-05-14 01:50:35 +00001492 permissions & lldb::ePermissionsReadable ? "r" : "",
1493 permissions & lldb::ePermissionsWritable ? "w" : "",
1494 permissions & lldb::ePermissionsExecutable ? "x" : "");
Andy Gibbsa297a972013-06-19 19:04:53 +00001495 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001496 StringExtractorGDBRemote response;
1497 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1498 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001499 if (!response.IsErrorResponse())
Greg Clayton2a48f522011-05-14 01:50:35 +00001500 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1501 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00001502 else
1503 {
1504 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1505 }
Greg Clayton576d8832011-03-22 04:00:09 +00001506 }
1507 return LLDB_INVALID_ADDRESS;
1508}
1509
1510bool
1511GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1512{
Greg Clayton70b57652011-05-15 01:25:55 +00001513 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001514 {
Greg Clayton70b57652011-05-15 01:25:55 +00001515 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001516 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001517 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001518 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001519 StringExtractorGDBRemote response;
1520 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1521 {
1522 if (response.IsOKResponse())
1523 return true;
Greg Clayton17a0cb62011-05-15 23:46:54 +00001524 }
1525 else
1526 {
1527 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton2a48f522011-05-14 01:50:35 +00001528 }
Greg Clayton576d8832011-03-22 04:00:09 +00001529 }
1530 return false;
1531}
1532
Jim Inghamacff8952013-05-02 00:27:30 +00001533Error
1534GDBRemoteCommunicationClient::Detach (bool keep_stopped)
Greg Clayton37a0a242012-04-11 00:24:49 +00001535{
Jim Inghamacff8952013-05-02 00:27:30 +00001536 Error error;
1537
1538 if (keep_stopped)
1539 {
1540 if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
1541 {
1542 char packet[64];
1543 const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001544 assert (packet_len < (int)sizeof(packet));
Jim Inghamacff8952013-05-02 00:27:30 +00001545 StringExtractorGDBRemote response;
1546 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1547 {
1548 m_supports_detach_stay_stopped = eLazyBoolYes;
1549 }
1550 else
1551 {
1552 m_supports_detach_stay_stopped = eLazyBoolNo;
1553 }
1554 }
1555
1556 if (m_supports_detach_stay_stopped == eLazyBoolNo)
1557 {
1558 error.SetErrorString("Stays stopped not supported by this target.");
1559 return error;
1560 }
1561 else
1562 {
1563 size_t num_sent = SendPacket ("D1", 2);
1564 if (num_sent == 0)
1565 error.SetErrorString ("Sending extended disconnect packet failed.");
1566 }
1567 }
1568 else
1569 {
1570 size_t num_sent = SendPacket ("D", 1);
1571 if (num_sent == 0)
1572 error.SetErrorString ("Sending disconnect packet failed.");
1573 }
1574 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001575}
1576
Greg Clayton46fb5582011-11-18 07:03:08 +00001577Error
1578GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
1579 lldb_private::MemoryRegionInfo &region_info)
1580{
1581 Error error;
1582 region_info.Clear();
1583
1584 if (m_supports_memory_region_info != eLazyBoolNo)
1585 {
1586 m_supports_memory_region_info = eLazyBoolYes;
1587 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001588 const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001589 assert (packet_len < (int)sizeof(packet));
Greg Clayton46fb5582011-11-18 07:03:08 +00001590 StringExtractorGDBRemote response;
1591 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1592 {
1593 std::string name;
1594 std::string value;
1595 addr_t addr_value;
1596 bool success = true;
Jason Molendacb349ee2011-12-13 05:39:38 +00001597 bool saw_permissions = false;
Greg Clayton46fb5582011-11-18 07:03:08 +00001598 while (success && response.GetNameColonValue(name, value))
1599 {
1600 if (name.compare ("start") == 0)
1601 {
1602 addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
1603 if (success)
1604 region_info.GetRange().SetRangeBase(addr_value);
1605 }
1606 else if (name.compare ("size") == 0)
1607 {
1608 addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
1609 if (success)
1610 region_info.GetRange().SetByteSize (addr_value);
1611 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001612 else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
Greg Clayton46fb5582011-11-18 07:03:08 +00001613 {
Jason Molendacb349ee2011-12-13 05:39:38 +00001614 saw_permissions = true;
1615 if (region_info.GetRange().Contains (addr))
1616 {
1617 if (value.find('r') != std::string::npos)
1618 region_info.SetReadable (MemoryRegionInfo::eYes);
1619 else
1620 region_info.SetReadable (MemoryRegionInfo::eNo);
1621
1622 if (value.find('w') != std::string::npos)
1623 region_info.SetWritable (MemoryRegionInfo::eYes);
1624 else
1625 region_info.SetWritable (MemoryRegionInfo::eNo);
1626
1627 if (value.find('x') != std::string::npos)
1628 region_info.SetExecutable (MemoryRegionInfo::eYes);
1629 else
1630 region_info.SetExecutable (MemoryRegionInfo::eNo);
1631 }
1632 else
1633 {
1634 // The reported region does not contain this address -- we're looking at an unmapped page
1635 region_info.SetReadable (MemoryRegionInfo::eNo);
1636 region_info.SetWritable (MemoryRegionInfo::eNo);
1637 region_info.SetExecutable (MemoryRegionInfo::eNo);
1638 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001639 }
1640 else if (name.compare ("error") == 0)
1641 {
1642 StringExtractorGDBRemote name_extractor;
1643 // Swap "value" over into "name_extractor"
1644 name_extractor.GetStringRef().swap(value);
1645 // Now convert the HEX bytes into a string value
1646 name_extractor.GetHexByteString (value);
1647 error.SetErrorString(value.c_str());
1648 }
1649 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001650
1651 // We got a valid address range back but no permissions -- which means this is an unmapped page
1652 if (region_info.GetRange().IsValid() && saw_permissions == false)
1653 {
1654 region_info.SetReadable (MemoryRegionInfo::eNo);
1655 region_info.SetWritable (MemoryRegionInfo::eNo);
1656 region_info.SetExecutable (MemoryRegionInfo::eNo);
1657 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001658 }
1659 else
1660 {
1661 m_supports_memory_region_info = eLazyBoolNo;
1662 }
1663 }
1664
1665 if (m_supports_memory_region_info == eLazyBoolNo)
1666 {
1667 error.SetErrorString("qMemoryRegionInfo is not supported");
1668 }
1669 if (error.Fail())
1670 region_info.Clear();
1671 return error;
1672
1673}
1674
Johnny Chen64637202012-05-23 21:09:52 +00001675Error
1676GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
1677{
1678 Error error;
1679
1680 if (m_supports_watchpoint_support_info == eLazyBoolYes)
1681 {
1682 num = m_num_supported_hardware_watchpoints;
1683 return error;
1684 }
1685
1686 // Set num to 0 first.
1687 num = 0;
1688 if (m_supports_watchpoint_support_info != eLazyBoolNo)
1689 {
1690 char packet[64];
1691 const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001692 assert (packet_len < (int)sizeof(packet));
Johnny Chen64637202012-05-23 21:09:52 +00001693 StringExtractorGDBRemote response;
1694 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1695 {
1696 m_supports_watchpoint_support_info = eLazyBoolYes;
1697 std::string name;
1698 std::string value;
1699 while (response.GetNameColonValue(name, value))
1700 {
1701 if (name.compare ("num") == 0)
1702 {
1703 num = Args::StringToUInt32(value.c_str(), 0, 0);
1704 m_num_supported_hardware_watchpoints = num;
1705 }
1706 }
1707 }
1708 else
1709 {
1710 m_supports_watchpoint_support_info = eLazyBoolNo;
1711 }
1712 }
1713
1714 if (m_supports_watchpoint_support_info == eLazyBoolNo)
1715 {
1716 error.SetErrorString("qWatchpointSupportInfo is not supported");
1717 }
1718 return error;
1719
1720}
Greg Clayton46fb5582011-11-18 07:03:08 +00001721
Enrico Granataf04a2192012-07-13 23:18:48 +00001722lldb_private::Error
1723GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after)
1724{
1725 Error error(GetWatchpointSupportInfo(num));
1726 if (error.Success())
1727 error = GetWatchpointsTriggerAfterInstruction(after);
1728 return error;
1729}
1730
1731lldb_private::Error
1732GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after)
1733{
1734 Error error;
1735
1736 // we assume watchpoints will happen after running the relevant opcode
1737 // and we only want to override this behavior if we have explicitly
1738 // received a qHostInfo telling us otherwise
1739 if (m_qHostInfo_is_valid != eLazyBoolYes)
1740 after = true;
1741 else
1742 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1743 return error;
1744}
1745
Greg Clayton576d8832011-03-22 04:00:09 +00001746int
1747GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1748{
1749 if (path && path[0])
1750 {
1751 StreamString packet;
1752 packet.PutCString("QSetSTDIN:");
1753 packet.PutBytesAsRawHex8(path, strlen(path));
1754
1755 StringExtractorGDBRemote response;
1756 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1757 {
1758 if (response.IsOKResponse())
1759 return 0;
1760 uint8_t error = response.GetError();
1761 if (error)
1762 return error;
1763 }
1764 }
1765 return -1;
1766}
1767
1768int
1769GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1770{
1771 if (path && path[0])
1772 {
1773 StreamString packet;
1774 packet.PutCString("QSetSTDOUT:");
1775 packet.PutBytesAsRawHex8(path, strlen(path));
1776
1777 StringExtractorGDBRemote response;
1778 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1779 {
1780 if (response.IsOKResponse())
1781 return 0;
1782 uint8_t error = response.GetError();
1783 if (error)
1784 return error;
1785 }
1786 }
1787 return -1;
1788}
1789
1790int
1791GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1792{
1793 if (path && path[0])
1794 {
1795 StreamString packet;
1796 packet.PutCString("QSetSTDERR:");
1797 packet.PutBytesAsRawHex8(path, strlen(path));
1798
1799 StringExtractorGDBRemote response;
1800 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1801 {
1802 if (response.IsOKResponse())
1803 return 0;
1804 uint8_t error = response.GetError();
1805 if (error)
1806 return error;
1807 }
1808 }
1809 return -1;
1810}
1811
Greg Claytonfbb76342013-11-20 21:07:01 +00001812bool
1813GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd)
1814{
1815 StringExtractorGDBRemote response;
1816 if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false))
1817 {
1818 if (response.IsUnsupportedResponse())
1819 return false;
1820 if (response.IsErrorResponse())
1821 return false;
1822 response.GetHexByteString (cwd);
1823 return !cwd.empty();
1824 }
1825 return false;
1826}
1827
Greg Clayton576d8832011-03-22 04:00:09 +00001828int
1829GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1830{
1831 if (path && path[0])
1832 {
1833 StreamString packet;
1834 packet.PutCString("QSetWorkingDir:");
1835 packet.PutBytesAsRawHex8(path, strlen(path));
1836
1837 StringExtractorGDBRemote response;
1838 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1839 {
1840 if (response.IsOKResponse())
1841 return 0;
1842 uint8_t error = response.GetError();
1843 if (error)
1844 return error;
1845 }
1846 }
1847 return -1;
1848}
1849
1850int
1851GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1852{
Greg Clayton32e0a752011-03-30 18:16:51 +00001853 char packet[32];
1854 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
Andy Gibbsa297a972013-06-19 19:04:53 +00001855 assert (packet_len < (int)sizeof(packet));
Greg Clayton576d8832011-03-22 04:00:09 +00001856 StringExtractorGDBRemote response;
Greg Clayton32e0a752011-03-30 18:16:51 +00001857 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton576d8832011-03-22 04:00:09 +00001858 {
1859 if (response.IsOKResponse())
1860 return 0;
1861 uint8_t error = response.GetError();
1862 if (error)
1863 return error;
1864 }
1865 return -1;
1866}
Greg Clayton32e0a752011-03-30 18:16:51 +00001867
1868bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001869GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00001870{
1871 if (response.IsNormalResponse())
1872 {
1873 std::string name;
1874 std::string value;
1875 StringExtractor extractor;
1876
1877 while (response.GetNameColonValue(name, value))
1878 {
1879 if (name.compare("pid") == 0)
1880 {
1881 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1882 }
1883 else if (name.compare("ppid") == 0)
1884 {
1885 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1886 }
1887 else if (name.compare("uid") == 0)
1888 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001889 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00001890 }
1891 else if (name.compare("euid") == 0)
1892 {
1893 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1894 }
1895 else if (name.compare("gid") == 0)
1896 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001897 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00001898 }
1899 else if (name.compare("egid") == 0)
1900 {
1901 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1902 }
1903 else if (name.compare("triple") == 0)
1904 {
1905 // The triple comes as ASCII hex bytes since it contains '-' chars
1906 extractor.GetStringRef().swap(value);
1907 extractor.SetFilePos(0);
1908 extractor.GetHexByteString (value);
Greg Clayton70512312012-05-08 01:45:38 +00001909 process_info.GetArchitecture ().SetTriple (value.c_str());
Greg Clayton32e0a752011-03-30 18:16:51 +00001910 }
1911 else if (name.compare("name") == 0)
1912 {
1913 StringExtractor extractor;
Filipe Cabecinhasf86cf782012-05-07 09:30:51 +00001914 // The process name from ASCII hex bytes since we can't
Greg Clayton32e0a752011-03-30 18:16:51 +00001915 // control the characters in a process name
1916 extractor.GetStringRef().swap(value);
1917 extractor.SetFilePos(0);
1918 extractor.GetHexByteString (value);
Greg Clayton144f3a92011-11-15 03:53:30 +00001919 process_info.GetExecutableFile().SetFile (value.c_str(), false);
Greg Clayton32e0a752011-03-30 18:16:51 +00001920 }
1921 }
1922
1923 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1924 return true;
1925 }
1926 return false;
1927}
1928
1929bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001930GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00001931{
1932 process_info.Clear();
1933
1934 if (m_supports_qProcessInfoPID)
1935 {
1936 char packet[32];
Daniel Malead01b2952012-11-29 21:49:15 +00001937 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00001938 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00001939 StringExtractorGDBRemote response;
1940 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1941 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001942 return DecodeProcessInfoResponse (response, process_info);
1943 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00001944 else
1945 {
1946 m_supports_qProcessInfoPID = false;
1947 return false;
1948 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001949 }
1950 return false;
1951}
1952
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001953bool
1954GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
1955{
1956 if (m_qProcessInfo_is_valid == eLazyBoolYes)
1957 return true;
1958 if (m_qProcessInfo_is_valid == eLazyBoolNo)
1959 return false;
1960
1961 GetHostInfo ();
1962
1963 StringExtractorGDBRemote response;
1964 if (SendPacketAndWaitForResponse ("qProcessInfo", response, false))
1965 {
1966 if (response.IsNormalResponse())
1967 {
1968 std::string name;
1969 std::string value;
1970 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1971 uint32_t sub = 0;
1972 std::string arch_name;
1973 std::string os_name;
1974 std::string vendor_name;
1975 std::string triple;
1976 uint32_t pointer_byte_size = 0;
1977 StringExtractor extractor;
1978 ByteOrder byte_order = eByteOrderInvalid;
1979 uint32_t num_keys_decoded = 0;
1980 while (response.GetNameColonValue(name, value))
1981 {
1982 if (name.compare("cputype") == 0)
1983 {
1984 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
1985 if (cpu != LLDB_INVALID_CPUTYPE)
1986 ++num_keys_decoded;
1987 }
1988 else if (name.compare("cpusubtype") == 0)
1989 {
1990 sub = Args::StringToUInt32 (value.c_str(), 0, 16);
1991 if (sub != 0)
1992 ++num_keys_decoded;
1993 }
1994 else if (name.compare("ostype") == 0)
1995 {
1996 os_name.swap (value);
1997 ++num_keys_decoded;
1998 }
1999 else if (name.compare("vendor") == 0)
2000 {
2001 vendor_name.swap(value);
2002 ++num_keys_decoded;
2003 }
2004 else if (name.compare("endian") == 0)
2005 {
2006 ++num_keys_decoded;
2007 if (value.compare("little") == 0)
2008 byte_order = eByteOrderLittle;
2009 else if (value.compare("big") == 0)
2010 byte_order = eByteOrderBig;
2011 else if (value.compare("pdp") == 0)
2012 byte_order = eByteOrderPDP;
2013 else
2014 --num_keys_decoded;
2015 }
2016 else if (name.compare("ptrsize") == 0)
2017 {
2018 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
2019 if (pointer_byte_size != 0)
2020 ++num_keys_decoded;
2021 }
2022 }
2023 if (num_keys_decoded > 0)
2024 m_qProcessInfo_is_valid = eLazyBoolYes;
2025 if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
2026 {
2027 m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
2028 if (pointer_byte_size)
2029 {
2030 assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
2031 }
2032 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
2033 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
2034 return true;
2035 }
2036 }
2037 }
2038 else
2039 {
2040 m_qProcessInfo_is_valid = eLazyBoolNo;
2041 }
2042
2043 return false;
2044}
2045
2046
Greg Clayton32e0a752011-03-30 18:16:51 +00002047uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00002048GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
2049 ProcessInstanceInfoList &process_infos)
Greg Clayton32e0a752011-03-30 18:16:51 +00002050{
2051 process_infos.Clear();
2052
2053 if (m_supports_qfProcessInfo)
2054 {
2055 StreamString packet;
2056 packet.PutCString ("qfProcessInfo");
2057 if (!match_info.MatchAllProcesses())
2058 {
2059 packet.PutChar (':');
2060 const char *name = match_info.GetProcessInfo().GetName();
2061 bool has_name_match = false;
2062 if (name && name[0])
2063 {
2064 has_name_match = true;
2065 NameMatchType name_match_type = match_info.GetNameMatchType();
2066 switch (name_match_type)
2067 {
2068 case eNameMatchIgnore:
2069 has_name_match = false;
2070 break;
2071
2072 case eNameMatchEquals:
2073 packet.PutCString ("name_match:equals;");
2074 break;
2075
2076 case eNameMatchContains:
2077 packet.PutCString ("name_match:contains;");
2078 break;
2079
2080 case eNameMatchStartsWith:
2081 packet.PutCString ("name_match:starts_with;");
2082 break;
2083
2084 case eNameMatchEndsWith:
2085 packet.PutCString ("name_match:ends_with;");
2086 break;
2087
2088 case eNameMatchRegularExpression:
2089 packet.PutCString ("name_match:regex;");
2090 break;
2091 }
2092 if (has_name_match)
2093 {
2094 packet.PutCString ("name:");
2095 packet.PutBytesAsRawHex8(name, ::strlen(name));
2096 packet.PutChar (';');
2097 }
2098 }
2099
2100 if (match_info.GetProcessInfo().ProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002101 packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002102 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002103 packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
Greg Clayton8b82f082011-04-12 05:54:46 +00002104 if (match_info.GetProcessInfo().UserIDIsValid())
2105 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
2106 if (match_info.GetProcessInfo().GroupIDIsValid())
2107 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002108 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2109 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
2110 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2111 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
2112 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2113 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
2114 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
2115 {
2116 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
2117 const llvm::Triple &triple = match_arch.GetTriple();
2118 packet.PutCString("triple:");
2119 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
2120 packet.PutChar (';');
2121 }
2122 }
2123 StringExtractorGDBRemote response;
2124 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
2125 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002126 do
2127 {
Greg Clayton8b82f082011-04-12 05:54:46 +00002128 ProcessInstanceInfo process_info;
Greg Clayton32e0a752011-03-30 18:16:51 +00002129 if (!DecodeProcessInfoResponse (response, process_info))
2130 break;
2131 process_infos.Append(process_info);
2132 response.GetStringRef().clear();
2133 response.SetFilePos(0);
2134 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
2135 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002136 else
2137 {
2138 m_supports_qfProcessInfo = false;
2139 return 0;
2140 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002141 }
2142 return process_infos.GetSize();
2143
2144}
2145
2146bool
2147GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
2148{
2149 if (m_supports_qUserName)
2150 {
2151 char packet[32];
2152 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002153 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002154 StringExtractorGDBRemote response;
2155 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
2156 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002157 if (response.IsNormalResponse())
2158 {
2159 // Make sure we parsed the right number of characters. The response is
2160 // the hex encoded user name and should make up the entire packet.
2161 // If there are any non-hex ASCII bytes, the length won't match below..
2162 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2163 return true;
2164 }
2165 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002166 else
2167 {
2168 m_supports_qUserName = false;
2169 return false;
2170 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002171 }
2172 return false;
2173
2174}
2175
2176bool
2177GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
2178{
2179 if (m_supports_qGroupName)
2180 {
2181 char packet[32];
2182 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002183 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002184 StringExtractorGDBRemote response;
2185 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
2186 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002187 if (response.IsNormalResponse())
2188 {
2189 // Make sure we parsed the right number of characters. The response is
2190 // the hex encoded group name and should make up the entire packet.
2191 // If there are any non-hex ASCII bytes, the length won't match below..
2192 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2193 return true;
2194 }
2195 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002196 else
2197 {
2198 m_supports_qGroupName = false;
2199 return false;
2200 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002201 }
2202 return false;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002203}
Greg Clayton32e0a752011-03-30 18:16:51 +00002204
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002205void
2206GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
2207{
2208 uint32_t i;
2209 TimeValue start_time, end_time;
2210 uint64_t total_time_nsec;
2211 float packets_per_second;
2212 if (SendSpeedTestPacket (0, 0))
2213 {
2214 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
2215 {
2216 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
2217 {
2218 start_time = TimeValue::Now();
2219 for (i=0; i<num_packets; ++i)
2220 {
2221 SendSpeedTestPacket (send_size, recv_size);
2222 }
2223 end_time = TimeValue::Now();
2224 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002225 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Daniel Malead01b2952012-11-29 21:49:15 +00002226 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %" PRIu64 ".%9.9" PRIu64 " sec for %f packets/sec.\n",
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002227 num_packets,
2228 send_size,
2229 recv_size,
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002230 total_time_nsec / TimeValue::NanoSecPerSec,
2231 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002232 packets_per_second);
2233 if (recv_size == 0)
2234 recv_size = 32;
2235 }
2236 if (send_size == 0)
2237 send_size = 32;
2238 }
2239 }
2240 else
2241 {
2242 start_time = TimeValue::Now();
2243 for (i=0; i<num_packets; ++i)
2244 {
2245 GetCurrentProcessID ();
2246 }
2247 end_time = TimeValue::Now();
2248 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002249 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Daniel Malead01b2952012-11-29 21:49:15 +00002250 printf ("%u 'qC' packets packets in 0x%" PRIu64 "%9.9" PRIu64 " sec for %f packets/sec.\n",
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002251 num_packets,
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002252 total_time_nsec / TimeValue::NanoSecPerSec,
2253 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002254 packets_per_second);
2255 }
2256}
2257
2258bool
2259GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
2260{
2261 StreamString packet;
2262 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
2263 uint32_t bytes_left = send_size;
2264 while (bytes_left > 0)
2265 {
2266 if (bytes_left >= 26)
2267 {
2268 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2269 bytes_left -= 26;
2270 }
2271 else
2272 {
2273 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
2274 bytes_left = 0;
2275 }
2276 }
2277
2278 StringExtractorGDBRemote response;
Greg Clayton17a0cb62011-05-15 23:46:54 +00002279 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002280 return false;
Greg Clayton32e0a752011-03-30 18:16:51 +00002281}
Greg Clayton8b82f082011-04-12 05:54:46 +00002282
2283uint16_t
Daniel Maleae0f8f572013-08-26 23:57:52 +00002284GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002285{
Daniel Maleae0f8f572013-08-26 23:57:52 +00002286 pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton8b82f082011-04-12 05:54:46 +00002287 StringExtractorGDBRemote response;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002288 StreamString stream;
2289 stream.PutCString("qLaunchGDBServer:port:0;");
2290 std::string hostname;
2291 if (Host::GetHostname (hostname))
2292 {
2293 // Make the GDB server we launch only accept connections from this host
2294 stream.Printf("host:%s;", hostname.c_str());
2295 }
2296 else
2297 {
2298 // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
2299 stream.Printf("host:*;");
2300 }
2301 const char *packet = stream.GetData();
2302 int packet_len = stream.GetSize();
2303
2304 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
Greg Clayton8b82f082011-04-12 05:54:46 +00002305 {
2306 std::string name;
2307 std::string value;
2308 uint16_t port = 0;
Greg Clayton8b82f082011-04-12 05:54:46 +00002309 while (response.GetNameColonValue(name, value))
2310 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00002311 if (name.compare("port") == 0)
Greg Clayton8b82f082011-04-12 05:54:46 +00002312 port = Args::StringToUInt32(value.c_str(), 0, 0);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002313 else if (name.compare("pid") == 0)
2314 pid = Args::StringToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
Greg Clayton8b82f082011-04-12 05:54:46 +00002315 }
2316 return port;
2317 }
2318 return 0;
2319}
2320
2321bool
Daniel Maleae0f8f572013-08-26 23:57:52 +00002322GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
2323{
2324 StreamString stream;
2325 stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
2326 const char *packet = stream.GetData();
2327 int packet_len = stream.GetSize();
Sylvestre Ledrufd654c42013-10-06 09:51:02 +00002328
Daniel Maleae0f8f572013-08-26 23:57:52 +00002329 StringExtractorGDBRemote response;
2330 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2331 {
2332 if (response.IsOKResponse())
2333 return true;
2334 }
2335 return false;
2336}
2337
2338bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002339GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002340{
2341 if (m_curr_tid == tid)
2342 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002343
Greg Clayton8b82f082011-04-12 05:54:46 +00002344 char packet[32];
2345 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002346 if (tid == UINT64_MAX)
2347 packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002348 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002349 packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002350 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002351 StringExtractorGDBRemote response;
2352 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2353 {
2354 if (response.IsOKResponse())
2355 {
2356 m_curr_tid = tid;
2357 return true;
2358 }
2359 }
2360 return false;
2361}
2362
2363bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002364GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002365{
2366 if (m_curr_tid_run == tid)
2367 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002368
Greg Clayton8b82f082011-04-12 05:54:46 +00002369 char packet[32];
2370 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002371 if (tid == UINT64_MAX)
2372 packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002373 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002374 packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
2375
Andy Gibbsa297a972013-06-19 19:04:53 +00002376 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002377 StringExtractorGDBRemote response;
2378 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2379 {
2380 if (response.IsOKResponse())
2381 {
2382 m_curr_tid_run = tid;
2383 return true;
2384 }
2385 }
2386 return false;
2387}
2388
2389bool
2390GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
2391{
2392 if (SendPacketAndWaitForResponse("?", 1, response, false))
2393 return response.IsNormalResponse();
2394 return false;
2395}
2396
2397bool
Greg Claytonf402f782012-10-13 02:11:55 +00002398GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
Greg Clayton8b82f082011-04-12 05:54:46 +00002399{
2400 if (m_supports_qThreadStopInfo)
2401 {
2402 char packet[256];
Daniel Malead01b2952012-11-29 21:49:15 +00002403 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002404 assert (packet_len < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002405 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2406 {
Greg Claytonef8180a2013-10-15 00:14:28 +00002407 if (response.IsUnsupportedResponse())
2408 m_supports_qThreadStopInfo = false;
2409 else if (response.IsNormalResponse())
Greg Clayton8b82f082011-04-12 05:54:46 +00002410 return true;
2411 else
2412 return false;
2413 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002414 else
2415 {
2416 m_supports_qThreadStopInfo = false;
2417 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002418 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002419 return false;
2420}
2421
2422
2423uint8_t
2424GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
2425{
2426 switch (type)
2427 {
2428 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
2429 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
2430 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
2431 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
2432 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
Greg Clayton8b82f082011-04-12 05:54:46 +00002433 }
2434
2435 char packet[64];
2436 const int packet_len = ::snprintf (packet,
2437 sizeof(packet),
Daniel Malead01b2952012-11-29 21:49:15 +00002438 "%c%i,%" PRIx64 ",%x",
Greg Clayton8b82f082011-04-12 05:54:46 +00002439 insert ? 'Z' : 'z',
2440 type,
2441 addr,
2442 length);
2443
Andy Gibbsa297a972013-06-19 19:04:53 +00002444 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002445 StringExtractorGDBRemote response;
2446 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
2447 {
2448 if (response.IsOKResponse())
2449 return 0;
Greg Clayton8b82f082011-04-12 05:54:46 +00002450 else if (response.IsErrorResponse())
2451 return response.GetError();
2452 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002453 else
2454 {
2455 switch (type)
2456 {
2457 case eBreakpointSoftware: m_supports_z0 = false; break;
2458 case eBreakpointHardware: m_supports_z1 = false; break;
2459 case eWatchpointWrite: m_supports_z2 = false; break;
2460 case eWatchpointRead: m_supports_z3 = false; break;
2461 case eWatchpointReadWrite: m_supports_z4 = false; break;
Greg Clayton17a0cb62011-05-15 23:46:54 +00002462 }
2463 }
2464
Greg Clayton8b82f082011-04-12 05:54:46 +00002465 return UINT8_MAX;
2466}
Greg Claytonadc00cb2011-05-20 23:38:13 +00002467
2468size_t
2469GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
2470 bool &sequence_mutex_unavailable)
2471{
2472 Mutex::Locker locker;
2473 thread_ids.clear();
2474
Jim Ingham4ceb9282012-06-08 22:50:40 +00002475 if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
Greg Claytonadc00cb2011-05-20 23:38:13 +00002476 {
2477 sequence_mutex_unavailable = false;
2478 StringExtractorGDBRemote response;
2479
Greg Clayton73bf5db2011-06-17 01:22:15 +00002480 for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
Greg Claytonadc00cb2011-05-20 23:38:13 +00002481 response.IsNormalResponse();
Greg Clayton73bf5db2011-06-17 01:22:15 +00002482 SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()))
Greg Claytonadc00cb2011-05-20 23:38:13 +00002483 {
2484 char ch = response.GetChar();
2485 if (ch == 'l')
2486 break;
2487 if (ch == 'm')
2488 {
2489 do
2490 {
Jason Molendae9ca4af2013-02-23 02:04:45 +00002491 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
Greg Claytonadc00cb2011-05-20 23:38:13 +00002492
2493 if (tid != LLDB_INVALID_THREAD_ID)
2494 {
2495 thread_ids.push_back (tid);
2496 }
2497 ch = response.GetChar(); // Skip the command separator
2498 } while (ch == ','); // Make sure we got a comma separator
2499 }
2500 }
2501 }
2502 else
2503 {
Jim Ingham4ceb9282012-06-08 22:50:40 +00002504#if defined (LLDB_CONFIGURATION_DEBUG)
2505 // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
2506#else
Greg Clayton5160ce52013-03-27 23:08:40 +00002507 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Claytonc3c0b0e2012-04-12 19:04:34 +00002508 if (log)
2509 log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
Jim Ingham4ceb9282012-06-08 22:50:40 +00002510#endif
Greg Claytonadc00cb2011-05-20 23:38:13 +00002511 sequence_mutex_unavailable = true;
2512 }
2513 return thread_ids.size();
2514}
Greg Clayton37a0a242012-04-11 00:24:49 +00002515
2516lldb::addr_t
2517GDBRemoteCommunicationClient::GetShlibInfoAddr()
2518{
2519 if (!IsRunning())
2520 {
2521 StringExtractorGDBRemote response;
2522 if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false))
2523 {
2524 if (response.IsNormalResponse())
2525 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2526 }
2527 }
2528 return LLDB_INVALID_ADDRESS;
2529}
2530
Daniel Maleae0f8f572013-08-26 23:57:52 +00002531lldb_private::Error
2532GDBRemoteCommunicationClient::RunShellCommand (const char *command, // Shouldn't be NULL
2533 const char *working_dir, // Pass NULL to use the current working directory
2534 int *status_ptr, // Pass NULL if you don't want the process exit status
2535 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
2536 std::string *command_output, // Pass NULL if you don't want the command output
2537 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
2538{
2539 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00002540 stream.PutCString("qPlatform_shell:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00002541 stream.PutBytesAsRawHex8(command, strlen(command));
2542 stream.PutChar(',');
2543 stream.PutHex32(timeout_sec);
2544 if (working_dir && *working_dir)
2545 {
2546 stream.PutChar(',');
2547 stream.PutBytesAsRawHex8(working_dir, strlen(working_dir));
2548 }
2549 const char *packet = stream.GetData();
2550 int packet_len = stream.GetSize();
2551 StringExtractorGDBRemote response;
2552 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2553 {
2554 if (response.GetChar() != 'F')
2555 return Error("malformed reply");
2556 if (response.GetChar() != ',')
2557 return Error("malformed reply");
2558 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2559 if (exitcode == UINT32_MAX)
2560 return Error("unable to run remote process");
2561 else if (status_ptr)
2562 *status_ptr = exitcode;
2563 if (response.GetChar() != ',')
2564 return Error("malformed reply");
2565 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2566 if (signo_ptr)
2567 *signo_ptr = signo;
2568 if (response.GetChar() != ',')
2569 return Error("malformed reply");
2570 std::string output;
2571 response.GetEscapedBinaryData(output);
2572 if (command_output)
2573 command_output->assign(output);
2574 return Error();
2575 }
2576 return Error("unable to send packet");
2577}
2578
Greg Claytonfbb76342013-11-20 21:07:01 +00002579Error
2580GDBRemoteCommunicationClient::MakeDirectory (const char *path,
2581 uint32_t file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002582{
2583 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00002584 stream.PutCString("qPlatform_mkdir:");
2585 stream.PutHex32(file_permissions);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002586 stream.PutChar(',');
Greg Claytonfbb76342013-11-20 21:07:01 +00002587 stream.PutBytesAsRawHex8(path, strlen(path));
Daniel Maleae0f8f572013-08-26 23:57:52 +00002588 const char *packet = stream.GetData();
2589 int packet_len = stream.GetSize();
2590 StringExtractorGDBRemote response;
2591 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2592 {
Greg Claytonfbb76342013-11-20 21:07:01 +00002593 return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002594 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002595 return Error();
Daniel Maleae0f8f572013-08-26 23:57:52 +00002596
2597}
2598
Greg Claytonfbb76342013-11-20 21:07:01 +00002599Error
2600GDBRemoteCommunicationClient::SetFilePermissions (const char *path,
2601 uint32_t file_permissions)
2602{
2603 lldb_private::StreamString stream;
2604 stream.PutCString("qPlatform_chmod:");
2605 stream.PutHex32(file_permissions);
2606 stream.PutChar(',');
2607 stream.PutBytesAsRawHex8(path, strlen(path));
2608 const char *packet = stream.GetData();
2609 int packet_len = stream.GetSize();
2610 StringExtractorGDBRemote response;
2611 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2612 {
2613 return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
2614 }
2615 return Error();
2616
2617}
2618
Daniel Maleae0f8f572013-08-26 23:57:52 +00002619static uint64_t
2620ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
2621 uint64_t fail_result,
2622 Error &error)
2623{
2624 response.SetFilePos(0);
2625 if (response.GetChar() != 'F')
2626 return fail_result;
2627 int32_t result = response.GetS32 (-2);
2628 if (result == -2)
2629 return fail_result;
2630 if (response.GetChar() == ',')
2631 {
2632 int result_errno = response.GetS32 (-2);
2633 if (result_errno != -2)
2634 error.SetError(result_errno, eErrorTypePOSIX);
2635 else
2636 error.SetError(-1, eErrorTypeGeneric);
2637 }
2638 else
2639 error.Clear();
2640 return result;
2641}
2642lldb::user_id_t
2643GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
2644 uint32_t flags,
2645 mode_t mode,
2646 Error &error)
2647{
2648 lldb_private::StreamString stream;
2649 stream.PutCString("vFile:open:");
2650 std::string path (file_spec.GetPath());
2651 if (path.empty())
2652 return UINT64_MAX;
2653 stream.PutCStringAsRawHex8(path.c_str());
2654 stream.PutChar(',');
2655 const uint32_t posix_open_flags = File::ConvertOpenOptionsForPOSIXOpen(flags);
2656 stream.PutHex32(posix_open_flags);
2657 stream.PutChar(',');
2658 stream.PutHex32(mode);
2659 const char* packet = stream.GetData();
2660 int packet_len = stream.GetSize();
2661 StringExtractorGDBRemote response;
2662 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2663 {
2664 return ParseHostIOPacketResponse (response, UINT64_MAX, error);
2665 }
2666 return UINT64_MAX;
2667}
2668
2669bool
2670GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
2671 Error &error)
2672{
2673 lldb_private::StreamString stream;
2674 stream.Printf("vFile:close:%i", (int)fd);
2675 const char* packet = stream.GetData();
2676 int packet_len = stream.GetSize();
2677 StringExtractorGDBRemote response;
2678 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2679 {
2680 return ParseHostIOPacketResponse (response, -1, error) == 0;
2681 }
Deepak Panickald66b50c2013-10-22 12:27:43 +00002682 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002683}
2684
2685// Extension of host I/O packets to get the file size.
2686lldb::user_id_t
2687GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
2688{
2689 lldb_private::StreamString stream;
2690 stream.PutCString("vFile:size:");
2691 std::string path (file_spec.GetPath());
2692 stream.PutCStringAsRawHex8(path.c_str());
2693 const char* packet = stream.GetData();
2694 int packet_len = stream.GetSize();
2695 StringExtractorGDBRemote response;
2696 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2697 {
2698 if (response.GetChar() != 'F')
2699 return UINT64_MAX;
2700 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2701 return retcode;
2702 }
2703 return UINT64_MAX;
2704}
2705
Greg Claytonfbb76342013-11-20 21:07:01 +00002706Error
2707GDBRemoteCommunicationClient::GetFilePermissions(const char *path, uint32_t &file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002708{
Greg Claytonfbb76342013-11-20 21:07:01 +00002709 Error error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002710 lldb_private::StreamString stream;
2711 stream.PutCString("vFile:mode:");
Greg Claytonfbb76342013-11-20 21:07:01 +00002712 stream.PutCStringAsRawHex8(path);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002713 const char* packet = stream.GetData();
2714 int packet_len = stream.GetSize();
2715 StringExtractorGDBRemote response;
2716 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2717 {
2718 if (response.GetChar() != 'F')
2719 {
2720 error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002721 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002722 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00002723 {
Greg Claytonfbb76342013-11-20 21:07:01 +00002724 const uint32_t mode = response.GetS32(-1);
2725 if (mode == -1)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002726 {
Greg Claytonfbb76342013-11-20 21:07:01 +00002727 if (response.GetChar() == ',')
2728 {
2729 int response_errno = response.GetS32(-1);
2730 if (response_errno > 0)
2731 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2732 else
2733 error.SetErrorToGenericError();
2734 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002735 else
2736 error.SetErrorToGenericError();
2737 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002738 else
2739 {
2740 file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
2741 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002742 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002743 }
2744 else
2745 {
2746 error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
2747 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002748 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002749}
2750
2751uint64_t
2752GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
2753 uint64_t offset,
2754 void *dst,
2755 uint64_t dst_len,
2756 Error &error)
2757{
2758 lldb_private::StreamString stream;
2759 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
2760 const char* packet = stream.GetData();
2761 int packet_len = stream.GetSize();
2762 StringExtractorGDBRemote response;
2763 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2764 {
2765 if (response.GetChar() != 'F')
2766 return 0;
2767 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
2768 if (retcode == UINT32_MAX)
2769 return retcode;
2770 const char next = (response.Peek() ? *response.Peek() : 0);
2771 if (next == ',')
2772 return 0;
2773 if (next == ';')
2774 {
2775 response.GetChar(); // skip the semicolon
2776 std::string buffer;
2777 if (response.GetEscapedBinaryData(buffer))
2778 {
2779 const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
2780 if (data_to_write > 0)
2781 memcpy(dst, &buffer[0], data_to_write);
2782 return data_to_write;
2783 }
2784 }
2785 }
2786 return 0;
2787}
2788
2789uint64_t
2790GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
2791 uint64_t offset,
2792 const void* src,
2793 uint64_t src_len,
2794 Error &error)
2795{
2796 lldb_private::StreamGDBRemote stream;
2797 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
2798 stream.PutEscapedBytes(src, src_len);
2799 const char* packet = stream.GetData();
2800 int packet_len = stream.GetSize();
2801 StringExtractorGDBRemote response;
2802 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2803 {
2804 if (response.GetChar() != 'F')
2805 {
2806 error.SetErrorStringWithFormat("write file failed");
2807 return 0;
2808 }
2809 uint64_t bytes_written = response.GetU64(UINT64_MAX);
2810 if (bytes_written == UINT64_MAX)
2811 {
2812 error.SetErrorToGenericError();
2813 if (response.GetChar() == ',')
2814 {
2815 int response_errno = response.GetS32(-1);
2816 if (response_errno > 0)
2817 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2818 }
2819 return 0;
2820 }
2821 return bytes_written;
2822 }
2823 else
2824 {
2825 error.SetErrorString ("failed to send vFile:pwrite packet");
2826 }
2827 return 0;
2828}
2829
Greg Claytonfbb76342013-11-20 21:07:01 +00002830Error
2831GDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst)
2832{
2833 Error error;
2834 lldb_private::StreamGDBRemote stream;
2835 stream.PutCString("vFile:symlink:");
2836 // the unix symlink() command reverses its parameters where the dst if first,
2837 // so we follow suit here
2838 stream.PutCStringAsRawHex8(dst);
2839 stream.PutChar(',');
2840 stream.PutCStringAsRawHex8(src);
2841 const char* packet = stream.GetData();
2842 int packet_len = stream.GetSize();
2843 StringExtractorGDBRemote response;
2844 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2845 {
2846 if (response.GetChar() == 'F')
2847 {
2848 uint32_t result = response.GetU32(UINT32_MAX);
2849 if (result != 0)
2850 {
2851 error.SetErrorToGenericError();
2852 if (response.GetChar() == ',')
2853 {
2854 int response_errno = response.GetS32(-1);
2855 if (response_errno > 0)
2856 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2857 }
2858 }
2859 }
2860 else
2861 {
2862 // Should have returned with 'F<result>[,<errno>]'
2863 error.SetErrorStringWithFormat("symlink failed");
2864 }
2865 }
2866 else
2867 {
2868 error.SetErrorString ("failed to send vFile:symlink packet");
2869 }
2870 return error;
2871}
2872
2873Error
2874GDBRemoteCommunicationClient::Unlink (const char *path)
2875{
2876 Error error;
2877 lldb_private::StreamGDBRemote stream;
2878 stream.PutCString("vFile:unlink:");
2879 // the unix symlink() command reverses its parameters where the dst if first,
2880 // so we follow suit here
2881 stream.PutCStringAsRawHex8(path);
2882 const char* packet = stream.GetData();
2883 int packet_len = stream.GetSize();
2884 StringExtractorGDBRemote response;
2885 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2886 {
2887 if (response.GetChar() == 'F')
2888 {
2889 uint32_t result = response.GetU32(UINT32_MAX);
2890 if (result != 0)
2891 {
2892 error.SetErrorToGenericError();
2893 if (response.GetChar() == ',')
2894 {
2895 int response_errno = response.GetS32(-1);
2896 if (response_errno > 0)
2897 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2898 }
2899 }
2900 }
2901 else
2902 {
2903 // Should have returned with 'F<result>[,<errno>]'
2904 error.SetErrorStringWithFormat("unlink failed");
2905 }
2906 }
2907 else
2908 {
2909 error.SetErrorString ("failed to send vFile:unlink packet");
2910 }
2911 return error;
2912}
2913
Daniel Maleae0f8f572013-08-26 23:57:52 +00002914// Extension of host I/O packets to get whether a file exists.
2915bool
2916GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
2917{
2918 lldb_private::StreamString stream;
2919 stream.PutCString("vFile:exists:");
2920 std::string path (file_spec.GetPath());
2921 stream.PutCStringAsRawHex8(path.c_str());
2922 const char* packet = stream.GetData();
2923 int packet_len = stream.GetSize();
2924 StringExtractorGDBRemote response;
2925 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2926 {
2927 if (response.GetChar() != 'F')
2928 return false;
2929 if (response.GetChar() != ',')
2930 return false;
2931 bool retcode = (response.GetChar() != '0');
2932 return retcode;
2933 }
2934 return false;
2935}
2936
2937bool
2938GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
2939 uint64_t &high,
2940 uint64_t &low)
2941{
2942 lldb_private::StreamString stream;
2943 stream.PutCString("vFile:MD5:");
2944 std::string path (file_spec.GetPath());
2945 stream.PutCStringAsRawHex8(path.c_str());
2946 const char* packet = stream.GetData();
2947 int packet_len = stream.GetSize();
2948 StringExtractorGDBRemote response;
2949 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2950 {
2951 if (response.GetChar() != 'F')
2952 return false;
2953 if (response.GetChar() != ',')
2954 return false;
2955 if (response.Peek() && *response.Peek() == 'x')
2956 return false;
2957 low = response.GetHexMaxU64(false, UINT64_MAX);
2958 high = response.GetHexMaxU64(false, UINT64_MAX);
2959 return true;
2960 }
2961 return false;
2962}
Greg Claytonf74cf862013-11-13 23:28:31 +00002963
2964bool
2965GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
2966{
2967 Mutex::Locker locker;
2968 if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet."))
2969 {
2970 const bool thread_suffix_supported = GetThreadSuffixSupported();
2971
2972 if (thread_suffix_supported || SetCurrentThread(tid))
2973 {
2974 char packet[64];
2975 int packet_len = 0;
2976 if (thread_suffix_supported)
2977 packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid);
2978 else
2979 packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
2980 assert (packet_len < ((int)sizeof(packet) - 1));
2981 return SendPacketAndWaitForResponse(packet, response, false);
2982 }
2983 }
2984 return false;
2985
2986}
2987
2988
2989bool
2990GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response)
2991{
2992 Mutex::Locker locker;
2993 if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet."))
2994 {
2995 const bool thread_suffix_supported = GetThreadSuffixSupported();
2996
2997 if (thread_suffix_supported || SetCurrentThread(tid))
2998 {
2999 char packet[64];
3000 int packet_len = 0;
3001 // Get all registers in one packet
3002 if (thread_suffix_supported)
3003 packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid);
3004 else
3005 packet_len = ::snprintf (packet, sizeof(packet), "g");
3006 assert (packet_len < ((int)sizeof(packet) - 1));
3007 return SendPacketAndWaitForResponse(packet, response, false);
3008 }
3009 }
3010 return false;
3011}
3012bool
3013GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
3014{
3015 save_id = 0; // Set to invalid save ID
3016 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3017 return false;
3018
3019 m_supports_QSaveRegisterState = eLazyBoolYes;
3020 Mutex::Locker locker;
3021 if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState."))
3022 {
3023 const bool thread_suffix_supported = GetThreadSuffixSupported();
3024 if (thread_suffix_supported || SetCurrentThread(tid))
3025 {
3026 char packet[256];
3027 if (thread_suffix_supported)
3028 ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid);
3029 else
3030 ::strncpy (packet, "QSaveRegisterState", sizeof(packet));
3031
3032 StringExtractorGDBRemote response;
3033
3034 if (SendPacketAndWaitForResponse(packet, response, false))
3035 {
3036 if (response.IsUnsupportedResponse())
3037 {
3038 // This packet isn't supported, don't try calling it again
3039 m_supports_QSaveRegisterState = eLazyBoolNo;
3040 }
3041
3042 const uint32_t response_save_id = response.GetU32(0);
3043 if (response_save_id != 0)
3044 {
3045 save_id = response_save_id;
3046 return true;
3047 }
3048 }
3049 }
3050 }
3051 return false;
3052}
3053
3054bool
3055GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
3056{
3057 // We use the "m_supports_QSaveRegisterState" variable here becuase the
3058 // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
3059 // order to be useful
3060 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3061 return false;
3062
3063 Mutex::Locker locker;
3064 if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState."))
3065 {
3066 const bool thread_suffix_supported = GetThreadSuffixSupported();
3067 if (thread_suffix_supported || SetCurrentThread(tid))
3068 {
3069 char packet[256];
3070 if (thread_suffix_supported)
3071 ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid);
3072 else
3073 ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id);
3074
3075 StringExtractorGDBRemote response;
3076
3077 if (SendPacketAndWaitForResponse(packet, response, false))
3078 {
3079 if (response.IsOKResponse())
3080 {
3081 return true;
3082 }
3083 else if (response.IsUnsupportedResponse())
3084 {
3085 // This packet isn't supported, don't try calling this packet or
3086 // QSaveRegisterState again...
3087 m_supports_QSaveRegisterState = eLazyBoolNo;
3088 }
3089 }
3090 }
3091 }
3092 return false;
3093}