blob: 038ba3086788194ba597977525576861aa2796a3 [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
Greg Claytone034a042015-05-21 20:52:06 +000014#include <math.h>
Daniel Maleab89d0492013-08-28 16:06:16 +000015#include <sys/stat.h>
16
Greg Clayton576d8832011-03-22 04:00:09 +000017// C++ Includes
Han Ming Ong4b6459f2013-01-18 23:11:53 +000018#include <sstream>
Greg Claytone034a042015-05-21 20:52:06 +000019#include <numeric>
Han Ming Ong4b6459f2013-01-18 23:11:53 +000020
Greg Clayton576d8832011-03-22 04:00:09 +000021// Other libraries and framework includes
Greg Clayton576d8832011-03-22 04:00:09 +000022#include "lldb/Core/Log.h"
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +000023#include "lldb/Core/ModuleSpec.h"
Greg Clayton576d8832011-03-22 04:00:09 +000024#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"
Pavel Labathb42b48e2016-08-19 12:31:49 +000027#include "lldb/Core/DataBufferHeap.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000028#include "lldb/Host/HostInfo.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000029#include "lldb/Host/StringConvert.h"
Greg Clayton576d8832011-03-22 04:00:09 +000030#include "lldb/Host/TimeValue.h"
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000031#include "lldb/Interpreter/Args.h"
Greg Clayton0b90be12015-06-23 21:27:50 +000032#include "lldb/Symbol/Symbol.h"
Pavel Labath4cb69922016-07-29 15:41:52 +000033#include "lldb/Target/MemoryRegionInfo.h"
Todd Fiala75930012016-08-19 04:21:48 +000034#include "lldb/Target/UnixSignals.h"
35#include "lldb/Utility/LLDBAssert.h"
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000036#include "lldb/Target/Target.h"
Greg Clayton576d8832011-03-22 04:00:09 +000037
38// Project includes
39#include "Utility/StringExtractorGDBRemote.h"
40#include "ProcessGDBRemote.h"
41#include "ProcessGDBRemoteLog.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000042#include "lldb/Host/Config.h"
Greg Clayton576d8832011-03-22 04:00:09 +000043
Jason Molenda91ffe0a2015-06-18 21:46:06 +000044#if defined (HAVE_LIBCOMPRESSION)
45#include <compression.h>
46#endif
47
Greg Clayton576d8832011-03-22 04:00:09 +000048using namespace lldb;
49using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000050using namespace lldb_private::process_gdb_remote;
Greg Clayton576d8832011-03-22 04:00:09 +000051
52//----------------------------------------------------------------------
53// GDBRemoteCommunicationClient constructor
54//----------------------------------------------------------------------
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000055GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000056 : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000057 m_supports_not_sending_acks(eLazyBoolCalculate),
58 m_supports_thread_suffix(eLazyBoolCalculate),
59 m_supports_threads_in_stop_reply(eLazyBoolCalculate),
60 m_supports_vCont_all(eLazyBoolCalculate),
61 m_supports_vCont_any(eLazyBoolCalculate),
62 m_supports_vCont_c(eLazyBoolCalculate),
63 m_supports_vCont_C(eLazyBoolCalculate),
64 m_supports_vCont_s(eLazyBoolCalculate),
65 m_supports_vCont_S(eLazyBoolCalculate),
66 m_qHostInfo_is_valid(eLazyBoolCalculate),
67 m_curr_pid_is_valid(eLazyBoolCalculate),
68 m_qProcessInfo_is_valid(eLazyBoolCalculate),
69 m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
70 m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
71 m_supports_memory_region_info(eLazyBoolCalculate),
72 m_supports_watchpoint_support_info(eLazyBoolCalculate),
73 m_supports_detach_stay_stopped(eLazyBoolCalculate),
74 m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
75 m_attach_or_wait_reply(eLazyBoolCalculate),
76 m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
77 m_supports_p(eLazyBoolCalculate),
78 m_supports_x(eLazyBoolCalculate),
79 m_avoid_g_packets(eLazyBoolCalculate),
80 m_supports_QSaveRegisterState(eLazyBoolCalculate),
81 m_supports_qXfer_auxv_read(eLazyBoolCalculate),
82 m_supports_qXfer_libraries_read(eLazyBoolCalculate),
83 m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
84 m_supports_qXfer_features_read(eLazyBoolCalculate),
85 m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
86 m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
87 m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000088 m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000089 m_supports_qProcessInfoPID(true),
90 m_supports_qfProcessInfo(true),
91 m_supports_qUserName(true),
92 m_supports_qGroupName(true),
93 m_supports_qThreadStopInfo(true),
94 m_supports_z0(true),
95 m_supports_z1(true),
96 m_supports_z2(true),
97 m_supports_z3(true),
98 m_supports_z4(true),
99 m_supports_QEnvironment(true),
100 m_supports_QEnvironmentHexEncoded(true),
101 m_supports_qSymbol(true),
102 m_qSymbol_requests_done(false),
103 m_supports_qModuleInfo(true),
104 m_supports_jThreadsInfo(true),
105 m_curr_pid(LLDB_INVALID_PROCESS_ID),
106 m_curr_tid(LLDB_INVALID_THREAD_ID),
107 m_curr_tid_run(LLDB_INVALID_THREAD_ID),
108 m_num_supported_hardware_watchpoints(0),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000109 m_host_arch(),
110 m_process_arch(),
111 m_os_version_major(UINT32_MAX),
112 m_os_version_minor(UINT32_MAX),
113 m_os_version_update(UINT32_MAX),
114 m_os_build(),
115 m_os_kernel(),
116 m_hostname(),
117 m_gdb_server_name(),
118 m_gdb_server_version(UINT32_MAX),
119 m_default_packet_timeout(0),
Todd Fiala75930012016-08-19 04:21:48 +0000120 m_max_packet_size(0),
121 m_qSupported_response(),
122 m_supported_async_json_packets_is_valid(false),
123 m_supported_async_json_packets_sp()
Greg Clayton576d8832011-03-22 04:00:09 +0000124{
Greg Clayton576d8832011-03-22 04:00:09 +0000125}
126
127//----------------------------------------------------------------------
128// Destructor
129//----------------------------------------------------------------------
130GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
131{
Greg Clayton576d8832011-03-22 04:00:09 +0000132 if (IsConnected())
Greg Clayton576d8832011-03-22 04:00:09 +0000133 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000134}
135
136bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000137GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
138{
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000139 ResetDiscoverableSettings(false);
Greg Claytonfb909312013-11-23 01:58:15 +0000140
Greg Clayton1cb64962011-03-24 04:28:38 +0000141 // Start the read thread after we send the handshake ack since if we
142 // fail to send the handshake ack, there is no reason to continue...
143 if (SendAck())
Greg Claytonfb909312013-11-23 01:58:15 +0000144 {
Ed Maste48f986f2013-12-18 15:31:45 +0000145 // Wait for any responses that might have been queued up in the remote
146 // GDB server and flush them all
147 StringExtractorGDBRemote response;
148 PacketResult packet_result = PacketResult::Success;
149 const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response
150 while (packet_result == PacketResult::Success)
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000151 packet_result = ReadPacket (response, timeout_usec, false);
Ed Maste48f986f2013-12-18 15:31:45 +0000152
Greg Claytonfb909312013-11-23 01:58:15 +0000153 // The return value from QueryNoAckModeSupported() is true if the packet
154 // was sent and _any_ response (including UNIMPLEMENTED) was received),
155 // or false if no response was received. This quickly tells us if we have
156 // a live connection to a remote GDB server...
157 if (QueryNoAckModeSupported())
158 {
159 return true;
160 }
161 else
162 {
163 if (error_ptr)
164 error_ptr->SetErrorString("failed to get reply to handshake packet");
165 }
166 }
167 else
168 {
169 if (error_ptr)
170 error_ptr->SetErrorString("failed to send the handshake ack");
171 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000172 return false;
173}
174
Greg Claytonfb909312013-11-23 01:58:15 +0000175bool
Greg Claytonb30c50c2015-05-29 00:01:55 +0000176GDBRemoteCommunicationClient::GetEchoSupported ()
177{
178 if (m_supports_qEcho == eLazyBoolCalculate)
179 {
180 GetRemoteQSupported();
181 }
182 return m_supports_qEcho == eLazyBoolYes;
183}
184
185
186bool
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000187GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
188{
189 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
190 {
191 GetRemoteQSupported();
192 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000193 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000194}
195
196bool
197GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
198{
199 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
200 {
201 GetRemoteQSupported();
202 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000203 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000204}
205
206bool
207GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
208{
209 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
210 {
211 GetRemoteQSupported();
212 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000213 return m_supports_qXfer_libraries_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000214}
215
Steve Pucci03904ac2014-03-04 23:18:46 +0000216bool
217GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
218{
219 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
220 {
221 GetRemoteQSupported();
222 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000223 return m_supports_qXfer_auxv_read == eLazyBoolYes;
Steve Pucci03904ac2014-03-04 23:18:46 +0000224}
225
Colin Rileyc3c95b22015-04-16 15:51:33 +0000226bool
227GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported ()
228{
229 if (m_supports_qXfer_features_read == eLazyBoolCalculate)
230 {
231 GetRemoteQSupported();
232 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000233 return m_supports_qXfer_features_read == eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000234}
235
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000236uint64_t
237GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
238{
239 if (m_max_packet_size == 0)
240 {
241 GetRemoteQSupported();
242 }
243 return m_max_packet_size;
244}
245
246bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000247GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton576d8832011-03-22 04:00:09 +0000248{
249 if (m_supports_not_sending_acks == eLazyBoolCalculate)
250 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000251 m_send_acks = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000252 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000253
Jason Molenda36a216e2014-07-24 01:36:24 +0000254 // This is the first real packet that we'll send in a debug session and it may take a little
255 // longer than normal to receive a reply. Wait at least 6 seconds for a reply to this packet.
256
257 const uint32_t minimum_timeout = 6;
258 uint32_t old_timeout = GetPacketTimeoutInMicroSeconds() / lldb_private::TimeValue::MicroSecPerSec;
Tamas Berghammer912800c2015-02-24 10:23:39 +0000259 GDBRemoteCommunication::ScopedTimeout timeout (*this, std::max (old_timeout, minimum_timeout));
Jason Molenda36a216e2014-07-24 01:36:24 +0000260
Greg Clayton1cb64962011-03-24 04:28:38 +0000261 StringExtractorGDBRemote response;
Tamas Berghammer912800c2015-02-24 10:23:39 +0000262 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000263 {
264 if (response.IsOKResponse())
Greg Clayton1cb64962011-03-24 04:28:38 +0000265 {
266 m_send_acks = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000267 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton1cb64962011-03-24 04:28:38 +0000268 }
Greg Claytonfb909312013-11-23 01:58:15 +0000269 return true;
Greg Clayton576d8832011-03-22 04:00:09 +0000270 }
271 }
Greg Claytonfb909312013-11-23 01:58:15 +0000272 return false;
Greg Clayton576d8832011-03-22 04:00:09 +0000273}
274
275void
Greg Clayton44633992012-04-10 03:22:03 +0000276GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
277{
278 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
279 {
280 m_supports_threads_in_stop_reply = eLazyBoolNo;
281
282 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000283 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
Greg Clayton44633992012-04-10 03:22:03 +0000284 {
285 if (response.IsOKResponse())
286 m_supports_threads_in_stop_reply = eLazyBoolYes;
287 }
288 }
289}
290
Jim Inghamcd16df92012-07-20 21:37:13 +0000291bool
292GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
293{
294 if (m_attach_or_wait_reply == eLazyBoolCalculate)
295 {
296 m_attach_or_wait_reply = eLazyBoolNo;
297
298 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000299 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
Jim Inghamcd16df92012-07-20 21:37:13 +0000300 {
301 if (response.IsOKResponse())
302 m_attach_or_wait_reply = eLazyBoolYes;
303 }
304 }
305 if (m_attach_or_wait_reply == eLazyBoolYes)
306 return true;
307 else
308 return false;
309}
310
Jim Ingham279ceec2012-07-25 21:12:43 +0000311bool
312GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
313{
314 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
315 {
316 m_prepare_for_reg_writing_reply = eLazyBoolNo;
317
318 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000319 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
Jim Ingham279ceec2012-07-25 21:12:43 +0000320 {
321 if (response.IsOKResponse())
322 m_prepare_for_reg_writing_reply = eLazyBoolYes;
323 }
324 }
325 if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
326 return true;
327 else
328 return false;
329}
330
Greg Clayton44633992012-04-10 03:22:03 +0000331
332void
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000333GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
Greg Clayton576d8832011-03-22 04:00:09 +0000334{
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000335 if (did_exec == false)
336 {
337 // Hard reset everything, this is when we first connect to a GDB server
338 m_supports_not_sending_acks = eLazyBoolCalculate;
339 m_supports_thread_suffix = eLazyBoolCalculate;
340 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
341 m_supports_vCont_c = eLazyBoolCalculate;
342 m_supports_vCont_C = eLazyBoolCalculate;
343 m_supports_vCont_s = eLazyBoolCalculate;
344 m_supports_vCont_S = eLazyBoolCalculate;
345 m_supports_p = eLazyBoolCalculate;
346 m_supports_x = eLazyBoolCalculate;
347 m_supports_QSaveRegisterState = eLazyBoolCalculate;
348 m_qHostInfo_is_valid = eLazyBoolCalculate;
349 m_curr_pid_is_valid = eLazyBoolCalculate;
350 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
351 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
352 m_supports_memory_region_info = eLazyBoolCalculate;
353 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
354 m_attach_or_wait_reply = eLazyBoolCalculate;
355 m_avoid_g_packets = eLazyBoolCalculate;
356 m_supports_qXfer_auxv_read = eLazyBoolCalculate;
357 m_supports_qXfer_libraries_read = eLazyBoolCalculate;
358 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
359 m_supports_qXfer_features_read = eLazyBoolCalculate;
360 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
361 m_supports_qProcessInfoPID = true;
362 m_supports_qfProcessInfo = true;
363 m_supports_qUserName = true;
364 m_supports_qGroupName = true;
365 m_supports_qThreadStopInfo = true;
366 m_supports_z0 = true;
367 m_supports_z1 = true;
368 m_supports_z2 = true;
369 m_supports_z3 = true;
370 m_supports_z4 = true;
371 m_supports_QEnvironment = true;
372 m_supports_QEnvironmentHexEncoded = true;
373 m_supports_qSymbol = true;
Jason Molenda50018d32016-01-13 04:08:10 +0000374 m_qSymbol_requests_done = false;
Stephane Sezer6f455292016-01-08 00:00:17 +0000375 m_supports_qModuleInfo = true;
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000376 m_host_arch.Clear();
377 m_os_version_major = UINT32_MAX;
378 m_os_version_minor = UINT32_MAX;
379 m_os_version_update = UINT32_MAX;
380 m_os_build.clear();
381 m_os_kernel.clear();
382 m_hostname.clear();
383 m_gdb_server_name.clear();
384 m_gdb_server_version = UINT32_MAX;
385 m_default_packet_timeout = 0;
386 m_max_packet_size = 0;
Todd Fiala75930012016-08-19 04:21:48 +0000387 m_qSupported_response.clear();
388 m_supported_async_json_packets_is_valid = false;
389 m_supported_async_json_packets_sp.reset();
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000390 }
391
392 // These flags should be reset when we first connect to a GDB server
393 // and when our inferior process execs
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000394 m_qProcessInfo_is_valid = eLazyBoolCalculate;
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000395 m_process_arch.Clear();
Greg Clayton576d8832011-03-22 04:00:09 +0000396}
397
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000398void
399GDBRemoteCommunicationClient::GetRemoteQSupported ()
400{
401 // Clear out any capabilities we expect to see in the qSupported response
Steve Pucci03904ac2014-03-04 23:18:46 +0000402 m_supports_qXfer_auxv_read = eLazyBoolNo;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000403 m_supports_qXfer_libraries_read = eLazyBoolNo;
Steve Pucci03904ac2014-03-04 23:18:46 +0000404 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000405 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000406 m_supports_qXfer_features_read = eLazyBoolNo;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000407 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if not, we assume no limit
408
Colin Rileyc3c95b22015-04-16 15:51:33 +0000409 // build the qSupported packet
410 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
411 StreamString packet;
412 packet.PutCString( "qSupported" );
413 for ( uint32_t i = 0; i < features.size( ); ++i )
414 {
415 packet.PutCString( i==0 ? ":" : ";");
416 packet.PutCString( features[i].c_str( ) );
417 }
418
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000419 StringExtractorGDBRemote response;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000420 if (SendPacketAndWaitForResponse(packet.GetData(),
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000421 response,
422 /*send_async=*/false) == PacketResult::Success)
423 {
424 const char *response_cstr = response.GetStringRef().c_str();
Todd Fiala75930012016-08-19 04:21:48 +0000425
426 // Hang on to the qSupported packet, so that platforms can do custom
427 // configuration of the transport before attaching/launching the
428 // process.
429 m_qSupported_response = response_cstr;
430
Steve Pucci03904ac2014-03-04 23:18:46 +0000431 if (::strstr (response_cstr, "qXfer:auxv:read+"))
432 m_supports_qXfer_auxv_read = eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000433 if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
434 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
435 if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
436 {
437 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
438 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
439 }
440 if (::strstr (response_cstr, "qXfer:libraries:read+"))
441 m_supports_qXfer_libraries_read = eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000442 if (::strstr (response_cstr, "qXfer:features:read+"))
443 m_supports_qXfer_features_read = eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000444
Jason Molenda91ffe0a2015-06-18 21:46:06 +0000445
446 // Look for a list of compressions in the features list e.g.
447 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
448 const char *features_list = ::strstr (response_cstr, "qXfer:features:");
449 if (features_list)
450 {
451 const char *compressions = ::strstr (features_list, "SupportedCompressions=");
452 if (compressions)
453 {
454 std::vector<std::string> supported_compressions;
455 compressions += sizeof ("SupportedCompressions=") - 1;
456 const char *end_of_compressions = strchr (compressions, ';');
457 if (end_of_compressions == NULL)
458 {
459 end_of_compressions = strchr (compressions, '\0');
460 }
461 const char *current_compression = compressions;
462 while (current_compression < end_of_compressions)
463 {
464 const char *next_compression_name = strchr (current_compression, ',');
465 const char *end_of_this_word = next_compression_name;
466 if (next_compression_name == NULL || end_of_compressions < next_compression_name)
467 {
468 end_of_this_word = end_of_compressions;
469 }
470
471 if (end_of_this_word)
472 {
473 if (end_of_this_word == current_compression)
474 {
475 current_compression++;
476 }
477 else
478 {
479 std::string this_compression (current_compression, end_of_this_word - current_compression);
480 supported_compressions.push_back (this_compression);
481 current_compression = end_of_this_word + 1;
482 }
483 }
484 else
485 {
486 supported_compressions.push_back (current_compression);
487 current_compression = end_of_compressions;
488 }
489 }
490
491 if (supported_compressions.size() > 0)
492 {
493 MaybeEnableCompression (supported_compressions);
494 }
495 }
496 }
497
Greg Claytonb30c50c2015-05-29 00:01:55 +0000498 if (::strstr (response_cstr, "qEcho"))
499 m_supports_qEcho = eLazyBoolYes;
500 else
501 m_supports_qEcho = eLazyBoolNo;
502
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000503 const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
504 if (packet_size_str)
505 {
506 StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
507 m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
508 if (m_max_packet_size == 0)
509 {
510 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
511 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
512 if (log)
513 log->Printf ("Garbled PacketSize spec in qSupported response");
514 }
515 }
516 }
517}
Greg Clayton576d8832011-03-22 04:00:09 +0000518
519bool
520GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
521{
522 if (m_supports_thread_suffix == eLazyBoolCalculate)
523 {
524 StringExtractorGDBRemote response;
525 m_supports_thread_suffix = eLazyBoolNo;
Greg Clayton3dedae12013-12-06 21:45:27 +0000526 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000527 {
528 if (response.IsOKResponse())
529 m_supports_thread_suffix = eLazyBoolYes;
530 }
531 }
532 return m_supports_thread_suffix;
533}
534bool
535GDBRemoteCommunicationClient::GetVContSupported (char flavor)
536{
537 if (m_supports_vCont_c == eLazyBoolCalculate)
538 {
539 StringExtractorGDBRemote response;
540 m_supports_vCont_any = eLazyBoolNo;
541 m_supports_vCont_all = eLazyBoolNo;
542 m_supports_vCont_c = eLazyBoolNo;
543 m_supports_vCont_C = eLazyBoolNo;
544 m_supports_vCont_s = eLazyBoolNo;
545 m_supports_vCont_S = eLazyBoolNo;
Greg Clayton3dedae12013-12-06 21:45:27 +0000546 if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000547 {
548 const char *response_cstr = response.GetStringRef().c_str();
549 if (::strstr (response_cstr, ";c"))
550 m_supports_vCont_c = eLazyBoolYes;
551
552 if (::strstr (response_cstr, ";C"))
553 m_supports_vCont_C = eLazyBoolYes;
554
555 if (::strstr (response_cstr, ";s"))
556 m_supports_vCont_s = eLazyBoolYes;
557
558 if (::strstr (response_cstr, ";S"))
559 m_supports_vCont_S = eLazyBoolYes;
560
561 if (m_supports_vCont_c == eLazyBoolYes &&
562 m_supports_vCont_C == eLazyBoolYes &&
563 m_supports_vCont_s == eLazyBoolYes &&
564 m_supports_vCont_S == eLazyBoolYes)
565 {
566 m_supports_vCont_all = eLazyBoolYes;
567 }
568
569 if (m_supports_vCont_c == eLazyBoolYes ||
570 m_supports_vCont_C == eLazyBoolYes ||
571 m_supports_vCont_s == eLazyBoolYes ||
572 m_supports_vCont_S == eLazyBoolYes)
573 {
574 m_supports_vCont_any = eLazyBoolYes;
575 }
576 }
577 }
578
579 switch (flavor)
580 {
581 case 'a': return m_supports_vCont_any;
582 case 'A': return m_supports_vCont_all;
583 case 'c': return m_supports_vCont_c;
584 case 'C': return m_supports_vCont_C;
585 case 's': return m_supports_vCont_s;
586 case 'S': return m_supports_vCont_S;
587 default: break;
588 }
589 return false;
590}
591
Pavel Labath4b6f9592016-08-18 08:30:03 +0000592GDBRemoteCommunication::PacketResult
593GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload,
594 StringExtractorGDBRemote &response,
595 bool send_async)
596{
597 Lock lock(*this, send_async);
598 if (!lock)
599 {
600 if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
601 log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex for %s packet.", __FUNCTION__,
602 payload.GetString().c_str());
603 return PacketResult::ErrorNoSequenceLock;
604 }
605
606 if (GetThreadSuffixSupported())
607 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
608 else
609 {
610 if (!SetCurrentThread(tid))
611 return PacketResult::ErrorSendFailed;
612 }
613
614 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
615}
616
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000617// Check if the target supports 'p' packet. It sends out a 'p'
618// packet and checks the response. A normal packet will tell us
619// that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000620//
621// Takes a valid thread ID because p needs to apply to a thread.
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000622bool
Sean Callananb1de1142013-09-04 23:24:15 +0000623GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000624{
625 if (m_supports_p == eLazyBoolCalculate)
626 {
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000627 m_supports_p = eLazyBoolNo;
Pavel Labath4b6f9592016-08-18 08:30:03 +0000628 StreamString payload;
629 payload.PutCString("p0");
630 StringExtractorGDBRemote response;
631 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) ==
632 PacketResult::Success &&
633 response.IsNormalResponse())
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000634 {
Pavel Labath4b6f9592016-08-18 08:30:03 +0000635 m_supports_p = eLazyBoolYes;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000636 }
637 }
638 return m_supports_p;
639}
Greg Clayton576d8832011-03-22 04:00:09 +0000640
Greg Clayton358cf1e2015-06-25 21:46:34 +0000641StructuredData::ObjectSP
642GDBRemoteCommunicationClient::GetThreadsInfo()
643{
644 // Get information on all threads at one using the "jThreadsInfo" packet
645 StructuredData::ObjectSP object_sp;
646
647 if (m_supports_jThreadsInfo)
648 {
649 StringExtractorGDBRemote response;
Greg Clayton830c81d2016-04-01 00:41:29 +0000650 response.SetResponseValidatorToJSON();
Greg Clayton358cf1e2015-06-25 21:46:34 +0000651 if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success)
652 {
653 if (response.IsUnsupportedResponse())
654 {
655 m_supports_jThreadsInfo = false;
656 }
657 else if (!response.Empty())
658 {
659 object_sp = StructuredData::ParseJSON (response.GetStringRef());
660 }
661 }
662 }
663 return object_sp;
664}
665
666
Jason Molendabdc4f122014-05-06 02:59:39 +0000667bool
Jason Molenda705b1802014-06-13 02:37:02 +0000668GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported ()
669{
670 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate)
671 {
672 StringExtractorGDBRemote response;
673 m_supports_jThreadExtendedInfo = eLazyBoolNo;
674 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) == PacketResult::Success)
675 {
676 if (response.IsOKResponse())
677 {
678 m_supports_jThreadExtendedInfo = eLazyBoolYes;
679 }
680 }
681 }
682 return m_supports_jThreadExtendedInfo;
683}
684
685bool
Jason Molenda20ee21b2015-07-10 23:15:22 +0000686GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported ()
687{
688 if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate)
689 {
690 StringExtractorGDBRemote response;
691 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
692 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:", response, false) == PacketResult::Success)
693 {
694 if (response.IsOKResponse())
695 {
696 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
697 }
698 }
699 }
700 return m_supports_jLoadedDynamicLibrariesInfos;
701}
702
703bool
Jason Molenda37397352016-07-22 00:17:55 +0000704GDBRemoteCommunicationClient::GetSharedCacheInfoSupported ()
705{
706 if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate)
707 {
708 StringExtractorGDBRemote response;
709 m_supports_jGetSharedCacheInfo = eLazyBoolNo;
710 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) == PacketResult::Success)
711 {
712 if (response.IsOKResponse())
713 {
714 m_supports_jGetSharedCacheInfo = eLazyBoolYes;
715 }
716 }
717 }
718 return m_supports_jGetSharedCacheInfo;
719}
720
721bool
Jason Molendabdc4f122014-05-06 02:59:39 +0000722GDBRemoteCommunicationClient::GetxPacketSupported ()
723{
724 if (m_supports_x == eLazyBoolCalculate)
725 {
726 StringExtractorGDBRemote response;
727 m_supports_x = eLazyBoolNo;
728 char packet[256];
729 snprintf (packet, sizeof (packet), "x0,0");
730 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
731 {
732 if (response.IsOKResponse())
733 m_supports_x = eLazyBoolYes;
734 }
735 }
736 return m_supports_x;
737}
738
Greg Clayton3dedae12013-12-06 21:45:27 +0000739GDBRemoteCommunicationClient::PacketResult
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000740GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses
741(
742 const char *payload_prefix,
743 std::string &response_string
744)
745{
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000746 Lock lock(*this, false);
747 if (!lock)
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000748 {
749 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
750 if (log)
751 log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'",
752 payload_prefix);
753 return PacketResult::ErrorNoSequenceLock;
754 }
755
756 response_string = "";
757 std::string payload_prefix_str(payload_prefix);
758 unsigned int response_size = 0x1000;
759 if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
760 response_size = GetRemoteMaxPacketSize();
761 }
762
763 for (unsigned int offset = 0; true; offset += response_size)
764 {
765 StringExtractorGDBRemote this_response;
766 // Construct payload
767 char sizeDescriptor[128];
768 snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size);
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000769 PacketResult result = SendPacketAndWaitForResponseNoLock(payload_prefix_str + sizeDescriptor, this_response);
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000770 if (result != PacketResult::Success)
771 return result;
772
773 const std::string &this_string = this_response.GetStringRef();
774
775 // Check for m or l as first character; l seems to mean this is the last chunk
776 char first_char = *this_string.c_str();
777 if (first_char != 'm' && first_char != 'l')
778 {
779 return PacketResult::ErrorReplyInvalid;
780 }
Steve Pucci03904ac2014-03-04 23:18:46 +0000781 // Concatenate the result so far (skipping 'm' or 'l')
782 response_string.append(this_string, 1, std::string::npos);
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000783 if (first_char == 'l')
784 // We're done
785 return PacketResult::Success;
786 }
787}
788
Greg Clayton576d8832011-03-22 04:00:09 +0000789lldb::pid_t
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000790GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy)
Greg Clayton576d8832011-03-22 04:00:09 +0000791{
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000792 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000793 return m_curr_pid;
794
795 // First try to retrieve the pid via the qProcessInfo request.
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000796 GetCurrentProcessInfo (allow_lazy);
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000797 if (m_curr_pid_is_valid == eLazyBoolYes)
Greg Clayton576d8832011-03-22 04:00:09 +0000798 {
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000799 // We really got it.
800 return m_curr_pid;
Greg Clayton576d8832011-03-22 04:00:09 +0000801 }
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000802 else
803 {
Todd Fialae24614f2014-05-14 00:15:32 +0000804 // If we don't get a response for qProcessInfo, check if $qC gives us a result.
805 // $qC only returns a real process id on older debugserver and lldb-platform stubs.
806 // The gdb remote protocol documents $qC as returning the thread id, which newer
807 // debugserver and lldb-gdbserver stubs return correctly.
808 StringExtractorGDBRemote response;
809 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success)
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000810 {
Todd Fialae24614f2014-05-14 00:15:32 +0000811 if (response.GetChar() == 'Q')
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000812 {
Todd Fialae24614f2014-05-14 00:15:32 +0000813 if (response.GetChar() == 'C')
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000814 {
Todd Fialae24614f2014-05-14 00:15:32 +0000815 m_curr_pid = response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
816 if (m_curr_pid != LLDB_INVALID_PROCESS_ID)
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000817 {
Todd Fialae24614f2014-05-14 00:15:32 +0000818 m_curr_pid_is_valid = eLazyBoolYes;
819 return m_curr_pid;
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000820 }
821 }
822 }
823 }
Jaydeep Patil1142f832015-08-13 03:46:36 +0000824
825 // If we don't get a response for $qC, check if $qfThreadID gives us a result.
826 if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
827 {
828 std::vector<lldb::tid_t> thread_ids;
829 bool sequence_mutex_unavailable;
830 size_t size;
831 size = GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
832 if (size && sequence_mutex_unavailable == false)
833 {
834 m_curr_pid = thread_ids.front();
835 m_curr_pid_is_valid = eLazyBoolYes;
836 return m_curr_pid;
837 }
838 }
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000839 }
840
Greg Clayton576d8832011-03-22 04:00:09 +0000841 return LLDB_INVALID_PROCESS_ID;
842}
843
844bool
845GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
846{
847 error_str.clear();
848 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000849 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000850 {
851 if (response.IsOKResponse())
852 return true;
853 if (response.GetChar() == 'E')
854 {
855 // A string the describes what failed when launching...
856 error_str = response.GetStringRef().substr(1);
857 }
858 else
859 {
860 error_str.assign ("unknown error occurred launching process");
861 }
862 }
863 else
864 {
Jim Ingham98d6da52012-06-28 20:30:23 +0000865 error_str.assign ("timed out waiting for app to launch");
Greg Clayton576d8832011-03-22 04:00:09 +0000866 }
867 return false;
868}
869
870int
Greg Claytonfbb76342013-11-20 21:07:01 +0000871GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
Greg Clayton576d8832011-03-22 04:00:09 +0000872{
Greg Claytonfbb76342013-11-20 21:07:01 +0000873 // Since we don't get the send argv0 separate from the executable path, we need to
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000874 // make sure to use the actual executable path found in the launch_info...
Greg Claytonfbb76342013-11-20 21:07:01 +0000875 std::vector<const char *> argv;
876 FileSpec exe_file = launch_info.GetExecutableFile();
877 std::string exe_path;
878 const char *arg = NULL;
879 const Args &launch_args = launch_info.GetArguments();
880 if (exe_file)
Chaoren Lind3173f32015-05-29 19:52:29 +0000881 exe_path = exe_file.GetPath(false);
Greg Claytonfbb76342013-11-20 21:07:01 +0000882 else
883 {
884 arg = launch_args.GetArgumentAtIndex(0);
885 if (arg)
886 exe_path = arg;
887 }
888 if (!exe_path.empty())
889 {
890 argv.push_back(exe_path.c_str());
891 for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
892 {
893 if (arg)
894 argv.push_back(arg);
895 }
896 }
897 if (!argv.empty())
Greg Clayton576d8832011-03-22 04:00:09 +0000898 {
899 StreamString packet;
900 packet.PutChar('A');
Greg Claytonfbb76342013-11-20 21:07:01 +0000901 for (size_t i = 0, n = argv.size(); i < n; ++i)
Greg Clayton576d8832011-03-22 04:00:09 +0000902 {
Greg Claytonfbb76342013-11-20 21:07:01 +0000903 arg = argv[i];
Greg Clayton576d8832011-03-22 04:00:09 +0000904 const int arg_len = strlen(arg);
905 if (i > 0)
906 packet.PutChar(',');
Greg Claytonfbb76342013-11-20 21:07:01 +0000907 packet.Printf("%i,%i,", arg_len * 2, (int)i);
Greg Clayton576d8832011-03-22 04:00:09 +0000908 packet.PutBytesAsRawHex8 (arg, arg_len);
909 }
910
911 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000912 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000913 {
914 if (response.IsOKResponse())
915 return 0;
916 uint8_t error = response.GetError();
917 if (error)
918 return error;
919 }
920 }
921 return -1;
922}
923
924int
925GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
926{
927 if (name_equal_value && name_equal_value[0])
928 {
929 StreamString packet;
Greg Clayton89600582013-10-10 17:53:50 +0000930 bool send_hex_encoding = false;
931 for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p)
Greg Clayton576d8832011-03-22 04:00:09 +0000932 {
Greg Clayton89600582013-10-10 17:53:50 +0000933 if (isprint(*p))
934 {
935 switch (*p)
936 {
937 case '$':
938 case '#':
Jason Molenda60bdafb2015-11-05 23:51:05 +0000939 case '*':
Tim Northover974ff612015-11-09 22:05:05 +0000940 case '}':
Greg Clayton89600582013-10-10 17:53:50 +0000941 send_hex_encoding = true;
942 break;
943 default:
944 break;
945 }
946 }
947 else
948 {
949 // We have non printable characters, lets hex encode this...
950 send_hex_encoding = true;
951 }
952 }
953
954 StringExtractorGDBRemote response;
955 if (send_hex_encoding)
956 {
957 if (m_supports_QEnvironmentHexEncoded)
958 {
959 packet.PutCString("QEnvironmentHexEncoded:");
960 packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
Greg Clayton3dedae12013-12-06 21:45:27 +0000961 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton89600582013-10-10 17:53:50 +0000962 {
963 if (response.IsOKResponse())
964 return 0;
965 uint8_t error = response.GetError();
966 if (error)
967 return error;
968 if (response.IsUnsupportedResponse())
969 m_supports_QEnvironmentHexEncoded = false;
970 }
971 }
972
973 }
974 else if (m_supports_QEnvironment)
975 {
976 packet.Printf("QEnvironment:%s", name_equal_value);
Greg Clayton3dedae12013-12-06 21:45:27 +0000977 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton89600582013-10-10 17:53:50 +0000978 {
979 if (response.IsOKResponse())
980 return 0;
981 uint8_t error = response.GetError();
982 if (error)
983 return error;
984 if (response.IsUnsupportedResponse())
985 m_supports_QEnvironment = false;
986 }
Greg Clayton576d8832011-03-22 04:00:09 +0000987 }
988 }
989 return -1;
990}
991
Greg Claytonc4103b32011-05-08 04:53:50 +0000992int
993GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
994{
995 if (arch && arch[0])
996 {
997 StreamString packet;
998 packet.Printf("QLaunchArch:%s", arch);
999 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001000 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Claytonc4103b32011-05-08 04:53:50 +00001001 {
1002 if (response.IsOKResponse())
1003 return 0;
1004 uint8_t error = response.GetError();
1005 if (error)
1006 return error;
1007 }
1008 }
1009 return -1;
1010}
1011
Jason Molendaa3329782014-03-29 18:54:20 +00001012int
1013GDBRemoteCommunicationClient::SendLaunchEventDataPacket (char const *data, bool *was_supported)
1014{
1015 if (data && *data != '\0')
1016 {
1017 StreamString packet;
1018 packet.Printf("QSetProcessEvent:%s", data);
1019 StringExtractorGDBRemote response;
1020 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1021 {
1022 if (response.IsOKResponse())
1023 {
1024 if (was_supported)
1025 *was_supported = true;
1026 return 0;
1027 }
1028 else if (response.IsUnsupportedResponse())
1029 {
1030 if (was_supported)
1031 *was_supported = false;
1032 return -1;
1033 }
1034 else
1035 {
1036 uint8_t error = response.GetError();
1037 if (was_supported)
1038 *was_supported = true;
1039 if (error)
1040 return error;
1041 }
1042 }
1043 }
1044 return -1;
1045}
1046
Greg Clayton576d8832011-03-22 04:00:09 +00001047bool
Greg Clayton1cb64962011-03-24 04:28:38 +00001048GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
1049 uint32_t &minor,
1050 uint32_t &update)
1051{
1052 if (GetHostInfo ())
1053 {
1054 if (m_os_version_major != UINT32_MAX)
1055 {
1056 major = m_os_version_major;
1057 minor = m_os_version_minor;
1058 update = m_os_version_update;
1059 return true;
1060 }
1061 }
1062 return false;
1063}
1064
1065bool
1066GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
1067{
1068 if (GetHostInfo ())
1069 {
1070 if (!m_os_build.empty())
1071 {
1072 s = m_os_build;
1073 return true;
1074 }
1075 }
1076 s.clear();
1077 return false;
1078}
1079
1080
1081bool
1082GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
1083{
1084 if (GetHostInfo ())
1085 {
1086 if (!m_os_kernel.empty())
1087 {
1088 s = m_os_kernel;
1089 return true;
1090 }
1091 }
1092 s.clear();
1093 return false;
1094}
1095
1096bool
1097GDBRemoteCommunicationClient::GetHostname (std::string &s)
1098{
1099 if (GetHostInfo ())
1100 {
1101 if (!m_hostname.empty())
1102 {
1103 s = m_hostname;
1104 return true;
1105 }
1106 }
1107 s.clear();
1108 return false;
1109}
1110
1111ArchSpec
1112GDBRemoteCommunicationClient::GetSystemArchitecture ()
1113{
1114 if (GetHostInfo ())
1115 return m_host_arch;
1116 return ArchSpec();
1117}
1118
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001119const lldb_private::ArchSpec &
1120GDBRemoteCommunicationClient::GetProcessArchitecture ()
1121{
1122 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1123 GetCurrentProcessInfo ();
1124 return m_process_arch;
1125}
1126
Jason Molendaa3329782014-03-29 18:54:20 +00001127bool
1128GDBRemoteCommunicationClient::GetGDBServerVersion()
1129{
1130 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate)
1131 {
1132 m_gdb_server_name.clear();
1133 m_gdb_server_version = 0;
1134 m_qGDBServerVersion_is_valid = eLazyBoolNo;
1135
1136 StringExtractorGDBRemote response;
1137 if (SendPacketAndWaitForResponse ("qGDBServerVersion", response, false) == PacketResult::Success)
1138 {
1139 if (response.IsNormalResponse())
1140 {
1141 std::string name;
1142 std::string value;
1143 bool success = false;
1144 while (response.GetNameColonValue(name, value))
1145 {
1146 if (name.compare("name") == 0)
1147 {
1148 success = true;
1149 m_gdb_server_name.swap(value);
1150 }
1151 else if (name.compare("version") == 0)
1152 {
1153 size_t dot_pos = value.find('.');
1154 if (dot_pos != std::string::npos)
1155 value[dot_pos] = '\0';
Vince Harron5275aaa2015-01-15 20:08:35 +00001156 const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
Jason Molendaa3329782014-03-29 18:54:20 +00001157 if (version != UINT32_MAX)
1158 {
1159 success = true;
1160 m_gdb_server_version = version;
1161 }
1162 }
1163 }
1164 if (success)
1165 m_qGDBServerVersion_is_valid = eLazyBoolYes;
1166 }
1167 }
1168 }
1169 return m_qGDBServerVersion_is_valid == eLazyBoolYes;
1170}
1171
Jason Molenda91ffe0a2015-06-18 21:46:06 +00001172void
1173GDBRemoteCommunicationClient::MaybeEnableCompression (std::vector<std::string> supported_compressions)
1174{
1175 CompressionType avail_type = CompressionType::None;
1176 std::string avail_name;
1177
1178#if defined (HAVE_LIBCOMPRESSION)
1179 // libcompression is weak linked so test if compression_decode_buffer() is available
1180 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1181 {
1182 for (auto compression : supported_compressions)
1183 {
1184 if (compression == "lzfse")
1185 {
1186 avail_type = CompressionType::LZFSE;
1187 avail_name = compression;
1188 break;
1189 }
1190 }
1191 }
1192#endif
1193
1194#if defined (HAVE_LIBCOMPRESSION)
1195 // libcompression is weak linked so test if compression_decode_buffer() is available
1196 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1197 {
1198 for (auto compression : supported_compressions)
1199 {
1200 if (compression == "zlib-deflate")
1201 {
1202 avail_type = CompressionType::ZlibDeflate;
1203 avail_name = compression;
1204 break;
1205 }
1206 }
1207 }
1208#endif
1209
1210#if defined (HAVE_LIBZ)
1211 if (avail_type == CompressionType::None)
1212 {
1213 for (auto compression : supported_compressions)
1214 {
1215 if (compression == "zlib-deflate")
1216 {
1217 avail_type = CompressionType::ZlibDeflate;
1218 avail_name = compression;
1219 break;
1220 }
1221 }
1222 }
1223#endif
1224
1225#if defined (HAVE_LIBCOMPRESSION)
1226 // libcompression is weak linked so test if compression_decode_buffer() is available
1227 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1228 {
1229 for (auto compression : supported_compressions)
1230 {
1231 if (compression == "lz4")
1232 {
1233 avail_type = CompressionType::LZ4;
1234 avail_name = compression;
1235 break;
1236 }
1237 }
1238 }
1239#endif
1240
1241#if defined (HAVE_LIBCOMPRESSION)
1242 // libcompression is weak linked so test if compression_decode_buffer() is available
1243 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1244 {
1245 for (auto compression : supported_compressions)
1246 {
1247 if (compression == "lzma")
1248 {
1249 avail_type = CompressionType::LZMA;
1250 avail_name = compression;
1251 break;
1252 }
1253 }
1254 }
1255#endif
1256
1257 if (avail_type != CompressionType::None)
1258 {
1259 StringExtractorGDBRemote response;
1260 std::string packet = "QEnableCompression:type:" + avail_name + ";";
1261 if (SendPacketAndWaitForResponse (packet.c_str(), response, false) != PacketResult::Success)
1262 return;
1263
1264 if (response.IsOKResponse())
1265 {
1266 m_compression_type = avail_type;
1267 }
1268 }
1269}
1270
Jason Molendaa3329782014-03-29 18:54:20 +00001271const char *
1272GDBRemoteCommunicationClient::GetGDBServerProgramName()
1273{
1274 if (GetGDBServerVersion())
1275 {
1276 if (!m_gdb_server_name.empty())
1277 return m_gdb_server_name.c_str();
1278 }
1279 return NULL;
1280}
1281
1282uint32_t
1283GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
1284{
1285 if (GetGDBServerVersion())
1286 return m_gdb_server_version;
1287 return 0;
1288}
Greg Clayton1cb64962011-03-24 04:28:38 +00001289
1290bool
Ewan Crawford78baa192015-05-13 09:18:18 +00001291GDBRemoteCommunicationClient::GetDefaultThreadId (lldb::tid_t &tid)
1292{
1293 StringExtractorGDBRemote response;
1294 if (SendPacketAndWaitForResponse("qC",response,false) != PacketResult::Success)
1295 return false;
1296
1297 if (!response.IsNormalResponse())
1298 return false;
1299
1300 if (response.GetChar() == 'Q' && response.GetChar() == 'C')
1301 tid = response.GetHexMaxU32(true, -1);
1302
1303 return true;
1304}
1305
1306bool
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001307GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton576d8832011-03-22 04:00:09 +00001308{
Todd Fialaaf245d12014-06-30 21:05:18 +00001309 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));
1310
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001311 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001312 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001313 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +00001314 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001315 if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001316 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001317 if (response.IsNormalResponse())
Greg Claytond314e812011-03-23 00:09:55 +00001318 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001319 std::string name;
1320 std::string value;
1321 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1322 uint32_t sub = 0;
1323 std::string arch_name;
1324 std::string os_name;
1325 std::string vendor_name;
1326 std::string triple;
Todd Fialaa9ddb0e2014-01-18 03:02:39 +00001327 std::string distribution_id;
Greg Clayton32e0a752011-03-30 18:16:51 +00001328 uint32_t pointer_byte_size = 0;
1329 StringExtractor extractor;
1330 ByteOrder byte_order = eByteOrderInvalid;
1331 uint32_t num_keys_decoded = 0;
1332 while (response.GetNameColonValue(name, value))
Greg Claytond314e812011-03-23 00:09:55 +00001333 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001334 if (name.compare("cputype") == 0)
Greg Clayton1cb64962011-03-24 04:28:38 +00001335 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001336 // exception type in big endian hex
Vince Harron5275aaa2015-01-15 20:08:35 +00001337 cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
Greg Clayton32e0a752011-03-30 18:16:51 +00001338 if (cpu != LLDB_INVALID_CPUTYPE)
1339 ++num_keys_decoded;
1340 }
1341 else if (name.compare("cpusubtype") == 0)
1342 {
1343 // exception count in big endian hex
Vince Harron5275aaa2015-01-15 20:08:35 +00001344 sub = StringConvert::ToUInt32 (value.c_str(), 0, 0);
Greg Clayton32e0a752011-03-30 18:16:51 +00001345 if (sub != 0)
1346 ++num_keys_decoded;
1347 }
1348 else if (name.compare("arch") == 0)
1349 {
1350 arch_name.swap (value);
1351 ++num_keys_decoded;
1352 }
1353 else if (name.compare("triple") == 0)
1354 {
Greg Clayton44272a42014-09-18 00:18:32 +00001355 extractor.GetStringRef ().swap (value);
1356 extractor.SetFilePos(0);
1357 extractor.GetHexByteString (triple);
Greg Clayton32e0a752011-03-30 18:16:51 +00001358 ++num_keys_decoded;
1359 }
Todd Fialaa9ddb0e2014-01-18 03:02:39 +00001360 else if (name.compare ("distribution_id") == 0)
1361 {
1362 extractor.GetStringRef ().swap (value);
1363 extractor.SetFilePos (0);
1364 extractor.GetHexByteString (distribution_id);
1365 ++num_keys_decoded;
1366 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001367 else if (name.compare("os_build") == 0)
1368 {
1369 extractor.GetStringRef().swap(value);
1370 extractor.SetFilePos(0);
1371 extractor.GetHexByteString (m_os_build);
1372 ++num_keys_decoded;
1373 }
1374 else if (name.compare("hostname") == 0)
1375 {
1376 extractor.GetStringRef().swap(value);
1377 extractor.SetFilePos(0);
1378 extractor.GetHexByteString (m_hostname);
1379 ++num_keys_decoded;
1380 }
1381 else if (name.compare("os_kernel") == 0)
1382 {
1383 extractor.GetStringRef().swap(value);
1384 extractor.SetFilePos(0);
1385 extractor.GetHexByteString (m_os_kernel);
1386 ++num_keys_decoded;
1387 }
1388 else if (name.compare("ostype") == 0)
1389 {
1390 os_name.swap (value);
1391 ++num_keys_decoded;
1392 }
1393 else if (name.compare("vendor") == 0)
1394 {
1395 vendor_name.swap(value);
1396 ++num_keys_decoded;
1397 }
1398 else if (name.compare("endian") == 0)
1399 {
1400 ++num_keys_decoded;
1401 if (value.compare("little") == 0)
1402 byte_order = eByteOrderLittle;
1403 else if (value.compare("big") == 0)
1404 byte_order = eByteOrderBig;
1405 else if (value.compare("pdp") == 0)
1406 byte_order = eByteOrderPDP;
1407 else
1408 --num_keys_decoded;
1409 }
1410 else if (name.compare("ptrsize") == 0)
1411 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001412 pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0);
Greg Clayton32e0a752011-03-30 18:16:51 +00001413 if (pointer_byte_size != 0)
1414 ++num_keys_decoded;
1415 }
Greg Clayton17499dd2016-01-28 00:16:11 +00001416 else if ((name.compare("os_version") == 0) ||
1417 (name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"...
Greg Clayton32e0a752011-03-30 18:16:51 +00001418 {
1419 Args::StringToVersion (value.c_str(),
1420 m_os_version_major,
1421 m_os_version_minor,
1422 m_os_version_update);
1423 if (m_os_version_major != UINT32_MAX)
1424 ++num_keys_decoded;
1425 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001426 else if (name.compare("watchpoint_exceptions_received") == 0)
1427 {
1428 ++num_keys_decoded;
1429 if (strcmp(value.c_str(),"before") == 0)
1430 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1431 else if (strcmp(value.c_str(),"after") == 0)
1432 m_watchpoints_trigger_after_instruction = eLazyBoolYes;
1433 else
1434 --num_keys_decoded;
1435 }
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00001436 else if (name.compare("default_packet_timeout") == 0)
1437 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001438 m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0);
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00001439 if (m_default_packet_timeout > 0)
1440 {
1441 SetPacketTimeout(m_default_packet_timeout);
1442 ++num_keys_decoded;
1443 }
1444 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001445
Greg Clayton32e0a752011-03-30 18:16:51 +00001446 }
1447
1448 if (num_keys_decoded > 0)
1449 m_qHostInfo_is_valid = eLazyBoolYes;
1450
1451 if (triple.empty())
1452 {
1453 if (arch_name.empty())
1454 {
1455 if (cpu != LLDB_INVALID_CPUTYPE)
1456 {
1457 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
1458 if (pointer_byte_size)
1459 {
1460 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1461 }
1462 if (byte_order != eByteOrderInvalid)
1463 {
1464 assert (byte_order == m_host_arch.GetByteOrder());
1465 }
Greg Clayton70512312012-05-08 01:45:38 +00001466
Greg Clayton32e0a752011-03-30 18:16:51 +00001467 if (!vendor_name.empty())
1468 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
1469 if (!os_name.empty())
Greg Claytone1dadb82011-09-15 00:21:03 +00001470 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Greg Clayton32e0a752011-03-30 18:16:51 +00001471
1472 }
1473 }
1474 else
1475 {
1476 std::string triple;
1477 triple += arch_name;
Greg Clayton70512312012-05-08 01:45:38 +00001478 if (!vendor_name.empty() || !os_name.empty())
1479 {
1480 triple += '-';
1481 if (vendor_name.empty())
1482 triple += "unknown";
1483 else
1484 triple += vendor_name;
1485 triple += '-';
1486 if (os_name.empty())
1487 triple += "unknown";
1488 else
1489 triple += os_name;
1490 }
1491 m_host_arch.SetTriple (triple.c_str());
1492
1493 llvm::Triple &host_triple = m_host_arch.GetTriple();
1494 if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
1495 {
1496 switch (m_host_arch.GetMachine())
1497 {
Todd Fialad8eaa172014-07-23 14:37:35 +00001498 case llvm::Triple::aarch64:
Greg Clayton70512312012-05-08 01:45:38 +00001499 case llvm::Triple::arm:
1500 case llvm::Triple::thumb:
1501 host_triple.setOS(llvm::Triple::IOS);
1502 break;
1503 default:
1504 host_triple.setOS(llvm::Triple::MacOSX);
1505 break;
1506 }
1507 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001508 if (pointer_byte_size)
1509 {
1510 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1511 }
1512 if (byte_order != eByteOrderInvalid)
1513 {
1514 assert (byte_order == m_host_arch.GetByteOrder());
1515 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001516
Greg Clayton1cb64962011-03-24 04:28:38 +00001517 }
1518 }
1519 else
1520 {
Greg Clayton70512312012-05-08 01:45:38 +00001521 m_host_arch.SetTriple (triple.c_str());
Greg Claytond314e812011-03-23 00:09:55 +00001522 if (pointer_byte_size)
1523 {
1524 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1525 }
1526 if (byte_order != eByteOrderInvalid)
1527 {
1528 assert (byte_order == m_host_arch.GetByteOrder());
1529 }
Todd Fialaaf245d12014-06-30 21:05:18 +00001530
1531 if (log)
1532 log->Printf ("GDBRemoteCommunicationClient::%s parsed host architecture as %s, triple as %s from triple text %s", __FUNCTION__, m_host_arch.GetArchitectureName () ? m_host_arch.GetArchitectureName () : "<null-arch-name>", m_host_arch.GetTriple ().getTriple ().c_str(), triple.c_str ());
Todd Fialaa9ddb0e2014-01-18 03:02:39 +00001533 }
1534 if (!distribution_id.empty ())
1535 m_host_arch.SetDistributionId (distribution_id.c_str ());
Greg Claytond314e812011-03-23 00:09:55 +00001536 }
Greg Clayton576d8832011-03-22 04:00:09 +00001537 }
1538 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001539 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001540}
1541
1542int
1543GDBRemoteCommunicationClient::SendAttach
1544(
1545 lldb::pid_t pid,
1546 StringExtractorGDBRemote& response
1547)
1548{
1549 if (pid != LLDB_INVALID_PROCESS_ID)
1550 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001551 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001552 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00001553 assert (packet_len < (int)sizeof(packet));
Greg Clayton3dedae12013-12-06 21:45:27 +00001554 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001555 {
1556 if (response.IsErrorResponse())
1557 return response.GetError();
1558 return 0;
1559 }
1560 }
1561 return -1;
1562}
1563
Vince Harrone0be4252015-02-06 18:32:57 +00001564int
1565GDBRemoteCommunicationClient::SendStdinNotification (const char* data, size_t data_len)
1566{
1567 StreamString packet;
1568 packet.PutCString("I");
1569 packet.PutBytesAsRawHex8(data, data_len);
1570 StringExtractorGDBRemote response;
1571 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1572 {
1573 return 0;
1574 }
1575 return response.GetError();
1576
1577}
1578
Greg Clayton576d8832011-03-22 04:00:09 +00001579const lldb_private::ArchSpec &
1580GDBRemoteCommunicationClient::GetHostArchitecture ()
1581{
Greg Clayton32e0a752011-03-30 18:16:51 +00001582 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001583 GetHostInfo ();
Greg Claytond314e812011-03-23 00:09:55 +00001584 return m_host_arch;
Greg Clayton576d8832011-03-22 04:00:09 +00001585}
1586
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00001587uint32_t
1588GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
1589{
1590 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1591 GetHostInfo ();
1592 return m_default_packet_timeout;
1593}
1594
Greg Clayton576d8832011-03-22 04:00:09 +00001595addr_t
1596GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1597{
Greg Clayton70b57652011-05-15 01:25:55 +00001598 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001599 {
Greg Clayton70b57652011-05-15 01:25:55 +00001600 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001601 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001602 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
Greg Clayton43e0af02012-09-18 18:04:04 +00001603 (uint64_t)size,
Greg Clayton2a48f522011-05-14 01:50:35 +00001604 permissions & lldb::ePermissionsReadable ? "r" : "",
1605 permissions & lldb::ePermissionsWritable ? "w" : "",
1606 permissions & lldb::ePermissionsExecutable ? "x" : "");
Andy Gibbsa297a972013-06-19 19:04:53 +00001607 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001608 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001609 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton2a48f522011-05-14 01:50:35 +00001610 {
Todd Fialaf105f582014-06-21 00:48:09 +00001611 if (response.IsUnsupportedResponse())
1612 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1613 else if (!response.IsErrorResponse())
Greg Clayton2a48f522011-05-14 01:50:35 +00001614 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1615 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00001616 else
1617 {
1618 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1619 }
Greg Clayton576d8832011-03-22 04:00:09 +00001620 }
1621 return LLDB_INVALID_ADDRESS;
1622}
1623
1624bool
1625GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1626{
Greg Clayton70b57652011-05-15 01:25:55 +00001627 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00001628 {
Greg Clayton70b57652011-05-15 01:25:55 +00001629 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00001630 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001631 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001632 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00001633 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001634 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton2a48f522011-05-14 01:50:35 +00001635 {
Todd Fialaf105f582014-06-21 00:48:09 +00001636 if (response.IsUnsupportedResponse())
1637 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1638 else if (response.IsOKResponse())
Greg Clayton2a48f522011-05-14 01:50:35 +00001639 return true;
Greg Clayton17a0cb62011-05-15 23:46:54 +00001640 }
1641 else
1642 {
1643 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton2a48f522011-05-14 01:50:35 +00001644 }
Greg Clayton576d8832011-03-22 04:00:09 +00001645 }
1646 return false;
1647}
1648
Jim Inghamacff8952013-05-02 00:27:30 +00001649Error
1650GDBRemoteCommunicationClient::Detach (bool keep_stopped)
Greg Clayton37a0a242012-04-11 00:24:49 +00001651{
Jim Inghamacff8952013-05-02 00:27:30 +00001652 Error error;
1653
1654 if (keep_stopped)
1655 {
1656 if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
1657 {
1658 char packet[64];
1659 const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001660 assert (packet_len < (int)sizeof(packet));
Jim Inghamacff8952013-05-02 00:27:30 +00001661 StringExtractorGDBRemote response;
Jim Ingham4920a4e2015-07-15 00:59:25 +00001662 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success
1663 && response.IsOKResponse())
Jim Inghamacff8952013-05-02 00:27:30 +00001664 {
1665 m_supports_detach_stay_stopped = eLazyBoolYes;
1666 }
1667 else
1668 {
1669 m_supports_detach_stay_stopped = eLazyBoolNo;
1670 }
1671 }
1672
1673 if (m_supports_detach_stay_stopped == eLazyBoolNo)
1674 {
1675 error.SetErrorString("Stays stopped not supported by this target.");
1676 return error;
1677 }
1678 else
1679 {
Jim Ingham6c8824d2014-03-28 20:00:07 +00001680 StringExtractorGDBRemote response;
Jason Molenda2a667382015-07-15 00:16:09 +00001681 PacketResult packet_result = SendPacketAndWaitForResponse ("D1", 2, response, false);
Greg Clayton3dedae12013-12-06 21:45:27 +00001682 if (packet_result != PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00001683 error.SetErrorString ("Sending extended disconnect packet failed.");
1684 }
1685 }
1686 else
1687 {
Jim Ingham6c8824d2014-03-28 20:00:07 +00001688 StringExtractorGDBRemote response;
1689 PacketResult packet_result = SendPacketAndWaitForResponse ("D", 1, response, false);
Greg Clayton3dedae12013-12-06 21:45:27 +00001690 if (packet_result != PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00001691 error.SetErrorString ("Sending disconnect packet failed.");
1692 }
1693 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001694}
1695
Greg Clayton46fb5582011-11-18 07:03:08 +00001696Error
1697GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
1698 lldb_private::MemoryRegionInfo &region_info)
1699{
1700 Error error;
1701 region_info.Clear();
1702
1703 if (m_supports_memory_region_info != eLazyBoolNo)
1704 {
1705 m_supports_memory_region_info = eLazyBoolYes;
1706 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00001707 const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00001708 assert (packet_len < (int)sizeof(packet));
Greg Clayton46fb5582011-11-18 07:03:08 +00001709 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001710 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton46fb5582011-11-18 07:03:08 +00001711 {
1712 std::string name;
1713 std::string value;
1714 addr_t addr_value;
1715 bool success = true;
Jason Molendacb349ee2011-12-13 05:39:38 +00001716 bool saw_permissions = false;
Greg Clayton46fb5582011-11-18 07:03:08 +00001717 while (success && response.GetNameColonValue(name, value))
1718 {
1719 if (name.compare ("start") == 0)
1720 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001721 addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
Greg Clayton46fb5582011-11-18 07:03:08 +00001722 if (success)
1723 region_info.GetRange().SetRangeBase(addr_value);
1724 }
1725 else if (name.compare ("size") == 0)
1726 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001727 addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success);
Greg Clayton46fb5582011-11-18 07:03:08 +00001728 if (success)
1729 region_info.GetRange().SetByteSize (addr_value);
1730 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001731 else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
Greg Clayton46fb5582011-11-18 07:03:08 +00001732 {
Jason Molendacb349ee2011-12-13 05:39:38 +00001733 saw_permissions = true;
1734 if (region_info.GetRange().Contains (addr))
1735 {
1736 if (value.find('r') != std::string::npos)
1737 region_info.SetReadable (MemoryRegionInfo::eYes);
1738 else
1739 region_info.SetReadable (MemoryRegionInfo::eNo);
1740
1741 if (value.find('w') != std::string::npos)
1742 region_info.SetWritable (MemoryRegionInfo::eYes);
1743 else
1744 region_info.SetWritable (MemoryRegionInfo::eNo);
1745
1746 if (value.find('x') != std::string::npos)
1747 region_info.SetExecutable (MemoryRegionInfo::eYes);
1748 else
1749 region_info.SetExecutable (MemoryRegionInfo::eNo);
Howard Hellyerad007562016-07-07 08:21:28 +00001750
1751 region_info.SetMapped(MemoryRegionInfo::eYes);
Jason Molendacb349ee2011-12-13 05:39:38 +00001752 }
1753 else
1754 {
1755 // The reported region does not contain this address -- we're looking at an unmapped page
1756 region_info.SetReadable (MemoryRegionInfo::eNo);
1757 region_info.SetWritable (MemoryRegionInfo::eNo);
1758 region_info.SetExecutable (MemoryRegionInfo::eNo);
Howard Hellyerad007562016-07-07 08:21:28 +00001759 region_info.SetMapped(MemoryRegionInfo::eNo);
Jason Molendacb349ee2011-12-13 05:39:38 +00001760 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001761 }
Tamas Berghammerd7d69f82016-07-22 12:55:35 +00001762 else if (name.compare ("name") == 0)
1763 {
1764 StringExtractorGDBRemote name_extractor;
1765 name_extractor.GetStringRef().swap(value);
1766 name_extractor.GetHexByteString(value);
1767 region_info.SetName(value.c_str());
1768 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001769 else if (name.compare ("error") == 0)
1770 {
1771 StringExtractorGDBRemote name_extractor;
1772 // Swap "value" over into "name_extractor"
1773 name_extractor.GetStringRef().swap(value);
1774 // Now convert the HEX bytes into a string value
1775 name_extractor.GetHexByteString (value);
1776 error.SetErrorString(value.c_str());
1777 }
1778 }
Jason Molendacb349ee2011-12-13 05:39:38 +00001779
1780 // We got a valid address range back but no permissions -- which means this is an unmapped page
1781 if (region_info.GetRange().IsValid() && saw_permissions == false)
1782 {
1783 region_info.SetReadable (MemoryRegionInfo::eNo);
1784 region_info.SetWritable (MemoryRegionInfo::eNo);
1785 region_info.SetExecutable (MemoryRegionInfo::eNo);
Howard Hellyerad007562016-07-07 08:21:28 +00001786 region_info.SetMapped(MemoryRegionInfo::eNo);
Jason Molendacb349ee2011-12-13 05:39:38 +00001787 }
Greg Clayton46fb5582011-11-18 07:03:08 +00001788 }
1789 else
1790 {
1791 m_supports_memory_region_info = eLazyBoolNo;
1792 }
1793 }
1794
1795 if (m_supports_memory_region_info == eLazyBoolNo)
1796 {
1797 error.SetErrorString("qMemoryRegionInfo is not supported");
1798 }
1799 if (error.Fail())
1800 region_info.Clear();
1801 return error;
1802
1803}
1804
Johnny Chen64637202012-05-23 21:09:52 +00001805Error
1806GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
1807{
1808 Error error;
1809
1810 if (m_supports_watchpoint_support_info == eLazyBoolYes)
1811 {
1812 num = m_num_supported_hardware_watchpoints;
1813 return error;
1814 }
1815
1816 // Set num to 0 first.
1817 num = 0;
1818 if (m_supports_watchpoint_support_info != eLazyBoolNo)
1819 {
1820 char packet[64];
1821 const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
Andy Gibbsa297a972013-06-19 19:04:53 +00001822 assert (packet_len < (int)sizeof(packet));
Johnny Chen64637202012-05-23 21:09:52 +00001823 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001824 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Johnny Chen64637202012-05-23 21:09:52 +00001825 {
1826 m_supports_watchpoint_support_info = eLazyBoolYes;
1827 std::string name;
1828 std::string value;
1829 while (response.GetNameColonValue(name, value))
1830 {
1831 if (name.compare ("num") == 0)
1832 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001833 num = StringConvert::ToUInt32(value.c_str(), 0, 0);
Johnny Chen64637202012-05-23 21:09:52 +00001834 m_num_supported_hardware_watchpoints = num;
1835 }
1836 }
1837 }
1838 else
1839 {
1840 m_supports_watchpoint_support_info = eLazyBoolNo;
1841 }
1842 }
1843
1844 if (m_supports_watchpoint_support_info == eLazyBoolNo)
1845 {
1846 error.SetErrorString("qWatchpointSupportInfo is not supported");
1847 }
1848 return error;
1849
1850}
Greg Clayton46fb5582011-11-18 07:03:08 +00001851
Enrico Granataf04a2192012-07-13 23:18:48 +00001852lldb_private::Error
Jaydeep Patil725666c2015-08-13 03:46:01 +00001853GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch)
Enrico Granataf04a2192012-07-13 23:18:48 +00001854{
1855 Error error(GetWatchpointSupportInfo(num));
1856 if (error.Success())
Jaydeep Patil725666c2015-08-13 03:46:01 +00001857 error = GetWatchpointsTriggerAfterInstruction(after, arch);
Enrico Granataf04a2192012-07-13 23:18:48 +00001858 return error;
1859}
1860
1861lldb_private::Error
Jaydeep Patil725666c2015-08-13 03:46:01 +00001862GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch)
Enrico Granataf04a2192012-07-13 23:18:48 +00001863{
1864 Error error;
Jaydeep Patil725666c2015-08-13 03:46:01 +00001865 llvm::Triple::ArchType atype = arch.GetMachine();
Enrico Granataf04a2192012-07-13 23:18:48 +00001866
1867 // we assume watchpoints will happen after running the relevant opcode
1868 // and we only want to override this behavior if we have explicitly
1869 // received a qHostInfo telling us otherwise
1870 if (m_qHostInfo_is_valid != eLazyBoolYes)
Jaydeep Patil725666c2015-08-13 03:46:01 +00001871 {
1872 // On targets like MIPS, watchpoint exceptions are always generated
1873 // before the instruction is executed. The connected target may not
1874 // support qHostInfo or qWatchpointSupportInfo packets.
1875 if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
1876 || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
1877 after = false;
1878 else
1879 after = true;
1880 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001881 else
Jaydeep Patil725666c2015-08-13 03:46:01 +00001882 {
1883 // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
1884 // if it is not calculated before.
1885 if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
1886 (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
1887 || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
1888 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1889
Enrico Granataf04a2192012-07-13 23:18:48 +00001890 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
Jaydeep Patil725666c2015-08-13 03:46:01 +00001891 }
Enrico Granataf04a2192012-07-13 23:18:48 +00001892 return error;
1893}
1894
Greg Clayton576d8832011-03-22 04:00:09 +00001895int
Chaoren Lind3173f32015-05-29 19:52:29 +00001896GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00001897{
Chaoren Lind3173f32015-05-29 19:52:29 +00001898 if (file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00001899 {
Chaoren Lind3173f32015-05-29 19:52:29 +00001900 std::string path{file_spec.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00001901 StreamString packet;
1902 packet.PutCString("QSetSTDIN:");
Chaoren Lind3173f32015-05-29 19:52:29 +00001903 packet.PutCStringAsRawHex8(path.c_str());
Greg Clayton576d8832011-03-22 04:00:09 +00001904
1905 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001906 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001907 {
1908 if (response.IsOKResponse())
1909 return 0;
1910 uint8_t error = response.GetError();
1911 if (error)
1912 return error;
1913 }
1914 }
1915 return -1;
1916}
1917
1918int
Chaoren Lind3173f32015-05-29 19:52:29 +00001919GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00001920{
Chaoren Lind3173f32015-05-29 19:52:29 +00001921 if (file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00001922 {
Chaoren Lind3173f32015-05-29 19:52:29 +00001923 std::string path{file_spec.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00001924 StreamString packet;
1925 packet.PutCString("QSetSTDOUT:");
Chaoren Lind3173f32015-05-29 19:52:29 +00001926 packet.PutCStringAsRawHex8(path.c_str());
1927
Greg Clayton576d8832011-03-22 04:00:09 +00001928 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001929 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001930 {
1931 if (response.IsOKResponse())
1932 return 0;
1933 uint8_t error = response.GetError();
1934 if (error)
1935 return error;
1936 }
1937 }
1938 return -1;
1939}
1940
1941int
Chaoren Lind3173f32015-05-29 19:52:29 +00001942GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00001943{
Chaoren Lind3173f32015-05-29 19:52:29 +00001944 if (file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00001945 {
Chaoren Lind3173f32015-05-29 19:52:29 +00001946 std::string path{file_spec.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00001947 StreamString packet;
1948 packet.PutCString("QSetSTDERR:");
Chaoren Lind3173f32015-05-29 19:52:29 +00001949 packet.PutCStringAsRawHex8(path.c_str());
1950
Greg Clayton576d8832011-03-22 04:00:09 +00001951 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001952 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001953 {
1954 if (response.IsOKResponse())
1955 return 0;
1956 uint8_t error = response.GetError();
1957 if (error)
1958 return error;
1959 }
1960 }
1961 return -1;
1962}
1963
Greg Claytonfbb76342013-11-20 21:07:01 +00001964bool
Chaoren Lind3173f32015-05-29 19:52:29 +00001965GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir)
Greg Claytonfbb76342013-11-20 21:07:01 +00001966{
1967 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001968 if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00001969 {
1970 if (response.IsUnsupportedResponse())
1971 return false;
1972 if (response.IsErrorResponse())
1973 return false;
Chaoren Lind3173f32015-05-29 19:52:29 +00001974 std::string cwd;
1975 response.GetHexByteString(cwd);
Chaoren Lin44145d72015-05-29 19:52:37 +00001976 working_dir.SetFile(cwd, false, GetHostArchitecture());
Greg Claytonfbb76342013-11-20 21:07:01 +00001977 return !cwd.empty();
1978 }
1979 return false;
1980}
1981
Greg Clayton576d8832011-03-22 04:00:09 +00001982int
Chaoren Lind3173f32015-05-29 19:52:29 +00001983GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir)
Greg Clayton576d8832011-03-22 04:00:09 +00001984{
Chaoren Lind3173f32015-05-29 19:52:29 +00001985 if (working_dir)
Greg Clayton576d8832011-03-22 04:00:09 +00001986 {
Chaoren Lind3173f32015-05-29 19:52:29 +00001987 std::string path{working_dir.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00001988 StreamString packet;
1989 packet.PutCString("QSetWorkingDir:");
Chaoren Lind3173f32015-05-29 19:52:29 +00001990 packet.PutCStringAsRawHex8(path.c_str());
1991
Greg Clayton576d8832011-03-22 04:00:09 +00001992 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001993 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001994 {
1995 if (response.IsOKResponse())
1996 return 0;
1997 uint8_t error = response.GetError();
1998 if (error)
1999 return error;
2000 }
2001 }
2002 return -1;
2003}
2004
2005int
2006GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
2007{
Greg Clayton32e0a752011-03-30 18:16:51 +00002008 char packet[32];
2009 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
Andy Gibbsa297a972013-06-19 19:04:53 +00002010 assert (packet_len < (int)sizeof(packet));
Greg Clayton576d8832011-03-22 04:00:09 +00002011 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002012 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00002013 {
2014 if (response.IsOKResponse())
2015 return 0;
2016 uint8_t error = response.GetError();
2017 if (error)
2018 return error;
2019 }
2020 return -1;
2021}
Greg Clayton32e0a752011-03-30 18:16:51 +00002022
Jim Ingham106d0282014-06-25 02:32:56 +00002023int
2024GDBRemoteCommunicationClient::SetDetachOnError (bool enable)
2025{
2026 char packet[32];
2027 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDetachOnError:%i", enable ? 1 : 0);
2028 assert (packet_len < (int)sizeof(packet));
2029 StringExtractorGDBRemote response;
2030 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
2031 {
2032 if (response.IsOKResponse())
2033 return 0;
2034 uint8_t error = response.GetError();
2035 if (error)
2036 return error;
2037 }
2038 return -1;
2039}
2040
2041
Greg Clayton32e0a752011-03-30 18:16:51 +00002042bool
Greg Clayton8b82f082011-04-12 05:54:46 +00002043GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00002044{
2045 if (response.IsNormalResponse())
2046 {
2047 std::string name;
2048 std::string value;
2049 StringExtractor extractor;
Jason Molenda89c37492014-01-27 22:23:20 +00002050
2051 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2052 uint32_t sub = 0;
2053 std::string vendor;
2054 std::string os_type;
Greg Clayton32e0a752011-03-30 18:16:51 +00002055
2056 while (response.GetNameColonValue(name, value))
2057 {
2058 if (name.compare("pid") == 0)
2059 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002060 process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002061 }
2062 else if (name.compare("ppid") == 0)
2063 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002064 process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002065 }
2066 else if (name.compare("uid") == 0)
2067 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002068 process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002069 }
2070 else if (name.compare("euid") == 0)
2071 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002072 process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002073 }
2074 else if (name.compare("gid") == 0)
2075 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002076 process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002077 }
2078 else if (name.compare("egid") == 0)
2079 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002080 process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002081 }
2082 else if (name.compare("triple") == 0)
2083 {
Greg Clayton44272a42014-09-18 00:18:32 +00002084 StringExtractor extractor;
2085 extractor.GetStringRef().swap(value);
2086 extractor.SetFilePos(0);
2087 extractor.GetHexByteString (value);
Greg Clayton70512312012-05-08 01:45:38 +00002088 process_info.GetArchitecture ().SetTriple (value.c_str());
Greg Clayton32e0a752011-03-30 18:16:51 +00002089 }
2090 else if (name.compare("name") == 0)
2091 {
2092 StringExtractor extractor;
Filipe Cabecinhasf86cf782012-05-07 09:30:51 +00002093 // The process name from ASCII hex bytes since we can't
Greg Clayton32e0a752011-03-30 18:16:51 +00002094 // control the characters in a process name
2095 extractor.GetStringRef().swap(value);
2096 extractor.SetFilePos(0);
2097 extractor.GetHexByteString (value);
Greg Clayton144f3a92011-11-15 03:53:30 +00002098 process_info.GetExecutableFile().SetFile (value.c_str(), false);
Greg Clayton32e0a752011-03-30 18:16:51 +00002099 }
Jason Molenda89c37492014-01-27 22:23:20 +00002100 else if (name.compare("cputype") == 0)
2101 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002102 cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
Jason Molenda89c37492014-01-27 22:23:20 +00002103 }
2104 else if (name.compare("cpusubtype") == 0)
2105 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002106 sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
Jason Molenda89c37492014-01-27 22:23:20 +00002107 }
2108 else if (name.compare("vendor") == 0)
2109 {
2110 vendor = value;
2111 }
2112 else if (name.compare("ostype") == 0)
2113 {
2114 os_type = value;
2115 }
2116 }
2117
2118 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty())
2119 {
2120 if (vendor == "apple")
2121 {
2122 process_info.GetArchitecture().SetArchitecture (eArchTypeMachO, cpu, sub);
2123 process_info.GetArchitecture().GetTriple().setVendorName (llvm::StringRef (vendor));
2124 process_info.GetArchitecture().GetTriple().setOSName (llvm::StringRef (os_type));
2125 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002126 }
2127
2128 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
2129 return true;
2130 }
2131 return false;
2132}
2133
2134bool
Greg Clayton8b82f082011-04-12 05:54:46 +00002135GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00002136{
2137 process_info.Clear();
2138
2139 if (m_supports_qProcessInfoPID)
2140 {
2141 char packet[32];
Daniel Malead01b2952012-11-29 21:49:15 +00002142 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002143 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002144 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002145 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002146 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002147 return DecodeProcessInfoResponse (response, process_info);
2148 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002149 else
2150 {
2151 m_supports_qProcessInfoPID = false;
2152 return false;
2153 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002154 }
2155 return false;
2156}
2157
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002158bool
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00002159GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002160{
Todd Fiala3daa1762014-09-15 16:01:29 +00002161 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
2162
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00002163 if (allow_lazy)
2164 {
2165 if (m_qProcessInfo_is_valid == eLazyBoolYes)
2166 return true;
2167 if (m_qProcessInfo_is_valid == eLazyBoolNo)
2168 return false;
2169 }
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002170
2171 GetHostInfo ();
2172
2173 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002174 if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success)
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002175 {
2176 if (response.IsNormalResponse())
2177 {
2178 std::string name;
2179 std::string value;
2180 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2181 uint32_t sub = 0;
2182 std::string arch_name;
2183 std::string os_name;
2184 std::string vendor_name;
2185 std::string triple;
2186 uint32_t pointer_byte_size = 0;
2187 StringExtractor extractor;
Todd Fiala5c9d5bf2014-09-15 15:31:11 +00002188 ByteOrder byte_order = eByteOrderInvalid;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002189 uint32_t num_keys_decoded = 0;
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002190 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002191 while (response.GetNameColonValue(name, value))
2192 {
2193 if (name.compare("cputype") == 0)
2194 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002195 cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002196 if (cpu != LLDB_INVALID_CPUTYPE)
2197 ++num_keys_decoded;
2198 }
2199 else if (name.compare("cpusubtype") == 0)
2200 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002201 sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002202 if (sub != 0)
2203 ++num_keys_decoded;
2204 }
Todd Fialac540dd02014-08-26 18:21:02 +00002205 else if (name.compare("triple") == 0)
2206 {
Greg Clayton44272a42014-09-18 00:18:32 +00002207 StringExtractor extractor;
2208 extractor.GetStringRef().swap(value);
2209 extractor.SetFilePos(0);
2210 extractor.GetHexByteString (triple);
Todd Fialac540dd02014-08-26 18:21:02 +00002211 ++num_keys_decoded;
2212 }
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002213 else if (name.compare("ostype") == 0)
2214 {
2215 os_name.swap (value);
2216 ++num_keys_decoded;
2217 }
2218 else if (name.compare("vendor") == 0)
2219 {
2220 vendor_name.swap(value);
2221 ++num_keys_decoded;
2222 }
2223 else if (name.compare("endian") == 0)
2224 {
Todd Fiala5c9d5bf2014-09-15 15:31:11 +00002225 ++num_keys_decoded;
2226 if (value.compare("little") == 0)
2227 byte_order = eByteOrderLittle;
2228 else if (value.compare("big") == 0)
2229 byte_order = eByteOrderBig;
2230 else if (value.compare("pdp") == 0)
2231 byte_order = eByteOrderPDP;
2232 else
2233 --num_keys_decoded;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002234 }
2235 else if (name.compare("ptrsize") == 0)
2236 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002237 pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16);
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002238 if (pointer_byte_size != 0)
2239 ++num_keys_decoded;
2240 }
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002241 else if (name.compare("pid") == 0)
2242 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002243 pid = StringConvert::ToUInt64(value.c_str(), 0, 16);
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002244 if (pid != LLDB_INVALID_PROCESS_ID)
2245 ++num_keys_decoded;
2246 }
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002247 }
2248 if (num_keys_decoded > 0)
2249 m_qProcessInfo_is_valid = eLazyBoolYes;
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002250 if (pid != LLDB_INVALID_PROCESS_ID)
2251 {
2252 m_curr_pid_is_valid = eLazyBoolYes;
2253 m_curr_pid = pid;
2254 }
Todd Fialac540dd02014-08-26 18:21:02 +00002255
2256 // Set the ArchSpec from the triple if we have it.
2257 if (!triple.empty ())
2258 {
2259 m_process_arch.SetTriple (triple.c_str ());
2260 if (pointer_byte_size)
2261 {
2262 assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
2263 }
2264 }
2265 else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002266 {
Todd Fiala3daa1762014-09-15 16:01:29 +00002267 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2268
2269 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2270 switch (triple.getObjectFormat()) {
2271 case llvm::Triple::MachO:
2272 m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
2273 break;
2274 case llvm::Triple::ELF:
2275 m_process_arch.SetArchitecture (eArchTypeELF, cpu, sub);
2276 break;
2277 case llvm::Triple::COFF:
2278 m_process_arch.SetArchitecture (eArchTypeCOFF, cpu, sub);
2279 break;
2280 case llvm::Triple::UnknownObjectFormat:
2281 if (log)
2282 log->Printf("error: failed to determine target architecture");
2283 return false;
2284 }
2285
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002286 if (pointer_byte_size)
2287 {
2288 assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
2289 }
Todd Fiala5c9d5bf2014-09-15 15:31:11 +00002290 if (byte_order != eByteOrderInvalid)
2291 {
2292 assert (byte_order == m_process_arch.GetByteOrder());
2293 }
Todd Fiala0cc371c2014-09-05 14:56:13 +00002294 m_process_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
Greg Clayton7ab7f892014-05-29 21:33:45 +00002295 m_process_arch.GetTriple().setOSName(llvm::StringRef (os_name));
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002296 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
2297 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002298 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00002299 return true;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002300 }
2301 }
2302 else
2303 {
2304 m_qProcessInfo_is_valid = eLazyBoolNo;
2305 }
2306
2307 return false;
2308}
2309
2310
Greg Clayton32e0a752011-03-30 18:16:51 +00002311uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00002312GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
2313 ProcessInstanceInfoList &process_infos)
Greg Clayton32e0a752011-03-30 18:16:51 +00002314{
2315 process_infos.Clear();
2316
2317 if (m_supports_qfProcessInfo)
2318 {
2319 StreamString packet;
2320 packet.PutCString ("qfProcessInfo");
2321 if (!match_info.MatchAllProcesses())
2322 {
2323 packet.PutChar (':');
2324 const char *name = match_info.GetProcessInfo().GetName();
2325 bool has_name_match = false;
2326 if (name && name[0])
2327 {
2328 has_name_match = true;
2329 NameMatchType name_match_type = match_info.GetNameMatchType();
2330 switch (name_match_type)
2331 {
2332 case eNameMatchIgnore:
2333 has_name_match = false;
2334 break;
2335
2336 case eNameMatchEquals:
2337 packet.PutCString ("name_match:equals;");
2338 break;
2339
2340 case eNameMatchContains:
2341 packet.PutCString ("name_match:contains;");
2342 break;
2343
2344 case eNameMatchStartsWith:
2345 packet.PutCString ("name_match:starts_with;");
2346 break;
2347
2348 case eNameMatchEndsWith:
2349 packet.PutCString ("name_match:ends_with;");
2350 break;
2351
2352 case eNameMatchRegularExpression:
2353 packet.PutCString ("name_match:regex;");
2354 break;
2355 }
2356 if (has_name_match)
2357 {
2358 packet.PutCString ("name:");
2359 packet.PutBytesAsRawHex8(name, ::strlen(name));
2360 packet.PutChar (';');
2361 }
2362 }
2363
2364 if (match_info.GetProcessInfo().ProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002365 packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002366 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002367 packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
Greg Clayton8b82f082011-04-12 05:54:46 +00002368 if (match_info.GetProcessInfo().UserIDIsValid())
2369 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
2370 if (match_info.GetProcessInfo().GroupIDIsValid())
2371 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002372 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2373 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
2374 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2375 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
2376 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2377 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
2378 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
2379 {
2380 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
2381 const llvm::Triple &triple = match_arch.GetTriple();
2382 packet.PutCString("triple:");
Matthew Gardinerf39ebbe2014-08-01 05:12:23 +00002383 packet.PutCString(triple.getTriple().c_str());
Greg Clayton32e0a752011-03-30 18:16:51 +00002384 packet.PutChar (';');
2385 }
2386 }
2387 StringExtractorGDBRemote response;
Siva Chandra8fd94c92015-05-20 00:30:31 +00002388 // Increase timeout as the first qfProcessInfo packet takes a long time
2389 // on Android. The value of 1min was arrived at empirically.
2390 GDBRemoteCommunication::ScopedTimeout timeout (*this, 60);
Greg Clayton3dedae12013-12-06 21:45:27 +00002391 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002392 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002393 do
2394 {
Greg Clayton8b82f082011-04-12 05:54:46 +00002395 ProcessInstanceInfo process_info;
Greg Clayton32e0a752011-03-30 18:16:51 +00002396 if (!DecodeProcessInfoResponse (response, process_info))
2397 break;
2398 process_infos.Append(process_info);
2399 response.GetStringRef().clear();
2400 response.SetFilePos(0);
Greg Clayton3dedae12013-12-06 21:45:27 +00002401 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
Greg Clayton32e0a752011-03-30 18:16:51 +00002402 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002403 else
2404 {
2405 m_supports_qfProcessInfo = false;
2406 return 0;
2407 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002408 }
2409 return process_infos.GetSize();
2410
2411}
2412
2413bool
2414GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
2415{
2416 if (m_supports_qUserName)
2417 {
2418 char packet[32];
2419 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002420 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002421 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002422 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002423 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002424 if (response.IsNormalResponse())
2425 {
2426 // Make sure we parsed the right number of characters. The response is
2427 // the hex encoded user name and should make up the entire packet.
2428 // If there are any non-hex ASCII bytes, the length won't match below..
2429 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2430 return true;
2431 }
2432 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002433 else
2434 {
2435 m_supports_qUserName = false;
2436 return false;
2437 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002438 }
2439 return false;
2440
2441}
2442
2443bool
2444GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
2445{
2446 if (m_supports_qGroupName)
2447 {
2448 char packet[32];
2449 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002450 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002451 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002452 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002453 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002454 if (response.IsNormalResponse())
2455 {
2456 // Make sure we parsed the right number of characters. The response is
2457 // the hex encoded group name and should make up the entire packet.
2458 // If there are any non-hex ASCII bytes, the length won't match below..
2459 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2460 return true;
2461 }
2462 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002463 else
2464 {
2465 m_supports_qGroupName = false;
2466 return false;
2467 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002468 }
2469 return false;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002470}
Greg Clayton32e0a752011-03-30 18:16:51 +00002471
Ewan Crawford78baa192015-05-13 09:18:18 +00002472bool
2473GDBRemoteCommunicationClient::SetNonStopMode (const bool enable)
2474{
2475 // Form non-stop packet request
2476 char packet[32];
2477 const int packet_len = ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
2478 assert(packet_len < (int)sizeof(packet));
2479
2480 StringExtractorGDBRemote response;
2481 // Send to target
2482 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2483 if (response.IsOKResponse())
2484 return true;
2485
2486 // Failed or not supported
2487 return false;
2488
2489}
2490
Greg Claytone034a042015-05-21 20:52:06 +00002491static void
2492MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
2493{
2494 packet.Clear();
2495 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
2496 uint32_t bytes_left = send_size;
2497 while (bytes_left > 0)
2498 {
2499 if (bytes_left >= 26)
2500 {
2501 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2502 bytes_left -= 26;
2503 }
2504 else
2505 {
2506 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
2507 bytes_left = 0;
2508 }
2509 }
2510}
2511
2512template<typename T>
2513T calculate_standard_deviation(const std::vector<T> &v)
2514{
2515 T sum = std::accumulate(std::begin(v), std::end(v), T(0));
2516 T mean = sum / (T)v.size();
2517 T accum = T(0);
2518 std::for_each (std::begin(v), std::end(v), [&](const T d) {
2519 T delta = d - mean;
2520 accum += delta * delta;
2521 });
2522
2523 T stdev = sqrt(accum / (v.size()-1));
2524 return stdev;
2525}
2526
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002527void
Greg Claytone034a042015-05-21 20:52:06 +00002528GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm)
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002529{
2530 uint32_t i;
2531 TimeValue start_time, end_time;
2532 uint64_t total_time_nsec;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002533 if (SendSpeedTestPacket (0, 0))
2534 {
Greg Claytone034a042015-05-21 20:52:06 +00002535 StreamString packet;
2536 if (json)
2537 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n \"results\" : [", num_packets);
2538 else
2539 strm.Printf("Testing sending %u packets of various sizes:\n", num_packets);
2540 strm.Flush();
Greg Clayton700e5082014-02-21 19:11:28 +00002541
Greg Claytone034a042015-05-21 20:52:06 +00002542 uint32_t result_idx = 0;
2543 uint32_t send_size;
2544 std::vector<float> packet_times;
2545
2546 for (send_size = 0; send_size <= max_send; send_size ? send_size *= 2 : send_size = 4)
2547 {
2548 for (uint32_t recv_size = 0; recv_size <= max_recv; recv_size ? recv_size *= 2 : recv_size = 4)
2549 {
2550 MakeSpeedTestPacket (packet, send_size, recv_size);
2551
2552 packet_times.clear();
2553 // Test how long it takes to send 'num_packets' packets
Greg Clayton700e5082014-02-21 19:11:28 +00002554 start_time = TimeValue::Now();
Greg Claytone034a042015-05-21 20:52:06 +00002555 for (i=0; i<num_packets; ++i)
Greg Clayton700e5082014-02-21 19:11:28 +00002556 {
Greg Claytone034a042015-05-21 20:52:06 +00002557 TimeValue packet_start_time = TimeValue::Now();
2558 StringExtractorGDBRemote response;
2559 SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
2560 TimeValue packet_end_time = TimeValue::Now();
2561 uint64_t packet_time_nsec = packet_end_time.GetAsNanoSecondsSinceJan1_1970() - packet_start_time.GetAsNanoSecondsSinceJan1_1970();
2562 packet_times.push_back((float)packet_time_nsec);
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002563 }
2564 end_time = TimeValue::Now();
2565 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Greg Claytone034a042015-05-21 20:52:06 +00002566
2567 float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
2568 float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
2569 float average_ms_per_packet = total_ms / num_packets;
2570 const float standard_deviation = calculate_standard_deviation<float>(packet_times);
2571 if (json)
Greg Clayton700e5082014-02-21 19:11:28 +00002572 {
Greg Claytone034a042015-05-21 20:52:06 +00002573 strm.Printf ("%s\n {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 ", \"standard_deviation_nsec\" : %9" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec, (uint64_t)standard_deviation);
2574 ++result_idx;
Greg Clayton700e5082014-02-21 19:11:28 +00002575 }
2576 else
2577 {
Greg Claytone034a042015-05-21 20:52:06 +00002578 strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %9.2f packets/sec (%10.6f ms per packet) with standard deviation of %10.6f ms\n",
2579 send_size,
2580 recv_size,
2581 total_time_nsec / TimeValue::NanoSecPerSec,
2582 total_time_nsec % TimeValue::NanoSecPerSec,
2583 packets_per_second,
2584 average_ms_per_packet,
2585 standard_deviation/(float)TimeValue::NanoSecPerMilliSec);
Greg Clayton700e5082014-02-21 19:11:28 +00002586 }
Greg Claytone034a042015-05-21 20:52:06 +00002587 strm.Flush();
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002588 }
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002589 }
Greg Claytone034a042015-05-21 20:52:06 +00002590
2591 const uint64_t k_recv_amount = 4*1024*1024; // Receive amount in bytes
2592
2593 const float k_recv_amount_mb = (float)k_recv_amount/(1024.0f*1024.0f);
2594 if (json)
2595 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" : %" PRIu64 ",\n \"results\" : [", k_recv_amount);
2596 else
2597 strm.Printf("Testing receiving %2.1fMB of data using varying receive packet sizes:\n", k_recv_amount_mb);
2598 strm.Flush();
2599 send_size = 0;
2600 result_idx = 0;
2601 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2)
2602 {
2603 MakeSpeedTestPacket (packet, send_size, recv_size);
2604
2605 // If we have a receive size, test how long it takes to receive 4MB of data
2606 if (recv_size > 0)
2607 {
2608 start_time = TimeValue::Now();
2609 uint32_t bytes_read = 0;
2610 uint32_t packet_count = 0;
2611 while (bytes_read < k_recv_amount)
2612 {
2613 StringExtractorGDBRemote response;
2614 SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
2615 bytes_read += recv_size;
2616 ++packet_count;
2617 }
2618 end_time = TimeValue::Now();
2619 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
2620 float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
2621 float packets_per_second = (((float)packet_count)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
2622 float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
2623 float average_ms_per_packet = total_ms / packet_count;
2624
2625 if (json)
2626 {
2627 strm.Printf ("%s\n {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec);
2628 ++result_idx;
2629 }
2630 else
2631 {
2632 strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to receive %2.1fMB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per packet)\n",
2633 send_size,
2634 recv_size,
2635 packet_count,
2636 k_recv_amount_mb,
2637 total_time_nsec / TimeValue::NanoSecPerSec,
2638 total_time_nsec % TimeValue::NanoSecPerSec,
2639 mb_second,
2640 packets_per_second,
2641 average_ms_per_packet);
2642 }
2643 strm.Flush();
2644 }
2645 }
2646 if (json)
2647 strm.Printf("\n ]\n }\n}\n");
2648 else
2649 strm.EOL();
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002650 }
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00002651}
2652
2653bool
2654GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
2655{
2656 StreamString packet;
2657 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
2658 uint32_t bytes_left = send_size;
2659 while (bytes_left > 0)
2660 {
2661 if (bytes_left >= 26)
2662 {
2663 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2664 bytes_left -= 26;
2665 }
2666 else
2667 {
2668 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
2669 bytes_left = 0;
2670 }
2671 }
2672
2673 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002674 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
Greg Clayton32e0a752011-03-30 18:16:51 +00002675}
Greg Clayton8b82f082011-04-12 05:54:46 +00002676
Oleksiy Vyalov9fe526c2015-10-21 19:34:26 +00002677bool
2678GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostname,
2679 lldb::pid_t &pid,
2680 uint16_t &port,
2681 std::string &socket_name)
Greg Clayton8b82f082011-04-12 05:54:46 +00002682{
Daniel Maleae0f8f572013-08-26 23:57:52 +00002683 pid = LLDB_INVALID_PROCESS_ID;
Oleksiy Vyalov9fe526c2015-10-21 19:34:26 +00002684 port = 0;
2685 socket_name.clear();
2686
Greg Clayton8b82f082011-04-12 05:54:46 +00002687 StringExtractorGDBRemote response;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002688 StreamString stream;
Greg Clayton29b8fc42013-11-21 01:44:58 +00002689 stream.PutCString("qLaunchGDBServer;");
Daniel Maleae0f8f572013-08-26 23:57:52 +00002690 std::string hostname;
Greg Claytondbf04572013-12-04 19:40:33 +00002691 if (remote_accept_hostname && remote_accept_hostname[0])
2692 hostname = remote_accept_hostname;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002693 else
2694 {
Zachary Turner97a14e62014-08-19 17:18:29 +00002695 if (HostInfo::GetHostname(hostname))
Greg Claytondbf04572013-12-04 19:40:33 +00002696 {
2697 // Make the GDB server we launch only accept connections from this host
2698 stream.Printf("host:%s;", hostname.c_str());
2699 }
2700 else
2701 {
2702 // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
2703 stream.Printf("host:*;");
2704 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002705 }
2706 const char *packet = stream.GetData();
2707 int packet_len = stream.GetSize();
2708
Vince Harron1b5a74e2015-01-21 22:42:49 +00002709 // give the process a few seconds to startup
Tamas Berghammer912800c2015-02-24 10:23:39 +00002710 GDBRemoteCommunication::ScopedTimeout timeout (*this, 10);
Oleksiy Vyalov9fe526c2015-10-21 19:34:26 +00002711
Tamas Berghammer912800c2015-02-24 10:23:39 +00002712 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002713 {
2714 std::string name;
2715 std::string value;
Oleksiy Vyalov9fe526c2015-10-21 19:34:26 +00002716 StringExtractor extractor;
Greg Clayton8b82f082011-04-12 05:54:46 +00002717 while (response.GetNameColonValue(name, value))
2718 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00002719 if (name.compare("port") == 0)
Vince Harron5275aaa2015-01-15 20:08:35 +00002720 port = StringConvert::ToUInt32(value.c_str(), 0, 0);
Daniel Maleae0f8f572013-08-26 23:57:52 +00002721 else if (name.compare("pid") == 0)
Vince Harron5275aaa2015-01-15 20:08:35 +00002722 pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
Oleksiy Vyalov9fe526c2015-10-21 19:34:26 +00002723 else if (name.compare("socket_name") == 0)
2724 {
2725 extractor.GetStringRef().swap(value);
2726 extractor.SetFilePos(0);
2727 extractor.GetHexByteString(value);
2728
2729 socket_name = value;
2730 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002731 }
Oleksiy Vyalov9fe526c2015-10-21 19:34:26 +00002732 return true;
Greg Clayton8b82f082011-04-12 05:54:46 +00002733 }
Oleksiy Vyalov9fe526c2015-10-21 19:34:26 +00002734 return false;
Greg Clayton8b82f082011-04-12 05:54:46 +00002735}
2736
Tamas Berghammerccd6cff2015-12-08 14:08:19 +00002737size_t
2738GDBRemoteCommunicationClient::QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls)
2739{
2740 connection_urls.clear();
2741
2742 StringExtractorGDBRemote response;
2743 if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != PacketResult::Success)
2744 return 0;
2745
2746 StructuredData::ObjectSP data = StructuredData::ParseJSON(response.GetStringRef());
2747 if (!data)
2748 return 0;
2749
2750 StructuredData::Array* array = data->GetAsArray();
2751 if (!array)
2752 return 0;
2753
2754 for (size_t i = 0, count = array->GetSize(); i < count; ++i)
2755 {
2756 StructuredData::Dictionary* element = nullptr;
2757 if (!array->GetItemAtIndexAsDictionary(i, element))
2758 continue;
2759
2760 uint16_t port = 0;
2761 if (StructuredData::ObjectSP port_osp = element->GetValueForKey(llvm::StringRef("port")))
2762 port = port_osp->GetIntegerValue(0);
2763
2764 std::string socket_name;
2765 if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name")))
2766 socket_name = socket_name_osp->GetStringValue();
2767
2768 if (port != 0 || !socket_name.empty())
2769 connection_urls.emplace_back(port, socket_name);
2770 }
2771 return connection_urls.size();
2772}
2773
Greg Clayton8b82f082011-04-12 05:54:46 +00002774bool
Daniel Maleae0f8f572013-08-26 23:57:52 +00002775GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
2776{
2777 StreamString stream;
2778 stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
2779 const char *packet = stream.GetData();
2780 int packet_len = stream.GetSize();
Sylvestre Ledrufd654c42013-10-06 09:51:02 +00002781
Daniel Maleae0f8f572013-08-26 23:57:52 +00002782 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.IsOKResponse())
2786 return true;
2787 }
2788 return false;
2789}
2790
2791bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002792GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002793{
2794 if (m_curr_tid == tid)
2795 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002796
Greg Clayton8b82f082011-04-12 05:54:46 +00002797 char packet[32];
2798 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002799 if (tid == UINT64_MAX)
2800 packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002801 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002802 packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002803 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002804 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002805 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002806 {
2807 if (response.IsOKResponse())
2808 {
2809 m_curr_tid = tid;
2810 return true;
2811 }
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00002812
2813 /*
2814 * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hg packet.
2815 * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
2816 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2817 */
2818 if (response.IsUnsupportedResponse() && IsConnected())
2819 {
2820 m_curr_tid = 1;
2821 return true;
2822 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002823 }
2824 return false;
2825}
2826
2827bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00002828GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00002829{
2830 if (m_curr_tid_run == tid)
2831 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002832
Greg Clayton8b82f082011-04-12 05:54:46 +00002833 char packet[32];
2834 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00002835 if (tid == UINT64_MAX)
2836 packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00002837 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00002838 packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
2839
Andy Gibbsa297a972013-06-19 19:04:53 +00002840 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002841 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002842 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002843 {
2844 if (response.IsOKResponse())
2845 {
2846 m_curr_tid_run = tid;
2847 return true;
2848 }
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00002849
2850 /*
2851 * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hc packet.
2852 * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
2853 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2854 */
2855 if (response.IsUnsupportedResponse() && IsConnected())
2856 {
2857 m_curr_tid_run = 1;
2858 return true;
2859 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002860 }
2861 return false;
2862}
2863
2864bool
2865GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
2866{
Greg Clayton3dedae12013-12-06 21:45:27 +00002867 if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002868 return response.IsNormalResponse();
2869 return false;
2870}
2871
2872bool
Greg Claytonf402f782012-10-13 02:11:55 +00002873GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
Greg Clayton8b82f082011-04-12 05:54:46 +00002874{
2875 if (m_supports_qThreadStopInfo)
2876 {
2877 char packet[256];
Daniel Malead01b2952012-11-29 21:49:15 +00002878 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002879 assert (packet_len < (int)sizeof(packet));
Greg Clayton3dedae12013-12-06 21:45:27 +00002880 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002881 {
Greg Claytonef8180a2013-10-15 00:14:28 +00002882 if (response.IsUnsupportedResponse())
2883 m_supports_qThreadStopInfo = false;
2884 else if (response.IsNormalResponse())
Greg Clayton8b82f082011-04-12 05:54:46 +00002885 return true;
2886 else
2887 return false;
2888 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002889 else
2890 {
2891 m_supports_qThreadStopInfo = false;
2892 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002893 }
Greg Clayton8b82f082011-04-12 05:54:46 +00002894 return false;
2895}
2896
2897
2898uint8_t
2899GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
2900{
Todd Fiala616b8272014-10-09 00:55:04 +00002901 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
2902 if (log)
2903 log->Printf ("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2904 __FUNCTION__, insert ? "add" : "remove", addr);
2905
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00002906 // Check if the stub is known not to support this breakpoint type
2907 if (!SupportsGDBStoppointPacket(type))
2908 return UINT8_MAX;
2909 // Construct the breakpoint packet
Greg Clayton8b82f082011-04-12 05:54:46 +00002910 char packet[64];
2911 const int packet_len = ::snprintf (packet,
2912 sizeof(packet),
Daniel Malead01b2952012-11-29 21:49:15 +00002913 "%c%i,%" PRIx64 ",%x",
Greg Clayton8b82f082011-04-12 05:54:46 +00002914 insert ? 'Z' : 'z',
2915 type,
2916 addr,
2917 length);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002918 // Check we haven't overwritten the end of the packet buffer
Andy Gibbsa297a972013-06-19 19:04:53 +00002919 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00002920 StringExtractorGDBRemote response;
Greg Clayton830c81d2016-04-01 00:41:29 +00002921 // Make sure the response is either "OK", "EXX" where XX are two hex digits, or "" (unsupported)
2922 response.SetResponseValidatorToOKErrorNotSupported();
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00002923 // Try to send the breakpoint packet, and check that it was correctly sent
Greg Clayton3dedae12013-12-06 21:45:27 +00002924 if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00002925 {
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00002926 // Receive and OK packet when the breakpoint successfully placed
Greg Clayton8b82f082011-04-12 05:54:46 +00002927 if (response.IsOKResponse())
2928 return 0;
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00002929
2930 // Error while setting breakpoint, send back specific error
2931 if (response.IsErrorResponse())
Greg Clayton8b82f082011-04-12 05:54:46 +00002932 return response.GetError();
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00002933
2934 // Empty packet informs us that breakpoint is not supported
2935 if (response.IsUnsupportedResponse())
Greg Clayton17a0cb62011-05-15 23:46:54 +00002936 {
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00002937 // Disable this breakpoint type since it is unsupported
2938 switch (type)
2939 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00002940 case eBreakpointSoftware: m_supports_z0 = false; break;
2941 case eBreakpointHardware: m_supports_z1 = false; break;
2942 case eWatchpointWrite: m_supports_z2 = false; break;
2943 case eWatchpointRead: m_supports_z3 = false; break;
2944 case eWatchpointReadWrite: m_supports_z4 = false; break;
Chaoren Lin0be9ebb2015-02-03 01:51:50 +00002945 case eStoppointInvalid: return UINT8_MAX;
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00002946 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002947 }
2948 }
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002949 // Signal generic failure
Greg Clayton8b82f082011-04-12 05:54:46 +00002950 return UINT8_MAX;
2951}
Greg Claytonadc00cb2011-05-20 23:38:13 +00002952
2953size_t
2954GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
2955 bool &sequence_mutex_unavailable)
2956{
Greg Claytonadc00cb2011-05-20 23:38:13 +00002957 thread_ids.clear();
Saleem Abdulrasool2d6a9ec2016-07-28 17:32:20 +00002958
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00002959 Lock lock(*this, false);
2960 if (lock)
Greg Claytonadc00cb2011-05-20 23:38:13 +00002961 {
2962 sequence_mutex_unavailable = false;
2963 StringExtractorGDBRemote response;
2964
Greg Clayton3dedae12013-12-06 21:45:27 +00002965 PacketResult packet_result;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00002966 for (packet_result = SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
Greg Clayton3dedae12013-12-06 21:45:27 +00002967 packet_result == PacketResult::Success && response.IsNormalResponse();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00002968 packet_result = SendPacketAndWaitForResponseNoLock("qsThreadInfo", response))
Greg Claytonadc00cb2011-05-20 23:38:13 +00002969 {
2970 char ch = response.GetChar();
2971 if (ch == 'l')
2972 break;
2973 if (ch == 'm')
2974 {
2975 do
2976 {
Jason Molendae9ca4af2013-02-23 02:04:45 +00002977 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
Greg Claytonadc00cb2011-05-20 23:38:13 +00002978
2979 if (tid != LLDB_INVALID_THREAD_ID)
2980 {
2981 thread_ids.push_back (tid);
2982 }
2983 ch = response.GetChar(); // Skip the command separator
2984 } while (ch == ','); // Make sure we got a comma separator
2985 }
2986 }
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00002987
2988 /*
2989 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2990 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet could
2991 * be as simple as 'S05'. There is no packet which can give us pid and/or tid.
2992 * Assume pid=tid=1 in such cases.
2993 */
2994 if (response.IsUnsupportedResponse() && thread_ids.size() == 0 && IsConnected())
2995 {
2996 thread_ids.push_back (1);
2997 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00002998 }
2999 else
3000 {
Jim Ingham4ceb9282012-06-08 22:50:40 +00003001#if defined (LLDB_CONFIGURATION_DEBUG)
3002 // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
3003#else
Greg Clayton5160ce52013-03-27 23:08:40 +00003004 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Claytonc3c0b0e2012-04-12 19:04:34 +00003005 if (log)
3006 log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
Jim Ingham4ceb9282012-06-08 22:50:40 +00003007#endif
Greg Claytonadc00cb2011-05-20 23:38:13 +00003008 sequence_mutex_unavailable = true;
3009 }
3010 return thread_ids.size();
3011}
Greg Clayton37a0a242012-04-11 00:24:49 +00003012
3013lldb::addr_t
3014GDBRemoteCommunicationClient::GetShlibInfoAddr()
3015{
Pavel Labath83082a02016-08-18 14:33:55 +00003016 StringExtractorGDBRemote response;
3017 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) != PacketResult::Success || !response.IsNormalResponse())
3018 return LLDB_INVALID_ADDRESS;
3019 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
Greg Clayton37a0a242012-04-11 00:24:49 +00003020}
3021
Daniel Maleae0f8f572013-08-26 23:57:52 +00003022lldb_private::Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003023GDBRemoteCommunicationClient::RunShellCommand(const char *command, // Shouldn't be NULL
3024 const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
3025 int *status_ptr, // Pass NULL if you don't want the process exit status
3026 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
3027 std::string *command_output, // Pass NULL if you don't want the command output
3028 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
Daniel Maleae0f8f572013-08-26 23:57:52 +00003029{
3030 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00003031 stream.PutCString("qPlatform_shell:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003032 stream.PutBytesAsRawHex8(command, strlen(command));
3033 stream.PutChar(',');
3034 stream.PutHex32(timeout_sec);
Chaoren Lind3173f32015-05-29 19:52:29 +00003035 if (working_dir)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003036 {
Chaoren Lind3173f32015-05-29 19:52:29 +00003037 std::string path{working_dir.GetPath(false)};
Daniel Maleae0f8f572013-08-26 23:57:52 +00003038 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003039 stream.PutCStringAsRawHex8(path.c_str());
Daniel Maleae0f8f572013-08-26 23:57:52 +00003040 }
3041 const char *packet = stream.GetData();
3042 int packet_len = stream.GetSize();
3043 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003044 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003045 {
3046 if (response.GetChar() != 'F')
3047 return Error("malformed reply");
3048 if (response.GetChar() != ',')
3049 return Error("malformed reply");
3050 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
3051 if (exitcode == UINT32_MAX)
3052 return Error("unable to run remote process");
3053 else if (status_ptr)
3054 *status_ptr = exitcode;
3055 if (response.GetChar() != ',')
3056 return Error("malformed reply");
3057 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
3058 if (signo_ptr)
3059 *signo_ptr = signo;
3060 if (response.GetChar() != ',')
3061 return Error("malformed reply");
3062 std::string output;
3063 response.GetEscapedBinaryData(output);
3064 if (command_output)
3065 command_output->assign(output);
3066 return Error();
3067 }
3068 return Error("unable to send packet");
3069}
3070
Greg Claytonfbb76342013-11-20 21:07:01 +00003071Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003072GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
3073 uint32_t file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003074{
Chaoren Lind3173f32015-05-29 19:52:29 +00003075 std::string path{file_spec.GetPath(false)};
Daniel Maleae0f8f572013-08-26 23:57:52 +00003076 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00003077 stream.PutCString("qPlatform_mkdir:");
3078 stream.PutHex32(file_permissions);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003079 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003080 stream.PutCStringAsRawHex8(path.c_str());
Daniel Maleae0f8f572013-08-26 23:57:52 +00003081 const char *packet = stream.GetData();
3082 int packet_len = stream.GetSize();
3083 StringExtractorGDBRemote response;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003084
Tamas Berghammer0f86b742015-02-23 11:03:08 +00003085 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
3086 return Error("failed to send '%s' packet", packet);
3087
3088 if (response.GetChar() != 'F')
3089 return Error("invalid response to '%s' packet", packet);
3090
3091 return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003092}
3093
Greg Claytonfbb76342013-11-20 21:07:01 +00003094Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003095GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
3096 uint32_t file_permissions)
Greg Claytonfbb76342013-11-20 21:07:01 +00003097{
Chaoren Lind3173f32015-05-29 19:52:29 +00003098 std::string path{file_spec.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003099 lldb_private::StreamString stream;
3100 stream.PutCString("qPlatform_chmod:");
3101 stream.PutHex32(file_permissions);
3102 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003103 stream.PutCStringAsRawHex8(path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003104 const char *packet = stream.GetData();
3105 int packet_len = stream.GetSize();
3106 StringExtractorGDBRemote response;
Tamas Berghammer0f86b742015-02-23 11:03:08 +00003107
3108 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
3109 return Error("failed to send '%s' packet", packet);
3110
3111 if (response.GetChar() != 'F')
3112 return Error("invalid response to '%s' packet", packet);
3113
Chaoren Lince36c4c2015-05-05 18:43:19 +00003114 return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Greg Claytonfbb76342013-11-20 21:07:01 +00003115}
3116
Daniel Maleae0f8f572013-08-26 23:57:52 +00003117static uint64_t
3118ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
3119 uint64_t fail_result,
3120 Error &error)
3121{
3122 response.SetFilePos(0);
3123 if (response.GetChar() != 'F')
3124 return fail_result;
3125 int32_t result = response.GetS32 (-2);
3126 if (result == -2)
3127 return fail_result;
3128 if (response.GetChar() == ',')
3129 {
3130 int result_errno = response.GetS32 (-2);
3131 if (result_errno != -2)
3132 error.SetError(result_errno, eErrorTypePOSIX);
3133 else
3134 error.SetError(-1, eErrorTypeGeneric);
3135 }
3136 else
3137 error.Clear();
3138 return result;
3139}
3140lldb::user_id_t
3141GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
3142 uint32_t flags,
3143 mode_t mode,
3144 Error &error)
3145{
Chaoren Lind3173f32015-05-29 19:52:29 +00003146 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003147 lldb_private::StreamString stream;
3148 stream.PutCString("vFile:open:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003149 if (path.empty())
3150 return UINT64_MAX;
3151 stream.PutCStringAsRawHex8(path.c_str());
3152 stream.PutChar(',');
Robert Flackebc56092015-03-18 13:55:48 +00003153 stream.PutHex32(flags);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003154 stream.PutChar(',');
3155 stream.PutHex32(mode);
3156 const char* packet = stream.GetData();
3157 int packet_len = stream.GetSize();
3158 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003159 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003160 {
3161 return ParseHostIOPacketResponse (response, UINT64_MAX, error);
3162 }
3163 return UINT64_MAX;
3164}
3165
3166bool
3167GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
3168 Error &error)
3169{
3170 lldb_private::StreamString stream;
3171 stream.Printf("vFile:close:%i", (int)fd);
3172 const char* packet = stream.GetData();
3173 int packet_len = stream.GetSize();
3174 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003175 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003176 {
3177 return ParseHostIOPacketResponse (response, -1, error) == 0;
3178 }
Deepak Panickald66b50c2013-10-22 12:27:43 +00003179 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003180}
3181
3182// Extension of host I/O packets to get the file size.
3183lldb::user_id_t
3184GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
3185{
Chaoren Lind3173f32015-05-29 19:52:29 +00003186 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003187 lldb_private::StreamString stream;
3188 stream.PutCString("vFile:size:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003189 stream.PutCStringAsRawHex8(path.c_str());
3190 const char* packet = stream.GetData();
3191 int packet_len = stream.GetSize();
3192 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003193 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003194 {
3195 if (response.GetChar() != 'F')
3196 return UINT64_MAX;
3197 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
3198 return retcode;
3199 }
3200 return UINT64_MAX;
3201}
3202
Greg Claytonfbb76342013-11-20 21:07:01 +00003203Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003204GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
3205 uint32_t &file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003206{
Chaoren Lind3173f32015-05-29 19:52:29 +00003207 std::string path{file_spec.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003208 Error error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003209 lldb_private::StreamString stream;
3210 stream.PutCString("vFile:mode:");
Chaoren Lind3173f32015-05-29 19:52:29 +00003211 stream.PutCStringAsRawHex8(path.c_str());
Daniel Maleae0f8f572013-08-26 23:57:52 +00003212 const char* packet = stream.GetData();
3213 int packet_len = stream.GetSize();
3214 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003215 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003216 {
3217 if (response.GetChar() != 'F')
3218 {
3219 error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003220 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003221 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00003222 {
Greg Claytonfbb76342013-11-20 21:07:01 +00003223 const uint32_t mode = response.GetS32(-1);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00003224 if (static_cast<int32_t>(mode) == -1)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003225 {
Greg Claytonfbb76342013-11-20 21:07:01 +00003226 if (response.GetChar() == ',')
3227 {
3228 int response_errno = response.GetS32(-1);
3229 if (response_errno > 0)
3230 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3231 else
3232 error.SetErrorToGenericError();
3233 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003234 else
3235 error.SetErrorToGenericError();
3236 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003237 else
3238 {
3239 file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
3240 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003241 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003242 }
3243 else
3244 {
3245 error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
3246 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003247 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003248}
3249
3250uint64_t
3251GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
3252 uint64_t offset,
3253 void *dst,
3254 uint64_t dst_len,
3255 Error &error)
3256{
3257 lldb_private::StreamString stream;
3258 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
3259 const char* packet = stream.GetData();
3260 int packet_len = stream.GetSize();
3261 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003262 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003263 {
3264 if (response.GetChar() != 'F')
3265 return 0;
3266 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
3267 if (retcode == UINT32_MAX)
3268 return retcode;
3269 const char next = (response.Peek() ? *response.Peek() : 0);
3270 if (next == ',')
3271 return 0;
3272 if (next == ';')
3273 {
3274 response.GetChar(); // skip the semicolon
3275 std::string buffer;
3276 if (response.GetEscapedBinaryData(buffer))
3277 {
3278 const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
3279 if (data_to_write > 0)
3280 memcpy(dst, &buffer[0], data_to_write);
3281 return data_to_write;
3282 }
3283 }
3284 }
3285 return 0;
3286}
3287
3288uint64_t
3289GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
3290 uint64_t offset,
3291 const void* src,
3292 uint64_t src_len,
3293 Error &error)
3294{
3295 lldb_private::StreamGDBRemote stream;
3296 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3297 stream.PutEscapedBytes(src, src_len);
3298 const char* packet = stream.GetData();
3299 int packet_len = stream.GetSize();
3300 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003301 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003302 {
3303 if (response.GetChar() != 'F')
3304 {
3305 error.SetErrorStringWithFormat("write file failed");
3306 return 0;
3307 }
3308 uint64_t bytes_written = response.GetU64(UINT64_MAX);
3309 if (bytes_written == UINT64_MAX)
3310 {
3311 error.SetErrorToGenericError();
3312 if (response.GetChar() == ',')
3313 {
3314 int response_errno = response.GetS32(-1);
3315 if (response_errno > 0)
3316 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3317 }
3318 return 0;
3319 }
3320 return bytes_written;
3321 }
3322 else
3323 {
3324 error.SetErrorString ("failed to send vFile:pwrite packet");
3325 }
3326 return 0;
3327}
3328
Greg Claytonfbb76342013-11-20 21:07:01 +00003329Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003330GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, const FileSpec &dst)
Greg Claytonfbb76342013-11-20 21:07:01 +00003331{
Chaoren Lind3173f32015-05-29 19:52:29 +00003332 std::string src_path{src.GetPath(false)},
3333 dst_path{dst.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003334 Error error;
3335 lldb_private::StreamGDBRemote stream;
3336 stream.PutCString("vFile:symlink:");
3337 // the unix symlink() command reverses its parameters where the dst if first,
3338 // so we follow suit here
Chaoren Lind3173f32015-05-29 19:52:29 +00003339 stream.PutCStringAsRawHex8(dst_path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003340 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003341 stream.PutCStringAsRawHex8(src_path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003342 const char* packet = stream.GetData();
3343 int packet_len = stream.GetSize();
3344 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003345 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00003346 {
3347 if (response.GetChar() == 'F')
3348 {
3349 uint32_t result = response.GetU32(UINT32_MAX);
3350 if (result != 0)
3351 {
3352 error.SetErrorToGenericError();
3353 if (response.GetChar() == ',')
3354 {
3355 int response_errno = response.GetS32(-1);
3356 if (response_errno > 0)
3357 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3358 }
3359 }
3360 }
3361 else
3362 {
3363 // Should have returned with 'F<result>[,<errno>]'
3364 error.SetErrorStringWithFormat("symlink failed");
3365 }
3366 }
3367 else
3368 {
3369 error.SetErrorString ("failed to send vFile:symlink packet");
3370 }
3371 return error;
3372}
3373
3374Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003375GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec)
Greg Claytonfbb76342013-11-20 21:07:01 +00003376{
Chaoren Lind3173f32015-05-29 19:52:29 +00003377 std::string path{file_spec.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003378 Error error;
3379 lldb_private::StreamGDBRemote stream;
3380 stream.PutCString("vFile:unlink:");
3381 // the unix symlink() command reverses its parameters where the dst if first,
3382 // so we follow suit here
Chaoren Lind3173f32015-05-29 19:52:29 +00003383 stream.PutCStringAsRawHex8(path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003384 const char* packet = stream.GetData();
3385 int packet_len = stream.GetSize();
3386 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003387 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00003388 {
3389 if (response.GetChar() == 'F')
3390 {
3391 uint32_t result = response.GetU32(UINT32_MAX);
3392 if (result != 0)
3393 {
3394 error.SetErrorToGenericError();
3395 if (response.GetChar() == ',')
3396 {
3397 int response_errno = response.GetS32(-1);
3398 if (response_errno > 0)
3399 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3400 }
3401 }
3402 }
3403 else
3404 {
3405 // Should have returned with 'F<result>[,<errno>]'
3406 error.SetErrorStringWithFormat("unlink failed");
3407 }
3408 }
3409 else
3410 {
3411 error.SetErrorString ("failed to send vFile:unlink packet");
3412 }
3413 return error;
3414}
3415
Daniel Maleae0f8f572013-08-26 23:57:52 +00003416// Extension of host I/O packets to get whether a file exists.
3417bool
3418GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
3419{
Chaoren Lind3173f32015-05-29 19:52:29 +00003420 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003421 lldb_private::StreamString stream;
3422 stream.PutCString("vFile:exists:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003423 stream.PutCStringAsRawHex8(path.c_str());
3424 const char* packet = stream.GetData();
3425 int packet_len = stream.GetSize();
3426 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003427 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003428 {
3429 if (response.GetChar() != 'F')
3430 return false;
3431 if (response.GetChar() != ',')
3432 return false;
3433 bool retcode = (response.GetChar() != '0');
3434 return retcode;
3435 }
3436 return false;
3437}
3438
3439bool
3440GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
3441 uint64_t &high,
3442 uint64_t &low)
3443{
Chaoren Lind3173f32015-05-29 19:52:29 +00003444 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003445 lldb_private::StreamString stream;
3446 stream.PutCString("vFile:MD5:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003447 stream.PutCStringAsRawHex8(path.c_str());
3448 const char* packet = stream.GetData();
3449 int packet_len = stream.GetSize();
3450 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003451 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003452 {
3453 if (response.GetChar() != 'F')
3454 return false;
3455 if (response.GetChar() != ',')
3456 return false;
3457 if (response.Peek() && *response.Peek() == 'x')
3458 return false;
3459 low = response.GetHexMaxU64(false, UINT64_MAX);
3460 high = response.GetHexMaxU64(false, UINT64_MAX);
3461 return true;
3462 }
3463 return false;
3464}
Greg Claytonf74cf862013-11-13 23:28:31 +00003465
3466bool
Jason Molendaa3329782014-03-29 18:54:20 +00003467GDBRemoteCommunicationClient::AvoidGPackets (ProcessGDBRemote *process)
3468{
3469 // Some targets have issues with g/G packets and we need to avoid using them
3470 if (m_avoid_g_packets == eLazyBoolCalculate)
3471 {
3472 if (process)
3473 {
3474 m_avoid_g_packets = eLazyBoolNo;
3475 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3476 if (arch.IsValid()
3477 && arch.GetTriple().getVendor() == llvm::Triple::Apple
3478 && arch.GetTriple().getOS() == llvm::Triple::IOS
Todd Fialad8eaa172014-07-23 14:37:35 +00003479 && arch.GetTriple().getArch() == llvm::Triple::aarch64)
Jason Molendaa3329782014-03-29 18:54:20 +00003480 {
3481 m_avoid_g_packets = eLazyBoolYes;
3482 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3483 if (gdb_server_version != 0)
3484 {
3485 const char *gdb_server_name = GetGDBServerProgramName();
3486 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0)
3487 {
3488 if (gdb_server_version >= 310)
3489 m_avoid_g_packets = eLazyBoolNo;
3490 }
3491 }
3492 }
3493 }
3494 }
3495 return m_avoid_g_packets == eLazyBoolYes;
3496}
3497
Pavel Labathb42b48e2016-08-19 12:31:49 +00003498DataBufferSP
3499GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg)
Greg Claytonf74cf862013-11-13 23:28:31 +00003500{
Pavel Labath4b6f9592016-08-18 08:30:03 +00003501 StreamString payload;
3502 payload.Printf("p%x", reg);
Pavel Labathb42b48e2016-08-19 12:31:49 +00003503 StringExtractorGDBRemote response;
3504 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success ||
3505 !response.IsNormalResponse())
3506 return nullptr;
3507
3508 DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3509 response.GetHexBytes(buffer_sp->GetBytes(), buffer_sp->GetByteSize(), '\xcc');
3510 return buffer_sp;
Greg Claytonf74cf862013-11-13 23:28:31 +00003511}
3512
Pavel Labathb42b48e2016-08-19 12:31:49 +00003513DataBufferSP
3514GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid)
Greg Claytonf74cf862013-11-13 23:28:31 +00003515{
Pavel Labath4b6f9592016-08-18 08:30:03 +00003516 StreamString payload;
3517 payload.PutChar('g');
Pavel Labathb42b48e2016-08-19 12:31:49 +00003518 StringExtractorGDBRemote response;
3519 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success ||
3520 !response.IsNormalResponse())
3521 return nullptr;
3522
3523 DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3524 response.GetHexBytes(buffer_sp->GetBytes(), buffer_sp->GetByteSize(), '\xcc');
3525 return buffer_sp;
Greg Claytonf74cf862013-11-13 23:28:31 +00003526}
Pavel Labath56d72622016-08-17 08:53:31 +00003527
3528bool
Pavel Labathb42b48e2016-08-19 12:31:49 +00003529GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef<uint8_t> data)
Pavel Labath56d72622016-08-17 08:53:31 +00003530{
Pavel Labath4b6f9592016-08-18 08:30:03 +00003531 StreamString payload;
3532 payload.Printf("P%x=", reg_num);
3533 payload.PutBytesAsRawHex8(data.data(), data.size(), endian::InlHostByteOrder(), endian::InlHostByteOrder());
Pavel Labath56d72622016-08-17 08:53:31 +00003534 StringExtractorGDBRemote response;
Pavel Labath4b6f9592016-08-18 08:30:03 +00003535 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) ==
Pavel Labathb42b48e2016-08-19 12:31:49 +00003536 PacketResult::Success &&
3537 response.IsOKResponse();
Pavel Labath56d72622016-08-17 08:53:31 +00003538}
3539
3540bool
Pavel Labathb42b48e2016-08-19 12:31:49 +00003541GDBRemoteCommunicationClient::WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data)
Pavel Labath56d72622016-08-17 08:53:31 +00003542{
Pavel Labath4b6f9592016-08-18 08:30:03 +00003543 StreamString payload;
3544 payload.PutChar('G');
Pavel Labathb42b48e2016-08-19 12:31:49 +00003545 payload.PutBytesAsRawHex8(data.data(), data.size(), endian::InlHostByteOrder(), endian::InlHostByteOrder());
Pavel Labath56d72622016-08-17 08:53:31 +00003546 StringExtractorGDBRemote response;
Pavel Labath4b6f9592016-08-18 08:30:03 +00003547 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) ==
Pavel Labathb42b48e2016-08-19 12:31:49 +00003548 PacketResult::Success &&
3549 response.IsOKResponse();
Pavel Labath56d72622016-08-17 08:53:31 +00003550}
3551
Greg Claytonf74cf862013-11-13 23:28:31 +00003552bool
3553GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
3554{
3555 save_id = 0; // Set to invalid save ID
3556 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3557 return false;
3558
3559 m_supports_QSaveRegisterState = eLazyBoolYes;
Pavel Labath4b6f9592016-08-18 08:30:03 +00003560 StreamString payload;
3561 payload.PutCString("QSaveRegisterState");
3562 StringExtractorGDBRemote response;
3563 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success)
3564 return false;
Greg Claytonf74cf862013-11-13 23:28:31 +00003565
Pavel Labath4b6f9592016-08-18 08:30:03 +00003566 if (response.IsUnsupportedResponse())
3567 m_supports_QSaveRegisterState = eLazyBoolNo;
3568
3569 const uint32_t response_save_id = response.GetU32(0);
3570 if (response_save_id == 0)
3571 return false;
3572
3573 save_id = response_save_id;
3574 return true;
Greg Claytonf74cf862013-11-13 23:28:31 +00003575}
3576
3577bool
3578GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
3579{
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003580 // We use the "m_supports_QSaveRegisterState" variable here because the
Greg Claytonf74cf862013-11-13 23:28:31 +00003581 // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
3582 // order to be useful
3583 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3584 return false;
Saleem Abdulrasool2d6a9ec2016-07-28 17:32:20 +00003585
Pavel Labath4b6f9592016-08-18 08:30:03 +00003586 StreamString payload;
3587 payload.Printf("QRestoreRegisterState:%u", save_id);
3588 StringExtractorGDBRemote response;
3589 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success)
3590 return false;
3591
3592 if (response.IsOKResponse())
3593 return true;
3594
3595 if (response.IsUnsupportedResponse())
3596 m_supports_QSaveRegisterState = eLazyBoolNo;
Greg Claytonf74cf862013-11-13 23:28:31 +00003597 return false;
3598}
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003599
3600bool
Pavel Labath27402d22016-08-18 12:32:41 +00003601GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid)
3602{
3603 if (!GetSyncThreadStateSupported())
3604 return false;
3605
3606 StreamString packet;
3607 StringExtractorGDBRemote response;
3608 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3609 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
3610 GDBRemoteCommunication::PacketResult::Success &&
3611 response.IsOKResponse();
3612}
3613
3614bool
3615GDBRemoteCommunicationClient::GetModuleInfo(const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3616 ModuleSpec &module_spec)
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003617{
Stephane Sezer6f455292016-01-08 00:00:17 +00003618 if (!m_supports_qModuleInfo)
3619 return false;
3620
Oleksiy Vyalov7d9d9412015-04-16 07:02:56 +00003621 std::string module_path = module_file_spec.GetPath (false);
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003622 if (module_path.empty ())
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003623 return false;
3624
3625 StreamString packet;
3626 packet.PutCString("qModuleInfo:");
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003627 packet.PutCStringAsRawHex8(module_path.c_str());
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003628 packet.PutCString(";");
Chaoren Linf34f4102015-05-09 01:21:32 +00003629 const auto& triple = arch_spec.GetTriple().getTriple();
Chaoren Lind3173f32015-05-29 19:52:29 +00003630 packet.PutCStringAsRawHex8(triple.c_str());
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003631
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003632 StringExtractorGDBRemote response;
3633 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success)
3634 return false;
3635
Stephane Sezer6f455292016-01-08 00:00:17 +00003636 if (response.IsErrorResponse ())
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003637 return false;
3638
Stephane Sezer6f455292016-01-08 00:00:17 +00003639 if (response.IsUnsupportedResponse ())
3640 {
3641 m_supports_qModuleInfo = false;
3642 return false;
3643 }
3644
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003645 std::string name;
3646 std::string value;
3647 bool success;
3648 StringExtractor extractor;
3649
3650 module_spec.Clear ();
3651 module_spec.GetFileSpec () = module_file_spec;
3652
3653 while (response.GetNameColonValue (name, value))
3654 {
3655 if (name == "uuid" || name == "md5")
3656 {
3657 extractor.GetStringRef ().swap (value);
3658 extractor.SetFilePos (0);
3659 extractor.GetHexByteString (value);
3660 module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2);
3661 }
3662 else if (name == "triple")
3663 {
3664 extractor.GetStringRef ().swap (value);
3665 extractor.SetFilePos (0);
3666 extractor.GetHexByteString (value);
3667 module_spec.GetArchitecture().SetTriple (value.c_str ());
3668 }
3669 else if (name == "file_offset")
3670 {
3671 const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
3672 if (success)
3673 module_spec.SetObjectOffset (ival);
3674 }
3675 else if (name == "file_size")
3676 {
3677 const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
3678 if (success)
3679 module_spec.SetObjectSize (ival);
3680 }
3681 else if (name == "file_path")
3682 {
3683 extractor.GetStringRef ().swap (value);
3684 extractor.SetFilePos (0);
3685 extractor.GetHexByteString (value);
Chaoren Linf34f4102015-05-09 01:21:32 +00003686 module_spec.GetFileSpec() = FileSpec(value.c_str(), false, arch_spec);
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003687 }
3688 }
3689
3690 return true;
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003691}
Colin Rileyc3c95b22015-04-16 15:51:33 +00003692
3693// query the target remote for extended information using the qXfer packet
3694//
3695// example: object='features', annex='target.xml', out=<xml output>
3696// return: 'true' on success
3697// 'false' on failure (err set)
3698bool
3699GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString object,
3700 const lldb_private::ConstString annex,
3701 std::string & out,
3702 lldb_private::Error & err) {
3703
3704 std::stringstream output;
3705 StringExtractorGDBRemote chunk;
3706
Greg Claytond04f0ed2015-05-26 18:00:51 +00003707 uint64_t size = GetRemoteMaxPacketSize();
3708 if (size == 0)
3709 size = 0x1000;
3710 size = size - 1; // Leave space for the 'm' or 'l' character in the response
3711 int offset = 0;
3712 bool active = true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003713
3714 // loop until all data has been read
3715 while ( active ) {
3716
3717 // send query extended feature packet
3718 std::stringstream packet;
3719 packet << "qXfer:"
Ewan Crawford682e8422015-06-26 09:38:27 +00003720 << object.AsCString("") << ":read:"
3721 << annex.AsCString("") << ":"
Colin Rileyc3c95b22015-04-16 15:51:33 +00003722 << std::hex << offset << ","
3723 << std::hex << size;
3724
3725 GDBRemoteCommunication::PacketResult res =
3726 SendPacketAndWaitForResponse( packet.str().c_str(),
3727 chunk,
3728 false );
3729
3730 if ( res != GDBRemoteCommunication::PacketResult::Success ) {
3731 err.SetErrorString( "Error sending $qXfer packet" );
3732 return false;
3733 }
3734
3735 const std::string & str = chunk.GetStringRef( );
3736 if ( str.length() == 0 ) {
3737 // should have some data in chunk
3738 err.SetErrorString( "Empty response from $qXfer packet" );
3739 return false;
3740 }
3741
3742 // check packet code
3743 switch ( str[0] ) {
3744 // last chunk
3745 case ( 'l' ):
3746 active = false;
Jason Molenda62e06812016-02-16 04:14:33 +00003747 LLVM_FALLTHROUGH;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003748
3749 // more chunks
3750 case ( 'm' ) :
3751 if ( str.length() > 1 )
3752 output << &str[1];
Aidan Doddsed9f6122015-04-29 10:08:17 +00003753 offset += size;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003754 break;
3755
3756 // unknown chunk
3757 default:
3758 err.SetErrorString( "Invalid continuation code from $qXfer packet" );
3759 return false;
3760 }
3761 }
3762
3763 out = output.str( );
3764 err.Success( );
3765 return true;
3766}
Greg Clayton0b90be12015-06-23 21:27:50 +00003767
3768// Notify the target that gdb is prepared to serve symbol lookup requests.
3769// packet: "qSymbol::"
3770// reply:
3771// OK The target does not need to look up any (more) symbols.
3772// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex encoded).
3773// LLDB may provide the value by sending another qSymbol packet
3774// in the form of"qSymbol:<sym_value>:<sym_name>".
Jason Molenda50018d32016-01-13 04:08:10 +00003775//
3776// Three examples:
3777//
3778// lldb sends: qSymbol::
3779// lldb receives: OK
3780// Remote gdb stub does not need to know the addresses of any symbols, lldb does not
3781// need to ask again in this session.
3782//
3783// lldb sends: qSymbol::
3784// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3785// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
3786// lldb receives: OK
3787// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does not know
3788// the address at this time. lldb needs to send qSymbol:: again when it has more
3789// solibs loaded.
3790//
3791// lldb sends: qSymbol::
3792// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3793// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
3794// lldb receives: OK
3795// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says that it
3796// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it does not
3797// need any more symbols. lldb does not need to ask again in this session.
Greg Clayton0b90be12015-06-23 21:27:50 +00003798
3799void
3800GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
3801{
Jason Molenda50018d32016-01-13 04:08:10 +00003802 // Set to true once we've resolved a symbol to an address for the remote stub.
3803 // If we get an 'OK' response after this, the remote stub doesn't need any more
3804 // symbols and we can stop asking.
3805 bool symbol_response_provided = false;
3806
Ed Maste75500e72016-07-19 15:28:02 +00003807 // Is this the initial qSymbol:: packet?
Jason Molenda50018d32016-01-13 04:08:10 +00003808 bool first_qsymbol_query = true;
3809
3810 if (m_supports_qSymbol && m_qSymbol_requests_done == false)
Greg Clayton0b90be12015-06-23 21:27:50 +00003811 {
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00003812 Lock lock(*this, false);
3813 if (lock)
Greg Clayton0b90be12015-06-23 21:27:50 +00003814 {
3815 StreamString packet;
3816 packet.PutCString ("qSymbol::");
Greg Clayton42b01482015-08-11 22:07:46 +00003817 StringExtractorGDBRemote response;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00003818 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) == PacketResult::Success)
Greg Clayton0b90be12015-06-23 21:27:50 +00003819 {
Greg Clayton42b01482015-08-11 22:07:46 +00003820 if (response.IsOKResponse())
Greg Clayton0b90be12015-06-23 21:27:50 +00003821 {
Jason Molenda50018d32016-01-13 04:08:10 +00003822 if (symbol_response_provided || first_qsymbol_query)
3823 {
3824 m_qSymbol_requests_done = true;
3825 }
3826
Greg Clayton42b01482015-08-11 22:07:46 +00003827 // We are done serving symbols requests
3828 return;
3829 }
Jason Molenda50018d32016-01-13 04:08:10 +00003830 first_qsymbol_query = false;
Greg Clayton0b90be12015-06-23 21:27:50 +00003831
Greg Clayton42b01482015-08-11 22:07:46 +00003832 if (response.IsUnsupportedResponse())
3833 {
3834 // qSymbol is not supported by the current GDB server we are connected to
3835 m_supports_qSymbol = false;
3836 return;
3837 }
3838 else
3839 {
3840 llvm::StringRef response_str(response.GetStringRef());
3841 if (response_str.startswith("qSymbol:"))
Greg Clayton0b90be12015-06-23 21:27:50 +00003842 {
Greg Clayton42b01482015-08-11 22:07:46 +00003843 response.SetFilePos(strlen("qSymbol:"));
3844 std::string symbol_name;
3845 if (response.GetHexByteString(symbol_name))
Greg Clayton0b90be12015-06-23 21:27:50 +00003846 {
Greg Clayton42b01482015-08-11 22:07:46 +00003847 if (symbol_name.empty())
3848 return;
3849
3850 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
3851 lldb_private::SymbolContextList sc_list;
3852 if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list))
Greg Clayton0b90be12015-06-23 21:27:50 +00003853 {
Greg Clayton42b01482015-08-11 22:07:46 +00003854 const size_t num_scs = sc_list.GetSize();
3855 for (size_t sc_idx=0; sc_idx<num_scs && symbol_load_addr == LLDB_INVALID_ADDRESS; ++sc_idx)
Greg Clayton0b90be12015-06-23 21:27:50 +00003856 {
Greg Clayton42b01482015-08-11 22:07:46 +00003857 SymbolContext sc;
3858 if (sc_list.GetContextAtIndex(sc_idx, sc))
Greg Clayton0b90be12015-06-23 21:27:50 +00003859 {
Greg Clayton42b01482015-08-11 22:07:46 +00003860 if (sc.symbol)
Greg Clayton358cf1e2015-06-25 21:46:34 +00003861 {
Greg Clayton42b01482015-08-11 22:07:46 +00003862 switch (sc.symbol->GetType())
Greg Clayton358cf1e2015-06-25 21:46:34 +00003863 {
Greg Clayton42b01482015-08-11 22:07:46 +00003864 case eSymbolTypeInvalid:
3865 case eSymbolTypeAbsolute:
3866 case eSymbolTypeUndefined:
3867 case eSymbolTypeSourceFile:
3868 case eSymbolTypeHeaderFile:
3869 case eSymbolTypeObjectFile:
3870 case eSymbolTypeCommonBlock:
3871 case eSymbolTypeBlock:
3872 case eSymbolTypeLocal:
3873 case eSymbolTypeParam:
3874 case eSymbolTypeVariable:
3875 case eSymbolTypeVariableType:
3876 case eSymbolTypeLineEntry:
3877 case eSymbolTypeLineHeader:
3878 case eSymbolTypeScopeBegin:
3879 case eSymbolTypeScopeEnd:
3880 case eSymbolTypeAdditional:
3881 case eSymbolTypeCompiler:
3882 case eSymbolTypeInstrumentation:
3883 case eSymbolTypeTrampoline:
3884 break;
Greg Clayton358cf1e2015-06-25 21:46:34 +00003885
Greg Clayton42b01482015-08-11 22:07:46 +00003886 case eSymbolTypeCode:
3887 case eSymbolTypeResolver:
3888 case eSymbolTypeData:
3889 case eSymbolTypeRuntime:
3890 case eSymbolTypeException:
3891 case eSymbolTypeObjCClass:
3892 case eSymbolTypeObjCMetaClass:
3893 case eSymbolTypeObjCIVar:
3894 case eSymbolTypeReExported:
3895 symbol_load_addr = sc.symbol->GetLoadAddress(&process->GetTarget());
3896 break;
Greg Clayton358cf1e2015-06-25 21:46:34 +00003897 }
3898 }
Greg Clayton0b90be12015-06-23 21:27:50 +00003899 }
3900 }
Greg Clayton0b90be12015-06-23 21:27:50 +00003901 }
Greg Clayton42b01482015-08-11 22:07:46 +00003902 // This is the normal path where our symbol lookup was successful and we want
3903 // to send a packet with the new symbol value and see if another lookup needs to be
3904 // done.
3905
3906 // Change "packet" to contain the requested symbol value and name
3907 packet.Clear();
3908 packet.PutCString("qSymbol:");
3909 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
Jason Molenda50018d32016-01-13 04:08:10 +00003910 {
Greg Clayton42b01482015-08-11 22:07:46 +00003911 packet.Printf("%" PRIx64, symbol_load_addr);
Jason Molenda50018d32016-01-13 04:08:10 +00003912 symbol_response_provided = true;
3913 }
3914 else
3915 {
3916 symbol_response_provided = false;
3917 }
Greg Clayton42b01482015-08-11 22:07:46 +00003918 packet.PutCString(":");
3919 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
3920 continue; // go back to the while loop and send "packet" and wait for another response
Greg Clayton0b90be12015-06-23 21:27:50 +00003921 }
3922 }
3923 }
3924 }
3925 // If we make it here, the symbol request packet response wasn't valid or
3926 // our symbol lookup failed so we must abort
3927 return;
3928
3929 }
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00003930 else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
3931 {
3932 log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.", __FUNCTION__);
3933 }
Greg Clayton0b90be12015-06-23 21:27:50 +00003934 }
3935}
3936
Todd Fiala75930012016-08-19 04:21:48 +00003937StructuredData::Array*
3938GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins()
3939{
3940 if (!m_supported_async_json_packets_is_valid)
3941 {
3942 // Query the server for the array of supported asynchronous JSON
3943 // packets.
3944 m_supported_async_json_packets_is_valid = true;
3945
3946 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
3947 GDBR_LOG_PROCESS));
3948
3949 // Poll it now.
3950 StringExtractorGDBRemote response;
3951 const bool send_async = false;
3952 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
3953 send_async) == PacketResult::Success)
3954 {
3955 m_supported_async_json_packets_sp = StructuredData::ParseJSON(
3956 response.GetStringRef());
3957 if (m_supported_async_json_packets_sp &&
3958 !m_supported_async_json_packets_sp->GetAsArray())
3959 {
3960 // We were returned something other than a JSON array. This
3961 // is invalid. Clear it out.
3962 if (log)
3963 log->Printf("GDBRemoteCommunicationClient::%s(): "
3964 "QSupportedAsyncJSONPackets returned invalid "
3965 "result: %s", __FUNCTION__,
3966 response.GetStringRef().c_str());
3967 m_supported_async_json_packets_sp.reset();
3968 }
3969 }
3970 else
3971 {
3972 if (log)
3973 log->Printf("GDBRemoteCommunicationClient::%s(): "
3974 "QSupportedAsyncJSONPackets unsupported",
3975 __FUNCTION__);
3976 }
3977
Pavel Labath849cc1a2016-08-23 12:10:09 +00003978 if (log && m_supported_async_json_packets_sp)
Todd Fiala75930012016-08-19 04:21:48 +00003979 {
3980 StreamString stream;
3981 m_supported_async_json_packets_sp->Dump(stream);
3982 log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
3983 "JSON packets: %s", __FUNCTION__,
3984 stream.GetString().c_str());
3985 }
3986 }
3987
3988 return m_supported_async_json_packets_sp
3989 ? m_supported_async_json_packets_sp->GetAsArray()
3990 : nullptr;
3991}
3992
3993Error
3994GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
3995 const ConstString &type_name,
3996 const StructuredData::ObjectSP &config_sp)
3997{
3998 Error error;
3999
4000 if (type_name.GetLength() == 0)
4001 {
4002 error.SetErrorString("invalid type_name argument");
4003 return error;
4004 }
4005
4006 // Build command: Configure{type_name}: serialized config
4007 // data.
4008 StreamGDBRemote stream;
4009 stream.PutCString("QConfigure");
4010 stream.PutCString(type_name.AsCString());
4011 stream.PutChar(':');
4012 if (config_sp)
4013 {
4014 // Gather the plain-text version of the configuration data.
4015 StreamString unescaped_stream;
4016 config_sp->Dump(unescaped_stream);
4017 unescaped_stream.Flush();
4018
4019 // Add it to the stream in escaped fashion.
4020 stream.PutEscapedBytes(unescaped_stream.GetData(),
4021 unescaped_stream.GetSize());
4022 }
4023 stream.Flush();
4024
4025 // Send the packet.
4026 const bool send_async = false;
4027 StringExtractorGDBRemote response;
4028 auto result = SendPacketAndWaitForResponse(stream.GetString().c_str(),
4029 response, send_async);
4030 if (result == PacketResult::Success)
4031 {
4032 // We failed if the config result comes back other than OK.
4033 if (strcmp(response.GetStringRef().c_str(), "OK") == 0)
4034 {
4035 // Okay!
4036 error.Clear();
4037 }
4038 else
4039 {
4040 error.SetErrorStringWithFormat("configuring StructuredData feature "
4041 "%s failed with error %s",
4042 type_name.AsCString(),
4043 response.GetStringRef().c_str());
4044 }
4045 }
4046 else
4047 {
4048 // Can we get more data here on the failure?
4049 error.SetErrorStringWithFormat("configuring StructuredData feature %s "
4050 "failed when sending packet: "
4051 "PacketResult=%d", type_name.AsCString(),
4052 result);
4053 }
4054 return error;
4055}
4056
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00004057void
4058GDBRemoteCommunicationClient::OnRunPacketSent(bool first)
4059{
4060 GDBRemoteClientBase::OnRunPacketSent(first);
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00004061 m_curr_tid = LLDB_INVALID_THREAD_ID;
4062}