blob: 7761b166d1c54af092d874d4c4329ec859cd0642 [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 Clayton32e0a752011-03-30 18:16:51 +000068 m_supports_qProcessInfoPID (true),
69 m_supports_qfProcessInfo (true),
70 m_supports_qUserName (true),
71 m_supports_qGroupName (true),
Greg Clayton8b82f082011-04-12 05:54:46 +000072 m_supports_qThreadStopInfo (true),
73 m_supports_z0 (true),
74 m_supports_z1 (true),
75 m_supports_z2 (true),
76 m_supports_z3 (true),
77 m_supports_z4 (true),
Greg Clayton89600582013-10-10 17:53:50 +000078 m_supports_QEnvironment (true),
79 m_supports_QEnvironmentHexEncoded (true),
Greg Clayton8b82f082011-04-12 05:54:46 +000080 m_curr_tid (LLDB_INVALID_THREAD_ID),
81 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Johnny Chen64637202012-05-23 21:09:52 +000082 m_num_supported_hardware_watchpoints (0),
Greg Clayton576d8832011-03-22 04:00:09 +000083 m_async_mutex (Mutex::eMutexTypeRecursive),
84 m_async_packet_predicate (false),
85 m_async_packet (),
86 m_async_response (),
87 m_async_signal (-1),
Han Ming Ong4b6459f2013-01-18 23:11:53 +000088 m_thread_id_to_used_usec_map (),
Greg Clayton1cb64962011-03-24 04:28:38 +000089 m_host_arch(),
Jason Molendaf17b5ac2012-12-19 02:54:03 +000090 m_process_arch(),
Greg Clayton1cb64962011-03-24 04:28:38 +000091 m_os_version_major (UINT32_MAX),
92 m_os_version_minor (UINT32_MAX),
93 m_os_version_update (UINT32_MAX)
Greg Clayton576d8832011-03-22 04:00:09 +000094{
Greg Clayton576d8832011-03-22 04:00:09 +000095}
96
97//----------------------------------------------------------------------
98// Destructor
99//----------------------------------------------------------------------
100GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
101{
Greg Clayton576d8832011-03-22 04:00:09 +0000102 if (IsConnected())
Greg Clayton576d8832011-03-22 04:00:09 +0000103 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000104}
105
106bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000107GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
108{
109 // Start the read thread after we send the handshake ack since if we
110 // fail to send the handshake ack, there is no reason to continue...
111 if (SendAck())
Greg Clayton73bf5db2011-06-17 01:22:15 +0000112 return true;
Greg Clayton1cb64962011-03-24 04:28:38 +0000113
114 if (error_ptr)
115 error_ptr->SetErrorString("failed to send the handshake ack");
116 return false;
117}
118
119void
120GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton576d8832011-03-22 04:00:09 +0000121{
122 if (m_supports_not_sending_acks == eLazyBoolCalculate)
123 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000124 m_send_acks = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000125 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000126
127 StringExtractorGDBRemote response;
Greg Clayton576d8832011-03-22 04:00:09 +0000128 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
129 {
130 if (response.IsOKResponse())
Greg Clayton1cb64962011-03-24 04:28:38 +0000131 {
132 m_send_acks = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000133 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton1cb64962011-03-24 04:28:38 +0000134 }
Greg Clayton576d8832011-03-22 04:00:09 +0000135 }
136 }
Greg Clayton576d8832011-03-22 04:00:09 +0000137}
138
139void
Greg Clayton44633992012-04-10 03:22:03 +0000140GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
141{
142 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
143 {
144 m_supports_threads_in_stop_reply = eLazyBoolNo;
145
146 StringExtractorGDBRemote response;
147 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false))
148 {
149 if (response.IsOKResponse())
150 m_supports_threads_in_stop_reply = eLazyBoolYes;
151 }
152 }
153}
154
Jim Inghamcd16df92012-07-20 21:37:13 +0000155bool
156GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
157{
158 if (m_attach_or_wait_reply == eLazyBoolCalculate)
159 {
160 m_attach_or_wait_reply = eLazyBoolNo;
161
162 StringExtractorGDBRemote response;
163 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false))
164 {
165 if (response.IsOKResponse())
166 m_attach_or_wait_reply = eLazyBoolYes;
167 }
168 }
169 if (m_attach_or_wait_reply == eLazyBoolYes)
170 return true;
171 else
172 return false;
173}
174
Jim Ingham279ceec2012-07-25 21:12:43 +0000175bool
176GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
177{
178 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
179 {
180 m_prepare_for_reg_writing_reply = eLazyBoolNo;
181
182 StringExtractorGDBRemote response;
183 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false))
184 {
185 if (response.IsOKResponse())
186 m_prepare_for_reg_writing_reply = eLazyBoolYes;
187 }
188 }
189 if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
190 return true;
191 else
192 return false;
193}
194
Greg Clayton44633992012-04-10 03:22:03 +0000195
196void
Greg Clayton576d8832011-03-22 04:00:09 +0000197GDBRemoteCommunicationClient::ResetDiscoverableSettings()
198{
199 m_supports_not_sending_acks = eLazyBoolCalculate;
200 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton44633992012-04-10 03:22:03 +0000201 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
Greg Clayton576d8832011-03-22 04:00:09 +0000202 m_supports_vCont_c = eLazyBoolCalculate;
203 m_supports_vCont_C = eLazyBoolCalculate;
204 m_supports_vCont_s = eLazyBoolCalculate;
205 m_supports_vCont_S = eLazyBoolCalculate;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000206 m_supports_p = eLazyBoolCalculate;
Greg Clayton32e0a752011-03-30 18:16:51 +0000207 m_qHostInfo_is_valid = eLazyBoolCalculate;
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000208 m_qProcessInfo_is_valid = eLazyBoolCalculate;
Greg Clayton70b57652011-05-15 01:25:55 +0000209 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
Greg Clayton46fb5582011-11-18 07:03:08 +0000210 m_supports_memory_region_info = eLazyBoolCalculate;
Jim Ingham279ceec2012-07-25 21:12:43 +0000211 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
212 m_attach_or_wait_reply = eLazyBoolCalculate;
Greg Clayton2a48f522011-05-14 01:50:35 +0000213
Greg Clayton32e0a752011-03-30 18:16:51 +0000214 m_supports_qProcessInfoPID = true;
215 m_supports_qfProcessInfo = true;
216 m_supports_qUserName = true;
217 m_supports_qGroupName = true;
Greg Clayton8b82f082011-04-12 05:54:46 +0000218 m_supports_qThreadStopInfo = true;
219 m_supports_z0 = true;
220 m_supports_z1 = true;
221 m_supports_z2 = true;
222 m_supports_z3 = true;
223 m_supports_z4 = true;
Greg Clayton89600582013-10-10 17:53:50 +0000224 m_supports_QEnvironment = true;
225 m_supports_QEnvironmentHexEncoded = true;
Greg Claytond314e812011-03-23 00:09:55 +0000226 m_host_arch.Clear();
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000227 m_process_arch.Clear();
Greg Clayton576d8832011-03-22 04:00:09 +0000228}
229
230
231bool
232GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
233{
234 if (m_supports_thread_suffix == eLazyBoolCalculate)
235 {
236 StringExtractorGDBRemote response;
237 m_supports_thread_suffix = eLazyBoolNo;
238 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
239 {
240 if (response.IsOKResponse())
241 m_supports_thread_suffix = eLazyBoolYes;
242 }
243 }
244 return m_supports_thread_suffix;
245}
246bool
247GDBRemoteCommunicationClient::GetVContSupported (char flavor)
248{
249 if (m_supports_vCont_c == eLazyBoolCalculate)
250 {
251 StringExtractorGDBRemote response;
252 m_supports_vCont_any = eLazyBoolNo;
253 m_supports_vCont_all = eLazyBoolNo;
254 m_supports_vCont_c = eLazyBoolNo;
255 m_supports_vCont_C = eLazyBoolNo;
256 m_supports_vCont_s = eLazyBoolNo;
257 m_supports_vCont_S = eLazyBoolNo;
258 if (SendPacketAndWaitForResponse("vCont?", response, false))
259 {
260 const char *response_cstr = response.GetStringRef().c_str();
261 if (::strstr (response_cstr, ";c"))
262 m_supports_vCont_c = eLazyBoolYes;
263
264 if (::strstr (response_cstr, ";C"))
265 m_supports_vCont_C = eLazyBoolYes;
266
267 if (::strstr (response_cstr, ";s"))
268 m_supports_vCont_s = eLazyBoolYes;
269
270 if (::strstr (response_cstr, ";S"))
271 m_supports_vCont_S = eLazyBoolYes;
272
273 if (m_supports_vCont_c == eLazyBoolYes &&
274 m_supports_vCont_C == eLazyBoolYes &&
275 m_supports_vCont_s == eLazyBoolYes &&
276 m_supports_vCont_S == eLazyBoolYes)
277 {
278 m_supports_vCont_all = eLazyBoolYes;
279 }
280
281 if (m_supports_vCont_c == eLazyBoolYes ||
282 m_supports_vCont_C == eLazyBoolYes ||
283 m_supports_vCont_s == eLazyBoolYes ||
284 m_supports_vCont_S == eLazyBoolYes)
285 {
286 m_supports_vCont_any = eLazyBoolYes;
287 }
288 }
289 }
290
291 switch (flavor)
292 {
293 case 'a': return m_supports_vCont_any;
294 case 'A': return m_supports_vCont_all;
295 case 'c': return m_supports_vCont_c;
296 case 'C': return m_supports_vCont_C;
297 case 's': return m_supports_vCont_s;
298 case 'S': return m_supports_vCont_S;
299 default: break;
300 }
301 return false;
302}
303
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000304// Check if the target supports 'p' packet. It sends out a 'p'
305// packet and checks the response. A normal packet will tell us
306// that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000307//
308// Takes a valid thread ID because p needs to apply to a thread.
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000309bool
Sean Callananb1de1142013-09-04 23:24:15 +0000310GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000311{
312 if (m_supports_p == eLazyBoolCalculate)
313 {
314 StringExtractorGDBRemote response;
315 m_supports_p = eLazyBoolNo;
Sean Callananb1de1142013-09-04 23:24:15 +0000316 char packet[256];
317 if (GetThreadSuffixSupported())
318 snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
319 else
320 snprintf(packet, sizeof(packet), "p0");
321
322 if (SendPacketAndWaitForResponse(packet, response, false))
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000323 {
324 if (response.IsNormalResponse())
325 m_supports_p = eLazyBoolYes;
326 }
327 }
328 return m_supports_p;
329}
Greg Clayton576d8832011-03-22 04:00:09 +0000330
331size_t
332GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
333(
334 const char *payload,
335 StringExtractorGDBRemote &response,
336 bool send_async
337)
338{
339 return SendPacketAndWaitForResponse (payload,
340 ::strlen (payload),
341 response,
342 send_async);
343}
344
345size_t
346GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
347(
348 const char *payload,
349 size_t payload_length,
350 StringExtractorGDBRemote &response,
351 bool send_async
352)
353{
354 Mutex::Locker locker;
Greg Clayton5160ce52013-03-27 23:08:40 +0000355 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton644247c2011-07-07 01:59:51 +0000356 size_t response_len = 0;
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000357 if (GetSequenceMutex (locker))
Greg Clayton576d8832011-03-22 04:00:09 +0000358 {
Greg Clayton5fe15d22011-05-20 03:15:54 +0000359 if (SendPacketNoLock (payload, payload_length))
Greg Clayton644247c2011-07-07 01:59:51 +0000360 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
361 else
362 {
363 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000364 log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
Greg Clayton644247c2011-07-07 01:59:51 +0000365 }
Greg Clayton576d8832011-03-22 04:00:09 +0000366 }
367 else
368 {
369 if (send_async)
370 {
Greg Claytond3544052012-05-31 21:24:20 +0000371 if (IsRunning())
Greg Clayton576d8832011-03-22 04:00:09 +0000372 {
Greg Claytond3544052012-05-31 21:24:20 +0000373 Mutex::Locker async_locker (m_async_mutex);
374 m_async_packet.assign(payload, payload_length);
375 m_async_packet_predicate.SetValue (true, eBroadcastNever);
376
377 if (log)
378 log->Printf ("async: async packet = %s", m_async_packet.c_str());
379
380 bool timed_out = false;
381 if (SendInterrupt(locker, 2, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +0000382 {
Greg Claytond3544052012-05-31 21:24:20 +0000383 if (m_interrupt_sent)
Greg Clayton576d8832011-03-22 04:00:09 +0000384 {
Jim Inghambabfc382012-06-06 00:32:39 +0000385 m_interrupt_sent = false;
Greg Claytond3544052012-05-31 21:24:20 +0000386 TimeValue timeout_time;
387 timeout_time = TimeValue::Now();
388 timeout_time.OffsetWithSeconds (m_packet_timeout);
389
Greg Clayton576d8832011-03-22 04:00:09 +0000390 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000391 log->Printf ("async: sent interrupt");
Greg Clayton644247c2011-07-07 01:59:51 +0000392
Greg Claytond3544052012-05-31 21:24:20 +0000393 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
Greg Claytone889ad62011-10-27 22:04:16 +0000394 {
Greg Claytond3544052012-05-31 21:24:20 +0000395 if (log)
396 log->Printf ("async: got response");
397
398 // Swap the response buffer to avoid malloc and string copy
399 response.GetStringRef().swap (m_async_response.GetStringRef());
400 response_len = response.GetStringRef().size();
401 }
402 else
403 {
404 if (log)
405 log->Printf ("async: timed out waiting for response");
406 }
407
408 // Make sure we wait until the continue packet has been sent again...
409 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
410 {
411 if (log)
412 {
413 if (timed_out)
414 log->Printf ("async: timed out waiting for process to resume, but process was resumed");
415 else
416 log->Printf ("async: async packet sent");
417 }
418 }
419 else
420 {
421 if (log)
422 log->Printf ("async: timed out waiting for process to resume");
Greg Claytone889ad62011-10-27 22:04:16 +0000423 }
424 }
425 else
426 {
Greg Claytond3544052012-05-31 21:24:20 +0000427 // We had a racy condition where we went to send the interrupt
428 // yet we were able to get the lock, so the process must have
429 // just stopped?
Greg Clayton576d8832011-03-22 04:00:09 +0000430 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000431 log->Printf ("async: got lock without sending interrupt");
432 // Send the packet normally since we got the lock
433 if (SendPacketNoLock (payload, payload_length))
434 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
435 else
436 {
437 if (log)
438 log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
439 }
Greg Clayton576d8832011-03-22 04:00:09 +0000440 }
441 }
442 else
443 {
Greg Clayton644247c2011-07-07 01:59:51 +0000444 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000445 log->Printf ("async: failed to interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +0000446 }
447 }
448 else
449 {
450 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000451 log->Printf ("async: not running, async is ignored");
Greg Clayton576d8832011-03-22 04:00:09 +0000452 }
453 }
454 else
455 {
456 if (log)
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000457 log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
Greg Clayton576d8832011-03-22 04:00:09 +0000458 }
459 }
Greg Clayton644247c2011-07-07 01:59:51 +0000460 if (response_len == 0)
461 {
462 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000463 log->Printf("error: failed to get response for '%*s'", (int) payload_length, payload);
Greg Clayton644247c2011-07-07 01:59:51 +0000464 }
465 return response_len;
Greg Clayton576d8832011-03-22 04:00:09 +0000466}
467
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000468static const char *end_delimiter = "--end--;";
469static const int end_delimiter_len = 8;
470
471std::string
472GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
473( ProcessGDBRemote *process,
474 StringExtractorGDBRemote& profileDataExtractor
475)
476{
477 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
478 std::stringstream final_output;
479 std::string name, value;
480
481 // Going to assuming thread_used_usec comes first, else bail out.
482 while (profileDataExtractor.GetNameColonValue(name, value))
483 {
484 if (name.compare("thread_used_id") == 0)
485 {
486 StringExtractor threadIDHexExtractor(value.c_str());
487 uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
488
489 bool has_used_usec = false;
490 uint32_t curr_used_usec = 0;
491 std::string usec_name, usec_value;
492 uint32_t input_file_pos = profileDataExtractor.GetFilePos();
493 if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
494 {
495 if (usec_name.compare("thread_used_usec") == 0)
496 {
497 has_used_usec = true;
498 curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
499 }
500 else
501 {
502 // We didn't find what we want, it is probably
503 // an older version. Bail out.
504 profileDataExtractor.SetFilePos(input_file_pos);
505 }
506 }
507
508 if (has_used_usec)
509 {
510 uint32_t prev_used_usec = 0;
511 std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
512 if (iterator != m_thread_id_to_used_usec_map.end())
513 {
514 prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
515 }
516
517 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
518 // A good first time record is one that runs for at least 0.25 sec
519 bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
520 bool good_subsequent_time = (prev_used_usec > 0) &&
521 ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
522
523 if (good_first_time || good_subsequent_time)
524 {
525 // We try to avoid doing too many index id reservation,
526 // resulting in fast increase of index ids.
527
528 final_output << name << ":";
529 int32_t index_id = process->AssignIndexIDToThread(thread_id);
530 final_output << index_id << ";";
531
532 final_output << usec_name << ":" << usec_value << ";";
533 }
534 else
535 {
536 // Skip past 'thread_used_name'.
537 std::string local_name, local_value;
538 profileDataExtractor.GetNameColonValue(local_name, local_value);
539 }
540
541 // Store current time as previous time so that they can be compared later.
542 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
543 }
544 else
545 {
546 // Bail out and use old string.
547 final_output << name << ":" << value << ";";
548 }
549 }
550 else
551 {
552 final_output << name << ":" << value << ";";
553 }
554 }
555 final_output << end_delimiter;
556 m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
557
558 return final_output.str();
559}
560
Greg Clayton576d8832011-03-22 04:00:09 +0000561StateType
562GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
563(
564 ProcessGDBRemote *process,
565 const char *payload,
566 size_t packet_length,
567 StringExtractorGDBRemote &response
568)
569{
Greg Clayton1f5181a2012-07-02 22:05:25 +0000570 m_curr_tid = LLDB_INVALID_THREAD_ID;
Greg Clayton5160ce52013-03-27 23:08:40 +0000571 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton576d8832011-03-22 04:00:09 +0000572 if (log)
573 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
574
575 Mutex::Locker locker(m_sequence_mutex);
576 StateType state = eStateRunning;
577
578 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
579 m_public_is_running.SetValue (true, eBroadcastNever);
580 // Set the starting continue packet into "continue_packet". This packet
Jim Inghambabfc382012-06-06 00:32:39 +0000581 // may change if we are interrupted and we continue after an async packet...
Greg Clayton576d8832011-03-22 04:00:09 +0000582 std::string continue_packet(payload, packet_length);
583
Greg Clayton3f875c52013-02-22 22:23:55 +0000584 bool got_async_packet = false;
Greg Claytonaf247d72011-05-19 03:54:16 +0000585
Greg Clayton576d8832011-03-22 04:00:09 +0000586 while (state == eStateRunning)
587 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000588 if (!got_async_packet)
Greg Claytonaf247d72011-05-19 03:54:16 +0000589 {
590 if (log)
591 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
Greg Clayton37a0a242012-04-11 00:24:49 +0000592 if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) == 0)
Greg Claytonaf247d72011-05-19 03:54:16 +0000593 state = eStateInvalid;
Greg Clayton576d8832011-03-22 04:00:09 +0000594
Greg Claytone889ad62011-10-27 22:04:16 +0000595 m_private_is_running.SetValue (true, eBroadcastAlways);
Greg Claytonaf247d72011-05-19 03:54:16 +0000596 }
597
Greg Clayton3f875c52013-02-22 22:23:55 +0000598 got_async_packet = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000599
600 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000601 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
Greg Clayton576d8832011-03-22 04:00:09 +0000602
Greg Clayton37a0a242012-04-11 00:24:49 +0000603 if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX))
Greg Clayton576d8832011-03-22 04:00:09 +0000604 {
605 if (response.Empty())
606 state = eStateInvalid;
607 else
608 {
609 const char stop_type = response.GetChar();
610 if (log)
611 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
612 switch (stop_type)
613 {
614 case 'T':
615 case 'S':
Greg Clayton576d8832011-03-22 04:00:09 +0000616 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000617 if (process->GetStopID() == 0)
Greg Clayton576d8832011-03-22 04:00:09 +0000618 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000619 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
620 {
621 lldb::pid_t pid = GetCurrentProcessID ();
622 if (pid != LLDB_INVALID_PROCESS_ID)
623 process->SetID (pid);
624 }
625 process->BuildDynamicRegisterInfo (true);
Greg Clayton576d8832011-03-22 04:00:09 +0000626 }
Greg Clayton2687cd12012-03-29 01:55:41 +0000627
628 // Privately notify any internal threads that we have stopped
629 // in case we wanted to interrupt our process, yet we might
630 // send a packet and continue without returning control to the
631 // user.
632 m_private_is_running.SetValue (false, eBroadcastAlways);
633
634 const uint8_t signo = response.GetHexU8 (UINT8_MAX);
635
Jim Inghambabfc382012-06-06 00:32:39 +0000636 bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
637 if (continue_after_async || m_interrupt_sent)
Greg Clayton2687cd12012-03-29 01:55:41 +0000638 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000639 // We sent an interrupt packet to stop the inferior process
640 // for an async signal or to send an async packet while running
641 // but we might have been single stepping and received the
642 // stop packet for the step instead of for the interrupt packet.
643 // Typically when an interrupt is sent a SIGINT or SIGSTOP
644 // is used, so if we get anything else, we need to try and
645 // get another stop reply packet that may have been sent
646 // due to sending the interrupt when the target is stopped
647 // which will just re-send a copy of the last stop reply
648 // packet. If we don't do this, then the reply for our
649 // async packet will be the repeat stop reply packet and cause
650 // a lot of trouble for us!
651 if (signo != SIGINT && signo != SIGSTOP)
652 {
Greg Claytonfb72fde2012-05-15 02:50:49 +0000653 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +0000654
655 // We didn't get a a SIGINT or SIGSTOP, so try for a
656 // very brief time (1 ms) to get another stop reply
657 // packet to make sure it doesn't get in the way
658 StringExtractorGDBRemote extra_stop_reply_packet;
659 uint32_t timeout_usec = 1000;
660 if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec))
661 {
662 switch (extra_stop_reply_packet.GetChar())
663 {
664 case 'T':
665 case 'S':
666 // We did get an extra stop reply, which means
667 // our interrupt didn't stop the target so we
668 // shouldn't continue after the async signal
669 // or packet is sent...
Greg Claytonfb72fde2012-05-15 02:50:49 +0000670 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +0000671 break;
672 }
673 }
674 }
675 }
676
677 if (m_async_signal != -1)
678 {
679 if (log)
680 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
681
682 // Save off the async signal we are supposed to send
683 const int async_signal = m_async_signal;
684 // Clear the async signal member so we don't end up
685 // sending the signal multiple times...
686 m_async_signal = -1;
687 // Check which signal we stopped with
688 if (signo == async_signal)
689 {
690 if (log)
691 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
692
693 // We already stopped with a signal that we wanted
694 // to stop with, so we are done
695 }
696 else
697 {
698 // We stopped with a different signal that the one
699 // we wanted to stop with, so now we must resume
700 // with the signal we want
701 char signal_packet[32];
702 int signal_packet_len = 0;
703 signal_packet_len = ::snprintf (signal_packet,
704 sizeof (signal_packet),
705 "C%2.2x",
706 async_signal);
707
708 if (log)
709 log->Printf ("async: stopped with signal %s, resume with %s",
710 Host::GetSignalAsCString (signo),
711 Host::GetSignalAsCString (async_signal));
712
713 // Set the continue packet to resume even if the
Greg Claytonfb72fde2012-05-15 02:50:49 +0000714 // interrupt didn't cause our stop (ignore continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +0000715 continue_packet.assign(signal_packet, signal_packet_len);
716 continue;
717 }
718 }
719 else if (m_async_packet_predicate.GetValue())
720 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000721 Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton2687cd12012-03-29 01:55:41 +0000722
723 // We are supposed to send an asynchronous packet while
724 // we are running.
725 m_async_response.Clear();
726 if (m_async_packet.empty())
727 {
728 if (packet_log)
729 packet_log->Printf ("async: error: empty async packet");
730
731 }
732 else
733 {
734 if (packet_log)
735 packet_log->Printf ("async: sending packet");
736
737 SendPacketAndWaitForResponse (&m_async_packet[0],
738 m_async_packet.size(),
739 m_async_response,
740 false);
741 }
742 // Let the other thread that was trying to send the async
743 // packet know that the packet has been sent and response is
744 // ready...
745 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
746
747 if (packet_log)
Greg Claytonfb72fde2012-05-15 02:50:49 +0000748 packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);
Greg Clayton2687cd12012-03-29 01:55:41 +0000749
750 // Set the continue packet to resume if our interrupt
751 // for the async packet did cause the stop
Greg Claytonfb72fde2012-05-15 02:50:49 +0000752 if (continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +0000753 {
Greg Claytonf1186de2012-05-24 23:42:14 +0000754 // Reverting this for now as it is causing deadlocks
755 // in programs (<rdar://problem/11529853>). In the future
756 // we should check our thread list and "do the right thing"
757 // for new threads that show up while we stop and run async
758 // packets. Setting the packet to 'c' to continue all threads
759 // is the right thing to do 99.99% of the time because if a
760 // thread was single stepping, and we sent an interrupt, we
761 // will notice above that we didn't stop due to an interrupt
762 // but stopped due to stepping and we would _not_ continue.
763 continue_packet.assign (1, 'c');
Greg Clayton2687cd12012-03-29 01:55:41 +0000764 continue;
765 }
766 }
767 // Stop with signal and thread info
768 state = eStateStopped;
Greg Clayton576d8832011-03-22 04:00:09 +0000769 }
Greg Clayton576d8832011-03-22 04:00:09 +0000770 break;
771
772 case 'W':
773 case 'X':
774 // process exited
775 state = eStateExited;
776 break;
777
778 case 'O':
779 // STDOUT
780 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000781 got_async_packet = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000782 std::string inferior_stdout;
783 inferior_stdout.reserve(response.GetBytesLeft () / 2);
784 char ch;
785 while ((ch = response.GetHexU8()) != '\0')
786 inferior_stdout.append(1, ch);
787 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
788 }
789 break;
790
Han Ming Ongab3b8b22012-11-17 00:21:04 +0000791 case 'A':
792 // Async miscellaneous reply. Right now, only profile data is coming through this channel.
793 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000794 got_async_packet = true;
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000795 std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
796 if (m_partial_profile_data.length() > 0)
797 {
798 m_partial_profile_data.append(input);
799 input = m_partial_profile_data;
800 m_partial_profile_data.clear();
801 }
802
803 size_t found, pos = 0, len = input.length();
804 while ((found = input.find(end_delimiter, pos)) != std::string::npos)
805 {
806 StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
Han Ming Ong91ed6b82013-06-24 18:15:05 +0000807 std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
808 process->BroadcastAsyncProfileData (profile_data);
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000809
810 pos = found + end_delimiter_len;
811 }
812
813 if (pos < len)
814 {
815 // Last incomplete chunk.
816 m_partial_profile_data = input.substr(pos);
817 }
Han Ming Ongab3b8b22012-11-17 00:21:04 +0000818 }
819 break;
820
Greg Clayton576d8832011-03-22 04:00:09 +0000821 case 'E':
822 // ERROR
823 state = eStateInvalid;
824 break;
825
826 default:
827 if (log)
828 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
829 state = eStateInvalid;
830 break;
831 }
832 }
833 }
834 else
835 {
836 if (log)
837 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
838 state = eStateInvalid;
839 }
840 }
841 if (log)
842 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
843 response.SetFilePos(0);
844 m_private_is_running.SetValue (false, eBroadcastAlways);
845 m_public_is_running.SetValue (false, eBroadcastAlways);
846 return state;
847}
848
849bool
850GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
851{
Greg Clayton2687cd12012-03-29 01:55:41 +0000852 Mutex::Locker async_locker (m_async_mutex);
Greg Clayton576d8832011-03-22 04:00:09 +0000853 m_async_signal = signo;
854 bool timed_out = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000855 Mutex::Locker locker;
Greg Clayton2687cd12012-03-29 01:55:41 +0000856 if (SendInterrupt (locker, 1, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +0000857 return true;
858 m_async_signal = -1;
859 return false;
860}
861
Greg Clayton37a0a242012-04-11 00:24:49 +0000862// This function takes a mutex locker as a parameter in case the GetSequenceMutex
Greg Clayton576d8832011-03-22 04:00:09 +0000863// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
864// (the expected result), then it will send the halt packet. If it does succeed
865// then the caller that requested the interrupt will want to keep the sequence
866// locked down so that no one else can send packets while the caller has control.
867// This function usually gets called when we are running and need to stop the
868// target. It can also be used when we are running and and we need to do something
869// else (like read/write memory), so we need to interrupt the running process
870// (gdb remote protocol requires this), and do what we need to do, then resume.
871
872bool
Greg Clayton2687cd12012-03-29 01:55:41 +0000873GDBRemoteCommunicationClient::SendInterrupt
Greg Clayton576d8832011-03-22 04:00:09 +0000874(
875 Mutex::Locker& locker,
876 uint32_t seconds_to_wait_for_stop,
Greg Clayton576d8832011-03-22 04:00:09 +0000877 bool &timed_out
878)
879{
Greg Clayton576d8832011-03-22 04:00:09 +0000880 timed_out = false;
Greg Clayton5160ce52013-03-27 23:08:40 +0000881 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Clayton576d8832011-03-22 04:00:09 +0000882
883 if (IsRunning())
884 {
885 // Only send an interrupt if our debugserver is running...
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000886 if (GetSequenceMutex (locker))
Greg Clayton37a0a242012-04-11 00:24:49 +0000887 {
888 if (log)
889 log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
890 }
891 else
Greg Clayton576d8832011-03-22 04:00:09 +0000892 {
893 // Someone has the mutex locked waiting for a response or for the
894 // inferior to stop, so send the interrupt on the down low...
895 char ctrl_c = '\x03';
896 ConnectionStatus status = eConnectionStatusSuccess;
Greg Clayton576d8832011-03-22 04:00:09 +0000897 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton2687cd12012-03-29 01:55:41 +0000898 if (log)
899 log->PutCString("send packet: \\x03");
Greg Clayton576d8832011-03-22 04:00:09 +0000900 if (bytes_written > 0)
901 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000902 m_interrupt_sent = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000903 if (seconds_to_wait_for_stop)
904 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000905 TimeValue timeout;
906 if (seconds_to_wait_for_stop)
907 {
908 timeout = TimeValue::Now();
909 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
910 }
Greg Clayton576d8832011-03-22 04:00:09 +0000911 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
912 {
913 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000914 log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
Greg Clayton576d8832011-03-22 04:00:09 +0000915 return true;
916 }
917 else
918 {
919 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000920 log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
Greg Clayton576d8832011-03-22 04:00:09 +0000921 }
922 }
923 else
924 {
925 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000926 log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
Greg Clayton576d8832011-03-22 04:00:09 +0000927 return true;
928 }
929 }
930 else
931 {
932 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000933 log->Printf ("SendInterrupt () - failed to write interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +0000934 }
935 return false;
936 }
Greg Clayton576d8832011-03-22 04:00:09 +0000937 }
Greg Clayton2687cd12012-03-29 01:55:41 +0000938 else
939 {
940 if (log)
941 log->Printf ("SendInterrupt () - not running");
942 }
Greg Clayton576d8832011-03-22 04:00:09 +0000943 return true;
944}
945
946lldb::pid_t
947GDBRemoteCommunicationClient::GetCurrentProcessID ()
948{
949 StringExtractorGDBRemote response;
950 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
951 {
952 if (response.GetChar() == 'Q')
953 if (response.GetChar() == 'C')
954 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
955 }
956 return LLDB_INVALID_PROCESS_ID;
957}
958
959bool
960GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
961{
962 error_str.clear();
963 StringExtractorGDBRemote response;
964 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
965 {
966 if (response.IsOKResponse())
967 return true;
968 if (response.GetChar() == 'E')
969 {
970 // A string the describes what failed when launching...
971 error_str = response.GetStringRef().substr(1);
972 }
973 else
974 {
975 error_str.assign ("unknown error occurred launching process");
976 }
977 }
978 else
979 {
Jim Ingham98d6da52012-06-28 20:30:23 +0000980 error_str.assign ("timed out waiting for app to launch");
Greg Clayton576d8832011-03-22 04:00:09 +0000981 }
982 return false;
983}
984
985int
986GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
987{
988 if (argv && argv[0])
989 {
990 StreamString packet;
991 packet.PutChar('A');
992 const char *arg;
993 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
994 {
995 const int arg_len = strlen(arg);
996 if (i > 0)
997 packet.PutChar(',');
998 packet.Printf("%i,%i,", arg_len * 2, i);
999 packet.PutBytesAsRawHex8 (arg, arg_len);
1000 }
1001
1002 StringExtractorGDBRemote response;
1003 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1004 {
1005 if (response.IsOKResponse())
1006 return 0;
1007 uint8_t error = response.GetError();
1008 if (error)
1009 return error;
1010 }
1011 }
1012 return -1;
1013}
1014
1015int
1016GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
1017{
1018 if (name_equal_value && name_equal_value[0])
1019 {
1020 StreamString packet;
Greg Clayton89600582013-10-10 17:53:50 +00001021 bool send_hex_encoding = false;
1022 for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p)
Greg Clayton576d8832011-03-22 04:00:09 +00001023 {
Greg Clayton89600582013-10-10 17:53:50 +00001024 if (isprint(*p))
1025 {
1026 switch (*p)
1027 {
1028 case '$':
1029 case '#':
1030 send_hex_encoding = true;
1031 break;
1032 default:
1033 break;
1034 }
1035 }
1036 else
1037 {
1038 // We have non printable characters, lets hex encode this...
1039 send_hex_encoding = true;
1040 }
1041 }
1042
1043 StringExtractorGDBRemote response;
1044 if (send_hex_encoding)
1045 {
1046 if (m_supports_QEnvironmentHexEncoded)
1047 {
1048 packet.PutCString("QEnvironmentHexEncoded:");
1049 packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
1050 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1051 {
1052 if (response.IsOKResponse())
1053 return 0;
1054 uint8_t error = response.GetError();
1055 if (error)
1056 return error;
1057 if (response.IsUnsupportedResponse())
1058 m_supports_QEnvironmentHexEncoded = false;
1059 }
1060 }
1061
1062 }
1063 else if (m_supports_QEnvironment)
1064 {
1065 packet.Printf("QEnvironment:%s", name_equal_value);
1066 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1067 {
1068 if (response.IsOKResponse())
1069 return 0;
1070 uint8_t error = response.GetError();
1071 if (error)
1072 return error;
1073 if (response.IsUnsupportedResponse())
1074 m_supports_QEnvironment = false;
1075 }
Greg Clayton576d8832011-03-22 04:00:09 +00001076 }
1077 }
1078 return -1;
1079}
1080
Greg Claytonc4103b32011-05-08 04:53:50 +00001081int
1082GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
1083{
1084 if (arch && arch[0])
1085 {
1086 StreamString packet;
1087 packet.Printf("QLaunchArch:%s", arch);
1088 StringExtractorGDBRemote response;
1089 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1090 {
1091 if (response.IsOKResponse())
1092 return 0;
1093 uint8_t error = response.GetError();
1094 if (error)
1095 return error;
1096 }
1097 }
1098 return -1;
1099}
1100
Greg Clayton576d8832011-03-22 04:00:09 +00001101bool
Greg Clayton1cb64962011-03-24 04:28:38 +00001102GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
1103 uint32_t &minor,
1104 uint32_t &update)
1105{
1106 if (GetHostInfo ())
1107 {
1108 if (m_os_version_major != UINT32_MAX)
1109 {
1110 major = m_os_version_major;
1111 minor = m_os_version_minor;
1112 update = m_os_version_update;
1113 return true;
1114 }
1115 }
1116 return false;
1117}
1118
1119bool
1120GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
1121{
1122 if (GetHostInfo ())
1123 {
1124 if (!m_os_build.empty())
1125 {
1126 s = m_os_build;
1127 return true;
1128 }
1129 }
1130 s.clear();
1131 return false;
1132}
1133
1134
1135bool
1136GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
1137{
1138 if (GetHostInfo ())
1139 {
1140 if (!m_os_kernel.empty())
1141 {
1142 s = m_os_kernel;
1143 return true;
1144 }
1145 }
1146 s.clear();
1147 return false;
1148}
1149
1150bool
1151GDBRemoteCommunicationClient::GetHostname (std::string &s)
1152{
1153 if (GetHostInfo ())
1154 {
1155 if (!m_hostname.empty())
1156 {
1157 s = m_hostname;
1158 return true;
1159 }
1160 }
1161 s.clear();
1162 return false;
1163}
1164
1165ArchSpec
1166GDBRemoteCommunicationClient::GetSystemArchitecture ()
1167{
1168 if (GetHostInfo ())
1169 return m_host_arch;
1170 return ArchSpec();
1171}
1172
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001173const lldb_private::ArchSpec &
1174GDBRemoteCommunicationClient::GetProcessArchitecture ()
1175{
1176 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1177 GetCurrentProcessInfo ();
1178 return m_process_arch;
1179}
1180
Greg Clayton1cb64962011-03-24 04:28:38 +00001181
1182bool
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001183GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton576d8832011-03-22 04:00:09 +00001184{
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001185 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001186 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001187 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +00001188 StringExtractorGDBRemote response;
1189 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
1190 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001191 if (response.IsNormalResponse())
Greg Claytond314e812011-03-23 00:09:55 +00001192 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001193 std::string name;
1194 std::string value;
1195 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1196 uint32_t sub = 0;
1197 std::string arch_name;
1198 std::string os_name;
1199 std::string vendor_name;
1200 std::string triple;
1201 uint32_t pointer_byte_size = 0;
1202 StringExtractor extractor;
1203 ByteOrder byte_order = eByteOrderInvalid;
1204 uint32_t num_keys_decoded = 0;
1205 while (response.GetNameColonValue(name, value))
Greg Claytond314e812011-03-23 00:09:55 +00001206 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001207 if (name.compare("cputype") == 0)
Greg Clayton1cb64962011-03-24 04:28:38 +00001208 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001209 // exception type in big endian hex
1210 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
1211 if (cpu != LLDB_INVALID_CPUTYPE)
1212 ++num_keys_decoded;
1213 }
1214 else if (name.compare("cpusubtype") == 0)
1215 {
1216 // exception count in big endian hex
1217 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
1218 if (sub != 0)
1219 ++num_keys_decoded;
1220 }
1221 else if (name.compare("arch") == 0)
1222 {
1223 arch_name.swap (value);
1224 ++num_keys_decoded;
1225 }
1226 else if (name.compare("triple") == 0)
1227 {
1228 // The triple comes as ASCII hex bytes since it contains '-' chars
1229 extractor.GetStringRef().swap(value);
1230 extractor.SetFilePos(0);
1231 extractor.GetHexByteString (triple);
1232 ++num_keys_decoded;
1233 }
1234 else if (name.compare("os_build") == 0)
1235 {
1236 extractor.GetStringRef().swap(value);
1237 extractor.SetFilePos(0);
1238 extractor.GetHexByteString (m_os_build);
1239 ++num_keys_decoded;
1240 }
1241 else if (name.compare("hostname") == 0)
1242 {
1243 extractor.GetStringRef().swap(value);
1244 extractor.SetFilePos(0);
1245 extractor.GetHexByteString (m_hostname);
1246 ++num_keys_decoded;
1247 }
1248 else if (name.compare("os_kernel") == 0)
1249 {
1250 extractor.GetStringRef().swap(value);
1251 extractor.SetFilePos(0);
1252 extractor.GetHexByteString (m_os_kernel);
1253 ++num_keys_decoded;
1254 }
1255 else if (name.compare("ostype") == 0)
1256 {
1257 os_name.swap (value);
1258 ++num_keys_decoded;
1259 }
1260 else if (name.compare("vendor") == 0)
1261 {
1262 vendor_name.swap(value);
1263 ++num_keys_decoded;
1264 }
1265 else if (name.compare("endian") == 0)
1266 {
1267 ++num_keys_decoded;
1268 if (value.compare("little") == 0)
1269 byte_order = eByteOrderLittle;
1270 else if (value.compare("big") == 0)
1271 byte_order = eByteOrderBig;
1272 else if (value.compare("pdp") == 0)
1273 byte_order = eByteOrderPDP;
1274 else
1275 --num_keys_decoded;
1276 }
1277 else if (name.compare("ptrsize") == 0)
1278 {
1279 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
1280 if (pointer_byte_size != 0)
1281 ++num_keys_decoded;
1282 }
1283 else if (name.compare("os_version") == 0)
1284 {
1285 Args::StringToVersion (value.c_str(),
1286 m_os_version_major,
1287 m_os_version_minor,
1288 m_os_version_update);
1289 if (m_os_version_major != UINT32_MAX)
1290 ++num_keys_decoded;
1291 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001292 else if (name.compare("watchpoint_exceptions_received") == 0)
1293 {
1294 ++num_keys_decoded;
1295 if (strcmp(value.c_str(),"before") == 0)
1296 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1297 else if (strcmp(value.c_str(),"after") == 0)
1298 m_watchpoints_trigger_after_instruction = eLazyBoolYes;
1299 else
1300 --num_keys_decoded;
1301 }
1302
Greg Clayton32e0a752011-03-30 18:16:51 +00001303 }
1304
1305 if (num_keys_decoded > 0)
1306 m_qHostInfo_is_valid = eLazyBoolYes;
1307
1308 if (triple.empty())
1309 {
1310 if (arch_name.empty())
1311 {
1312 if (cpu != LLDB_INVALID_CPUTYPE)
1313 {
1314 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
1315 if (pointer_byte_size)
1316 {
1317 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1318 }
1319 if (byte_order != eByteOrderInvalid)
1320 {
1321 assert (byte_order == m_host_arch.GetByteOrder());
1322 }
Greg Clayton70512312012-05-08 01:45:38 +00001323
1324 if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0)
1325 {
1326 switch (m_host_arch.GetMachine())
1327 {
1328 case llvm::Triple::arm:
1329 case llvm::Triple::thumb:
1330 os_name = "ios";
1331 break;
1332 default:
1333 os_name = "macosx";
1334 break;
1335 }
1336 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001337 if (!vendor_name.empty())
1338 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
1339 if (!os_name.empty())
Greg Claytone1dadb82011-09-15 00:21:03 +00001340 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Greg Clayton32e0a752011-03-30 18:16:51 +00001341
1342 }
1343 }
1344 else
1345 {
1346 std::string triple;
1347 triple += arch_name;
Greg Clayton70512312012-05-08 01:45:38 +00001348 if (!vendor_name.empty() || !os_name.empty())
1349 {
1350 triple += '-';
1351 if (vendor_name.empty())
1352 triple += "unknown";
1353 else
1354 triple += vendor_name;
1355 triple += '-';
1356 if (os_name.empty())
1357 triple += "unknown";
1358 else
1359 triple += os_name;
1360 }
1361 m_host_arch.SetTriple (triple.c_str());
1362
1363 llvm::Triple &host_triple = m_host_arch.GetTriple();
1364 if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
1365 {
1366 switch (m_host_arch.GetMachine())
1367 {
1368 case llvm::Triple::arm:
1369 case llvm::Triple::thumb:
1370 host_triple.setOS(llvm::Triple::IOS);
1371 break;
1372 default:
1373 host_triple.setOS(llvm::Triple::MacOSX);
1374 break;
1375 }
1376 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001377 if (pointer_byte_size)
1378 {
1379 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1380 }
1381 if (byte_order != eByteOrderInvalid)
1382 {
1383 assert (byte_order == m_host_arch.GetByteOrder());
1384 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001385
Greg Clayton1cb64962011-03-24 04:28:38 +00001386 }
1387 }
1388 else
1389 {
Greg Clayton70512312012-05-08 01:45:38 +00001390 m_host_arch.SetTriple (triple.c_str());
Greg Claytond314e812011-03-23 00:09:55 +00001391 if (pointer_byte_size)
1392 {
1393 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1394 }
1395 if (byte_order != eByteOrderInvalid)
1396 {
1397 assert (byte_order == m_host_arch.GetByteOrder());
1398 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001399 }
Greg Claytond314e812011-03-23 00:09:55 +00001400 }
Greg Clayton576d8832011-03-22 04:00:09 +00001401 }
1402 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001403 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001404}
1405
1406int
1407GDBRemoteCommunicationClient::SendAttach
1408(
1409 lldb::pid_t pid,
1410 StringExtractorGDBRemote& response
1411)
1412{
1413 if (pid != LLDB_INVALID_PROCESS_ID)
1414 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001415 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001416 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00001417 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00001418 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton576d8832011-03-22 04:00:09 +00001419 {
1420 if (response.IsErrorResponse())
1421 return response.GetError();
1422 return 0;
1423 }
1424 }
1425 return -1;
1426}
1427
1428const lldb_private::ArchSpec &
1429GDBRemoteCommunicationClient::GetHostArchitecture ()
1430{
Greg Clayton32e0a752011-03-30 18:16:51 +00001431 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001432 GetHostInfo ();
Greg Claytond314e812011-03-23 00:09:55 +00001433 return m_host_arch;
Greg Clayton576d8832011-03-22 04:00:09 +00001434}
1435
1436addr_t
1437GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1438{
Greg Clayton70b57652011-05-15 01:25:55 +00001439 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001440 {
Greg Clayton70b57652011-05-15 01:25:55 +00001441 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001442 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001443 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
Greg Clayton43e0af02012-09-18 18:04:04 +00001444 (uint64_t)size,
Greg Clayton2a48f522011-05-14 01:50:35 +00001445 permissions & lldb::ePermissionsReadable ? "r" : "",
1446 permissions & lldb::ePermissionsWritable ? "w" : "",
1447 permissions & lldb::ePermissionsExecutable ? "x" : "");
Andy Gibbsa297a972013-06-19 19:04:53 +00001448 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001449 StringExtractorGDBRemote response;
1450 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1451 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001452 if (!response.IsErrorResponse())
Greg Clayton2a48f522011-05-14 01:50:35 +00001453 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1454 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00001455 else
1456 {
1457 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1458 }
Greg Clayton576d8832011-03-22 04:00:09 +00001459 }
1460 return LLDB_INVALID_ADDRESS;
1461}
1462
1463bool
1464GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1465{
Greg Clayton70b57652011-05-15 01:25:55 +00001466 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001467 {
Greg Clayton70b57652011-05-15 01:25:55 +00001468 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001469 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001470 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001471 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001472 StringExtractorGDBRemote response;
1473 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1474 {
1475 if (response.IsOKResponse())
1476 return true;
Greg Clayton17a0cb62011-05-15 23:46:54 +00001477 }
1478 else
1479 {
1480 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton2a48f522011-05-14 01:50:35 +00001481 }
Greg Clayton576d8832011-03-22 04:00:09 +00001482 }
1483 return false;
1484}
1485
Jim Inghamacff8952013-05-02 00:27:30 +00001486Error
1487GDBRemoteCommunicationClient::Detach (bool keep_stopped)
Greg Clayton37a0a242012-04-11 00:24:49 +00001488{
Jim Inghamacff8952013-05-02 00:27:30 +00001489 Error error;
1490
1491 if (keep_stopped)
1492 {
1493 if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
1494 {
1495 char packet[64];
1496 const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001497 assert (packet_len < (int)sizeof(packet));
Jim Inghamacff8952013-05-02 00:27:30 +00001498 StringExtractorGDBRemote response;
1499 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1500 {
1501 m_supports_detach_stay_stopped = eLazyBoolYes;
1502 }
1503 else
1504 {
1505 m_supports_detach_stay_stopped = eLazyBoolNo;
1506 }
1507 }
1508
1509 if (m_supports_detach_stay_stopped == eLazyBoolNo)
1510 {
1511 error.SetErrorString("Stays stopped not supported by this target.");
1512 return error;
1513 }
1514 else
1515 {
1516 size_t num_sent = SendPacket ("D1", 2);
1517 if (num_sent == 0)
1518 error.SetErrorString ("Sending extended disconnect packet failed.");
1519 }
1520 }
1521 else
1522 {
1523 size_t num_sent = SendPacket ("D", 1);
1524 if (num_sent == 0)
1525 error.SetErrorString ("Sending disconnect packet failed.");
1526 }
1527 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001528}
1529
Greg Clayton46fb5582011-11-18 07:03:08 +00001530Error
1531GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
1532 lldb_private::MemoryRegionInfo &region_info)
1533{
1534 Error error;
1535 region_info.Clear();
1536
1537 if (m_supports_memory_region_info != eLazyBoolNo)
1538 {
1539 m_supports_memory_region_info = eLazyBoolYes;
1540 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001541 const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001542 assert (packet_len < (int)sizeof(packet));
Greg Clayton46fb5582011-11-18 07:03:08 +00001543 StringExtractorGDBRemote response;
1544 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1545 {
1546 std::string name;
1547 std::string value;
1548 addr_t addr_value;
1549 bool success = true;
Jason Molendacb349ee2011-12-13 05:39:38 +00001550 bool saw_permissions = false;
Greg Clayton46fb5582011-11-18 07:03:08 +00001551 while (success && response.GetNameColonValue(name, value))
1552 {
1553 if (name.compare ("start") == 0)
1554 {
1555 addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
1556 if (success)
1557 region_info.GetRange().SetRangeBase(addr_value);
1558 }
1559 else if (name.compare ("size") == 0)
1560 {
1561 addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
1562 if (success)
1563 region_info.GetRange().SetByteSize (addr_value);
1564 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001565 else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
Greg Clayton46fb5582011-11-18 07:03:08 +00001566 {
Jason Molendacb349ee2011-12-13 05:39:38 +00001567 saw_permissions = true;
1568 if (region_info.GetRange().Contains (addr))
1569 {
1570 if (value.find('r') != std::string::npos)
1571 region_info.SetReadable (MemoryRegionInfo::eYes);
1572 else
1573 region_info.SetReadable (MemoryRegionInfo::eNo);
1574
1575 if (value.find('w') != std::string::npos)
1576 region_info.SetWritable (MemoryRegionInfo::eYes);
1577 else
1578 region_info.SetWritable (MemoryRegionInfo::eNo);
1579
1580 if (value.find('x') != std::string::npos)
1581 region_info.SetExecutable (MemoryRegionInfo::eYes);
1582 else
1583 region_info.SetExecutable (MemoryRegionInfo::eNo);
1584 }
1585 else
1586 {
1587 // The reported region does not contain this address -- we're looking at an unmapped page
1588 region_info.SetReadable (MemoryRegionInfo::eNo);
1589 region_info.SetWritable (MemoryRegionInfo::eNo);
1590 region_info.SetExecutable (MemoryRegionInfo::eNo);
1591 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001592 }
1593 else if (name.compare ("error") == 0)
1594 {
1595 StringExtractorGDBRemote name_extractor;
1596 // Swap "value" over into "name_extractor"
1597 name_extractor.GetStringRef().swap(value);
1598 // Now convert the HEX bytes into a string value
1599 name_extractor.GetHexByteString (value);
1600 error.SetErrorString(value.c_str());
1601 }
1602 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001603
1604 // We got a valid address range back but no permissions -- which means this is an unmapped page
1605 if (region_info.GetRange().IsValid() && saw_permissions == false)
1606 {
1607 region_info.SetReadable (MemoryRegionInfo::eNo);
1608 region_info.SetWritable (MemoryRegionInfo::eNo);
1609 region_info.SetExecutable (MemoryRegionInfo::eNo);
1610 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001611 }
1612 else
1613 {
1614 m_supports_memory_region_info = eLazyBoolNo;
1615 }
1616 }
1617
1618 if (m_supports_memory_region_info == eLazyBoolNo)
1619 {
1620 error.SetErrorString("qMemoryRegionInfo is not supported");
1621 }
1622 if (error.Fail())
1623 region_info.Clear();
1624 return error;
1625
1626}
1627
Johnny Chen64637202012-05-23 21:09:52 +00001628Error
1629GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
1630{
1631 Error error;
1632
1633 if (m_supports_watchpoint_support_info == eLazyBoolYes)
1634 {
1635 num = m_num_supported_hardware_watchpoints;
1636 return error;
1637 }
1638
1639 // Set num to 0 first.
1640 num = 0;
1641 if (m_supports_watchpoint_support_info != eLazyBoolNo)
1642 {
1643 char packet[64];
1644 const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001645 assert (packet_len < (int)sizeof(packet));
Johnny Chen64637202012-05-23 21:09:52 +00001646 StringExtractorGDBRemote response;
1647 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1648 {
1649 m_supports_watchpoint_support_info = eLazyBoolYes;
1650 std::string name;
1651 std::string value;
1652 while (response.GetNameColonValue(name, value))
1653 {
1654 if (name.compare ("num") == 0)
1655 {
1656 num = Args::StringToUInt32(value.c_str(), 0, 0);
1657 m_num_supported_hardware_watchpoints = num;
1658 }
1659 }
1660 }
1661 else
1662 {
1663 m_supports_watchpoint_support_info = eLazyBoolNo;
1664 }
1665 }
1666
1667 if (m_supports_watchpoint_support_info == eLazyBoolNo)
1668 {
1669 error.SetErrorString("qWatchpointSupportInfo is not supported");
1670 }
1671 return error;
1672
1673}
Greg Clayton46fb5582011-11-18 07:03:08 +00001674
Enrico Granataf04a2192012-07-13 23:18:48 +00001675lldb_private::Error
1676GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after)
1677{
1678 Error error(GetWatchpointSupportInfo(num));
1679 if (error.Success())
1680 error = GetWatchpointsTriggerAfterInstruction(after);
1681 return error;
1682}
1683
1684lldb_private::Error
1685GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after)
1686{
1687 Error error;
1688
1689 // we assume watchpoints will happen after running the relevant opcode
1690 // and we only want to override this behavior if we have explicitly
1691 // received a qHostInfo telling us otherwise
1692 if (m_qHostInfo_is_valid != eLazyBoolYes)
1693 after = true;
1694 else
1695 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1696 return error;
1697}
1698
Greg Clayton576d8832011-03-22 04:00:09 +00001699int
1700GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1701{
1702 if (path && path[0])
1703 {
1704 StreamString packet;
1705 packet.PutCString("QSetSTDIN:");
1706 packet.PutBytesAsRawHex8(path, strlen(path));
1707
1708 StringExtractorGDBRemote response;
1709 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1710 {
1711 if (response.IsOKResponse())
1712 return 0;
1713 uint8_t error = response.GetError();
1714 if (error)
1715 return error;
1716 }
1717 }
1718 return -1;
1719}
1720
1721int
1722GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1723{
1724 if (path && path[0])
1725 {
1726 StreamString packet;
1727 packet.PutCString("QSetSTDOUT:");
1728 packet.PutBytesAsRawHex8(path, strlen(path));
1729
1730 StringExtractorGDBRemote response;
1731 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1732 {
1733 if (response.IsOKResponse())
1734 return 0;
1735 uint8_t error = response.GetError();
1736 if (error)
1737 return error;
1738 }
1739 }
1740 return -1;
1741}
1742
1743int
1744GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1745{
1746 if (path && path[0])
1747 {
1748 StreamString packet;
1749 packet.PutCString("QSetSTDERR:");
1750 packet.PutBytesAsRawHex8(path, strlen(path));
1751
1752 StringExtractorGDBRemote response;
1753 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1754 {
1755 if (response.IsOKResponse())
1756 return 0;
1757 uint8_t error = response.GetError();
1758 if (error)
1759 return error;
1760 }
1761 }
1762 return -1;
1763}
1764
1765int
1766GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1767{
1768 if (path && path[0])
1769 {
1770 StreamString packet;
1771 packet.PutCString("QSetWorkingDir:");
1772 packet.PutBytesAsRawHex8(path, strlen(path));
1773
1774 StringExtractorGDBRemote response;
1775 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1776 {
1777 if (response.IsOKResponse())
1778 return 0;
1779 uint8_t error = response.GetError();
1780 if (error)
1781 return error;
1782 }
1783 }
1784 return -1;
1785}
1786
1787int
1788GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1789{
Greg Clayton32e0a752011-03-30 18:16:51 +00001790 char packet[32];
1791 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
Andy Gibbsa297a972013-06-19 19:04:53 +00001792 assert (packet_len < (int)sizeof(packet));
Greg Clayton576d8832011-03-22 04:00:09 +00001793 StringExtractorGDBRemote response;
Greg Clayton32e0a752011-03-30 18:16:51 +00001794 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton576d8832011-03-22 04:00:09 +00001795 {
1796 if (response.IsOKResponse())
1797 return 0;
1798 uint8_t error = response.GetError();
1799 if (error)
1800 return error;
1801 }
1802 return -1;
1803}
Greg Clayton32e0a752011-03-30 18:16:51 +00001804
1805bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001806GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00001807{
1808 if (response.IsNormalResponse())
1809 {
1810 std::string name;
1811 std::string value;
1812 StringExtractor extractor;
1813
1814 while (response.GetNameColonValue(name, value))
1815 {
1816 if (name.compare("pid") == 0)
1817 {
1818 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1819 }
1820 else if (name.compare("ppid") == 0)
1821 {
1822 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1823 }
1824 else if (name.compare("uid") == 0)
1825 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001826 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00001827 }
1828 else if (name.compare("euid") == 0)
1829 {
1830 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1831 }
1832 else if (name.compare("gid") == 0)
1833 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001834 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00001835 }
1836 else if (name.compare("egid") == 0)
1837 {
1838 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1839 }
1840 else if (name.compare("triple") == 0)
1841 {
1842 // The triple comes as ASCII hex bytes since it contains '-' chars
1843 extractor.GetStringRef().swap(value);
1844 extractor.SetFilePos(0);
1845 extractor.GetHexByteString (value);
Greg Clayton70512312012-05-08 01:45:38 +00001846 process_info.GetArchitecture ().SetTriple (value.c_str());
Greg Clayton32e0a752011-03-30 18:16:51 +00001847 }
1848 else if (name.compare("name") == 0)
1849 {
1850 StringExtractor extractor;
Filipe Cabecinhasf86cf782012-05-07 09:30:51 +00001851 // The process name from ASCII hex bytes since we can't
Greg Clayton32e0a752011-03-30 18:16:51 +00001852 // control the characters in a process name
1853 extractor.GetStringRef().swap(value);
1854 extractor.SetFilePos(0);
1855 extractor.GetHexByteString (value);
Greg Clayton144f3a92011-11-15 03:53:30 +00001856 process_info.GetExecutableFile().SetFile (value.c_str(), false);
Greg Clayton32e0a752011-03-30 18:16:51 +00001857 }
1858 }
1859
1860 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1861 return true;
1862 }
1863 return false;
1864}
1865
1866bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001867GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00001868{
1869 process_info.Clear();
1870
1871 if (m_supports_qProcessInfoPID)
1872 {
1873 char packet[32];
Daniel Malead01b2952012-11-29 21:49:15 +00001874 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00001875 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00001876 StringExtractorGDBRemote response;
1877 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1878 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001879 return DecodeProcessInfoResponse (response, process_info);
1880 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00001881 else
1882 {
1883 m_supports_qProcessInfoPID = false;
1884 return false;
1885 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001886 }
1887 return false;
1888}
1889
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001890bool
1891GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
1892{
1893 if (m_qProcessInfo_is_valid == eLazyBoolYes)
1894 return true;
1895 if (m_qProcessInfo_is_valid == eLazyBoolNo)
1896 return false;
1897
1898 GetHostInfo ();
1899
1900 StringExtractorGDBRemote response;
1901 if (SendPacketAndWaitForResponse ("qProcessInfo", response, false))
1902 {
1903 if (response.IsNormalResponse())
1904 {
1905 std::string name;
1906 std::string value;
1907 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1908 uint32_t sub = 0;
1909 std::string arch_name;
1910 std::string os_name;
1911 std::string vendor_name;
1912 std::string triple;
1913 uint32_t pointer_byte_size = 0;
1914 StringExtractor extractor;
1915 ByteOrder byte_order = eByteOrderInvalid;
1916 uint32_t num_keys_decoded = 0;
1917 while (response.GetNameColonValue(name, value))
1918 {
1919 if (name.compare("cputype") == 0)
1920 {
1921 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
1922 if (cpu != LLDB_INVALID_CPUTYPE)
1923 ++num_keys_decoded;
1924 }
1925 else if (name.compare("cpusubtype") == 0)
1926 {
1927 sub = Args::StringToUInt32 (value.c_str(), 0, 16);
1928 if (sub != 0)
1929 ++num_keys_decoded;
1930 }
1931 else if (name.compare("ostype") == 0)
1932 {
1933 os_name.swap (value);
1934 ++num_keys_decoded;
1935 }
1936 else if (name.compare("vendor") == 0)
1937 {
1938 vendor_name.swap(value);
1939 ++num_keys_decoded;
1940 }
1941 else if (name.compare("endian") == 0)
1942 {
1943 ++num_keys_decoded;
1944 if (value.compare("little") == 0)
1945 byte_order = eByteOrderLittle;
1946 else if (value.compare("big") == 0)
1947 byte_order = eByteOrderBig;
1948 else if (value.compare("pdp") == 0)
1949 byte_order = eByteOrderPDP;
1950 else
1951 --num_keys_decoded;
1952 }
1953 else if (name.compare("ptrsize") == 0)
1954 {
1955 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
1956 if (pointer_byte_size != 0)
1957 ++num_keys_decoded;
1958 }
1959 }
1960 if (num_keys_decoded > 0)
1961 m_qProcessInfo_is_valid = eLazyBoolYes;
1962 if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
1963 {
1964 m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
1965 if (pointer_byte_size)
1966 {
1967 assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
1968 }
1969 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
1970 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
1971 return true;
1972 }
1973 }
1974 }
1975 else
1976 {
1977 m_qProcessInfo_is_valid = eLazyBoolNo;
1978 }
1979
1980 return false;
1981}
1982
1983
Greg Clayton32e0a752011-03-30 18:16:51 +00001984uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00001985GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1986 ProcessInstanceInfoList &process_infos)
Greg Clayton32e0a752011-03-30 18:16:51 +00001987{
1988 process_infos.Clear();
1989
1990 if (m_supports_qfProcessInfo)
1991 {
1992 StreamString packet;
1993 packet.PutCString ("qfProcessInfo");
1994 if (!match_info.MatchAllProcesses())
1995 {
1996 packet.PutChar (':');
1997 const char *name = match_info.GetProcessInfo().GetName();
1998 bool has_name_match = false;
1999 if (name && name[0])
2000 {
2001 has_name_match = true;
2002 NameMatchType name_match_type = match_info.GetNameMatchType();
2003 switch (name_match_type)
2004 {
2005 case eNameMatchIgnore:
2006 has_name_match = false;
2007 break;
2008
2009 case eNameMatchEquals:
2010 packet.PutCString ("name_match:equals;");
2011 break;
2012
2013 case eNameMatchContains:
2014 packet.PutCString ("name_match:contains;");
2015 break;
2016
2017 case eNameMatchStartsWith:
2018 packet.PutCString ("name_match:starts_with;");
2019 break;
2020
2021 case eNameMatchEndsWith:
2022 packet.PutCString ("name_match:ends_with;");
2023 break;
2024
2025 case eNameMatchRegularExpression:
2026 packet.PutCString ("name_match:regex;");
2027 break;
2028 }
2029 if (has_name_match)
2030 {
2031 packet.PutCString ("name:");
2032 packet.PutBytesAsRawHex8(name, ::strlen(name));
2033 packet.PutChar (';');
2034 }
2035 }
2036
2037 if (match_info.GetProcessInfo().ProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002038 packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002039 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002040 packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
Greg Clayton8b82f082011-04-12 05:54:46 +00002041 if (match_info.GetProcessInfo().UserIDIsValid())
2042 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
2043 if (match_info.GetProcessInfo().GroupIDIsValid())
2044 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002045 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2046 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
2047 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2048 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
2049 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2050 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
2051 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
2052 {
2053 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
2054 const llvm::Triple &triple = match_arch.GetTriple();
2055 packet.PutCString("triple:");
2056 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
2057 packet.PutChar (';');
2058 }
2059 }
2060 StringExtractorGDBRemote response;
2061 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
2062 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002063 do
2064 {
Greg Clayton8b82f082011-04-12 05:54:46 +00002065 ProcessInstanceInfo process_info;
Greg Clayton32e0a752011-03-30 18:16:51 +00002066 if (!DecodeProcessInfoResponse (response, process_info))
2067 break;
2068 process_infos.Append(process_info);
2069 response.GetStringRef().clear();
2070 response.SetFilePos(0);
2071 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
2072 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002073 else
2074 {
2075 m_supports_qfProcessInfo = false;
2076 return 0;
2077 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002078 }
2079 return process_infos.GetSize();
2080
2081}
2082
2083bool
2084GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
2085{
2086 if (m_supports_qUserName)
2087 {
2088 char packet[32];
2089 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002090 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002091 StringExtractorGDBRemote response;
2092 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
2093 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002094 if (response.IsNormalResponse())
2095 {
2096 // Make sure we parsed the right number of characters. The response is
2097 // the hex encoded user name and should make up the entire packet.
2098 // If there are any non-hex ASCII bytes, the length won't match below..
2099 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2100 return true;
2101 }
2102 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002103 else
2104 {
2105 m_supports_qUserName = false;
2106 return false;
2107 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002108 }
2109 return false;
2110
2111}
2112
2113bool
2114GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
2115{
2116 if (m_supports_qGroupName)
2117 {
2118 char packet[32];
2119 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002120 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002121 StringExtractorGDBRemote response;
2122 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
2123 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002124 if (response.IsNormalResponse())
2125 {
2126 // Make sure we parsed the right number of characters. The response is
2127 // the hex encoded group name and should make up the entire packet.
2128 // If there are any non-hex ASCII bytes, the length won't match below..
2129 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2130 return true;
2131 }
2132 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002133 else
2134 {
2135 m_supports_qGroupName = false;
2136 return false;
2137 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002138 }
2139 return false;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002140}
Greg Clayton32e0a752011-03-30 18:16:51 +00002141
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002142void
2143GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
2144{
2145 uint32_t i;
2146 TimeValue start_time, end_time;
2147 uint64_t total_time_nsec;
2148 float packets_per_second;
2149 if (SendSpeedTestPacket (0, 0))
2150 {
2151 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
2152 {
2153 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
2154 {
2155 start_time = TimeValue::Now();
2156 for (i=0; i<num_packets; ++i)
2157 {
2158 SendSpeedTestPacket (send_size, recv_size);
2159 }
2160 end_time = TimeValue::Now();
2161 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002162 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Daniel Malead01b2952012-11-29 21:49:15 +00002163 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 +00002164 num_packets,
2165 send_size,
2166 recv_size,
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002167 total_time_nsec / TimeValue::NanoSecPerSec,
2168 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002169 packets_per_second);
2170 if (recv_size == 0)
2171 recv_size = 32;
2172 }
2173 if (send_size == 0)
2174 send_size = 32;
2175 }
2176 }
2177 else
2178 {
2179 start_time = TimeValue::Now();
2180 for (i=0; i<num_packets; ++i)
2181 {
2182 GetCurrentProcessID ();
2183 }
2184 end_time = TimeValue::Now();
2185 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002186 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Daniel Malead01b2952012-11-29 21:49:15 +00002187 printf ("%u 'qC' packets packets in 0x%" PRIu64 "%9.9" PRIu64 " sec for %f packets/sec.\n",
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002188 num_packets,
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002189 total_time_nsec / TimeValue::NanoSecPerSec,
2190 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002191 packets_per_second);
2192 }
2193}
2194
2195bool
2196GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
2197{
2198 StreamString packet;
2199 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
2200 uint32_t bytes_left = send_size;
2201 while (bytes_left > 0)
2202 {
2203 if (bytes_left >= 26)
2204 {
2205 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2206 bytes_left -= 26;
2207 }
2208 else
2209 {
2210 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
2211 bytes_left = 0;
2212 }
2213 }
2214
2215 StringExtractorGDBRemote response;
Greg Clayton17a0cb62011-05-15 23:46:54 +00002216 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002217 return false;
Greg Clayton32e0a752011-03-30 18:16:51 +00002218}
Greg Clayton8b82f082011-04-12 05:54:46 +00002219
2220uint16_t
Daniel Maleae0f8f572013-08-26 23:57:52 +00002221GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002222{
Daniel Maleae0f8f572013-08-26 23:57:52 +00002223 pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton8b82f082011-04-12 05:54:46 +00002224 StringExtractorGDBRemote response;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002225 StreamString stream;
2226 stream.PutCString("qLaunchGDBServer:port:0;");
2227 std::string hostname;
2228 if (Host::GetHostname (hostname))
2229 {
2230 // Make the GDB server we launch only accept connections from this host
2231 stream.Printf("host:%s;", hostname.c_str());
2232 }
2233 else
2234 {
2235 // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
2236 stream.Printf("host:*;");
2237 }
2238 const char *packet = stream.GetData();
2239 int packet_len = stream.GetSize();
2240
2241 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
Greg Clayton8b82f082011-04-12 05:54:46 +00002242 {
2243 std::string name;
2244 std::string value;
2245 uint16_t port = 0;
Greg Clayton8b82f082011-04-12 05:54:46 +00002246 while (response.GetNameColonValue(name, value))
2247 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00002248 if (name.compare("port") == 0)
Greg Clayton8b82f082011-04-12 05:54:46 +00002249 port = Args::StringToUInt32(value.c_str(), 0, 0);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002250 else if (name.compare("pid") == 0)
2251 pid = Args::StringToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
Greg Clayton8b82f082011-04-12 05:54:46 +00002252 }
2253 return port;
2254 }
2255 return 0;
2256}
2257
2258bool
Daniel Maleae0f8f572013-08-26 23:57:52 +00002259GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
2260{
2261 StreamString stream;
2262 stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
2263 const char *packet = stream.GetData();
2264 int packet_len = stream.GetSize();
Sylvestre Ledrufd654c42013-10-06 09:51:02 +00002265
Daniel Maleae0f8f572013-08-26 23:57:52 +00002266 StringExtractorGDBRemote response;
2267 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2268 {
2269 if (response.IsOKResponse())
2270 return true;
2271 }
2272 return false;
2273}
2274
2275bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002276GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002277{
2278 if (m_curr_tid == tid)
2279 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002280
Greg Clayton8b82f082011-04-12 05:54:46 +00002281 char packet[32];
2282 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002283 if (tid == UINT64_MAX)
2284 packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002285 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002286 packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002287 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002288 StringExtractorGDBRemote response;
2289 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2290 {
2291 if (response.IsOKResponse())
2292 {
2293 m_curr_tid = tid;
2294 return true;
2295 }
2296 }
2297 return false;
2298}
2299
2300bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002301GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002302{
2303 if (m_curr_tid_run == tid)
2304 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002305
Greg Clayton8b82f082011-04-12 05:54:46 +00002306 char packet[32];
2307 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002308 if (tid == UINT64_MAX)
2309 packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002310 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002311 packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
2312
Andy Gibbsa297a972013-06-19 19:04:53 +00002313 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002314 StringExtractorGDBRemote response;
2315 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2316 {
2317 if (response.IsOKResponse())
2318 {
2319 m_curr_tid_run = tid;
2320 return true;
2321 }
2322 }
2323 return false;
2324}
2325
2326bool
2327GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
2328{
2329 if (SendPacketAndWaitForResponse("?", 1, response, false))
2330 return response.IsNormalResponse();
2331 return false;
2332}
2333
2334bool
Greg Claytonf402f782012-10-13 02:11:55 +00002335GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
Greg Clayton8b82f082011-04-12 05:54:46 +00002336{
2337 if (m_supports_qThreadStopInfo)
2338 {
2339 char packet[256];
Daniel Malead01b2952012-11-29 21:49:15 +00002340 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002341 assert (packet_len < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002342 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2343 {
Greg Claytonef8180a2013-10-15 00:14:28 +00002344 if (response.IsUnsupportedResponse())
2345 m_supports_qThreadStopInfo = false;
2346 else if (response.IsNormalResponse())
Greg Clayton8b82f082011-04-12 05:54:46 +00002347 return true;
2348 else
2349 return false;
2350 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002351 else
2352 {
2353 m_supports_qThreadStopInfo = false;
2354 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002355 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002356 return false;
2357}
2358
2359
2360uint8_t
2361GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
2362{
2363 switch (type)
2364 {
2365 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
2366 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
2367 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
2368 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
2369 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
Greg Clayton8b82f082011-04-12 05:54:46 +00002370 }
2371
2372 char packet[64];
2373 const int packet_len = ::snprintf (packet,
2374 sizeof(packet),
Daniel Malead01b2952012-11-29 21:49:15 +00002375 "%c%i,%" PRIx64 ",%x",
Greg Clayton8b82f082011-04-12 05:54:46 +00002376 insert ? 'Z' : 'z',
2377 type,
2378 addr,
2379 length);
2380
Andy Gibbsa297a972013-06-19 19:04:53 +00002381 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002382 StringExtractorGDBRemote response;
2383 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
2384 {
2385 if (response.IsOKResponse())
2386 return 0;
Greg Clayton8b82f082011-04-12 05:54:46 +00002387 else if (response.IsErrorResponse())
2388 return response.GetError();
2389 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002390 else
2391 {
2392 switch (type)
2393 {
2394 case eBreakpointSoftware: m_supports_z0 = false; break;
2395 case eBreakpointHardware: m_supports_z1 = false; break;
2396 case eWatchpointWrite: m_supports_z2 = false; break;
2397 case eWatchpointRead: m_supports_z3 = false; break;
2398 case eWatchpointReadWrite: m_supports_z4 = false; break;
Greg Clayton17a0cb62011-05-15 23:46:54 +00002399 }
2400 }
2401
Greg Clayton8b82f082011-04-12 05:54:46 +00002402 return UINT8_MAX;
2403}
Greg Claytonadc00cb2011-05-20 23:38:13 +00002404
2405size_t
2406GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
2407 bool &sequence_mutex_unavailable)
2408{
2409 Mutex::Locker locker;
2410 thread_ids.clear();
2411
Jim Ingham4ceb9282012-06-08 22:50:40 +00002412 if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
Greg Claytonadc00cb2011-05-20 23:38:13 +00002413 {
2414 sequence_mutex_unavailable = false;
2415 StringExtractorGDBRemote response;
2416
Greg Clayton73bf5db2011-06-17 01:22:15 +00002417 for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
Greg Claytonadc00cb2011-05-20 23:38:13 +00002418 response.IsNormalResponse();
Greg Clayton73bf5db2011-06-17 01:22:15 +00002419 SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()))
Greg Claytonadc00cb2011-05-20 23:38:13 +00002420 {
2421 char ch = response.GetChar();
2422 if (ch == 'l')
2423 break;
2424 if (ch == 'm')
2425 {
2426 do
2427 {
Jason Molendae9ca4af2013-02-23 02:04:45 +00002428 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
Greg Claytonadc00cb2011-05-20 23:38:13 +00002429
2430 if (tid != LLDB_INVALID_THREAD_ID)
2431 {
2432 thread_ids.push_back (tid);
2433 }
2434 ch = response.GetChar(); // Skip the command separator
2435 } while (ch == ','); // Make sure we got a comma separator
2436 }
2437 }
2438 }
2439 else
2440 {
Jim Ingham4ceb9282012-06-08 22:50:40 +00002441#if defined (LLDB_CONFIGURATION_DEBUG)
2442 // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
2443#else
Greg Clayton5160ce52013-03-27 23:08:40 +00002444 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Claytonc3c0b0e2012-04-12 19:04:34 +00002445 if (log)
2446 log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
Jim Ingham4ceb9282012-06-08 22:50:40 +00002447#endif
Greg Claytonadc00cb2011-05-20 23:38:13 +00002448 sequence_mutex_unavailable = true;
2449 }
2450 return thread_ids.size();
2451}
Greg Clayton37a0a242012-04-11 00:24:49 +00002452
2453lldb::addr_t
2454GDBRemoteCommunicationClient::GetShlibInfoAddr()
2455{
2456 if (!IsRunning())
2457 {
2458 StringExtractorGDBRemote response;
2459 if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false))
2460 {
2461 if (response.IsNormalResponse())
2462 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2463 }
2464 }
2465 return LLDB_INVALID_ADDRESS;
2466}
2467
Daniel Maleae0f8f572013-08-26 23:57:52 +00002468lldb_private::Error
2469GDBRemoteCommunicationClient::RunShellCommand (const char *command, // Shouldn't be NULL
2470 const char *working_dir, // Pass NULL to use the current working directory
2471 int *status_ptr, // Pass NULL if you don't want the process exit status
2472 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
2473 std::string *command_output, // Pass NULL if you don't want the command output
2474 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
2475{
2476 lldb_private::StreamString stream;
2477 stream.PutCString("qPlatform_RunCommand:");
2478 stream.PutBytesAsRawHex8(command, strlen(command));
2479 stream.PutChar(',');
2480 stream.PutHex32(timeout_sec);
2481 if (working_dir && *working_dir)
2482 {
2483 stream.PutChar(',');
2484 stream.PutBytesAsRawHex8(working_dir, strlen(working_dir));
2485 }
2486 const char *packet = stream.GetData();
2487 int packet_len = stream.GetSize();
2488 StringExtractorGDBRemote response;
2489 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2490 {
2491 if (response.GetChar() != 'F')
2492 return Error("malformed reply");
2493 if (response.GetChar() != ',')
2494 return Error("malformed reply");
2495 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2496 if (exitcode == UINT32_MAX)
2497 return Error("unable to run remote process");
2498 else if (status_ptr)
2499 *status_ptr = exitcode;
2500 if (response.GetChar() != ',')
2501 return Error("malformed reply");
2502 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2503 if (signo_ptr)
2504 *signo_ptr = signo;
2505 if (response.GetChar() != ',')
2506 return Error("malformed reply");
2507 std::string output;
2508 response.GetEscapedBinaryData(output);
2509 if (command_output)
2510 command_output->assign(output);
2511 return Error();
2512 }
2513 return Error("unable to send packet");
2514}
2515
2516uint32_t
2517GDBRemoteCommunicationClient::MakeDirectory (const std::string &path,
2518 mode_t mode)
2519{
2520 lldb_private::StreamString stream;
2521 stream.PutCString("qPlatform_IO_MkDir:");
2522 stream.PutHex32(mode);
2523 stream.PutChar(',');
2524 stream.PutBytesAsRawHex8(path.c_str(), path.size());
2525 const char *packet = stream.GetData();
2526 int packet_len = stream.GetSize();
2527 StringExtractorGDBRemote response;
2528 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2529 {
2530 return response.GetHexMaxU32(false, UINT32_MAX);
2531 }
2532 return UINT32_MAX;
2533
2534}
2535
2536static uint64_t
2537ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
2538 uint64_t fail_result,
2539 Error &error)
2540{
2541 response.SetFilePos(0);
2542 if (response.GetChar() != 'F')
2543 return fail_result;
2544 int32_t result = response.GetS32 (-2);
2545 if (result == -2)
2546 return fail_result;
2547 if (response.GetChar() == ',')
2548 {
2549 int result_errno = response.GetS32 (-2);
2550 if (result_errno != -2)
2551 error.SetError(result_errno, eErrorTypePOSIX);
2552 else
2553 error.SetError(-1, eErrorTypeGeneric);
2554 }
2555 else
2556 error.Clear();
2557 return result;
2558}
2559lldb::user_id_t
2560GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
2561 uint32_t flags,
2562 mode_t mode,
2563 Error &error)
2564{
2565 lldb_private::StreamString stream;
2566 stream.PutCString("vFile:open:");
2567 std::string path (file_spec.GetPath());
2568 if (path.empty())
2569 return UINT64_MAX;
2570 stream.PutCStringAsRawHex8(path.c_str());
2571 stream.PutChar(',');
2572 const uint32_t posix_open_flags = File::ConvertOpenOptionsForPOSIXOpen(flags);
2573 stream.PutHex32(posix_open_flags);
2574 stream.PutChar(',');
2575 stream.PutHex32(mode);
2576 const char* packet = stream.GetData();
2577 int packet_len = stream.GetSize();
2578 StringExtractorGDBRemote response;
2579 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2580 {
2581 return ParseHostIOPacketResponse (response, UINT64_MAX, error);
2582 }
2583 return UINT64_MAX;
2584}
2585
2586bool
2587GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
2588 Error &error)
2589{
2590 lldb_private::StreamString stream;
2591 stream.Printf("vFile:close:%i", (int)fd);
2592 const char* packet = stream.GetData();
2593 int packet_len = stream.GetSize();
2594 StringExtractorGDBRemote response;
2595 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2596 {
2597 return ParseHostIOPacketResponse (response, -1, error) == 0;
2598 }
2599 return UINT64_MAX;
2600}
2601
2602// Extension of host I/O packets to get the file size.
2603lldb::user_id_t
2604GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
2605{
2606 lldb_private::StreamString stream;
2607 stream.PutCString("vFile:size:");
2608 std::string path (file_spec.GetPath());
2609 stream.PutCStringAsRawHex8(path.c_str());
2610 const char* packet = stream.GetData();
2611 int packet_len = stream.GetSize();
2612 StringExtractorGDBRemote response;
2613 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2614 {
2615 if (response.GetChar() != 'F')
2616 return UINT64_MAX;
2617 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2618 return retcode;
2619 }
2620 return UINT64_MAX;
2621}
2622
2623uint32_t
2624GDBRemoteCommunicationClient::GetFilePermissions(const lldb_private::FileSpec& file_spec, Error &error)
2625{
2626 lldb_private::StreamString stream;
2627 stream.PutCString("vFile:mode:");
2628 std::string path (file_spec.GetPath());
2629 stream.PutCStringAsRawHex8(path.c_str());
2630 const char* packet = stream.GetData();
2631 int packet_len = stream.GetSize();
2632 StringExtractorGDBRemote response;
2633 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2634 {
2635 if (response.GetChar() != 'F')
2636 {
2637 error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
2638 return 0;
2639 }
2640 const uint32_t mode = response.GetS32(-1);
2641 if (mode == -1)
2642 {
2643 if (response.GetChar() == ',')
2644 {
2645 int response_errno = response.GetS32(-1);
2646 if (response_errno > 0)
2647 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2648 else
2649 error.SetErrorToGenericError();
2650 }
2651 }
2652 else
2653 error.Clear();
2654 return mode & (S_IRWXU|S_IRWXG|S_IRWXO);
2655 }
2656 else
2657 {
2658 error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
2659 }
2660 return 0;
2661}
2662
2663uint64_t
2664GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
2665 uint64_t offset,
2666 void *dst,
2667 uint64_t dst_len,
2668 Error &error)
2669{
2670 lldb_private::StreamString stream;
2671 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
2672 const char* packet = stream.GetData();
2673 int packet_len = stream.GetSize();
2674 StringExtractorGDBRemote response;
2675 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2676 {
2677 if (response.GetChar() != 'F')
2678 return 0;
2679 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
2680 if (retcode == UINT32_MAX)
2681 return retcode;
2682 const char next = (response.Peek() ? *response.Peek() : 0);
2683 if (next == ',')
2684 return 0;
2685 if (next == ';')
2686 {
2687 response.GetChar(); // skip the semicolon
2688 std::string buffer;
2689 if (response.GetEscapedBinaryData(buffer))
2690 {
2691 const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
2692 if (data_to_write > 0)
2693 memcpy(dst, &buffer[0], data_to_write);
2694 return data_to_write;
2695 }
2696 }
2697 }
2698 return 0;
2699}
2700
2701uint64_t
2702GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
2703 uint64_t offset,
2704 const void* src,
2705 uint64_t src_len,
2706 Error &error)
2707{
2708 lldb_private::StreamGDBRemote stream;
2709 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
2710 stream.PutEscapedBytes(src, src_len);
2711 const char* packet = stream.GetData();
2712 int packet_len = stream.GetSize();
2713 StringExtractorGDBRemote response;
2714 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2715 {
2716 if (response.GetChar() != 'F')
2717 {
2718 error.SetErrorStringWithFormat("write file failed");
2719 return 0;
2720 }
2721 uint64_t bytes_written = response.GetU64(UINT64_MAX);
2722 if (bytes_written == UINT64_MAX)
2723 {
2724 error.SetErrorToGenericError();
2725 if (response.GetChar() == ',')
2726 {
2727 int response_errno = response.GetS32(-1);
2728 if (response_errno > 0)
2729 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2730 }
2731 return 0;
2732 }
2733 return bytes_written;
2734 }
2735 else
2736 {
2737 error.SetErrorString ("failed to send vFile:pwrite packet");
2738 }
2739 return 0;
2740}
2741
2742// Extension of host I/O packets to get whether a file exists.
2743bool
2744GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
2745{
2746 lldb_private::StreamString stream;
2747 stream.PutCString("vFile:exists:");
2748 std::string path (file_spec.GetPath());
2749 stream.PutCStringAsRawHex8(path.c_str());
2750 const char* packet = stream.GetData();
2751 int packet_len = stream.GetSize();
2752 StringExtractorGDBRemote response;
2753 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2754 {
2755 if (response.GetChar() != 'F')
2756 return false;
2757 if (response.GetChar() != ',')
2758 return false;
2759 bool retcode = (response.GetChar() != '0');
2760 return retcode;
2761 }
2762 return false;
2763}
2764
2765bool
2766GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
2767 uint64_t &high,
2768 uint64_t &low)
2769{
2770 lldb_private::StreamString stream;
2771 stream.PutCString("vFile:MD5:");
2772 std::string path (file_spec.GetPath());
2773 stream.PutCStringAsRawHex8(path.c_str());
2774 const char* packet = stream.GetData();
2775 int packet_len = stream.GetSize();
2776 StringExtractorGDBRemote response;
2777 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
2778 {
2779 if (response.GetChar() != 'F')
2780 return false;
2781 if (response.GetChar() != ',')
2782 return false;
2783 if (response.Peek() && *response.Peek() == 'x')
2784 return false;
2785 low = response.GetHexMaxU64(false, UINT64_MAX);
2786 high = response.GetHexMaxU64(false, UINT64_MAX);
2787 return true;
2788 }
2789 return false;
2790}