blob: e708bc301ae0b260e1a452b416c8e8d9994c5d24 [file] [log] [blame]
Greg Clayton576d8832011-03-22 04:00:09 +00001//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11#include "GDBRemoteCommunicationClient.h"
12
13// C Includes
Daniel Maleab89d0492013-08-28 16:06:16 +000014#include <sys/stat.h>
15
Greg Clayton576d8832011-03-22 04:00:09 +000016// C++ Includes
Han Ming Ong4b6459f2013-01-18 23:11:53 +000017#include <sstream>
18
Greg Clayton576d8832011-03-22 04:00:09 +000019// Other libraries and framework includes
20#include "llvm/ADT/Triple.h"
21#include "lldb/Interpreter/Args.h"
22#include "lldb/Core/ConnectionFileDescriptor.h"
23#include "lldb/Core/Log.h"
24#include "lldb/Core/State.h"
Daniel Maleae0f8f572013-08-26 23:57:52 +000025#include "lldb/Core/StreamGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000026#include "lldb/Core/StreamString.h"
27#include "lldb/Host/Endian.h"
28#include "lldb/Host/Host.h"
29#include "lldb/Host/TimeValue.h"
30
31// Project includes
32#include "Utility/StringExtractorGDBRemote.h"
33#include "ProcessGDBRemote.h"
34#include "ProcessGDBRemoteLog.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000035#include "lldb/Host/Config.h"
Greg Clayton576d8832011-03-22 04:00:09 +000036
37using namespace lldb;
38using namespace lldb_private;
39
Virgile Bellob2f1fb22013-08-23 12:44:05 +000040#ifdef LLDB_DISABLE_POSIX
41#define SIGSTOP 17
42#endif
43
Greg Clayton576d8832011-03-22 04:00:09 +000044//----------------------------------------------------------------------
45// GDBRemoteCommunicationClient constructor
46//----------------------------------------------------------------------
Greg Clayton8b82f082011-04-12 05:54:46 +000047GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
48 GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
Greg Clayton576d8832011-03-22 04:00:09 +000049 m_supports_not_sending_acks (eLazyBoolCalculate),
50 m_supports_thread_suffix (eLazyBoolCalculate),
Greg Clayton44633992012-04-10 03:22:03 +000051 m_supports_threads_in_stop_reply (eLazyBoolCalculate),
Greg Clayton576d8832011-03-22 04:00:09 +000052 m_supports_vCont_all (eLazyBoolCalculate),
53 m_supports_vCont_any (eLazyBoolCalculate),
54 m_supports_vCont_c (eLazyBoolCalculate),
55 m_supports_vCont_C (eLazyBoolCalculate),
56 m_supports_vCont_s (eLazyBoolCalculate),
57 m_supports_vCont_S (eLazyBoolCalculate),
Greg Clayton32e0a752011-03-30 18:16:51 +000058 m_qHostInfo_is_valid (eLazyBoolCalculate),
Jason Molendaf17b5ac2012-12-19 02:54:03 +000059 m_qProcessInfo_is_valid (eLazyBoolCalculate),
Greg Clayton70b57652011-05-15 01:25:55 +000060 m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
Greg Clayton46fb5582011-11-18 07:03:08 +000061 m_supports_memory_region_info (eLazyBoolCalculate),
Johnny Chen64637202012-05-23 21:09:52 +000062 m_supports_watchpoint_support_info (eLazyBoolCalculate),
Jim Inghamacff8952013-05-02 00:27:30 +000063 m_supports_detach_stay_stopped (eLazyBoolCalculate),
Enrico Granataf04a2192012-07-13 23:18:48 +000064 m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
Jim Inghamcd16df92012-07-20 21:37:13 +000065 m_attach_or_wait_reply(eLazyBoolCalculate),
Jim Ingham279ceec2012-07-25 21:12:43 +000066 m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
Eric Christopher2490f5c2013-08-30 17:50:57 +000067 m_supports_p (eLazyBoolCalculate),
Greg Claytonf74cf862013-11-13 23:28:31 +000068 m_supports_QSaveRegisterState (eLazyBoolCalculate),
Greg Clayton32e0a752011-03-30 18:16:51 +000069 m_supports_qProcessInfoPID (true),
70 m_supports_qfProcessInfo (true),
71 m_supports_qUserName (true),
72 m_supports_qGroupName (true),
Greg Clayton8b82f082011-04-12 05:54:46 +000073 m_supports_qThreadStopInfo (true),
74 m_supports_z0 (true),
75 m_supports_z1 (true),
76 m_supports_z2 (true),
77 m_supports_z3 (true),
78 m_supports_z4 (true),
Greg Clayton89600582013-10-10 17:53:50 +000079 m_supports_QEnvironment (true),
80 m_supports_QEnvironmentHexEncoded (true),
Greg Clayton8b82f082011-04-12 05:54:46 +000081 m_curr_tid (LLDB_INVALID_THREAD_ID),
82 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Johnny Chen64637202012-05-23 21:09:52 +000083 m_num_supported_hardware_watchpoints (0),
Greg Clayton576d8832011-03-22 04:00:09 +000084 m_async_mutex (Mutex::eMutexTypeRecursive),
85 m_async_packet_predicate (false),
86 m_async_packet (),
87 m_async_response (),
88 m_async_signal (-1),
Han Ming Ong4b6459f2013-01-18 23:11:53 +000089 m_thread_id_to_used_usec_map (),
Greg Clayton1cb64962011-03-24 04:28:38 +000090 m_host_arch(),
Jason Molendaf17b5ac2012-12-19 02:54:03 +000091 m_process_arch(),
Greg Clayton1cb64962011-03-24 04:28:38 +000092 m_os_version_major (UINT32_MAX),
93 m_os_version_minor (UINT32_MAX),
Greg Clayton9ac6d2d2013-10-25 18:13:17 +000094 m_os_version_update (UINT32_MAX),
95 m_os_build (),
96 m_os_kernel (),
97 m_hostname (),
98 m_default_packet_timeout (0)
Greg Clayton576d8832011-03-22 04:00:09 +000099{
Greg Clayton576d8832011-03-22 04:00:09 +0000100}
101
102//----------------------------------------------------------------------
103// Destructor
104//----------------------------------------------------------------------
105GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
106{
Greg Clayton576d8832011-03-22 04:00:09 +0000107 if (IsConnected())
Greg Clayton576d8832011-03-22 04:00:09 +0000108 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000109}
110
111bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000112GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
113{
Greg Claytonfb909312013-11-23 01:58:15 +0000114 ResetDiscoverableSettings();
115
Greg Clayton1cb64962011-03-24 04:28:38 +0000116 // Start the read thread after we send the handshake ack since if we
117 // fail to send the handshake ack, there is no reason to continue...
118 if (SendAck())
Greg Claytonfb909312013-11-23 01:58:15 +0000119 {
120 // The return value from QueryNoAckModeSupported() is true if the packet
121 // was sent and _any_ response (including UNIMPLEMENTED) was received),
122 // or false if no response was received. This quickly tells us if we have
123 // a live connection to a remote GDB server...
124 if (QueryNoAckModeSupported())
125 {
126 return true;
127 }
128 else
129 {
130 if (error_ptr)
131 error_ptr->SetErrorString("failed to get reply to handshake packet");
132 }
133 }
134 else
135 {
136 if (error_ptr)
137 error_ptr->SetErrorString("failed to send the handshake ack");
138 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000139 return false;
140}
141
Greg Claytonfb909312013-11-23 01:58:15 +0000142bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000143GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton576d8832011-03-22 04:00:09 +0000144{
145 if (m_supports_not_sending_acks == eLazyBoolCalculate)
146 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000147 m_send_acks = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000148 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000149
150 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000151 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000152 {
153 if (response.IsOKResponse())
Greg Clayton1cb64962011-03-24 04:28:38 +0000154 {
155 m_send_acks = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000156 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton1cb64962011-03-24 04:28:38 +0000157 }
Greg Claytonfb909312013-11-23 01:58:15 +0000158 return true;
Greg Clayton576d8832011-03-22 04:00:09 +0000159 }
160 }
Greg Claytonfb909312013-11-23 01:58:15 +0000161 return false;
Greg Clayton576d8832011-03-22 04:00:09 +0000162}
163
164void
Greg Clayton44633992012-04-10 03:22:03 +0000165GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
166{
167 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
168 {
169 m_supports_threads_in_stop_reply = eLazyBoolNo;
170
171 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000172 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
Greg Clayton44633992012-04-10 03:22:03 +0000173 {
174 if (response.IsOKResponse())
175 m_supports_threads_in_stop_reply = eLazyBoolYes;
176 }
177 }
178}
179
Jim Inghamcd16df92012-07-20 21:37:13 +0000180bool
181GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
182{
183 if (m_attach_or_wait_reply == eLazyBoolCalculate)
184 {
185 m_attach_or_wait_reply = eLazyBoolNo;
186
187 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000188 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
Jim Inghamcd16df92012-07-20 21:37:13 +0000189 {
190 if (response.IsOKResponse())
191 m_attach_or_wait_reply = eLazyBoolYes;
192 }
193 }
194 if (m_attach_or_wait_reply == eLazyBoolYes)
195 return true;
196 else
197 return false;
198}
199
Jim Ingham279ceec2012-07-25 21:12:43 +0000200bool
201GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
202{
203 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
204 {
205 m_prepare_for_reg_writing_reply = eLazyBoolNo;
206
207 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000208 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
Jim Ingham279ceec2012-07-25 21:12:43 +0000209 {
210 if (response.IsOKResponse())
211 m_prepare_for_reg_writing_reply = eLazyBoolYes;
212 }
213 }
214 if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
215 return true;
216 else
217 return false;
218}
219
Greg Clayton44633992012-04-10 03:22:03 +0000220
221void
Greg Clayton576d8832011-03-22 04:00:09 +0000222GDBRemoteCommunicationClient::ResetDiscoverableSettings()
223{
224 m_supports_not_sending_acks = eLazyBoolCalculate;
225 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton44633992012-04-10 03:22:03 +0000226 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
Greg Clayton576d8832011-03-22 04:00:09 +0000227 m_supports_vCont_c = eLazyBoolCalculate;
228 m_supports_vCont_C = eLazyBoolCalculate;
229 m_supports_vCont_s = eLazyBoolCalculate;
230 m_supports_vCont_S = eLazyBoolCalculate;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000231 m_supports_p = eLazyBoolCalculate;
Greg Claytonf74cf862013-11-13 23:28:31 +0000232 m_supports_QSaveRegisterState = eLazyBoolCalculate;
Greg Clayton32e0a752011-03-30 18:16:51 +0000233 m_qHostInfo_is_valid = eLazyBoolCalculate;
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000234 m_qProcessInfo_is_valid = eLazyBoolCalculate;
Greg Clayton70b57652011-05-15 01:25:55 +0000235 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
Greg Clayton46fb5582011-11-18 07:03:08 +0000236 m_supports_memory_region_info = eLazyBoolCalculate;
Jim Ingham279ceec2012-07-25 21:12:43 +0000237 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
238 m_attach_or_wait_reply = eLazyBoolCalculate;
Greg Clayton2a48f522011-05-14 01:50:35 +0000239
Greg Clayton32e0a752011-03-30 18:16:51 +0000240 m_supports_qProcessInfoPID = true;
241 m_supports_qfProcessInfo = true;
242 m_supports_qUserName = true;
243 m_supports_qGroupName = true;
Greg Clayton8b82f082011-04-12 05:54:46 +0000244 m_supports_qThreadStopInfo = true;
245 m_supports_z0 = true;
246 m_supports_z1 = true;
247 m_supports_z2 = true;
248 m_supports_z3 = true;
249 m_supports_z4 = true;
Greg Clayton89600582013-10-10 17:53:50 +0000250 m_supports_QEnvironment = true;
251 m_supports_QEnvironmentHexEncoded = true;
Greg Claytond314e812011-03-23 00:09:55 +0000252 m_host_arch.Clear();
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000253 m_process_arch.Clear();
Greg Clayton576d8832011-03-22 04:00:09 +0000254}
255
256
257bool
258GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
259{
260 if (m_supports_thread_suffix == eLazyBoolCalculate)
261 {
262 StringExtractorGDBRemote response;
263 m_supports_thread_suffix = eLazyBoolNo;
Greg Clayton3dedae12013-12-06 21:45:27 +0000264 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000265 {
266 if (response.IsOKResponse())
267 m_supports_thread_suffix = eLazyBoolYes;
268 }
269 }
270 return m_supports_thread_suffix;
271}
272bool
273GDBRemoteCommunicationClient::GetVContSupported (char flavor)
274{
275 if (m_supports_vCont_c == eLazyBoolCalculate)
276 {
277 StringExtractorGDBRemote response;
278 m_supports_vCont_any = eLazyBoolNo;
279 m_supports_vCont_all = eLazyBoolNo;
280 m_supports_vCont_c = eLazyBoolNo;
281 m_supports_vCont_C = eLazyBoolNo;
282 m_supports_vCont_s = eLazyBoolNo;
283 m_supports_vCont_S = eLazyBoolNo;
Greg Clayton3dedae12013-12-06 21:45:27 +0000284 if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000285 {
286 const char *response_cstr = response.GetStringRef().c_str();
287 if (::strstr (response_cstr, ";c"))
288 m_supports_vCont_c = eLazyBoolYes;
289
290 if (::strstr (response_cstr, ";C"))
291 m_supports_vCont_C = eLazyBoolYes;
292
293 if (::strstr (response_cstr, ";s"))
294 m_supports_vCont_s = eLazyBoolYes;
295
296 if (::strstr (response_cstr, ";S"))
297 m_supports_vCont_S = eLazyBoolYes;
298
299 if (m_supports_vCont_c == eLazyBoolYes &&
300 m_supports_vCont_C == eLazyBoolYes &&
301 m_supports_vCont_s == eLazyBoolYes &&
302 m_supports_vCont_S == eLazyBoolYes)
303 {
304 m_supports_vCont_all = eLazyBoolYes;
305 }
306
307 if (m_supports_vCont_c == eLazyBoolYes ||
308 m_supports_vCont_C == eLazyBoolYes ||
309 m_supports_vCont_s == eLazyBoolYes ||
310 m_supports_vCont_S == eLazyBoolYes)
311 {
312 m_supports_vCont_any = eLazyBoolYes;
313 }
314 }
315 }
316
317 switch (flavor)
318 {
319 case 'a': return m_supports_vCont_any;
320 case 'A': return m_supports_vCont_all;
321 case 'c': return m_supports_vCont_c;
322 case 'C': return m_supports_vCont_C;
323 case 's': return m_supports_vCont_s;
324 case 'S': return m_supports_vCont_S;
325 default: break;
326 }
327 return false;
328}
329
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000330// Check if the target supports 'p' packet. It sends out a 'p'
331// packet and checks the response. A normal packet will tell us
332// that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000333//
334// Takes a valid thread ID because p needs to apply to a thread.
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000335bool
Sean Callananb1de1142013-09-04 23:24:15 +0000336GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000337{
338 if (m_supports_p == eLazyBoolCalculate)
339 {
340 StringExtractorGDBRemote response;
341 m_supports_p = eLazyBoolNo;
Sean Callananb1de1142013-09-04 23:24:15 +0000342 char packet[256];
343 if (GetThreadSuffixSupported())
344 snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
345 else
346 snprintf(packet, sizeof(packet), "p0");
347
Greg Clayton3dedae12013-12-06 21:45:27 +0000348 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000349 {
350 if (response.IsNormalResponse())
351 m_supports_p = eLazyBoolYes;
352 }
353 }
354 return m_supports_p;
355}
Greg Clayton576d8832011-03-22 04:00:09 +0000356
Greg Clayton3dedae12013-12-06 21:45:27 +0000357GDBRemoteCommunicationClient::PacketResult
Greg Clayton576d8832011-03-22 04:00:09 +0000358GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
359(
360 const char *payload,
361 StringExtractorGDBRemote &response,
362 bool send_async
363)
364{
365 return SendPacketAndWaitForResponse (payload,
366 ::strlen (payload),
367 response,
368 send_async);
369}
370
Greg Clayton3dedae12013-12-06 21:45:27 +0000371GDBRemoteCommunicationClient::PacketResult
372GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload,
373 size_t payload_length,
374 StringExtractorGDBRemote &response)
375{
376 PacketResult packet_result = SendPacketNoLock (payload, payload_length);
377 if (packet_result == PacketResult::Success)
378 packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
379 return packet_result;
380}
381
382GDBRemoteCommunicationClient::PacketResult
Greg Clayton576d8832011-03-22 04:00:09 +0000383GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
384(
385 const char *payload,
386 size_t payload_length,
387 StringExtractorGDBRemote &response,
388 bool send_async
389)
390{
Greg Clayton3dedae12013-12-06 21:45:27 +0000391 PacketResult packet_result = PacketResult::ErrorSendFailed;
Greg Clayton576d8832011-03-22 04:00:09 +0000392 Mutex::Locker locker;
Greg Clayton5160ce52013-03-27 23:08:40 +0000393 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton644247c2011-07-07 01:59:51 +0000394 size_t response_len = 0;
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000395 if (GetSequenceMutex (locker))
Greg Clayton576d8832011-03-22 04:00:09 +0000396 {
Greg Clayton3dedae12013-12-06 21:45:27 +0000397 packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
Greg Clayton576d8832011-03-22 04:00:09 +0000398 }
399 else
400 {
401 if (send_async)
402 {
Greg Claytond3544052012-05-31 21:24:20 +0000403 if (IsRunning())
Greg Clayton576d8832011-03-22 04:00:09 +0000404 {
Greg Claytond3544052012-05-31 21:24:20 +0000405 Mutex::Locker async_locker (m_async_mutex);
406 m_async_packet.assign(payload, payload_length);
407 m_async_packet_predicate.SetValue (true, eBroadcastNever);
408
409 if (log)
410 log->Printf ("async: async packet = %s", m_async_packet.c_str());
411
412 bool timed_out = false;
413 if (SendInterrupt(locker, 2, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +0000414 {
Greg Claytond3544052012-05-31 21:24:20 +0000415 if (m_interrupt_sent)
Greg Clayton576d8832011-03-22 04:00:09 +0000416 {
Jim Inghambabfc382012-06-06 00:32:39 +0000417 m_interrupt_sent = false;
Greg Claytond3544052012-05-31 21:24:20 +0000418 TimeValue timeout_time;
419 timeout_time = TimeValue::Now();
420 timeout_time.OffsetWithSeconds (m_packet_timeout);
421
Greg Clayton576d8832011-03-22 04:00:09 +0000422 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000423 log->Printf ("async: sent interrupt");
Greg Clayton644247c2011-07-07 01:59:51 +0000424
Greg Claytond3544052012-05-31 21:24:20 +0000425 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
Greg Claytone889ad62011-10-27 22:04:16 +0000426 {
Greg Claytond3544052012-05-31 21:24:20 +0000427 if (log)
428 log->Printf ("async: got response");
429
430 // Swap the response buffer to avoid malloc and string copy
431 response.GetStringRef().swap (m_async_response.GetStringRef());
432 response_len = response.GetStringRef().size();
433 }
434 else
435 {
436 if (log)
437 log->Printf ("async: timed out waiting for response");
438 }
439
440 // Make sure we wait until the continue packet has been sent again...
441 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
442 {
443 if (log)
444 {
445 if (timed_out)
446 log->Printf ("async: timed out waiting for process to resume, but process was resumed");
447 else
448 log->Printf ("async: async packet sent");
449 }
450 }
451 else
452 {
453 if (log)
454 log->Printf ("async: timed out waiting for process to resume");
Greg Claytone889ad62011-10-27 22:04:16 +0000455 }
456 }
457 else
458 {
Greg Claytond3544052012-05-31 21:24:20 +0000459 // We had a racy condition where we went to send the interrupt
460 // yet we were able to get the lock, so the process must have
461 // just stopped?
Greg Clayton576d8832011-03-22 04:00:09 +0000462 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000463 log->Printf ("async: got lock without sending interrupt");
464 // Send the packet normally since we got the lock
Greg Clayton3dedae12013-12-06 21:45:27 +0000465 packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
Greg Clayton576d8832011-03-22 04:00:09 +0000466 }
467 }
468 else
469 {
Greg Clayton644247c2011-07-07 01:59:51 +0000470 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000471 log->Printf ("async: failed to interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +0000472 }
473 }
474 else
475 {
476 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000477 log->Printf ("async: not running, async is ignored");
Greg Clayton576d8832011-03-22 04:00:09 +0000478 }
479 }
480 else
481 {
482 if (log)
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000483 log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
Greg Clayton576d8832011-03-22 04:00:09 +0000484 }
485 }
Greg Clayton3dedae12013-12-06 21:45:27 +0000486 return packet_result;
Greg Clayton576d8832011-03-22 04:00:09 +0000487}
488
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000489static const char *end_delimiter = "--end--;";
490static const int end_delimiter_len = 8;
491
492std::string
493GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
494( ProcessGDBRemote *process,
495 StringExtractorGDBRemote& profileDataExtractor
496)
497{
498 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
499 std::stringstream final_output;
500 std::string name, value;
501
502 // Going to assuming thread_used_usec comes first, else bail out.
503 while (profileDataExtractor.GetNameColonValue(name, value))
504 {
505 if (name.compare("thread_used_id") == 0)
506 {
507 StringExtractor threadIDHexExtractor(value.c_str());
508 uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
509
510 bool has_used_usec = false;
511 uint32_t curr_used_usec = 0;
512 std::string usec_name, usec_value;
513 uint32_t input_file_pos = profileDataExtractor.GetFilePos();
514 if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
515 {
516 if (usec_name.compare("thread_used_usec") == 0)
517 {
518 has_used_usec = true;
519 curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
520 }
521 else
522 {
523 // We didn't find what we want, it is probably
524 // an older version. Bail out.
525 profileDataExtractor.SetFilePos(input_file_pos);
526 }
527 }
528
529 if (has_used_usec)
530 {
531 uint32_t prev_used_usec = 0;
532 std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
533 if (iterator != m_thread_id_to_used_usec_map.end())
534 {
535 prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
536 }
537
538 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
539 // A good first time record is one that runs for at least 0.25 sec
540 bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
541 bool good_subsequent_time = (prev_used_usec > 0) &&
542 ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
543
544 if (good_first_time || good_subsequent_time)
545 {
546 // We try to avoid doing too many index id reservation,
547 // resulting in fast increase of index ids.
548
549 final_output << name << ":";
550 int32_t index_id = process->AssignIndexIDToThread(thread_id);
551 final_output << index_id << ";";
552
553 final_output << usec_name << ":" << usec_value << ";";
554 }
555 else
556 {
557 // Skip past 'thread_used_name'.
558 std::string local_name, local_value;
559 profileDataExtractor.GetNameColonValue(local_name, local_value);
560 }
561
562 // Store current time as previous time so that they can be compared later.
563 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
564 }
565 else
566 {
567 // Bail out and use old string.
568 final_output << name << ":" << value << ";";
569 }
570 }
571 else
572 {
573 final_output << name << ":" << value << ";";
574 }
575 }
576 final_output << end_delimiter;
577 m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
578
579 return final_output.str();
580}
581
Greg Clayton576d8832011-03-22 04:00:09 +0000582StateType
583GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
584(
585 ProcessGDBRemote *process,
586 const char *payload,
587 size_t packet_length,
588 StringExtractorGDBRemote &response
589)
590{
Greg Clayton1f5181a2012-07-02 22:05:25 +0000591 m_curr_tid = LLDB_INVALID_THREAD_ID;
Greg Clayton5160ce52013-03-27 23:08:40 +0000592 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton576d8832011-03-22 04:00:09 +0000593 if (log)
594 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
595
596 Mutex::Locker locker(m_sequence_mutex);
597 StateType state = eStateRunning;
598
599 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
600 m_public_is_running.SetValue (true, eBroadcastNever);
601 // Set the starting continue packet into "continue_packet". This packet
Jim Inghambabfc382012-06-06 00:32:39 +0000602 // may change if we are interrupted and we continue after an async packet...
Greg Clayton576d8832011-03-22 04:00:09 +0000603 std::string continue_packet(payload, packet_length);
604
Greg Clayton3f875c52013-02-22 22:23:55 +0000605 bool got_async_packet = false;
Greg Claytonaf247d72011-05-19 03:54:16 +0000606
Greg Clayton576d8832011-03-22 04:00:09 +0000607 while (state == eStateRunning)
608 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000609 if (!got_async_packet)
Greg Claytonaf247d72011-05-19 03:54:16 +0000610 {
611 if (log)
612 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
Greg Clayton3dedae12013-12-06 21:45:27 +0000613 if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
Greg Claytonaf247d72011-05-19 03:54:16 +0000614 state = eStateInvalid;
Greg Clayton576d8832011-03-22 04:00:09 +0000615
Greg Claytone889ad62011-10-27 22:04:16 +0000616 m_private_is_running.SetValue (true, eBroadcastAlways);
Greg Claytonaf247d72011-05-19 03:54:16 +0000617 }
618
Greg Clayton3f875c52013-02-22 22:23:55 +0000619 got_async_packet = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000620
621 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000622 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
Greg Clayton576d8832011-03-22 04:00:09 +0000623
Greg Clayton3dedae12013-12-06 21:45:27 +0000624 if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000625 {
626 if (response.Empty())
627 state = eStateInvalid;
628 else
629 {
630 const char stop_type = response.GetChar();
631 if (log)
632 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
633 switch (stop_type)
634 {
635 case 'T':
636 case 'S':
Greg Clayton576d8832011-03-22 04:00:09 +0000637 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000638 if (process->GetStopID() == 0)
Greg Clayton576d8832011-03-22 04:00:09 +0000639 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000640 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
641 {
642 lldb::pid_t pid = GetCurrentProcessID ();
643 if (pid != LLDB_INVALID_PROCESS_ID)
644 process->SetID (pid);
645 }
646 process->BuildDynamicRegisterInfo (true);
Greg Clayton576d8832011-03-22 04:00:09 +0000647 }
Greg Clayton2687cd12012-03-29 01:55:41 +0000648
649 // Privately notify any internal threads that we have stopped
650 // in case we wanted to interrupt our process, yet we might
651 // send a packet and continue without returning control to the
652 // user.
653 m_private_is_running.SetValue (false, eBroadcastAlways);
654
655 const uint8_t signo = response.GetHexU8 (UINT8_MAX);
656
Jim Inghambabfc382012-06-06 00:32:39 +0000657 bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
658 if (continue_after_async || m_interrupt_sent)
Greg Clayton2687cd12012-03-29 01:55:41 +0000659 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000660 // We sent an interrupt packet to stop the inferior process
661 // for an async signal or to send an async packet while running
662 // but we might have been single stepping and received the
663 // stop packet for the step instead of for the interrupt packet.
664 // Typically when an interrupt is sent a SIGINT or SIGSTOP
665 // is used, so if we get anything else, we need to try and
666 // get another stop reply packet that may have been sent
667 // due to sending the interrupt when the target is stopped
668 // which will just re-send a copy of the last stop reply
669 // packet. If we don't do this, then the reply for our
670 // async packet will be the repeat stop reply packet and cause
671 // a lot of trouble for us!
672 if (signo != SIGINT && signo != SIGSTOP)
673 {
Greg Claytonfb72fde2012-05-15 02:50:49 +0000674 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +0000675
676 // We didn't get a a SIGINT or SIGSTOP, so try for a
677 // very brief time (1 ms) to get another stop reply
678 // packet to make sure it doesn't get in the way
679 StringExtractorGDBRemote extra_stop_reply_packet;
680 uint32_t timeout_usec = 1000;
Greg Clayton3dedae12013-12-06 21:45:27 +0000681 if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec) == PacketResult::Success)
Greg Clayton2687cd12012-03-29 01:55:41 +0000682 {
683 switch (extra_stop_reply_packet.GetChar())
684 {
685 case 'T':
686 case 'S':
687 // We did get an extra stop reply, which means
688 // our interrupt didn't stop the target so we
689 // shouldn't continue after the async signal
690 // or packet is sent...
Greg Claytonfb72fde2012-05-15 02:50:49 +0000691 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +0000692 break;
693 }
694 }
695 }
696 }
697
698 if (m_async_signal != -1)
699 {
700 if (log)
701 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
702
703 // Save off the async signal we are supposed to send
704 const int async_signal = m_async_signal;
705 // Clear the async signal member so we don't end up
706 // sending the signal multiple times...
707 m_async_signal = -1;
708 // Check which signal we stopped with
709 if (signo == async_signal)
710 {
711 if (log)
712 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
713
714 // We already stopped with a signal that we wanted
715 // to stop with, so we are done
716 }
717 else
718 {
719 // We stopped with a different signal that the one
720 // we wanted to stop with, so now we must resume
721 // with the signal we want
722 char signal_packet[32];
723 int signal_packet_len = 0;
724 signal_packet_len = ::snprintf (signal_packet,
725 sizeof (signal_packet),
726 "C%2.2x",
727 async_signal);
728
729 if (log)
730 log->Printf ("async: stopped with signal %s, resume with %s",
731 Host::GetSignalAsCString (signo),
732 Host::GetSignalAsCString (async_signal));
733
734 // Set the continue packet to resume even if the
Greg Claytonfb72fde2012-05-15 02:50:49 +0000735 // interrupt didn't cause our stop (ignore continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +0000736 continue_packet.assign(signal_packet, signal_packet_len);
737 continue;
738 }
739 }
740 else if (m_async_packet_predicate.GetValue())
741 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000742 Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton2687cd12012-03-29 01:55:41 +0000743
744 // We are supposed to send an asynchronous packet while
745 // we are running.
746 m_async_response.Clear();
747 if (m_async_packet.empty())
748 {
749 if (packet_log)
750 packet_log->Printf ("async: error: empty async packet");
751
752 }
753 else
754 {
755 if (packet_log)
756 packet_log->Printf ("async: sending packet");
757
758 SendPacketAndWaitForResponse (&m_async_packet[0],
759 m_async_packet.size(),
760 m_async_response,
761 false);
762 }
763 // Let the other thread that was trying to send the async
764 // packet know that the packet has been sent and response is
765 // ready...
766 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
767
768 if (packet_log)
Greg Claytonfb72fde2012-05-15 02:50:49 +0000769 packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);
Greg Clayton2687cd12012-03-29 01:55:41 +0000770
771 // Set the continue packet to resume if our interrupt
772 // for the async packet did cause the stop
Greg Claytonfb72fde2012-05-15 02:50:49 +0000773 if (continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +0000774 {
Greg Claytonf1186de2012-05-24 23:42:14 +0000775 // Reverting this for now as it is causing deadlocks
776 // in programs (<rdar://problem/11529853>). In the future
777 // we should check our thread list and "do the right thing"
778 // for new threads that show up while we stop and run async
779 // packets. Setting the packet to 'c' to continue all threads
780 // is the right thing to do 99.99% of the time because if a
781 // thread was single stepping, and we sent an interrupt, we
782 // will notice above that we didn't stop due to an interrupt
783 // but stopped due to stepping and we would _not_ continue.
784 continue_packet.assign (1, 'c');
Greg Clayton2687cd12012-03-29 01:55:41 +0000785 continue;
786 }
787 }
788 // Stop with signal and thread info
789 state = eStateStopped;
Greg Clayton576d8832011-03-22 04:00:09 +0000790 }
Greg Clayton576d8832011-03-22 04:00:09 +0000791 break;
792
793 case 'W':
794 case 'X':
795 // process exited
796 state = eStateExited;
797 break;
798
799 case 'O':
800 // STDOUT
801 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000802 got_async_packet = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000803 std::string inferior_stdout;
804 inferior_stdout.reserve(response.GetBytesLeft () / 2);
805 char ch;
806 while ((ch = response.GetHexU8()) != '\0')
807 inferior_stdout.append(1, ch);
808 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
809 }
810 break;
811
Han Ming Ongab3b8b22012-11-17 00:21:04 +0000812 case 'A':
813 // Async miscellaneous reply. Right now, only profile data is coming through this channel.
814 {
Greg Clayton3f875c52013-02-22 22:23:55 +0000815 got_async_packet = true;
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000816 std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
817 if (m_partial_profile_data.length() > 0)
818 {
819 m_partial_profile_data.append(input);
820 input = m_partial_profile_data;
821 m_partial_profile_data.clear();
822 }
823
824 size_t found, pos = 0, len = input.length();
825 while ((found = input.find(end_delimiter, pos)) != std::string::npos)
826 {
827 StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
Han Ming Ong91ed6b82013-06-24 18:15:05 +0000828 std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
829 process->BroadcastAsyncProfileData (profile_data);
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000830
831 pos = found + end_delimiter_len;
832 }
833
834 if (pos < len)
835 {
836 // Last incomplete chunk.
837 m_partial_profile_data = input.substr(pos);
838 }
Han Ming Ongab3b8b22012-11-17 00:21:04 +0000839 }
840 break;
841
Greg Clayton576d8832011-03-22 04:00:09 +0000842 case 'E':
843 // ERROR
844 state = eStateInvalid;
845 break;
846
847 default:
848 if (log)
849 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
850 state = eStateInvalid;
851 break;
852 }
853 }
854 }
855 else
856 {
857 if (log)
858 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
859 state = eStateInvalid;
860 }
861 }
862 if (log)
863 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
864 response.SetFilePos(0);
865 m_private_is_running.SetValue (false, eBroadcastAlways);
866 m_public_is_running.SetValue (false, eBroadcastAlways);
867 return state;
868}
869
870bool
871GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
872{
Greg Clayton2687cd12012-03-29 01:55:41 +0000873 Mutex::Locker async_locker (m_async_mutex);
Greg Clayton576d8832011-03-22 04:00:09 +0000874 m_async_signal = signo;
875 bool timed_out = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000876 Mutex::Locker locker;
Greg Clayton2687cd12012-03-29 01:55:41 +0000877 if (SendInterrupt (locker, 1, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +0000878 return true;
879 m_async_signal = -1;
880 return false;
881}
882
Greg Clayton37a0a242012-04-11 00:24:49 +0000883// This function takes a mutex locker as a parameter in case the GetSequenceMutex
Greg Clayton576d8832011-03-22 04:00:09 +0000884// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
885// (the expected result), then it will send the halt packet. If it does succeed
886// then the caller that requested the interrupt will want to keep the sequence
887// locked down so that no one else can send packets while the caller has control.
888// This function usually gets called when we are running and need to stop the
889// target. It can also be used when we are running and and we need to do something
890// else (like read/write memory), so we need to interrupt the running process
891// (gdb remote protocol requires this), and do what we need to do, then resume.
892
893bool
Greg Clayton2687cd12012-03-29 01:55:41 +0000894GDBRemoteCommunicationClient::SendInterrupt
Greg Clayton576d8832011-03-22 04:00:09 +0000895(
896 Mutex::Locker& locker,
897 uint32_t seconds_to_wait_for_stop,
Greg Clayton576d8832011-03-22 04:00:09 +0000898 bool &timed_out
899)
900{
Greg Clayton576d8832011-03-22 04:00:09 +0000901 timed_out = false;
Greg Clayton5160ce52013-03-27 23:08:40 +0000902 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Clayton576d8832011-03-22 04:00:09 +0000903
904 if (IsRunning())
905 {
906 // Only send an interrupt if our debugserver is running...
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000907 if (GetSequenceMutex (locker))
Greg Clayton37a0a242012-04-11 00:24:49 +0000908 {
909 if (log)
910 log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
911 }
912 else
Greg Clayton576d8832011-03-22 04:00:09 +0000913 {
914 // Someone has the mutex locked waiting for a response or for the
915 // inferior to stop, so send the interrupt on the down low...
916 char ctrl_c = '\x03';
917 ConnectionStatus status = eConnectionStatusSuccess;
Greg Clayton576d8832011-03-22 04:00:09 +0000918 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton2687cd12012-03-29 01:55:41 +0000919 if (log)
920 log->PutCString("send packet: \\x03");
Greg Clayton576d8832011-03-22 04:00:09 +0000921 if (bytes_written > 0)
922 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000923 m_interrupt_sent = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000924 if (seconds_to_wait_for_stop)
925 {
Greg Clayton2687cd12012-03-29 01:55:41 +0000926 TimeValue timeout;
927 if (seconds_to_wait_for_stop)
928 {
929 timeout = TimeValue::Now();
930 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
931 }
Greg Clayton576d8832011-03-22 04:00:09 +0000932 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
933 {
934 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000935 log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
Greg Clayton576d8832011-03-22 04:00:09 +0000936 return true;
937 }
938 else
939 {
940 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000941 log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
Greg Clayton576d8832011-03-22 04:00:09 +0000942 }
943 }
944 else
945 {
946 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000947 log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
Greg Clayton576d8832011-03-22 04:00:09 +0000948 return true;
949 }
950 }
951 else
952 {
953 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +0000954 log->Printf ("SendInterrupt () - failed to write interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +0000955 }
956 return false;
957 }
Greg Clayton576d8832011-03-22 04:00:09 +0000958 }
Greg Clayton2687cd12012-03-29 01:55:41 +0000959 else
960 {
961 if (log)
962 log->Printf ("SendInterrupt () - not running");
963 }
Greg Clayton576d8832011-03-22 04:00:09 +0000964 return true;
965}
966
967lldb::pid_t
968GDBRemoteCommunicationClient::GetCurrentProcessID ()
969{
970 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000971 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000972 {
973 if (response.GetChar() == 'Q')
974 if (response.GetChar() == 'C')
975 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
976 }
977 return LLDB_INVALID_PROCESS_ID;
978}
979
980bool
981GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
982{
983 error_str.clear();
984 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000985 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000986 {
987 if (response.IsOKResponse())
988 return true;
989 if (response.GetChar() == 'E')
990 {
991 // A string the describes what failed when launching...
992 error_str = response.GetStringRef().substr(1);
993 }
994 else
995 {
996 error_str.assign ("unknown error occurred launching process");
997 }
998 }
999 else
1000 {
Jim Ingham98d6da52012-06-28 20:30:23 +00001001 error_str.assign ("timed out waiting for app to launch");
Greg Clayton576d8832011-03-22 04:00:09 +00001002 }
1003 return false;
1004}
1005
1006int
Greg Claytonfbb76342013-11-20 21:07:01 +00001007GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
Greg Clayton576d8832011-03-22 04:00:09 +00001008{
Greg Claytonfbb76342013-11-20 21:07:01 +00001009 // Since we don't get the send argv0 separate from the executable path, we need to
1010 // make sure to use the actual exectuable path found in the launch_info...
1011 std::vector<const char *> argv;
1012 FileSpec exe_file = launch_info.GetExecutableFile();
1013 std::string exe_path;
1014 const char *arg = NULL;
1015 const Args &launch_args = launch_info.GetArguments();
1016 if (exe_file)
1017 exe_path = exe_file.GetPath();
1018 else
1019 {
1020 arg = launch_args.GetArgumentAtIndex(0);
1021 if (arg)
1022 exe_path = arg;
1023 }
1024 if (!exe_path.empty())
1025 {
1026 argv.push_back(exe_path.c_str());
1027 for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
1028 {
1029 if (arg)
1030 argv.push_back(arg);
1031 }
1032 }
1033 if (!argv.empty())
Greg Clayton576d8832011-03-22 04:00:09 +00001034 {
1035 StreamString packet;
1036 packet.PutChar('A');
Greg Claytonfbb76342013-11-20 21:07:01 +00001037 for (size_t i = 0, n = argv.size(); i < n; ++i)
Greg Clayton576d8832011-03-22 04:00:09 +00001038 {
Greg Claytonfbb76342013-11-20 21:07:01 +00001039 arg = argv[i];
Greg Clayton576d8832011-03-22 04:00:09 +00001040 const int arg_len = strlen(arg);
1041 if (i > 0)
1042 packet.PutChar(',');
Greg Claytonfbb76342013-11-20 21:07:01 +00001043 packet.Printf("%i,%i,", arg_len * 2, (int)i);
Greg Clayton576d8832011-03-22 04:00:09 +00001044 packet.PutBytesAsRawHex8 (arg, arg_len);
1045 }
1046
1047 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001048 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001049 {
1050 if (response.IsOKResponse())
1051 return 0;
1052 uint8_t error = response.GetError();
1053 if (error)
1054 return error;
1055 }
1056 }
1057 return -1;
1058}
1059
1060int
1061GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
1062{
1063 if (name_equal_value && name_equal_value[0])
1064 {
1065 StreamString packet;
Greg Clayton89600582013-10-10 17:53:50 +00001066 bool send_hex_encoding = false;
1067 for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p)
Greg Clayton576d8832011-03-22 04:00:09 +00001068 {
Greg Clayton89600582013-10-10 17:53:50 +00001069 if (isprint(*p))
1070 {
1071 switch (*p)
1072 {
1073 case '$':
1074 case '#':
1075 send_hex_encoding = true;
1076 break;
1077 default:
1078 break;
1079 }
1080 }
1081 else
1082 {
1083 // We have non printable characters, lets hex encode this...
1084 send_hex_encoding = true;
1085 }
1086 }
1087
1088 StringExtractorGDBRemote response;
1089 if (send_hex_encoding)
1090 {
1091 if (m_supports_QEnvironmentHexEncoded)
1092 {
1093 packet.PutCString("QEnvironmentHexEncoded:");
1094 packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
Greg Clayton3dedae12013-12-06 21:45:27 +00001095 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton89600582013-10-10 17:53:50 +00001096 {
1097 if (response.IsOKResponse())
1098 return 0;
1099 uint8_t error = response.GetError();
1100 if (error)
1101 return error;
1102 if (response.IsUnsupportedResponse())
1103 m_supports_QEnvironmentHexEncoded = false;
1104 }
1105 }
1106
1107 }
1108 else if (m_supports_QEnvironment)
1109 {
1110 packet.Printf("QEnvironment:%s", name_equal_value);
Greg Clayton3dedae12013-12-06 21:45:27 +00001111 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton89600582013-10-10 17:53:50 +00001112 {
1113 if (response.IsOKResponse())
1114 return 0;
1115 uint8_t error = response.GetError();
1116 if (error)
1117 return error;
1118 if (response.IsUnsupportedResponse())
1119 m_supports_QEnvironment = false;
1120 }
Greg Clayton576d8832011-03-22 04:00:09 +00001121 }
1122 }
1123 return -1;
1124}
1125
Greg Claytonc4103b32011-05-08 04:53:50 +00001126int
1127GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
1128{
1129 if (arch && arch[0])
1130 {
1131 StreamString packet;
1132 packet.Printf("QLaunchArch:%s", arch);
1133 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001134 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Claytonc4103b32011-05-08 04:53:50 +00001135 {
1136 if (response.IsOKResponse())
1137 return 0;
1138 uint8_t error = response.GetError();
1139 if (error)
1140 return error;
1141 }
1142 }
1143 return -1;
1144}
1145
Greg Clayton576d8832011-03-22 04:00:09 +00001146bool
Greg Clayton1cb64962011-03-24 04:28:38 +00001147GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
1148 uint32_t &minor,
1149 uint32_t &update)
1150{
1151 if (GetHostInfo ())
1152 {
1153 if (m_os_version_major != UINT32_MAX)
1154 {
1155 major = m_os_version_major;
1156 minor = m_os_version_minor;
1157 update = m_os_version_update;
1158 return true;
1159 }
1160 }
1161 return false;
1162}
1163
1164bool
1165GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
1166{
1167 if (GetHostInfo ())
1168 {
1169 if (!m_os_build.empty())
1170 {
1171 s = m_os_build;
1172 return true;
1173 }
1174 }
1175 s.clear();
1176 return false;
1177}
1178
1179
1180bool
1181GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
1182{
1183 if (GetHostInfo ())
1184 {
1185 if (!m_os_kernel.empty())
1186 {
1187 s = m_os_kernel;
1188 return true;
1189 }
1190 }
1191 s.clear();
1192 return false;
1193}
1194
1195bool
1196GDBRemoteCommunicationClient::GetHostname (std::string &s)
1197{
1198 if (GetHostInfo ())
1199 {
1200 if (!m_hostname.empty())
1201 {
1202 s = m_hostname;
1203 return true;
1204 }
1205 }
1206 s.clear();
1207 return false;
1208}
1209
1210ArchSpec
1211GDBRemoteCommunicationClient::GetSystemArchitecture ()
1212{
1213 if (GetHostInfo ())
1214 return m_host_arch;
1215 return ArchSpec();
1216}
1217
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001218const lldb_private::ArchSpec &
1219GDBRemoteCommunicationClient::GetProcessArchitecture ()
1220{
1221 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1222 GetCurrentProcessInfo ();
1223 return m_process_arch;
1224}
1225
Greg Clayton1cb64962011-03-24 04:28:38 +00001226
1227bool
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001228GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton576d8832011-03-22 04:00:09 +00001229{
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001230 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001231 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001232 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +00001233 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001234 if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001235 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001236 if (response.IsNormalResponse())
Greg Claytond314e812011-03-23 00:09:55 +00001237 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001238 std::string name;
1239 std::string value;
1240 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1241 uint32_t sub = 0;
1242 std::string arch_name;
1243 std::string os_name;
1244 std::string vendor_name;
1245 std::string triple;
1246 uint32_t pointer_byte_size = 0;
1247 StringExtractor extractor;
1248 ByteOrder byte_order = eByteOrderInvalid;
1249 uint32_t num_keys_decoded = 0;
1250 while (response.GetNameColonValue(name, value))
Greg Claytond314e812011-03-23 00:09:55 +00001251 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001252 if (name.compare("cputype") == 0)
Greg Clayton1cb64962011-03-24 04:28:38 +00001253 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001254 // exception type in big endian hex
1255 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
1256 if (cpu != LLDB_INVALID_CPUTYPE)
1257 ++num_keys_decoded;
1258 }
1259 else if (name.compare("cpusubtype") == 0)
1260 {
1261 // exception count in big endian hex
1262 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
1263 if (sub != 0)
1264 ++num_keys_decoded;
1265 }
1266 else if (name.compare("arch") == 0)
1267 {
1268 arch_name.swap (value);
1269 ++num_keys_decoded;
1270 }
1271 else if (name.compare("triple") == 0)
1272 {
1273 // The triple comes as ASCII hex bytes since it contains '-' chars
1274 extractor.GetStringRef().swap(value);
1275 extractor.SetFilePos(0);
1276 extractor.GetHexByteString (triple);
1277 ++num_keys_decoded;
1278 }
1279 else if (name.compare("os_build") == 0)
1280 {
1281 extractor.GetStringRef().swap(value);
1282 extractor.SetFilePos(0);
1283 extractor.GetHexByteString (m_os_build);
1284 ++num_keys_decoded;
1285 }
1286 else if (name.compare("hostname") == 0)
1287 {
1288 extractor.GetStringRef().swap(value);
1289 extractor.SetFilePos(0);
1290 extractor.GetHexByteString (m_hostname);
1291 ++num_keys_decoded;
1292 }
1293 else if (name.compare("os_kernel") == 0)
1294 {
1295 extractor.GetStringRef().swap(value);
1296 extractor.SetFilePos(0);
1297 extractor.GetHexByteString (m_os_kernel);
1298 ++num_keys_decoded;
1299 }
1300 else if (name.compare("ostype") == 0)
1301 {
1302 os_name.swap (value);
1303 ++num_keys_decoded;
1304 }
1305 else if (name.compare("vendor") == 0)
1306 {
1307 vendor_name.swap(value);
1308 ++num_keys_decoded;
1309 }
1310 else if (name.compare("endian") == 0)
1311 {
1312 ++num_keys_decoded;
1313 if (value.compare("little") == 0)
1314 byte_order = eByteOrderLittle;
1315 else if (value.compare("big") == 0)
1316 byte_order = eByteOrderBig;
1317 else if (value.compare("pdp") == 0)
1318 byte_order = eByteOrderPDP;
1319 else
1320 --num_keys_decoded;
1321 }
1322 else if (name.compare("ptrsize") == 0)
1323 {
1324 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
1325 if (pointer_byte_size != 0)
1326 ++num_keys_decoded;
1327 }
1328 else if (name.compare("os_version") == 0)
1329 {
1330 Args::StringToVersion (value.c_str(),
1331 m_os_version_major,
1332 m_os_version_minor,
1333 m_os_version_update);
1334 if (m_os_version_major != UINT32_MAX)
1335 ++num_keys_decoded;
1336 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001337 else if (name.compare("watchpoint_exceptions_received") == 0)
1338 {
1339 ++num_keys_decoded;
1340 if (strcmp(value.c_str(),"before") == 0)
1341 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1342 else if (strcmp(value.c_str(),"after") == 0)
1343 m_watchpoints_trigger_after_instruction = eLazyBoolYes;
1344 else
1345 --num_keys_decoded;
1346 }
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00001347 else if (name.compare("default_packet_timeout") == 0)
1348 {
1349 m_default_packet_timeout = Args::StringToUInt32(value.c_str(), 0);
1350 if (m_default_packet_timeout > 0)
1351 {
1352 SetPacketTimeout(m_default_packet_timeout);
1353 ++num_keys_decoded;
1354 }
1355 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001356
Greg Clayton32e0a752011-03-30 18:16:51 +00001357 }
1358
1359 if (num_keys_decoded > 0)
1360 m_qHostInfo_is_valid = eLazyBoolYes;
1361
1362 if (triple.empty())
1363 {
1364 if (arch_name.empty())
1365 {
1366 if (cpu != LLDB_INVALID_CPUTYPE)
1367 {
1368 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
1369 if (pointer_byte_size)
1370 {
1371 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1372 }
1373 if (byte_order != eByteOrderInvalid)
1374 {
1375 assert (byte_order == m_host_arch.GetByteOrder());
1376 }
Greg Clayton70512312012-05-08 01:45:38 +00001377
1378 if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0)
1379 {
1380 switch (m_host_arch.GetMachine())
1381 {
1382 case llvm::Triple::arm:
1383 case llvm::Triple::thumb:
1384 os_name = "ios";
1385 break;
1386 default:
1387 os_name = "macosx";
1388 break;
1389 }
1390 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001391 if (!vendor_name.empty())
1392 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
1393 if (!os_name.empty())
Greg Claytone1dadb82011-09-15 00:21:03 +00001394 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Greg Clayton32e0a752011-03-30 18:16:51 +00001395
1396 }
1397 }
1398 else
1399 {
1400 std::string triple;
1401 triple += arch_name;
Greg Clayton70512312012-05-08 01:45:38 +00001402 if (!vendor_name.empty() || !os_name.empty())
1403 {
1404 triple += '-';
1405 if (vendor_name.empty())
1406 triple += "unknown";
1407 else
1408 triple += vendor_name;
1409 triple += '-';
1410 if (os_name.empty())
1411 triple += "unknown";
1412 else
1413 triple += os_name;
1414 }
1415 m_host_arch.SetTriple (triple.c_str());
1416
1417 llvm::Triple &host_triple = m_host_arch.GetTriple();
1418 if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
1419 {
1420 switch (m_host_arch.GetMachine())
1421 {
1422 case llvm::Triple::arm:
1423 case llvm::Triple::thumb:
1424 host_triple.setOS(llvm::Triple::IOS);
1425 break;
1426 default:
1427 host_triple.setOS(llvm::Triple::MacOSX);
1428 break;
1429 }
1430 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001431 if (pointer_byte_size)
1432 {
1433 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1434 }
1435 if (byte_order != eByteOrderInvalid)
1436 {
1437 assert (byte_order == m_host_arch.GetByteOrder());
1438 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001439
Greg Clayton1cb64962011-03-24 04:28:38 +00001440 }
1441 }
1442 else
1443 {
Greg Clayton70512312012-05-08 01:45:38 +00001444 m_host_arch.SetTriple (triple.c_str());
Greg Claytond314e812011-03-23 00:09:55 +00001445 if (pointer_byte_size)
1446 {
1447 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1448 }
1449 if (byte_order != eByteOrderInvalid)
1450 {
1451 assert (byte_order == m_host_arch.GetByteOrder());
1452 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001453 }
Greg Claytond314e812011-03-23 00:09:55 +00001454 }
Greg Clayton576d8832011-03-22 04:00:09 +00001455 }
1456 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001457 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001458}
1459
1460int
1461GDBRemoteCommunicationClient::SendAttach
1462(
1463 lldb::pid_t pid,
1464 StringExtractorGDBRemote& response
1465)
1466{
1467 if (pid != LLDB_INVALID_PROCESS_ID)
1468 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001469 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001470 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00001471 assert (packet_len < (int)sizeof(packet));
Greg Clayton3dedae12013-12-06 21:45:27 +00001472 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001473 {
1474 if (response.IsErrorResponse())
1475 return response.GetError();
1476 return 0;
1477 }
1478 }
1479 return -1;
1480}
1481
1482const lldb_private::ArchSpec &
1483GDBRemoteCommunicationClient::GetHostArchitecture ()
1484{
Greg Clayton32e0a752011-03-30 18:16:51 +00001485 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001486 GetHostInfo ();
Greg Claytond314e812011-03-23 00:09:55 +00001487 return m_host_arch;
Greg Clayton576d8832011-03-22 04:00:09 +00001488}
1489
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00001490uint32_t
1491GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
1492{
1493 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1494 GetHostInfo ();
1495 return m_default_packet_timeout;
1496}
1497
Greg Clayton576d8832011-03-22 04:00:09 +00001498addr_t
1499GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1500{
Greg Clayton70b57652011-05-15 01:25:55 +00001501 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001502 {
Greg Clayton70b57652011-05-15 01:25:55 +00001503 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001504 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001505 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
Greg Clayton43e0af02012-09-18 18:04:04 +00001506 (uint64_t)size,
Greg Clayton2a48f522011-05-14 01:50:35 +00001507 permissions & lldb::ePermissionsReadable ? "r" : "",
1508 permissions & lldb::ePermissionsWritable ? "w" : "",
1509 permissions & lldb::ePermissionsExecutable ? "x" : "");
Andy Gibbsa297a972013-06-19 19:04:53 +00001510 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001511 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001512 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton2a48f522011-05-14 01:50:35 +00001513 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001514 if (!response.IsErrorResponse())
Greg Clayton2a48f522011-05-14 01:50:35 +00001515 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1516 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00001517 else
1518 {
1519 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1520 }
Greg Clayton576d8832011-03-22 04:00:09 +00001521 }
1522 return LLDB_INVALID_ADDRESS;
1523}
1524
1525bool
1526GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1527{
Greg Clayton70b57652011-05-15 01:25:55 +00001528 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001529 {
Greg Clayton70b57652011-05-15 01:25:55 +00001530 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001531 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001532 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001533 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001534 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001535 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton2a48f522011-05-14 01:50:35 +00001536 {
1537 if (response.IsOKResponse())
1538 return true;
Greg Clayton17a0cb62011-05-15 23:46:54 +00001539 }
1540 else
1541 {
1542 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton2a48f522011-05-14 01:50:35 +00001543 }
Greg Clayton576d8832011-03-22 04:00:09 +00001544 }
1545 return false;
1546}
1547
Jim Inghamacff8952013-05-02 00:27:30 +00001548Error
1549GDBRemoteCommunicationClient::Detach (bool keep_stopped)
Greg Clayton37a0a242012-04-11 00:24:49 +00001550{
Jim Inghamacff8952013-05-02 00:27:30 +00001551 Error error;
1552
1553 if (keep_stopped)
1554 {
1555 if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
1556 {
1557 char packet[64];
1558 const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001559 assert (packet_len < (int)sizeof(packet));
Jim Inghamacff8952013-05-02 00:27:30 +00001560 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001561 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00001562 {
1563 m_supports_detach_stay_stopped = eLazyBoolYes;
1564 }
1565 else
1566 {
1567 m_supports_detach_stay_stopped = eLazyBoolNo;
1568 }
1569 }
1570
1571 if (m_supports_detach_stay_stopped == eLazyBoolNo)
1572 {
1573 error.SetErrorString("Stays stopped not supported by this target.");
1574 return error;
1575 }
1576 else
1577 {
Greg Clayton3dedae12013-12-06 21:45:27 +00001578 PacketResult packet_result = SendPacket ("D1", 2);
1579 if (packet_result != PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00001580 error.SetErrorString ("Sending extended disconnect packet failed.");
1581 }
1582 }
1583 else
1584 {
Greg Clayton3dedae12013-12-06 21:45:27 +00001585 PacketResult packet_result = SendPacket ("D", 1);
1586 if (packet_result != PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00001587 error.SetErrorString ("Sending disconnect packet failed.");
1588 }
1589 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001590}
1591
Greg Clayton46fb5582011-11-18 07:03:08 +00001592Error
1593GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
1594 lldb_private::MemoryRegionInfo &region_info)
1595{
1596 Error error;
1597 region_info.Clear();
1598
1599 if (m_supports_memory_region_info != eLazyBoolNo)
1600 {
1601 m_supports_memory_region_info = eLazyBoolYes;
1602 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001603 const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001604 assert (packet_len < (int)sizeof(packet));
Greg Clayton46fb5582011-11-18 07:03:08 +00001605 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001606 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton46fb5582011-11-18 07:03:08 +00001607 {
1608 std::string name;
1609 std::string value;
1610 addr_t addr_value;
1611 bool success = true;
Jason Molendacb349ee2011-12-13 05:39:38 +00001612 bool saw_permissions = false;
Greg Clayton46fb5582011-11-18 07:03:08 +00001613 while (success && response.GetNameColonValue(name, value))
1614 {
1615 if (name.compare ("start") == 0)
1616 {
1617 addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
1618 if (success)
1619 region_info.GetRange().SetRangeBase(addr_value);
1620 }
1621 else if (name.compare ("size") == 0)
1622 {
1623 addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
1624 if (success)
1625 region_info.GetRange().SetByteSize (addr_value);
1626 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001627 else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
Greg Clayton46fb5582011-11-18 07:03:08 +00001628 {
Jason Molendacb349ee2011-12-13 05:39:38 +00001629 saw_permissions = true;
1630 if (region_info.GetRange().Contains (addr))
1631 {
1632 if (value.find('r') != std::string::npos)
1633 region_info.SetReadable (MemoryRegionInfo::eYes);
1634 else
1635 region_info.SetReadable (MemoryRegionInfo::eNo);
1636
1637 if (value.find('w') != std::string::npos)
1638 region_info.SetWritable (MemoryRegionInfo::eYes);
1639 else
1640 region_info.SetWritable (MemoryRegionInfo::eNo);
1641
1642 if (value.find('x') != std::string::npos)
1643 region_info.SetExecutable (MemoryRegionInfo::eYes);
1644 else
1645 region_info.SetExecutable (MemoryRegionInfo::eNo);
1646 }
1647 else
1648 {
1649 // The reported region does not contain this address -- we're looking at an unmapped page
1650 region_info.SetReadable (MemoryRegionInfo::eNo);
1651 region_info.SetWritable (MemoryRegionInfo::eNo);
1652 region_info.SetExecutable (MemoryRegionInfo::eNo);
1653 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001654 }
1655 else if (name.compare ("error") == 0)
1656 {
1657 StringExtractorGDBRemote name_extractor;
1658 // Swap "value" over into "name_extractor"
1659 name_extractor.GetStringRef().swap(value);
1660 // Now convert the HEX bytes into a string value
1661 name_extractor.GetHexByteString (value);
1662 error.SetErrorString(value.c_str());
1663 }
1664 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001665
1666 // We got a valid address range back but no permissions -- which means this is an unmapped page
1667 if (region_info.GetRange().IsValid() && saw_permissions == false)
1668 {
1669 region_info.SetReadable (MemoryRegionInfo::eNo);
1670 region_info.SetWritable (MemoryRegionInfo::eNo);
1671 region_info.SetExecutable (MemoryRegionInfo::eNo);
1672 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001673 }
1674 else
1675 {
1676 m_supports_memory_region_info = eLazyBoolNo;
1677 }
1678 }
1679
1680 if (m_supports_memory_region_info == eLazyBoolNo)
1681 {
1682 error.SetErrorString("qMemoryRegionInfo is not supported");
1683 }
1684 if (error.Fail())
1685 region_info.Clear();
1686 return error;
1687
1688}
1689
Johnny Chen64637202012-05-23 21:09:52 +00001690Error
1691GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
1692{
1693 Error error;
1694
1695 if (m_supports_watchpoint_support_info == eLazyBoolYes)
1696 {
1697 num = m_num_supported_hardware_watchpoints;
1698 return error;
1699 }
1700
1701 // Set num to 0 first.
1702 num = 0;
1703 if (m_supports_watchpoint_support_info != eLazyBoolNo)
1704 {
1705 char packet[64];
1706 const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001707 assert (packet_len < (int)sizeof(packet));
Johnny Chen64637202012-05-23 21:09:52 +00001708 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001709 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Johnny Chen64637202012-05-23 21:09:52 +00001710 {
1711 m_supports_watchpoint_support_info = eLazyBoolYes;
1712 std::string name;
1713 std::string value;
1714 while (response.GetNameColonValue(name, value))
1715 {
1716 if (name.compare ("num") == 0)
1717 {
1718 num = Args::StringToUInt32(value.c_str(), 0, 0);
1719 m_num_supported_hardware_watchpoints = num;
1720 }
1721 }
1722 }
1723 else
1724 {
1725 m_supports_watchpoint_support_info = eLazyBoolNo;
1726 }
1727 }
1728
1729 if (m_supports_watchpoint_support_info == eLazyBoolNo)
1730 {
1731 error.SetErrorString("qWatchpointSupportInfo is not supported");
1732 }
1733 return error;
1734
1735}
Greg Clayton46fb5582011-11-18 07:03:08 +00001736
Enrico Granataf04a2192012-07-13 23:18:48 +00001737lldb_private::Error
1738GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after)
1739{
1740 Error error(GetWatchpointSupportInfo(num));
1741 if (error.Success())
1742 error = GetWatchpointsTriggerAfterInstruction(after);
1743 return error;
1744}
1745
1746lldb_private::Error
1747GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after)
1748{
1749 Error error;
1750
1751 // we assume watchpoints will happen after running the relevant opcode
1752 // and we only want to override this behavior if we have explicitly
1753 // received a qHostInfo telling us otherwise
1754 if (m_qHostInfo_is_valid != eLazyBoolYes)
1755 after = true;
1756 else
1757 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1758 return error;
1759}
1760
Greg Clayton576d8832011-03-22 04:00:09 +00001761int
1762GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1763{
1764 if (path && path[0])
1765 {
1766 StreamString packet;
1767 packet.PutCString("QSetSTDIN:");
1768 packet.PutBytesAsRawHex8(path, strlen(path));
1769
1770 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001771 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001772 {
1773 if (response.IsOKResponse())
1774 return 0;
1775 uint8_t error = response.GetError();
1776 if (error)
1777 return error;
1778 }
1779 }
1780 return -1;
1781}
1782
1783int
1784GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1785{
1786 if (path && path[0])
1787 {
1788 StreamString packet;
1789 packet.PutCString("QSetSTDOUT:");
1790 packet.PutBytesAsRawHex8(path, strlen(path));
1791
1792 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001793 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001794 {
1795 if (response.IsOKResponse())
1796 return 0;
1797 uint8_t error = response.GetError();
1798 if (error)
1799 return error;
1800 }
1801 }
1802 return -1;
1803}
1804
1805int
1806GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1807{
1808 if (path && path[0])
1809 {
1810 StreamString packet;
1811 packet.PutCString("QSetSTDERR:");
1812 packet.PutBytesAsRawHex8(path, strlen(path));
1813
1814 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001815 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001816 {
1817 if (response.IsOKResponse())
1818 return 0;
1819 uint8_t error = response.GetError();
1820 if (error)
1821 return error;
1822 }
1823 }
1824 return -1;
1825}
1826
Greg Claytonfbb76342013-11-20 21:07:01 +00001827bool
1828GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd)
1829{
1830 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001831 if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00001832 {
1833 if (response.IsUnsupportedResponse())
1834 return false;
1835 if (response.IsErrorResponse())
1836 return false;
1837 response.GetHexByteString (cwd);
1838 return !cwd.empty();
1839 }
1840 return false;
1841}
1842
Greg Clayton576d8832011-03-22 04:00:09 +00001843int
1844GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1845{
1846 if (path && path[0])
1847 {
1848 StreamString packet;
1849 packet.PutCString("QSetWorkingDir:");
1850 packet.PutBytesAsRawHex8(path, strlen(path));
1851
1852 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001853 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001854 {
1855 if (response.IsOKResponse())
1856 return 0;
1857 uint8_t error = response.GetError();
1858 if (error)
1859 return error;
1860 }
1861 }
1862 return -1;
1863}
1864
1865int
1866GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1867{
Greg Clayton32e0a752011-03-30 18:16:51 +00001868 char packet[32];
1869 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
Andy Gibbsa297a972013-06-19 19:04:53 +00001870 assert (packet_len < (int)sizeof(packet));
Greg Clayton576d8832011-03-22 04:00:09 +00001871 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001872 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001873 {
1874 if (response.IsOKResponse())
1875 return 0;
1876 uint8_t error = response.GetError();
1877 if (error)
1878 return error;
1879 }
1880 return -1;
1881}
Greg Clayton32e0a752011-03-30 18:16:51 +00001882
1883bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001884GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00001885{
1886 if (response.IsNormalResponse())
1887 {
1888 std::string name;
1889 std::string value;
1890 StringExtractor extractor;
1891
1892 while (response.GetNameColonValue(name, value))
1893 {
1894 if (name.compare("pid") == 0)
1895 {
1896 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1897 }
1898 else if (name.compare("ppid") == 0)
1899 {
1900 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1901 }
1902 else if (name.compare("uid") == 0)
1903 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001904 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00001905 }
1906 else if (name.compare("euid") == 0)
1907 {
1908 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1909 }
1910 else if (name.compare("gid") == 0)
1911 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001912 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00001913 }
1914 else if (name.compare("egid") == 0)
1915 {
1916 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1917 }
1918 else if (name.compare("triple") == 0)
1919 {
1920 // The triple comes as ASCII hex bytes since it contains '-' chars
1921 extractor.GetStringRef().swap(value);
1922 extractor.SetFilePos(0);
1923 extractor.GetHexByteString (value);
Greg Clayton70512312012-05-08 01:45:38 +00001924 process_info.GetArchitecture ().SetTriple (value.c_str());
Greg Clayton32e0a752011-03-30 18:16:51 +00001925 }
1926 else if (name.compare("name") == 0)
1927 {
1928 StringExtractor extractor;
Filipe Cabecinhasf86cf782012-05-07 09:30:51 +00001929 // The process name from ASCII hex bytes since we can't
Greg Clayton32e0a752011-03-30 18:16:51 +00001930 // control the characters in a process name
1931 extractor.GetStringRef().swap(value);
1932 extractor.SetFilePos(0);
1933 extractor.GetHexByteString (value);
Greg Clayton144f3a92011-11-15 03:53:30 +00001934 process_info.GetExecutableFile().SetFile (value.c_str(), false);
Greg Clayton32e0a752011-03-30 18:16:51 +00001935 }
1936 }
1937
1938 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1939 return true;
1940 }
1941 return false;
1942}
1943
1944bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001945GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00001946{
1947 process_info.Clear();
1948
1949 if (m_supports_qProcessInfoPID)
1950 {
1951 char packet[32];
Daniel Malead01b2952012-11-29 21:49:15 +00001952 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00001953 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00001954 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001955 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00001956 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001957 return DecodeProcessInfoResponse (response, process_info);
1958 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00001959 else
1960 {
1961 m_supports_qProcessInfoPID = false;
1962 return false;
1963 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001964 }
1965 return false;
1966}
1967
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001968bool
1969GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
1970{
1971 if (m_qProcessInfo_is_valid == eLazyBoolYes)
1972 return true;
1973 if (m_qProcessInfo_is_valid == eLazyBoolNo)
1974 return false;
1975
1976 GetHostInfo ();
1977
1978 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001979 if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success)
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001980 {
1981 if (response.IsNormalResponse())
1982 {
1983 std::string name;
1984 std::string value;
1985 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1986 uint32_t sub = 0;
1987 std::string arch_name;
1988 std::string os_name;
1989 std::string vendor_name;
1990 std::string triple;
1991 uint32_t pointer_byte_size = 0;
1992 StringExtractor extractor;
1993 ByteOrder byte_order = eByteOrderInvalid;
1994 uint32_t num_keys_decoded = 0;
1995 while (response.GetNameColonValue(name, value))
1996 {
1997 if (name.compare("cputype") == 0)
1998 {
1999 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
2000 if (cpu != LLDB_INVALID_CPUTYPE)
2001 ++num_keys_decoded;
2002 }
2003 else if (name.compare("cpusubtype") == 0)
2004 {
2005 sub = Args::StringToUInt32 (value.c_str(), 0, 16);
2006 if (sub != 0)
2007 ++num_keys_decoded;
2008 }
2009 else if (name.compare("ostype") == 0)
2010 {
2011 os_name.swap (value);
2012 ++num_keys_decoded;
2013 }
2014 else if (name.compare("vendor") == 0)
2015 {
2016 vendor_name.swap(value);
2017 ++num_keys_decoded;
2018 }
2019 else if (name.compare("endian") == 0)
2020 {
2021 ++num_keys_decoded;
2022 if (value.compare("little") == 0)
2023 byte_order = eByteOrderLittle;
2024 else if (value.compare("big") == 0)
2025 byte_order = eByteOrderBig;
2026 else if (value.compare("pdp") == 0)
2027 byte_order = eByteOrderPDP;
2028 else
2029 --num_keys_decoded;
2030 }
2031 else if (name.compare("ptrsize") == 0)
2032 {
2033 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
2034 if (pointer_byte_size != 0)
2035 ++num_keys_decoded;
2036 }
2037 }
2038 if (num_keys_decoded > 0)
2039 m_qProcessInfo_is_valid = eLazyBoolYes;
2040 if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
2041 {
2042 m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
2043 if (pointer_byte_size)
2044 {
2045 assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
2046 }
2047 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
2048 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
2049 return true;
2050 }
2051 }
2052 }
2053 else
2054 {
2055 m_qProcessInfo_is_valid = eLazyBoolNo;
2056 }
2057
2058 return false;
2059}
2060
2061
Greg Clayton32e0a752011-03-30 18:16:51 +00002062uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00002063GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
2064 ProcessInstanceInfoList &process_infos)
Greg Clayton32e0a752011-03-30 18:16:51 +00002065{
2066 process_infos.Clear();
2067
2068 if (m_supports_qfProcessInfo)
2069 {
2070 StreamString packet;
2071 packet.PutCString ("qfProcessInfo");
2072 if (!match_info.MatchAllProcesses())
2073 {
2074 packet.PutChar (':');
2075 const char *name = match_info.GetProcessInfo().GetName();
2076 bool has_name_match = false;
2077 if (name && name[0])
2078 {
2079 has_name_match = true;
2080 NameMatchType name_match_type = match_info.GetNameMatchType();
2081 switch (name_match_type)
2082 {
2083 case eNameMatchIgnore:
2084 has_name_match = false;
2085 break;
2086
2087 case eNameMatchEquals:
2088 packet.PutCString ("name_match:equals;");
2089 break;
2090
2091 case eNameMatchContains:
2092 packet.PutCString ("name_match:contains;");
2093 break;
2094
2095 case eNameMatchStartsWith:
2096 packet.PutCString ("name_match:starts_with;");
2097 break;
2098
2099 case eNameMatchEndsWith:
2100 packet.PutCString ("name_match:ends_with;");
2101 break;
2102
2103 case eNameMatchRegularExpression:
2104 packet.PutCString ("name_match:regex;");
2105 break;
2106 }
2107 if (has_name_match)
2108 {
2109 packet.PutCString ("name:");
2110 packet.PutBytesAsRawHex8(name, ::strlen(name));
2111 packet.PutChar (';');
2112 }
2113 }
2114
2115 if (match_info.GetProcessInfo().ProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002116 packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002117 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002118 packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
Greg Clayton8b82f082011-04-12 05:54:46 +00002119 if (match_info.GetProcessInfo().UserIDIsValid())
2120 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
2121 if (match_info.GetProcessInfo().GroupIDIsValid())
2122 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002123 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2124 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
2125 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2126 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
2127 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2128 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
2129 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
2130 {
2131 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
2132 const llvm::Triple &triple = match_arch.GetTriple();
2133 packet.PutCString("triple:");
2134 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
2135 packet.PutChar (';');
2136 }
2137 }
2138 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002139 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002140 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002141 do
2142 {
Greg Clayton8b82f082011-04-12 05:54:46 +00002143 ProcessInstanceInfo process_info;
Greg Clayton32e0a752011-03-30 18:16:51 +00002144 if (!DecodeProcessInfoResponse (response, process_info))
2145 break;
2146 process_infos.Append(process_info);
2147 response.GetStringRef().clear();
2148 response.SetFilePos(0);
Greg Clayton3dedae12013-12-06 21:45:27 +00002149 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
Greg Clayton32e0a752011-03-30 18:16:51 +00002150 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002151 else
2152 {
2153 m_supports_qfProcessInfo = false;
2154 return 0;
2155 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002156 }
2157 return process_infos.GetSize();
2158
2159}
2160
2161bool
2162GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
2163{
2164 if (m_supports_qUserName)
2165 {
2166 char packet[32];
2167 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002168 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002169 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002170 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002171 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002172 if (response.IsNormalResponse())
2173 {
2174 // Make sure we parsed the right number of characters. The response is
2175 // the hex encoded user name and should make up the entire packet.
2176 // If there are any non-hex ASCII bytes, the length won't match below..
2177 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2178 return true;
2179 }
2180 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002181 else
2182 {
2183 m_supports_qUserName = false;
2184 return false;
2185 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002186 }
2187 return false;
2188
2189}
2190
2191bool
2192GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
2193{
2194 if (m_supports_qGroupName)
2195 {
2196 char packet[32];
2197 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002198 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002199 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002200 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002201 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002202 if (response.IsNormalResponse())
2203 {
2204 // Make sure we parsed the right number of characters. The response is
2205 // the hex encoded group name and should make up the entire packet.
2206 // If there are any non-hex ASCII bytes, the length won't match below..
2207 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2208 return true;
2209 }
2210 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002211 else
2212 {
2213 m_supports_qGroupName = false;
2214 return false;
2215 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002216 }
2217 return false;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002218}
Greg Clayton32e0a752011-03-30 18:16:51 +00002219
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002220void
2221GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
2222{
2223 uint32_t i;
2224 TimeValue start_time, end_time;
2225 uint64_t total_time_nsec;
2226 float packets_per_second;
2227 if (SendSpeedTestPacket (0, 0))
2228 {
2229 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
2230 {
2231 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
2232 {
2233 start_time = TimeValue::Now();
2234 for (i=0; i<num_packets; ++i)
2235 {
2236 SendSpeedTestPacket (send_size, recv_size);
2237 }
2238 end_time = TimeValue::Now();
2239 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002240 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Daniel Malead01b2952012-11-29 21:49:15 +00002241 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 +00002242 num_packets,
2243 send_size,
2244 recv_size,
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002245 total_time_nsec / TimeValue::NanoSecPerSec,
2246 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002247 packets_per_second);
2248 if (recv_size == 0)
2249 recv_size = 32;
2250 }
2251 if (send_size == 0)
2252 send_size = 32;
2253 }
2254 }
2255 else
2256 {
2257 start_time = TimeValue::Now();
2258 for (i=0; i<num_packets; ++i)
2259 {
2260 GetCurrentProcessID ();
2261 }
2262 end_time = TimeValue::Now();
2263 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002264 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Daniel Malead01b2952012-11-29 21:49:15 +00002265 printf ("%u 'qC' packets packets in 0x%" PRIu64 "%9.9" PRIu64 " sec for %f packets/sec.\n",
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002266 num_packets,
Peter Collingbourneba23ca02011-06-18 23:52:14 +00002267 total_time_nsec / TimeValue::NanoSecPerSec,
2268 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002269 packets_per_second);
2270 }
2271}
2272
2273bool
2274GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
2275{
2276 StreamString packet;
2277 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
2278 uint32_t bytes_left = send_size;
2279 while (bytes_left > 0)
2280 {
2281 if (bytes_left >= 26)
2282 {
2283 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2284 bytes_left -= 26;
2285 }
2286 else
2287 {
2288 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
2289 bytes_left = 0;
2290 }
2291 }
2292
2293 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002294 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
Greg Clayton32e0a752011-03-30 18:16:51 +00002295}
Greg Clayton8b82f082011-04-12 05:54:46 +00002296
2297uint16_t
Greg Claytondbf04572013-12-04 19:40:33 +00002298GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname)
Greg Clayton8b82f082011-04-12 05:54:46 +00002299{
Daniel Maleae0f8f572013-08-26 23:57:52 +00002300 pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton8b82f082011-04-12 05:54:46 +00002301 StringExtractorGDBRemote response;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002302 StreamString stream;
Greg Clayton29b8fc42013-11-21 01:44:58 +00002303 stream.PutCString("qLaunchGDBServer;");
Daniel Maleae0f8f572013-08-26 23:57:52 +00002304 std::string hostname;
Greg Claytondbf04572013-12-04 19:40:33 +00002305 if (remote_accept_hostname && remote_accept_hostname[0])
2306 hostname = remote_accept_hostname;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002307 else
2308 {
Greg Claytondbf04572013-12-04 19:40:33 +00002309 if (Host::GetHostname (hostname))
2310 {
2311 // Make the GDB server we launch only accept connections from this host
2312 stream.Printf("host:%s;", hostname.c_str());
2313 }
2314 else
2315 {
2316 // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
2317 stream.Printf("host:*;");
2318 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002319 }
2320 const char *packet = stream.GetData();
2321 int packet_len = stream.GetSize();
2322
Greg Clayton3dedae12013-12-06 21:45:27 +00002323 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002324 {
2325 std::string name;
2326 std::string value;
2327 uint16_t port = 0;
Greg Clayton8b82f082011-04-12 05:54:46 +00002328 while (response.GetNameColonValue(name, value))
2329 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00002330 if (name.compare("port") == 0)
Greg Clayton8b82f082011-04-12 05:54:46 +00002331 port = Args::StringToUInt32(value.c_str(), 0, 0);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002332 else if (name.compare("pid") == 0)
2333 pid = Args::StringToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
Greg Clayton8b82f082011-04-12 05:54:46 +00002334 }
2335 return port;
2336 }
2337 return 0;
2338}
2339
2340bool
Daniel Maleae0f8f572013-08-26 23:57:52 +00002341GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
2342{
2343 StreamString stream;
2344 stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
2345 const char *packet = stream.GetData();
2346 int packet_len = stream.GetSize();
Sylvestre Ledrufd654c42013-10-06 09:51:02 +00002347
Daniel Maleae0f8f572013-08-26 23:57:52 +00002348 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002349 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002350 {
2351 if (response.IsOKResponse())
2352 return true;
2353 }
2354 return false;
2355}
2356
2357bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002358GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002359{
2360 if (m_curr_tid == tid)
2361 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002362
Greg Clayton8b82f082011-04-12 05:54:46 +00002363 char packet[32];
2364 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002365 if (tid == UINT64_MAX)
2366 packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002367 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002368 packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002369 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002370 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002371 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002372 {
2373 if (response.IsOKResponse())
2374 {
2375 m_curr_tid = tid;
2376 return true;
2377 }
2378 }
2379 return false;
2380}
2381
2382bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002383GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002384{
2385 if (m_curr_tid_run == tid)
2386 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002387
Greg Clayton8b82f082011-04-12 05:54:46 +00002388 char packet[32];
2389 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002390 if (tid == UINT64_MAX)
2391 packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002392 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002393 packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
2394
Andy Gibbsa297a972013-06-19 19:04:53 +00002395 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002396 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002397 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002398 {
2399 if (response.IsOKResponse())
2400 {
2401 m_curr_tid_run = tid;
2402 return true;
2403 }
2404 }
2405 return false;
2406}
2407
2408bool
2409GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
2410{
Greg Clayton3dedae12013-12-06 21:45:27 +00002411 if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002412 return response.IsNormalResponse();
2413 return false;
2414}
2415
2416bool
Greg Claytonf402f782012-10-13 02:11:55 +00002417GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
Greg Clayton8b82f082011-04-12 05:54:46 +00002418{
2419 if (m_supports_qThreadStopInfo)
2420 {
2421 char packet[256];
Daniel Malead01b2952012-11-29 21:49:15 +00002422 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002423 assert (packet_len < (int)sizeof(packet));
Greg Clayton3dedae12013-12-06 21:45:27 +00002424 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002425 {
Greg Claytonef8180a2013-10-15 00:14:28 +00002426 if (response.IsUnsupportedResponse())
2427 m_supports_qThreadStopInfo = false;
2428 else if (response.IsNormalResponse())
Greg Clayton8b82f082011-04-12 05:54:46 +00002429 return true;
2430 else
2431 return false;
2432 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002433 else
2434 {
2435 m_supports_qThreadStopInfo = false;
2436 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002437 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002438 return false;
2439}
2440
2441
2442uint8_t
2443GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
2444{
2445 switch (type)
2446 {
2447 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
2448 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
2449 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
2450 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
2451 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
Greg Clayton8b82f082011-04-12 05:54:46 +00002452 }
2453
2454 char packet[64];
2455 const int packet_len = ::snprintf (packet,
2456 sizeof(packet),
Daniel Malead01b2952012-11-29 21:49:15 +00002457 "%c%i,%" PRIx64 ",%x",
Greg Clayton8b82f082011-04-12 05:54:46 +00002458 insert ? 'Z' : 'z',
2459 type,
2460 addr,
2461 length);
2462
Andy Gibbsa297a972013-06-19 19:04:53 +00002463 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002464 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002465 if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002466 {
2467 if (response.IsOKResponse())
2468 return 0;
Greg Clayton8b82f082011-04-12 05:54:46 +00002469 else if (response.IsErrorResponse())
2470 return response.GetError();
2471 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002472 else
2473 {
2474 switch (type)
2475 {
2476 case eBreakpointSoftware: m_supports_z0 = false; break;
2477 case eBreakpointHardware: m_supports_z1 = false; break;
2478 case eWatchpointWrite: m_supports_z2 = false; break;
2479 case eWatchpointRead: m_supports_z3 = false; break;
2480 case eWatchpointReadWrite: m_supports_z4 = false; break;
Greg Clayton17a0cb62011-05-15 23:46:54 +00002481 }
2482 }
2483
Greg Clayton8b82f082011-04-12 05:54:46 +00002484 return UINT8_MAX;
2485}
Greg Claytonadc00cb2011-05-20 23:38:13 +00002486
2487size_t
2488GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
2489 bool &sequence_mutex_unavailable)
2490{
2491 Mutex::Locker locker;
2492 thread_ids.clear();
2493
Jim Ingham4ceb9282012-06-08 22:50:40 +00002494 if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
Greg Claytonadc00cb2011-05-20 23:38:13 +00002495 {
2496 sequence_mutex_unavailable = false;
2497 StringExtractorGDBRemote response;
2498
Greg Clayton3dedae12013-12-06 21:45:27 +00002499 PacketResult packet_result;
2500 for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response);
2501 packet_result == PacketResult::Success && response.IsNormalResponse();
2502 packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response))
Greg Claytonadc00cb2011-05-20 23:38:13 +00002503 {
2504 char ch = response.GetChar();
2505 if (ch == 'l')
2506 break;
2507 if (ch == 'm')
2508 {
2509 do
2510 {
Jason Molendae9ca4af2013-02-23 02:04:45 +00002511 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
Greg Claytonadc00cb2011-05-20 23:38:13 +00002512
2513 if (tid != LLDB_INVALID_THREAD_ID)
2514 {
2515 thread_ids.push_back (tid);
2516 }
2517 ch = response.GetChar(); // Skip the command separator
2518 } while (ch == ','); // Make sure we got a comma separator
2519 }
2520 }
2521 }
2522 else
2523 {
Jim Ingham4ceb9282012-06-08 22:50:40 +00002524#if defined (LLDB_CONFIGURATION_DEBUG)
2525 // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
2526#else
Greg Clayton5160ce52013-03-27 23:08:40 +00002527 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Claytonc3c0b0e2012-04-12 19:04:34 +00002528 if (log)
2529 log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
Jim Ingham4ceb9282012-06-08 22:50:40 +00002530#endif
Greg Claytonadc00cb2011-05-20 23:38:13 +00002531 sequence_mutex_unavailable = true;
2532 }
2533 return thread_ids.size();
2534}
Greg Clayton37a0a242012-04-11 00:24:49 +00002535
2536lldb::addr_t
2537GDBRemoteCommunicationClient::GetShlibInfoAddr()
2538{
2539 if (!IsRunning())
2540 {
2541 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002542 if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false) == PacketResult::Success)
Greg Clayton37a0a242012-04-11 00:24:49 +00002543 {
2544 if (response.IsNormalResponse())
2545 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2546 }
2547 }
2548 return LLDB_INVALID_ADDRESS;
2549}
2550
Daniel Maleae0f8f572013-08-26 23:57:52 +00002551lldb_private::Error
2552GDBRemoteCommunicationClient::RunShellCommand (const char *command, // Shouldn't be NULL
2553 const char *working_dir, // Pass NULL to use the current working directory
2554 int *status_ptr, // Pass NULL if you don't want the process exit status
2555 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
2556 std::string *command_output, // Pass NULL if you don't want the command output
2557 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
2558{
2559 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00002560 stream.PutCString("qPlatform_shell:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00002561 stream.PutBytesAsRawHex8(command, strlen(command));
2562 stream.PutChar(',');
2563 stream.PutHex32(timeout_sec);
2564 if (working_dir && *working_dir)
2565 {
2566 stream.PutChar(',');
2567 stream.PutBytesAsRawHex8(working_dir, strlen(working_dir));
2568 }
2569 const char *packet = stream.GetData();
2570 int packet_len = stream.GetSize();
2571 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002572 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002573 {
2574 if (response.GetChar() != 'F')
2575 return Error("malformed reply");
2576 if (response.GetChar() != ',')
2577 return Error("malformed reply");
2578 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2579 if (exitcode == UINT32_MAX)
2580 return Error("unable to run remote process");
2581 else if (status_ptr)
2582 *status_ptr = exitcode;
2583 if (response.GetChar() != ',')
2584 return Error("malformed reply");
2585 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2586 if (signo_ptr)
2587 *signo_ptr = signo;
2588 if (response.GetChar() != ',')
2589 return Error("malformed reply");
2590 std::string output;
2591 response.GetEscapedBinaryData(output);
2592 if (command_output)
2593 command_output->assign(output);
2594 return Error();
2595 }
2596 return Error("unable to send packet");
2597}
2598
Greg Claytonfbb76342013-11-20 21:07:01 +00002599Error
2600GDBRemoteCommunicationClient::MakeDirectory (const char *path,
2601 uint32_t file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002602{
2603 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00002604 stream.PutCString("qPlatform_mkdir:");
2605 stream.PutHex32(file_permissions);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002606 stream.PutChar(',');
Greg Claytonfbb76342013-11-20 21:07:01 +00002607 stream.PutBytesAsRawHex8(path, strlen(path));
Daniel Maleae0f8f572013-08-26 23:57:52 +00002608 const char *packet = stream.GetData();
2609 int packet_len = stream.GetSize();
2610 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002611 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002612 {
Greg Claytonfbb76342013-11-20 21:07:01 +00002613 return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002614 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002615 return Error();
Daniel Maleae0f8f572013-08-26 23:57:52 +00002616
2617}
2618
Greg Claytonfbb76342013-11-20 21:07:01 +00002619Error
2620GDBRemoteCommunicationClient::SetFilePermissions (const char *path,
2621 uint32_t file_permissions)
2622{
2623 lldb_private::StreamString stream;
2624 stream.PutCString("qPlatform_chmod:");
2625 stream.PutHex32(file_permissions);
2626 stream.PutChar(',');
2627 stream.PutBytesAsRawHex8(path, strlen(path));
2628 const char *packet = stream.GetData();
2629 int packet_len = stream.GetSize();
2630 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002631 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00002632 {
2633 return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
2634 }
2635 return Error();
2636
2637}
2638
Daniel Maleae0f8f572013-08-26 23:57:52 +00002639static uint64_t
2640ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
2641 uint64_t fail_result,
2642 Error &error)
2643{
2644 response.SetFilePos(0);
2645 if (response.GetChar() != 'F')
2646 return fail_result;
2647 int32_t result = response.GetS32 (-2);
2648 if (result == -2)
2649 return fail_result;
2650 if (response.GetChar() == ',')
2651 {
2652 int result_errno = response.GetS32 (-2);
2653 if (result_errno != -2)
2654 error.SetError(result_errno, eErrorTypePOSIX);
2655 else
2656 error.SetError(-1, eErrorTypeGeneric);
2657 }
2658 else
2659 error.Clear();
2660 return result;
2661}
2662lldb::user_id_t
2663GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
2664 uint32_t flags,
2665 mode_t mode,
2666 Error &error)
2667{
2668 lldb_private::StreamString stream;
2669 stream.PutCString("vFile:open:");
2670 std::string path (file_spec.GetPath());
2671 if (path.empty())
2672 return UINT64_MAX;
2673 stream.PutCStringAsRawHex8(path.c_str());
2674 stream.PutChar(',');
2675 const uint32_t posix_open_flags = File::ConvertOpenOptionsForPOSIXOpen(flags);
2676 stream.PutHex32(posix_open_flags);
2677 stream.PutChar(',');
2678 stream.PutHex32(mode);
2679 const char* packet = stream.GetData();
2680 int packet_len = stream.GetSize();
2681 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002682 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002683 {
2684 return ParseHostIOPacketResponse (response, UINT64_MAX, error);
2685 }
2686 return UINT64_MAX;
2687}
2688
2689bool
2690GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
2691 Error &error)
2692{
2693 lldb_private::StreamString stream;
2694 stream.Printf("vFile:close:%i", (int)fd);
2695 const char* packet = stream.GetData();
2696 int packet_len = stream.GetSize();
2697 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002698 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002699 {
2700 return ParseHostIOPacketResponse (response, -1, error) == 0;
2701 }
Deepak Panickald66b50c2013-10-22 12:27:43 +00002702 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002703}
2704
2705// Extension of host I/O packets to get the file size.
2706lldb::user_id_t
2707GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
2708{
2709 lldb_private::StreamString stream;
2710 stream.PutCString("vFile:size:");
2711 std::string path (file_spec.GetPath());
2712 stream.PutCStringAsRawHex8(path.c_str());
2713 const char* packet = stream.GetData();
2714 int packet_len = stream.GetSize();
2715 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002716 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002717 {
2718 if (response.GetChar() != 'F')
2719 return UINT64_MAX;
2720 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2721 return retcode;
2722 }
2723 return UINT64_MAX;
2724}
2725
Greg Claytonfbb76342013-11-20 21:07:01 +00002726Error
2727GDBRemoteCommunicationClient::GetFilePermissions(const char *path, uint32_t &file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002728{
Greg Claytonfbb76342013-11-20 21:07:01 +00002729 Error error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002730 lldb_private::StreamString stream;
2731 stream.PutCString("vFile:mode:");
Greg Claytonfbb76342013-11-20 21:07:01 +00002732 stream.PutCStringAsRawHex8(path);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002733 const char* packet = stream.GetData();
2734 int packet_len = stream.GetSize();
2735 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002736 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002737 {
2738 if (response.GetChar() != 'F')
2739 {
2740 error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002741 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002742 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00002743 {
Greg Claytonfbb76342013-11-20 21:07:01 +00002744 const uint32_t mode = response.GetS32(-1);
2745 if (mode == -1)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002746 {
Greg Claytonfbb76342013-11-20 21:07:01 +00002747 if (response.GetChar() == ',')
2748 {
2749 int response_errno = response.GetS32(-1);
2750 if (response_errno > 0)
2751 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2752 else
2753 error.SetErrorToGenericError();
2754 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002755 else
2756 error.SetErrorToGenericError();
2757 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002758 else
2759 {
2760 file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
2761 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002762 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002763 }
2764 else
2765 {
2766 error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
2767 }
Greg Claytonfbb76342013-11-20 21:07:01 +00002768 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002769}
2770
2771uint64_t
2772GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
2773 uint64_t offset,
2774 void *dst,
2775 uint64_t dst_len,
2776 Error &error)
2777{
2778 lldb_private::StreamString stream;
2779 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
2780 const char* packet = stream.GetData();
2781 int packet_len = stream.GetSize();
2782 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002783 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002784 {
2785 if (response.GetChar() != 'F')
2786 return 0;
2787 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
2788 if (retcode == UINT32_MAX)
2789 return retcode;
2790 const char next = (response.Peek() ? *response.Peek() : 0);
2791 if (next == ',')
2792 return 0;
2793 if (next == ';')
2794 {
2795 response.GetChar(); // skip the semicolon
2796 std::string buffer;
2797 if (response.GetEscapedBinaryData(buffer))
2798 {
2799 const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
2800 if (data_to_write > 0)
2801 memcpy(dst, &buffer[0], data_to_write);
2802 return data_to_write;
2803 }
2804 }
2805 }
2806 return 0;
2807}
2808
2809uint64_t
2810GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
2811 uint64_t offset,
2812 const void* src,
2813 uint64_t src_len,
2814 Error &error)
2815{
2816 lldb_private::StreamGDBRemote stream;
2817 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
2818 stream.PutEscapedBytes(src, src_len);
2819 const char* packet = stream.GetData();
2820 int packet_len = stream.GetSize();
2821 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002822 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002823 {
2824 if (response.GetChar() != 'F')
2825 {
2826 error.SetErrorStringWithFormat("write file failed");
2827 return 0;
2828 }
2829 uint64_t bytes_written = response.GetU64(UINT64_MAX);
2830 if (bytes_written == UINT64_MAX)
2831 {
2832 error.SetErrorToGenericError();
2833 if (response.GetChar() == ',')
2834 {
2835 int response_errno = response.GetS32(-1);
2836 if (response_errno > 0)
2837 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2838 }
2839 return 0;
2840 }
2841 return bytes_written;
2842 }
2843 else
2844 {
2845 error.SetErrorString ("failed to send vFile:pwrite packet");
2846 }
2847 return 0;
2848}
2849
Greg Claytonfbb76342013-11-20 21:07:01 +00002850Error
2851GDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst)
2852{
2853 Error error;
2854 lldb_private::StreamGDBRemote stream;
2855 stream.PutCString("vFile:symlink:");
2856 // the unix symlink() command reverses its parameters where the dst if first,
2857 // so we follow suit here
2858 stream.PutCStringAsRawHex8(dst);
2859 stream.PutChar(',');
2860 stream.PutCStringAsRawHex8(src);
2861 const char* packet = stream.GetData();
2862 int packet_len = stream.GetSize();
2863 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002864 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00002865 {
2866 if (response.GetChar() == 'F')
2867 {
2868 uint32_t result = response.GetU32(UINT32_MAX);
2869 if (result != 0)
2870 {
2871 error.SetErrorToGenericError();
2872 if (response.GetChar() == ',')
2873 {
2874 int response_errno = response.GetS32(-1);
2875 if (response_errno > 0)
2876 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2877 }
2878 }
2879 }
2880 else
2881 {
2882 // Should have returned with 'F<result>[,<errno>]'
2883 error.SetErrorStringWithFormat("symlink failed");
2884 }
2885 }
2886 else
2887 {
2888 error.SetErrorString ("failed to send vFile:symlink packet");
2889 }
2890 return error;
2891}
2892
2893Error
2894GDBRemoteCommunicationClient::Unlink (const char *path)
2895{
2896 Error error;
2897 lldb_private::StreamGDBRemote stream;
2898 stream.PutCString("vFile:unlink:");
2899 // the unix symlink() command reverses its parameters where the dst if first,
2900 // so we follow suit here
2901 stream.PutCStringAsRawHex8(path);
2902 const char* packet = stream.GetData();
2903 int packet_len = stream.GetSize();
2904 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002905 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00002906 {
2907 if (response.GetChar() == 'F')
2908 {
2909 uint32_t result = response.GetU32(UINT32_MAX);
2910 if (result != 0)
2911 {
2912 error.SetErrorToGenericError();
2913 if (response.GetChar() == ',')
2914 {
2915 int response_errno = response.GetS32(-1);
2916 if (response_errno > 0)
2917 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2918 }
2919 }
2920 }
2921 else
2922 {
2923 // Should have returned with 'F<result>[,<errno>]'
2924 error.SetErrorStringWithFormat("unlink failed");
2925 }
2926 }
2927 else
2928 {
2929 error.SetErrorString ("failed to send vFile:unlink packet");
2930 }
2931 return error;
2932}
2933
Daniel Maleae0f8f572013-08-26 23:57:52 +00002934// Extension of host I/O packets to get whether a file exists.
2935bool
2936GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
2937{
2938 lldb_private::StreamString stream;
2939 stream.PutCString("vFile:exists:");
2940 std::string path (file_spec.GetPath());
2941 stream.PutCStringAsRawHex8(path.c_str());
2942 const char* packet = stream.GetData();
2943 int packet_len = stream.GetSize();
2944 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002945 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002946 {
2947 if (response.GetChar() != 'F')
2948 return false;
2949 if (response.GetChar() != ',')
2950 return false;
2951 bool retcode = (response.GetChar() != '0');
2952 return retcode;
2953 }
2954 return false;
2955}
2956
2957bool
2958GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
2959 uint64_t &high,
2960 uint64_t &low)
2961{
2962 lldb_private::StreamString stream;
2963 stream.PutCString("vFile:MD5:");
2964 std::string path (file_spec.GetPath());
2965 stream.PutCStringAsRawHex8(path.c_str());
2966 const char* packet = stream.GetData();
2967 int packet_len = stream.GetSize();
2968 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002969 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002970 {
2971 if (response.GetChar() != 'F')
2972 return false;
2973 if (response.GetChar() != ',')
2974 return false;
2975 if (response.Peek() && *response.Peek() == 'x')
2976 return false;
2977 low = response.GetHexMaxU64(false, UINT64_MAX);
2978 high = response.GetHexMaxU64(false, UINT64_MAX);
2979 return true;
2980 }
2981 return false;
2982}
Greg Claytonf74cf862013-11-13 23:28:31 +00002983
2984bool
2985GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
2986{
2987 Mutex::Locker locker;
2988 if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet."))
2989 {
2990 const bool thread_suffix_supported = GetThreadSuffixSupported();
2991
2992 if (thread_suffix_supported || SetCurrentThread(tid))
2993 {
2994 char packet[64];
2995 int packet_len = 0;
2996 if (thread_suffix_supported)
2997 packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid);
2998 else
2999 packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
3000 assert (packet_len < ((int)sizeof(packet) - 1));
Greg Clayton3dedae12013-12-06 21:45:27 +00003001 return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
Greg Claytonf74cf862013-11-13 23:28:31 +00003002 }
3003 }
3004 return false;
3005
3006}
3007
3008
3009bool
3010GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response)
3011{
3012 Mutex::Locker locker;
3013 if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet."))
3014 {
3015 const bool thread_suffix_supported = GetThreadSuffixSupported();
3016
3017 if (thread_suffix_supported || SetCurrentThread(tid))
3018 {
3019 char packet[64];
3020 int packet_len = 0;
3021 // Get all registers in one packet
3022 if (thread_suffix_supported)
3023 packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid);
3024 else
3025 packet_len = ::snprintf (packet, sizeof(packet), "g");
3026 assert (packet_len < ((int)sizeof(packet) - 1));
Greg Clayton3dedae12013-12-06 21:45:27 +00003027 return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
Greg Claytonf74cf862013-11-13 23:28:31 +00003028 }
3029 }
3030 return false;
3031}
3032bool
3033GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
3034{
3035 save_id = 0; // Set to invalid save ID
3036 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3037 return false;
3038
3039 m_supports_QSaveRegisterState = eLazyBoolYes;
3040 Mutex::Locker locker;
3041 if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState."))
3042 {
3043 const bool thread_suffix_supported = GetThreadSuffixSupported();
3044 if (thread_suffix_supported || SetCurrentThread(tid))
3045 {
3046 char packet[256];
3047 if (thread_suffix_supported)
3048 ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid);
3049 else
3050 ::strncpy (packet, "QSaveRegisterState", sizeof(packet));
3051
3052 StringExtractorGDBRemote response;
3053
Greg Clayton3dedae12013-12-06 21:45:27 +00003054 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
Greg Claytonf74cf862013-11-13 23:28:31 +00003055 {
3056 if (response.IsUnsupportedResponse())
3057 {
3058 // This packet isn't supported, don't try calling it again
3059 m_supports_QSaveRegisterState = eLazyBoolNo;
3060 }
3061
3062 const uint32_t response_save_id = response.GetU32(0);
3063 if (response_save_id != 0)
3064 {
3065 save_id = response_save_id;
3066 return true;
3067 }
3068 }
3069 }
3070 }
3071 return false;
3072}
3073
3074bool
3075GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
3076{
3077 // We use the "m_supports_QSaveRegisterState" variable here becuase the
3078 // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
3079 // order to be useful
3080 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3081 return false;
3082
3083 Mutex::Locker locker;
3084 if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState."))
3085 {
3086 const bool thread_suffix_supported = GetThreadSuffixSupported();
3087 if (thread_suffix_supported || SetCurrentThread(tid))
3088 {
3089 char packet[256];
3090 if (thread_suffix_supported)
3091 ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid);
3092 else
3093 ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id);
3094
3095 StringExtractorGDBRemote response;
3096
Greg Clayton3dedae12013-12-06 21:45:27 +00003097 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
Greg Claytonf74cf862013-11-13 23:28:31 +00003098 {
3099 if (response.IsOKResponse())
3100 {
3101 return true;
3102 }
3103 else if (response.IsUnsupportedResponse())
3104 {
3105 // This packet isn't supported, don't try calling this packet or
3106 // QSaveRegisterState again...
3107 m_supports_QSaveRegisterState = eLazyBoolNo;
3108 }
3109 }
3110 }
3111 }
3112 return false;
3113}