blob: f0cce2c0e871e99289f7b1e0f7f8be092a70a073 [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
Saleem Abdulrasool28606952014-06-27 05:17:41 +000022#include "llvm/ADT/STLExtras.h"
Greg Clayton576d8832011-03-22 04:00:09 +000023#include "llvm/ADT/Triple.h"
24#include "lldb/Interpreter/Args.h"
Greg Clayton576d8832011-03-22 04:00:09 +000025#include "lldb/Core/Log.h"
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +000026#include "lldb/Core/ModuleSpec.h"
Greg Clayton576d8832011-03-22 04:00:09 +000027#include "lldb/Core/State.h"
Daniel Maleae0f8f572013-08-26 23:57:52 +000028#include "lldb/Core/StreamGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000029#include "lldb/Core/StreamString.h"
Zachary Turner93a66fc2014-10-06 21:22:36 +000030#include "lldb/Host/ConnectionFileDescriptor.h"
Greg Clayton576d8832011-03-22 04:00:09 +000031#include "lldb/Host/Endian.h"
32#include "lldb/Host/Host.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000033#include "lldb/Host/HostInfo.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000034#include "lldb/Host/StringConvert.h"
Greg Clayton576d8832011-03-22 04:00:09 +000035#include "lldb/Host/TimeValue.h"
Greg Clayton0b90be12015-06-23 21:27:50 +000036#include "lldb/Symbol/Symbol.h"
Jason Molendaa3329782014-03-29 18:54:20 +000037#include "lldb/Target/Target.h"
Zachary Turner93749ab2015-03-03 21:51:25 +000038#include "lldb/Target/MemoryRegionInfo.h"
Oleksiy Vyalov755d58a2015-05-22 23:14:39 +000039#include "lldb/Target/UnixSignals.h"
Greg Clayton576d8832011-03-22 04:00:09 +000040
41// Project includes
42#include "Utility/StringExtractorGDBRemote.h"
43#include "ProcessGDBRemote.h"
44#include "ProcessGDBRemoteLog.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000045#include "lldb/Host/Config.h"
Greg Clayton576d8832011-03-22 04:00:09 +000046
Jason Molenda91ffe0a2015-06-18 21:46:06 +000047#if defined (HAVE_LIBCOMPRESSION)
48#include <compression.h>
49#endif
50
Greg Clayton576d8832011-03-22 04:00:09 +000051using namespace lldb;
52using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000053using namespace lldb_private::process_gdb_remote;
Greg Clayton576d8832011-03-22 04:00:09 +000054
55//----------------------------------------------------------------------
56// GDBRemoteCommunicationClient constructor
57//----------------------------------------------------------------------
Tamas Berghammere13c2732015-02-11 10:29:30 +000058GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
59 GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
Greg Clayton576d8832011-03-22 04:00:09 +000060 m_supports_not_sending_acks (eLazyBoolCalculate),
61 m_supports_thread_suffix (eLazyBoolCalculate),
Greg Clayton44633992012-04-10 03:22:03 +000062 m_supports_threads_in_stop_reply (eLazyBoolCalculate),
Greg Clayton576d8832011-03-22 04:00:09 +000063 m_supports_vCont_all (eLazyBoolCalculate),
64 m_supports_vCont_any (eLazyBoolCalculate),
65 m_supports_vCont_c (eLazyBoolCalculate),
66 m_supports_vCont_C (eLazyBoolCalculate),
67 m_supports_vCont_s (eLazyBoolCalculate),
68 m_supports_vCont_S (eLazyBoolCalculate),
Greg Clayton32e0a752011-03-30 18:16:51 +000069 m_qHostInfo_is_valid (eLazyBoolCalculate),
Todd Fiala9f72b3a2014-05-07 19:28:21 +000070 m_curr_pid_is_valid (eLazyBoolCalculate),
Jason Molendaf17b5ac2012-12-19 02:54:03 +000071 m_qProcessInfo_is_valid (eLazyBoolCalculate),
Jason Molendaa3329782014-03-29 18:54:20 +000072 m_qGDBServerVersion_is_valid (eLazyBoolCalculate),
Greg Clayton70b57652011-05-15 01:25:55 +000073 m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
Greg Clayton46fb5582011-11-18 07:03:08 +000074 m_supports_memory_region_info (eLazyBoolCalculate),
Johnny Chen64637202012-05-23 21:09:52 +000075 m_supports_watchpoint_support_info (eLazyBoolCalculate),
Jim Inghamacff8952013-05-02 00:27:30 +000076 m_supports_detach_stay_stopped (eLazyBoolCalculate),
Enrico Granataf04a2192012-07-13 23:18:48 +000077 m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
Jim Inghamcd16df92012-07-20 21:37:13 +000078 m_attach_or_wait_reply(eLazyBoolCalculate),
Jim Ingham279ceec2012-07-25 21:12:43 +000079 m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
Eric Christopher2490f5c2013-08-30 17:50:57 +000080 m_supports_p (eLazyBoolCalculate),
Jason Molendabdc4f122014-05-06 02:59:39 +000081 m_supports_x (eLazyBoolCalculate),
Jason Molendaa3329782014-03-29 18:54:20 +000082 m_avoid_g_packets (eLazyBoolCalculate),
Greg Claytonf74cf862013-11-13 23:28:31 +000083 m_supports_QSaveRegisterState (eLazyBoolCalculate),
Steve Pucci03904ac2014-03-04 23:18:46 +000084 m_supports_qXfer_auxv_read (eLazyBoolCalculate),
Steve Pucci5ae54ae2014-01-25 05:46:51 +000085 m_supports_qXfer_libraries_read (eLazyBoolCalculate),
86 m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate),
Greg Clayton253204e2015-04-16 23:11:06 +000087 m_supports_qXfer_features_read (eLazyBoolCalculate),
Steve Pucci5ae54ae2014-01-25 05:46:51 +000088 m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate),
Jason Molenda705b1802014-06-13 02:37:02 +000089 m_supports_jThreadExtendedInfo (eLazyBoolCalculate),
Greg Clayton32e0a752011-03-30 18:16:51 +000090 m_supports_qProcessInfoPID (true),
91 m_supports_qfProcessInfo (true),
92 m_supports_qUserName (true),
93 m_supports_qGroupName (true),
Greg Clayton8b82f082011-04-12 05:54:46 +000094 m_supports_qThreadStopInfo (true),
95 m_supports_z0 (true),
96 m_supports_z1 (true),
97 m_supports_z2 (true),
98 m_supports_z3 (true),
99 m_supports_z4 (true),
Greg Clayton89600582013-10-10 17:53:50 +0000100 m_supports_QEnvironment (true),
101 m_supports_QEnvironmentHexEncoded (true),
Greg Clayton0b90be12015-06-23 21:27:50 +0000102 m_supports_qSymbol (true),
Greg Clayton358cf1e2015-06-25 21:46:34 +0000103 m_supports_jThreadsInfo (true),
Todd Fiala9f72b3a2014-05-07 19:28:21 +0000104 m_curr_pid (LLDB_INVALID_PROCESS_ID),
Greg Clayton8b82f082011-04-12 05:54:46 +0000105 m_curr_tid (LLDB_INVALID_THREAD_ID),
106 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Johnny Chen64637202012-05-23 21:09:52 +0000107 m_num_supported_hardware_watchpoints (0),
Greg Clayton576d8832011-03-22 04:00:09 +0000108 m_async_mutex (Mutex::eMutexTypeRecursive),
109 m_async_packet_predicate (false),
110 m_async_packet (),
Jim Inghama6195b72013-12-18 01:24:33 +0000111 m_async_result (PacketResult::Success),
Greg Clayton576d8832011-03-22 04:00:09 +0000112 m_async_response (),
113 m_async_signal (-1),
Jim Inghamb8cd5752014-04-16 02:24:17 +0000114 m_interrupt_sent (false),
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000115 m_thread_id_to_used_usec_map (),
Greg Clayton1cb64962011-03-24 04:28:38 +0000116 m_host_arch(),
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000117 m_process_arch(),
Greg Clayton1cb64962011-03-24 04:28:38 +0000118 m_os_version_major (UINT32_MAX),
119 m_os_version_minor (UINT32_MAX),
Greg Clayton9ac6d2d2013-10-25 18:13:17 +0000120 m_os_version_update (UINT32_MAX),
121 m_os_build (),
122 m_os_kernel (),
123 m_hostname (),
Jason Molendaa3329782014-03-29 18:54:20 +0000124 m_gdb_server_name(),
125 m_gdb_server_version(UINT32_MAX),
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000126 m_default_packet_timeout (0),
127 m_max_packet_size (0)
Greg Clayton576d8832011-03-22 04:00:09 +0000128{
Greg Clayton576d8832011-03-22 04:00:09 +0000129}
130
131//----------------------------------------------------------------------
132// Destructor
133//----------------------------------------------------------------------
134GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
135{
Greg Clayton576d8832011-03-22 04:00:09 +0000136 if (IsConnected())
Greg Clayton576d8832011-03-22 04:00:09 +0000137 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000138}
139
140bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000141GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
142{
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000143 ResetDiscoverableSettings(false);
Greg Claytonfb909312013-11-23 01:58:15 +0000144
Greg Clayton1cb64962011-03-24 04:28:38 +0000145 // Start the read thread after we send the handshake ack since if we
146 // fail to send the handshake ack, there is no reason to continue...
147 if (SendAck())
Greg Claytonfb909312013-11-23 01:58:15 +0000148 {
Ed Maste48f986f2013-12-18 15:31:45 +0000149 // Wait for any responses that might have been queued up in the remote
150 // GDB server and flush them all
151 StringExtractorGDBRemote response;
152 PacketResult packet_result = PacketResult::Success;
153 const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response
154 while (packet_result == PacketResult::Success)
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000155 packet_result = ReadPacket (response, timeout_usec, false);
Ed Maste48f986f2013-12-18 15:31:45 +0000156
Greg Claytonfb909312013-11-23 01:58:15 +0000157 // The return value from QueryNoAckModeSupported() is true if the packet
158 // was sent and _any_ response (including UNIMPLEMENTED) was received),
159 // or false if no response was received. This quickly tells us if we have
160 // a live connection to a remote GDB server...
161 if (QueryNoAckModeSupported())
162 {
163 return true;
164 }
165 else
166 {
167 if (error_ptr)
168 error_ptr->SetErrorString("failed to get reply to handshake packet");
169 }
170 }
171 else
172 {
173 if (error_ptr)
174 error_ptr->SetErrorString("failed to send the handshake ack");
175 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000176 return false;
177}
178
Greg Claytonfb909312013-11-23 01:58:15 +0000179bool
Greg Claytonb30c50c2015-05-29 00:01:55 +0000180GDBRemoteCommunicationClient::GetEchoSupported ()
181{
182 if (m_supports_qEcho == eLazyBoolCalculate)
183 {
184 GetRemoteQSupported();
185 }
186 return m_supports_qEcho == eLazyBoolYes;
187}
188
189
190bool
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000191GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
192{
193 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
194 {
195 GetRemoteQSupported();
196 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000197 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000198}
199
200bool
201GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
202{
203 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
204 {
205 GetRemoteQSupported();
206 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000207 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000208}
209
210bool
211GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
212{
213 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
214 {
215 GetRemoteQSupported();
216 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000217 return m_supports_qXfer_libraries_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000218}
219
Steve Pucci03904ac2014-03-04 23:18:46 +0000220bool
221GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
222{
223 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
224 {
225 GetRemoteQSupported();
226 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000227 return m_supports_qXfer_auxv_read == eLazyBoolYes;
Steve Pucci03904ac2014-03-04 23:18:46 +0000228}
229
Colin Rileyc3c95b22015-04-16 15:51:33 +0000230bool
231GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported ()
232{
233 if (m_supports_qXfer_features_read == eLazyBoolCalculate)
234 {
235 GetRemoteQSupported();
236 }
Greg Claytonb30c50c2015-05-29 00:01:55 +0000237 return m_supports_qXfer_features_read == eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000238}
239
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000240uint64_t
241GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
242{
243 if (m_max_packet_size == 0)
244 {
245 GetRemoteQSupported();
246 }
247 return m_max_packet_size;
248}
249
250bool
Greg Clayton1cb64962011-03-24 04:28:38 +0000251GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton576d8832011-03-22 04:00:09 +0000252{
253 if (m_supports_not_sending_acks == eLazyBoolCalculate)
254 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000255 m_send_acks = true;
Greg Clayton576d8832011-03-22 04:00:09 +0000256 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000257
Jason Molenda36a216e2014-07-24 01:36:24 +0000258 // This is the first real packet that we'll send in a debug session and it may take a little
259 // longer than normal to receive a reply. Wait at least 6 seconds for a reply to this packet.
260
261 const uint32_t minimum_timeout = 6;
262 uint32_t old_timeout = GetPacketTimeoutInMicroSeconds() / lldb_private::TimeValue::MicroSecPerSec;
Tamas Berghammer912800c2015-02-24 10:23:39 +0000263 GDBRemoteCommunication::ScopedTimeout timeout (*this, std::max (old_timeout, minimum_timeout));
Jason Molenda36a216e2014-07-24 01:36:24 +0000264
Greg Clayton1cb64962011-03-24 04:28:38 +0000265 StringExtractorGDBRemote response;
Tamas Berghammer912800c2015-02-24 10:23:39 +0000266 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000267 {
268 if (response.IsOKResponse())
Greg Clayton1cb64962011-03-24 04:28:38 +0000269 {
270 m_send_acks = false;
Greg Clayton576d8832011-03-22 04:00:09 +0000271 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton1cb64962011-03-24 04:28:38 +0000272 }
Greg Claytonfb909312013-11-23 01:58:15 +0000273 return true;
Greg Clayton576d8832011-03-22 04:00:09 +0000274 }
275 }
Greg Claytonfb909312013-11-23 01:58:15 +0000276 return false;
Greg Clayton576d8832011-03-22 04:00:09 +0000277}
278
279void
Greg Clayton44633992012-04-10 03:22:03 +0000280GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
281{
282 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
283 {
284 m_supports_threads_in_stop_reply = eLazyBoolNo;
285
286 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000287 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
Greg Clayton44633992012-04-10 03:22:03 +0000288 {
289 if (response.IsOKResponse())
290 m_supports_threads_in_stop_reply = eLazyBoolYes;
291 }
292 }
293}
294
Jim Inghamcd16df92012-07-20 21:37:13 +0000295bool
296GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
297{
298 if (m_attach_or_wait_reply == eLazyBoolCalculate)
299 {
300 m_attach_or_wait_reply = eLazyBoolNo;
301
302 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000303 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
Jim Inghamcd16df92012-07-20 21:37:13 +0000304 {
305 if (response.IsOKResponse())
306 m_attach_or_wait_reply = eLazyBoolYes;
307 }
308 }
309 if (m_attach_or_wait_reply == eLazyBoolYes)
310 return true;
311 else
312 return false;
313}
314
Jim Ingham279ceec2012-07-25 21:12:43 +0000315bool
316GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
317{
318 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
319 {
320 m_prepare_for_reg_writing_reply = eLazyBoolNo;
321
322 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +0000323 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
Jim Ingham279ceec2012-07-25 21:12:43 +0000324 {
325 if (response.IsOKResponse())
326 m_prepare_for_reg_writing_reply = eLazyBoolYes;
327 }
328 }
329 if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
330 return true;
331 else
332 return false;
333}
334
Greg Clayton44633992012-04-10 03:22:03 +0000335
336void
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000337GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
Greg Clayton576d8832011-03-22 04:00:09 +0000338{
Greg Clayton2e59d4f2015-06-29 20:08:51 +0000339 if (did_exec == false)
340 {
341 // Hard reset everything, this is when we first connect to a GDB server
342 m_supports_not_sending_acks = eLazyBoolCalculate;
343 m_supports_thread_suffix = eLazyBoolCalculate;
344 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
345 m_supports_vCont_c = eLazyBoolCalculate;
346 m_supports_vCont_C = eLazyBoolCalculate;
347 m_supports_vCont_s = eLazyBoolCalculate;
348 m_supports_vCont_S = eLazyBoolCalculate;
349 m_supports_p = eLazyBoolCalculate;
350 m_supports_x = eLazyBoolCalculate;
351 m_supports_QSaveRegisterState = eLazyBoolCalculate;
352 m_qHostInfo_is_valid = eLazyBoolCalculate;
353 m_curr_pid_is_valid = eLazyBoolCalculate;
354 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
355 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
356 m_supports_memory_region_info = eLazyBoolCalculate;
357 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
358 m_attach_or_wait_reply = eLazyBoolCalculate;
359 m_avoid_g_packets = eLazyBoolCalculate;
360 m_supports_qXfer_auxv_read = eLazyBoolCalculate;
361 m_supports_qXfer_libraries_read = eLazyBoolCalculate;
362 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
363 m_supports_qXfer_features_read = eLazyBoolCalculate;
364 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
365 m_supports_qProcessInfoPID = true;
366 m_supports_qfProcessInfo = true;
367 m_supports_qUserName = true;
368 m_supports_qGroupName = true;
369 m_supports_qThreadStopInfo = true;
370 m_supports_z0 = true;
371 m_supports_z1 = true;
372 m_supports_z2 = true;
373 m_supports_z3 = true;
374 m_supports_z4 = true;
375 m_supports_QEnvironment = true;
376 m_supports_QEnvironmentHexEncoded = true;
377 m_supports_qSymbol = true;
378 m_host_arch.Clear();
379 m_os_version_major = UINT32_MAX;
380 m_os_version_minor = UINT32_MAX;
381 m_os_version_update = UINT32_MAX;
382 m_os_build.clear();
383 m_os_kernel.clear();
384 m_hostname.clear();
385 m_gdb_server_name.clear();
386 m_gdb_server_version = UINT32_MAX;
387 m_default_packet_timeout = 0;
388 m_max_packet_size = 0;
389 }
390
391 // These flags should be reset when we first connect to a GDB server
392 // and when our inferior process execs
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000393 m_qProcessInfo_is_valid = eLazyBoolCalculate;
Jason Molendaf17b5ac2012-12-19 02:54:03 +0000394 m_process_arch.Clear();
Greg Clayton576d8832011-03-22 04:00:09 +0000395}
396
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000397void
398GDBRemoteCommunicationClient::GetRemoteQSupported ()
399{
400 // Clear out any capabilities we expect to see in the qSupported response
Steve Pucci03904ac2014-03-04 23:18:46 +0000401 m_supports_qXfer_auxv_read = eLazyBoolNo;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000402 m_supports_qXfer_libraries_read = eLazyBoolNo;
Steve Pucci03904ac2014-03-04 23:18:46 +0000403 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000404 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000405 m_supports_qXfer_features_read = eLazyBoolNo;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000406 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if not, we assume no limit
407
Colin Rileyc3c95b22015-04-16 15:51:33 +0000408 // build the qSupported packet
409 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
410 StreamString packet;
411 packet.PutCString( "qSupported" );
412 for ( uint32_t i = 0; i < features.size( ); ++i )
413 {
414 packet.PutCString( i==0 ? ":" : ";");
415 packet.PutCString( features[i].c_str( ) );
416 }
417
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000418 StringExtractorGDBRemote response;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000419 if (SendPacketAndWaitForResponse(packet.GetData(),
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000420 response,
421 /*send_async=*/false) == PacketResult::Success)
422 {
423 const char *response_cstr = response.GetStringRef().c_str();
Steve Pucci03904ac2014-03-04 23:18:46 +0000424 if (::strstr (response_cstr, "qXfer:auxv:read+"))
425 m_supports_qXfer_auxv_read = eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000426 if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
427 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
428 if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
429 {
430 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
431 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
432 }
433 if (::strstr (response_cstr, "qXfer:libraries:read+"))
434 m_supports_qXfer_libraries_read = eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000435 if (::strstr (response_cstr, "qXfer:features:read+"))
436 m_supports_qXfer_features_read = eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000437
Jason Molenda91ffe0a2015-06-18 21:46:06 +0000438
439 // Look for a list of compressions in the features list e.g.
440 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
441 const char *features_list = ::strstr (response_cstr, "qXfer:features:");
442 if (features_list)
443 {
444 const char *compressions = ::strstr (features_list, "SupportedCompressions=");
445 if (compressions)
446 {
447 std::vector<std::string> supported_compressions;
448 compressions += sizeof ("SupportedCompressions=") - 1;
449 const char *end_of_compressions = strchr (compressions, ';');
450 if (end_of_compressions == NULL)
451 {
452 end_of_compressions = strchr (compressions, '\0');
453 }
454 const char *current_compression = compressions;
455 while (current_compression < end_of_compressions)
456 {
457 const char *next_compression_name = strchr (current_compression, ',');
458 const char *end_of_this_word = next_compression_name;
459 if (next_compression_name == NULL || end_of_compressions < next_compression_name)
460 {
461 end_of_this_word = end_of_compressions;
462 }
463
464 if (end_of_this_word)
465 {
466 if (end_of_this_word == current_compression)
467 {
468 current_compression++;
469 }
470 else
471 {
472 std::string this_compression (current_compression, end_of_this_word - current_compression);
473 supported_compressions.push_back (this_compression);
474 current_compression = end_of_this_word + 1;
475 }
476 }
477 else
478 {
479 supported_compressions.push_back (current_compression);
480 current_compression = end_of_compressions;
481 }
482 }
483
484 if (supported_compressions.size() > 0)
485 {
486 MaybeEnableCompression (supported_compressions);
487 }
488 }
489 }
490
Greg Claytonb30c50c2015-05-29 00:01:55 +0000491 if (::strstr (response_cstr, "qEcho"))
492 m_supports_qEcho = eLazyBoolYes;
493 else
494 m_supports_qEcho = eLazyBoolNo;
495
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000496 const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
497 if (packet_size_str)
498 {
499 StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
500 m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
501 if (m_max_packet_size == 0)
502 {
503 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
504 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
505 if (log)
506 log->Printf ("Garbled PacketSize spec in qSupported response");
507 }
508 }
509 }
510}
Greg Clayton576d8832011-03-22 04:00:09 +0000511
512bool
513GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
514{
515 if (m_supports_thread_suffix == eLazyBoolCalculate)
516 {
517 StringExtractorGDBRemote response;
518 m_supports_thread_suffix = eLazyBoolNo;
Greg Clayton3dedae12013-12-06 21:45:27 +0000519 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000520 {
521 if (response.IsOKResponse())
522 m_supports_thread_suffix = eLazyBoolYes;
523 }
524 }
525 return m_supports_thread_suffix;
526}
527bool
528GDBRemoteCommunicationClient::GetVContSupported (char flavor)
529{
530 if (m_supports_vCont_c == eLazyBoolCalculate)
531 {
532 StringExtractorGDBRemote response;
533 m_supports_vCont_any = eLazyBoolNo;
534 m_supports_vCont_all = eLazyBoolNo;
535 m_supports_vCont_c = eLazyBoolNo;
536 m_supports_vCont_C = eLazyBoolNo;
537 m_supports_vCont_s = eLazyBoolNo;
538 m_supports_vCont_S = eLazyBoolNo;
Greg Clayton3dedae12013-12-06 21:45:27 +0000539 if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +0000540 {
541 const char *response_cstr = response.GetStringRef().c_str();
542 if (::strstr (response_cstr, ";c"))
543 m_supports_vCont_c = eLazyBoolYes;
544
545 if (::strstr (response_cstr, ";C"))
546 m_supports_vCont_C = eLazyBoolYes;
547
548 if (::strstr (response_cstr, ";s"))
549 m_supports_vCont_s = eLazyBoolYes;
550
551 if (::strstr (response_cstr, ";S"))
552 m_supports_vCont_S = eLazyBoolYes;
553
554 if (m_supports_vCont_c == eLazyBoolYes &&
555 m_supports_vCont_C == eLazyBoolYes &&
556 m_supports_vCont_s == eLazyBoolYes &&
557 m_supports_vCont_S == eLazyBoolYes)
558 {
559 m_supports_vCont_all = eLazyBoolYes;
560 }
561
562 if (m_supports_vCont_c == eLazyBoolYes ||
563 m_supports_vCont_C == eLazyBoolYes ||
564 m_supports_vCont_s == eLazyBoolYes ||
565 m_supports_vCont_S == eLazyBoolYes)
566 {
567 m_supports_vCont_any = eLazyBoolYes;
568 }
569 }
570 }
571
572 switch (flavor)
573 {
574 case 'a': return m_supports_vCont_any;
575 case 'A': return m_supports_vCont_all;
576 case 'c': return m_supports_vCont_c;
577 case 'C': return m_supports_vCont_C;
578 case 's': return m_supports_vCont_s;
579 case 'S': return m_supports_vCont_S;
580 default: break;
581 }
582 return false;
583}
584
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000585// Check if the target supports 'p' packet. It sends out a 'p'
586// packet and checks the response. A normal packet will tell us
587// that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000588//
589// Takes a valid thread ID because p needs to apply to a thread.
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000590bool
Sean Callananb1de1142013-09-04 23:24:15 +0000591GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000592{
593 if (m_supports_p == eLazyBoolCalculate)
594 {
595 StringExtractorGDBRemote response;
596 m_supports_p = eLazyBoolNo;
Sean Callananb1de1142013-09-04 23:24:15 +0000597 char packet[256];
598 if (GetThreadSuffixSupported())
599 snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
600 else
601 snprintf(packet, sizeof(packet), "p0");
602
Greg Clayton3dedae12013-12-06 21:45:27 +0000603 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000604 {
605 if (response.IsNormalResponse())
606 m_supports_p = eLazyBoolYes;
607 }
608 }
609 return m_supports_p;
610}
Greg Clayton576d8832011-03-22 04:00:09 +0000611
Greg Clayton358cf1e2015-06-25 21:46:34 +0000612StructuredData::ObjectSP
613GDBRemoteCommunicationClient::GetThreadsInfo()
614{
615 // Get information on all threads at one using the "jThreadsInfo" packet
616 StructuredData::ObjectSP object_sp;
617
618 if (m_supports_jThreadsInfo)
619 {
620 StringExtractorGDBRemote response;
621 m_supports_jThreadExtendedInfo = eLazyBoolNo;
622 if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success)
623 {
624 if (response.IsUnsupportedResponse())
625 {
626 m_supports_jThreadsInfo = false;
627 }
628 else if (!response.Empty())
629 {
630 object_sp = StructuredData::ParseJSON (response.GetStringRef());
631 }
632 }
633 }
634 return object_sp;
635}
636
637
Jason Molendabdc4f122014-05-06 02:59:39 +0000638bool
Jason Molenda705b1802014-06-13 02:37:02 +0000639GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported ()
640{
641 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate)
642 {
643 StringExtractorGDBRemote response;
644 m_supports_jThreadExtendedInfo = eLazyBoolNo;
645 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) == PacketResult::Success)
646 {
647 if (response.IsOKResponse())
648 {
649 m_supports_jThreadExtendedInfo = eLazyBoolYes;
650 }
651 }
652 }
653 return m_supports_jThreadExtendedInfo;
654}
655
656bool
Jason Molendabdc4f122014-05-06 02:59:39 +0000657GDBRemoteCommunicationClient::GetxPacketSupported ()
658{
659 if (m_supports_x == eLazyBoolCalculate)
660 {
661 StringExtractorGDBRemote response;
662 m_supports_x = eLazyBoolNo;
663 char packet[256];
664 snprintf (packet, sizeof (packet), "x0,0");
665 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
666 {
667 if (response.IsOKResponse())
668 m_supports_x = eLazyBoolYes;
669 }
670 }
671 return m_supports_x;
672}
673
Greg Clayton3dedae12013-12-06 21:45:27 +0000674GDBRemoteCommunicationClient::PacketResult
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000675GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses
676(
677 const char *payload_prefix,
678 std::string &response_string
679)
680{
681 Mutex::Locker locker;
682 if (!GetSequenceMutex(locker,
683 "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex"))
684 {
685 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
686 if (log)
687 log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'",
688 payload_prefix);
689 return PacketResult::ErrorNoSequenceLock;
690 }
691
692 response_string = "";
693 std::string payload_prefix_str(payload_prefix);
694 unsigned int response_size = 0x1000;
695 if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
696 response_size = GetRemoteMaxPacketSize();
697 }
698
699 for (unsigned int offset = 0; true; offset += response_size)
700 {
701 StringExtractorGDBRemote this_response;
702 // Construct payload
703 char sizeDescriptor[128];
704 snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size);
705 PacketResult result = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(),
706 this_response,
707 /*send_async=*/false);
708 if (result != PacketResult::Success)
709 return result;
710
711 const std::string &this_string = this_response.GetStringRef();
712
713 // Check for m or l as first character; l seems to mean this is the last chunk
714 char first_char = *this_string.c_str();
715 if (first_char != 'm' && first_char != 'l')
716 {
717 return PacketResult::ErrorReplyInvalid;
718 }
Steve Pucci03904ac2014-03-04 23:18:46 +0000719 // Concatenate the result so far (skipping 'm' or 'l')
720 response_string.append(this_string, 1, std::string::npos);
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000721 if (first_char == 'l')
722 // We're done
723 return PacketResult::Success;
724 }
725}
726
727GDBRemoteCommunicationClient::PacketResult
Greg Clayton576d8832011-03-22 04:00:09 +0000728GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
729(
730 const char *payload,
731 StringExtractorGDBRemote &response,
732 bool send_async
733)
734{
735 return SendPacketAndWaitForResponse (payload,
736 ::strlen (payload),
737 response,
738 send_async);
739}
740
Greg Clayton3dedae12013-12-06 21:45:27 +0000741GDBRemoteCommunicationClient::PacketResult
742GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload,
743 size_t payload_length,
744 StringExtractorGDBRemote &response)
745{
746 PacketResult packet_result = SendPacketNoLock (payload, payload_length);
747 if (packet_result == PacketResult::Success)
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000748 packet_result = ReadPacket (response, GetPacketTimeoutInMicroSeconds (), true);
Greg Clayton3dedae12013-12-06 21:45:27 +0000749 return packet_result;
750}
751
752GDBRemoteCommunicationClient::PacketResult
Greg Clayton576d8832011-03-22 04:00:09 +0000753GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
754(
755 const char *payload,
756 size_t payload_length,
757 StringExtractorGDBRemote &response,
758 bool send_async
759)
760{
Greg Clayton3dedae12013-12-06 21:45:27 +0000761 PacketResult packet_result = PacketResult::ErrorSendFailed;
Greg Clayton576d8832011-03-22 04:00:09 +0000762 Mutex::Locker locker;
Greg Clayton5160ce52013-03-27 23:08:40 +0000763 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000764
765 // In order to stop async notifications from being processed in the middle of the
766 // send/recieve sequence Hijack the broadcast. Then rebroadcast any events when we are done.
767 static Listener hijack_listener("lldb.NotifyHijacker");
768 HijackBroadcaster(&hijack_listener, eBroadcastBitGdbReadThreadGotNotify);
769
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000770 if (GetSequenceMutex (locker))
Greg Clayton576d8832011-03-22 04:00:09 +0000771 {
Greg Clayton3dedae12013-12-06 21:45:27 +0000772 packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
Greg Clayton576d8832011-03-22 04:00:09 +0000773 }
774 else
775 {
776 if (send_async)
777 {
Greg Claytond3544052012-05-31 21:24:20 +0000778 if (IsRunning())
Greg Clayton576d8832011-03-22 04:00:09 +0000779 {
Greg Claytond3544052012-05-31 21:24:20 +0000780 Mutex::Locker async_locker (m_async_mutex);
781 m_async_packet.assign(payload, payload_length);
782 m_async_packet_predicate.SetValue (true, eBroadcastNever);
783
784 if (log)
785 log->Printf ("async: async packet = %s", m_async_packet.c_str());
786
787 bool timed_out = false;
788 if (SendInterrupt(locker, 2, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +0000789 {
Greg Claytond3544052012-05-31 21:24:20 +0000790 if (m_interrupt_sent)
Greg Clayton576d8832011-03-22 04:00:09 +0000791 {
Jim Inghambabfc382012-06-06 00:32:39 +0000792 m_interrupt_sent = false;
Greg Claytond3544052012-05-31 21:24:20 +0000793 TimeValue timeout_time;
794 timeout_time = TimeValue::Now();
795 timeout_time.OffsetWithSeconds (m_packet_timeout);
796
Greg Clayton576d8832011-03-22 04:00:09 +0000797 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000798 log->Printf ("async: sent interrupt");
Greg Clayton644247c2011-07-07 01:59:51 +0000799
Greg Claytond3544052012-05-31 21:24:20 +0000800 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
Greg Claytone889ad62011-10-27 22:04:16 +0000801 {
Greg Claytond3544052012-05-31 21:24:20 +0000802 if (log)
803 log->Printf ("async: got response");
804
805 // Swap the response buffer to avoid malloc and string copy
806 response.GetStringRef().swap (m_async_response.GetStringRef());
Jim Inghama6195b72013-12-18 01:24:33 +0000807 packet_result = m_async_result;
Greg Claytond3544052012-05-31 21:24:20 +0000808 }
809 else
810 {
811 if (log)
812 log->Printf ("async: timed out waiting for response");
813 }
814
815 // Make sure we wait until the continue packet has been sent again...
816 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
817 {
818 if (log)
819 {
820 if (timed_out)
821 log->Printf ("async: timed out waiting for process to resume, but process was resumed");
822 else
823 log->Printf ("async: async packet sent");
824 }
825 }
826 else
827 {
828 if (log)
829 log->Printf ("async: timed out waiting for process to resume");
Greg Claytone889ad62011-10-27 22:04:16 +0000830 }
831 }
832 else
833 {
Greg Claytond3544052012-05-31 21:24:20 +0000834 // We had a racy condition where we went to send the interrupt
835 // yet we were able to get the lock, so the process must have
836 // just stopped?
Greg Clayton576d8832011-03-22 04:00:09 +0000837 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000838 log->Printf ("async: got lock without sending interrupt");
839 // Send the packet normally since we got the lock
Greg Clayton3dedae12013-12-06 21:45:27 +0000840 packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
Greg Clayton576d8832011-03-22 04:00:09 +0000841 }
842 }
843 else
844 {
Greg Clayton644247c2011-07-07 01:59:51 +0000845 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000846 log->Printf ("async: failed to interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +0000847 }
848 }
849 else
850 {
851 if (log)
Greg Claytond3544052012-05-31 21:24:20 +0000852 log->Printf ("async: not running, async is ignored");
Greg Clayton576d8832011-03-22 04:00:09 +0000853 }
854 }
855 else
856 {
857 if (log)
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000858 log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
Greg Clayton576d8832011-03-22 04:00:09 +0000859 }
860 }
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000861
862 // Remove our Hijacking listner from the broadcast.
863 RestoreBroadcaster();
864
865 // If a notification event occured, rebroadcast since it can now be processed safely.
866 EventSP event_sp;
867 if (hijack_listener.GetNextEvent(event_sp))
868 BroadcastEvent(event_sp);
869
Greg Clayton3dedae12013-12-06 21:45:27 +0000870 return packet_result;
Greg Clayton576d8832011-03-22 04:00:09 +0000871}
872
Han Ming Ong4b6459f2013-01-18 23:11:53 +0000873static const char *end_delimiter = "--end--;";
874static const int end_delimiter_len = 8;
875
876std::string
877GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
878( ProcessGDBRemote *process,
879 StringExtractorGDBRemote& profileDataExtractor
880)
881{
882 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
883 std::stringstream final_output;
884 std::string name, value;
885
886 // Going to assuming thread_used_usec comes first, else bail out.
887 while (profileDataExtractor.GetNameColonValue(name, value))
888 {
889 if (name.compare("thread_used_id") == 0)
890 {
891 StringExtractor threadIDHexExtractor(value.c_str());
892 uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
893
894 bool has_used_usec = false;
895 uint32_t curr_used_usec = 0;
896 std::string usec_name, usec_value;
897 uint32_t input_file_pos = profileDataExtractor.GetFilePos();
898 if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
899 {
900 if (usec_name.compare("thread_used_usec") == 0)
901 {
902 has_used_usec = true;
903 curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
904 }
905 else
906 {
907 // We didn't find what we want, it is probably
908 // an older version. Bail out.
909 profileDataExtractor.SetFilePos(input_file_pos);
910 }
911 }
912
913 if (has_used_usec)
914 {
915 uint32_t prev_used_usec = 0;
916 std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
917 if (iterator != m_thread_id_to_used_usec_map.end())
918 {
919 prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
920 }
921
922 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
923 // A good first time record is one that runs for at least 0.25 sec
924 bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
925 bool good_subsequent_time = (prev_used_usec > 0) &&
926 ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
927
928 if (good_first_time || good_subsequent_time)
929 {
930 // We try to avoid doing too many index id reservation,
931 // resulting in fast increase of index ids.
932
933 final_output << name << ":";
934 int32_t index_id = process->AssignIndexIDToThread(thread_id);
935 final_output << index_id << ";";
936
937 final_output << usec_name << ":" << usec_value << ";";
938 }
939 else
940 {
941 // Skip past 'thread_used_name'.
942 std::string local_name, local_value;
943 profileDataExtractor.GetNameColonValue(local_name, local_value);
944 }
945
946 // Store current time as previous time so that they can be compared later.
947 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
948 }
949 else
950 {
951 // Bail out and use old string.
952 final_output << name << ":" << value << ";";
953 }
954 }
955 else
956 {
957 final_output << name << ":" << value << ";";
958 }
959 }
960 final_output << end_delimiter;
961 m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
962
963 return final_output.str();
964}
965
Ewan Crawford76df2882015-06-23 12:32:06 +0000966bool
967GDBRemoteCommunicationClient::SendvContPacket
968(
969 ProcessGDBRemote *process,
970 const char *payload,
971 size_t packet_length,
972 StringExtractorGDBRemote &response
973)
974{
975
976 m_curr_tid = LLDB_INVALID_THREAD_ID;
977 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
978 if (log)
979 log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
980
981 // we want to lock down packet sending while we continue
982 Mutex::Locker locker(m_sequence_mutex);
983
984 // here we broadcast this before we even send the packet!!
985 // this signals doContinue() to exit
986 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
987
988 // set the public state to running
989 m_public_is_running.SetValue(true, eBroadcastNever);
990
991 // Set the starting continue packet into "continue_packet". This packet
992 // may change if we are interrupted and we continue after an async packet...
993 std::string continue_packet(payload, packet_length);
994
995 if (log)
996 log->Printf("GDBRemoteCommunicationClient::%s () sending vCont packet: %s", __FUNCTION__, continue_packet.c_str());
997
998 if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
999 return false;
1000
1001 // set the private state to running and broadcast this
1002 m_private_is_running.SetValue(true, eBroadcastAlways);
1003
1004 if (log)
1005 log->Printf("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());
1006
1007 // wait for the response to the vCont
1008 if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
1009 {
1010 if (response.IsOKResponse())
1011 return true;
1012 }
1013
1014 return false;
1015}
1016
Greg Clayton576d8832011-03-22 04:00:09 +00001017StateType
1018GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
1019(
1020 ProcessGDBRemote *process,
1021 const char *payload,
1022 size_t packet_length,
1023 StringExtractorGDBRemote &response
1024)
1025{
Greg Clayton1f5181a2012-07-02 22:05:25 +00001026 m_curr_tid = LLDB_INVALID_THREAD_ID;
Greg Clayton5160ce52013-03-27 23:08:40 +00001027 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton576d8832011-03-22 04:00:09 +00001028 if (log)
1029 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
1030
1031 Mutex::Locker locker(m_sequence_mutex);
1032 StateType state = eStateRunning;
1033
1034 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
1035 m_public_is_running.SetValue (true, eBroadcastNever);
1036 // Set the starting continue packet into "continue_packet". This packet
Jim Inghambabfc382012-06-06 00:32:39 +00001037 // may change if we are interrupted and we continue after an async packet...
Greg Clayton576d8832011-03-22 04:00:09 +00001038 std::string continue_packet(payload, packet_length);
Oleksiy Vyalov755d58a2015-05-22 23:14:39 +00001039
1040 const auto sigstop_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGSTOP");
1041 const auto sigint_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGINT");
1042
Greg Clayton3f875c52013-02-22 22:23:55 +00001043 bool got_async_packet = false;
Greg Claytonaf247d72011-05-19 03:54:16 +00001044
Greg Clayton576d8832011-03-22 04:00:09 +00001045 while (state == eStateRunning)
1046 {
Greg Clayton3f875c52013-02-22 22:23:55 +00001047 if (!got_async_packet)
Greg Claytonaf247d72011-05-19 03:54:16 +00001048 {
1049 if (log)
1050 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
Greg Clayton3dedae12013-12-06 21:45:27 +00001051 if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
Greg Claytonaf247d72011-05-19 03:54:16 +00001052 state = eStateInvalid;
Jim Inghamb8cd5752014-04-16 02:24:17 +00001053 else
1054 m_interrupt_sent = false;
Greg Clayton576d8832011-03-22 04:00:09 +00001055
Greg Claytone889ad62011-10-27 22:04:16 +00001056 m_private_is_running.SetValue (true, eBroadcastAlways);
Greg Claytonaf247d72011-05-19 03:54:16 +00001057 }
1058
Greg Clayton3f875c52013-02-22 22:23:55 +00001059 got_async_packet = false;
Greg Clayton576d8832011-03-22 04:00:09 +00001060
1061 if (log)
Ewan Crawfordfab40d32015-06-16 15:50:18 +00001062 log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());
Greg Clayton576d8832011-03-22 04:00:09 +00001063
Ewan Crawfordfab40d32015-06-16 15:50:18 +00001064 if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001065 {
1066 if (response.Empty())
1067 state = eStateInvalid;
1068 else
1069 {
1070 const char stop_type = response.GetChar();
1071 if (log)
1072 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
1073 switch (stop_type)
1074 {
1075 case 'T':
1076 case 'S':
Greg Clayton576d8832011-03-22 04:00:09 +00001077 {
Greg Clayton2687cd12012-03-29 01:55:41 +00001078 if (process->GetStopID() == 0)
Greg Clayton576d8832011-03-22 04:00:09 +00001079 {
Greg Clayton2687cd12012-03-29 01:55:41 +00001080 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
1081 {
1082 lldb::pid_t pid = GetCurrentProcessID ();
1083 if (pid != LLDB_INVALID_PROCESS_ID)
1084 process->SetID (pid);
1085 }
1086 process->BuildDynamicRegisterInfo (true);
Greg Clayton576d8832011-03-22 04:00:09 +00001087 }
Greg Clayton2687cd12012-03-29 01:55:41 +00001088
1089 // Privately notify any internal threads that we have stopped
1090 // in case we wanted to interrupt our process, yet we might
1091 // send a packet and continue without returning control to the
1092 // user.
1093 m_private_is_running.SetValue (false, eBroadcastAlways);
1094
1095 const uint8_t signo = response.GetHexU8 (UINT8_MAX);
1096
Jim Inghambabfc382012-06-06 00:32:39 +00001097 bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
1098 if (continue_after_async || m_interrupt_sent)
Greg Clayton2687cd12012-03-29 01:55:41 +00001099 {
Greg Clayton2687cd12012-03-29 01:55:41 +00001100 // We sent an interrupt packet to stop the inferior process
1101 // for an async signal or to send an async packet while running
1102 // but we might have been single stepping and received the
1103 // stop packet for the step instead of for the interrupt packet.
1104 // Typically when an interrupt is sent a SIGINT or SIGSTOP
1105 // is used, so if we get anything else, we need to try and
1106 // get another stop reply packet that may have been sent
1107 // due to sending the interrupt when the target is stopped
1108 // which will just re-send a copy of the last stop reply
1109 // packet. If we don't do this, then the reply for our
1110 // async packet will be the repeat stop reply packet and cause
1111 // a lot of trouble for us!
Oleksiy Vyalov755d58a2015-05-22 23:14:39 +00001112 if (signo != sigint_signo && signo != sigstop_signo)
Greg Clayton2687cd12012-03-29 01:55:41 +00001113 {
Greg Claytonfb72fde2012-05-15 02:50:49 +00001114 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +00001115
1116 // We didn't get a a SIGINT or SIGSTOP, so try for a
1117 // very brief time (1 ms) to get another stop reply
1118 // packet to make sure it doesn't get in the way
1119 StringExtractorGDBRemote extra_stop_reply_packet;
1120 uint32_t timeout_usec = 1000;
Ewan Crawfordfab40d32015-06-16 15:50:18 +00001121 if (ReadPacket (extra_stop_reply_packet, timeout_usec, false) == PacketResult::Success)
Greg Clayton2687cd12012-03-29 01:55:41 +00001122 {
1123 switch (extra_stop_reply_packet.GetChar())
1124 {
1125 case 'T':
1126 case 'S':
1127 // We did get an extra stop reply, which means
1128 // our interrupt didn't stop the target so we
1129 // shouldn't continue after the async signal
1130 // or packet is sent...
Greg Claytonfb72fde2012-05-15 02:50:49 +00001131 continue_after_async = false;
Greg Clayton2687cd12012-03-29 01:55:41 +00001132 break;
1133 }
1134 }
1135 }
1136 }
1137
1138 if (m_async_signal != -1)
1139 {
1140 if (log)
1141 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
1142
1143 // Save off the async signal we are supposed to send
1144 const int async_signal = m_async_signal;
1145 // Clear the async signal member so we don't end up
1146 // sending the signal multiple times...
1147 m_async_signal = -1;
1148 // Check which signal we stopped with
1149 if (signo == async_signal)
1150 {
1151 if (log)
1152 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
1153
1154 // We already stopped with a signal that we wanted
1155 // to stop with, so we are done
1156 }
1157 else
1158 {
1159 // We stopped with a different signal that the one
1160 // we wanted to stop with, so now we must resume
1161 // with the signal we want
1162 char signal_packet[32];
1163 int signal_packet_len = 0;
1164 signal_packet_len = ::snprintf (signal_packet,
1165 sizeof (signal_packet),
1166 "C%2.2x",
1167 async_signal);
1168
1169 if (log)
1170 log->Printf ("async: stopped with signal %s, resume with %s",
1171 Host::GetSignalAsCString (signo),
1172 Host::GetSignalAsCString (async_signal));
1173
1174 // Set the continue packet to resume even if the
Greg Claytonfb72fde2012-05-15 02:50:49 +00001175 // interrupt didn't cause our stop (ignore continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +00001176 continue_packet.assign(signal_packet, signal_packet_len);
1177 continue;
1178 }
1179 }
1180 else if (m_async_packet_predicate.GetValue())
1181 {
Greg Clayton5160ce52013-03-27 23:08:40 +00001182 Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton2687cd12012-03-29 01:55:41 +00001183
1184 // We are supposed to send an asynchronous packet while
Jim Inghama6195b72013-12-18 01:24:33 +00001185 // we are running.
Greg Clayton2687cd12012-03-29 01:55:41 +00001186 m_async_response.Clear();
1187 if (m_async_packet.empty())
1188 {
Jim Inghama6195b72013-12-18 01:24:33 +00001189 m_async_result = PacketResult::ErrorSendFailed;
1190 if (packet_log)
Greg Clayton2687cd12012-03-29 01:55:41 +00001191 packet_log->Printf ("async: error: empty async packet");
1192
1193 }
1194 else
1195 {
1196 if (packet_log)
1197 packet_log->Printf ("async: sending packet");
1198
Jim Inghama6195b72013-12-18 01:24:33 +00001199 m_async_result = SendPacketAndWaitForResponse (&m_async_packet[0],
1200 m_async_packet.size(),
1201 m_async_response,
1202 false);
Greg Clayton2687cd12012-03-29 01:55:41 +00001203 }
1204 // Let the other thread that was trying to send the async
1205 // packet know that the packet has been sent and response is
1206 // ready...
1207 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
1208
1209 if (packet_log)
Greg Claytonfb72fde2012-05-15 02:50:49 +00001210 packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);
Greg Clayton2687cd12012-03-29 01:55:41 +00001211
1212 // Set the continue packet to resume if our interrupt
1213 // for the async packet did cause the stop
Greg Claytonfb72fde2012-05-15 02:50:49 +00001214 if (continue_after_async)
Greg Clayton2687cd12012-03-29 01:55:41 +00001215 {
Greg Claytonf1186de2012-05-24 23:42:14 +00001216 // Reverting this for now as it is causing deadlocks
1217 // in programs (<rdar://problem/11529853>). In the future
1218 // we should check our thread list and "do the right thing"
1219 // for new threads that show up while we stop and run async
1220 // packets. Setting the packet to 'c' to continue all threads
1221 // is the right thing to do 99.99% of the time because if a
1222 // thread was single stepping, and we sent an interrupt, we
1223 // will notice above that we didn't stop due to an interrupt
1224 // but stopped due to stepping and we would _not_ continue.
1225 continue_packet.assign (1, 'c');
Greg Clayton2687cd12012-03-29 01:55:41 +00001226 continue;
1227 }
1228 }
1229 // Stop with signal and thread info
1230 state = eStateStopped;
Greg Clayton576d8832011-03-22 04:00:09 +00001231 }
Greg Clayton576d8832011-03-22 04:00:09 +00001232 break;
1233
1234 case 'W':
1235 case 'X':
1236 // process exited
1237 state = eStateExited;
1238 break;
1239
1240 case 'O':
1241 // STDOUT
1242 {
Greg Clayton3f875c52013-02-22 22:23:55 +00001243 got_async_packet = true;
Greg Clayton576d8832011-03-22 04:00:09 +00001244 std::string inferior_stdout;
1245 inferior_stdout.reserve(response.GetBytesLeft () / 2);
1246 char ch;
1247 while ((ch = response.GetHexU8()) != '\0')
1248 inferior_stdout.append(1, ch);
1249 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
1250 }
1251 break;
1252
Han Ming Ongab3b8b22012-11-17 00:21:04 +00001253 case 'A':
1254 // Async miscellaneous reply. Right now, only profile data is coming through this channel.
1255 {
Greg Clayton3f875c52013-02-22 22:23:55 +00001256 got_async_packet = true;
Han Ming Ong4b6459f2013-01-18 23:11:53 +00001257 std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
1258 if (m_partial_profile_data.length() > 0)
1259 {
1260 m_partial_profile_data.append(input);
1261 input = m_partial_profile_data;
1262 m_partial_profile_data.clear();
1263 }
1264
1265 size_t found, pos = 0, len = input.length();
1266 while ((found = input.find(end_delimiter, pos)) != std::string::npos)
1267 {
1268 StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
Han Ming Ong91ed6b82013-06-24 18:15:05 +00001269 std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
1270 process->BroadcastAsyncProfileData (profile_data);
Han Ming Ong4b6459f2013-01-18 23:11:53 +00001271
1272 pos = found + end_delimiter_len;
1273 }
1274
1275 if (pos < len)
1276 {
1277 // Last incomplete chunk.
1278 m_partial_profile_data = input.substr(pos);
1279 }
Han Ming Ongab3b8b22012-11-17 00:21:04 +00001280 }
1281 break;
1282
Greg Clayton576d8832011-03-22 04:00:09 +00001283 case 'E':
1284 // ERROR
1285 state = eStateInvalid;
1286 break;
1287
1288 default:
1289 if (log)
1290 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
1291 state = eStateInvalid;
1292 break;
1293 }
1294 }
1295 }
1296 else
1297 {
1298 if (log)
Ewan Crawfordfab40d32015-06-16 15:50:18 +00001299 log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(...) => false", __FUNCTION__);
Greg Clayton576d8832011-03-22 04:00:09 +00001300 state = eStateInvalid;
1301 }
1302 }
1303 if (log)
1304 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
1305 response.SetFilePos(0);
1306 m_private_is_running.SetValue (false, eBroadcastAlways);
1307 m_public_is_running.SetValue (false, eBroadcastAlways);
1308 return state;
1309}
1310
1311bool
1312GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
1313{
Greg Clayton2687cd12012-03-29 01:55:41 +00001314 Mutex::Locker async_locker (m_async_mutex);
Greg Clayton576d8832011-03-22 04:00:09 +00001315 m_async_signal = signo;
1316 bool timed_out = false;
Greg Clayton576d8832011-03-22 04:00:09 +00001317 Mutex::Locker locker;
Greg Clayton2687cd12012-03-29 01:55:41 +00001318 if (SendInterrupt (locker, 1, timed_out))
Greg Clayton576d8832011-03-22 04:00:09 +00001319 return true;
1320 m_async_signal = -1;
1321 return false;
1322}
1323
Greg Clayton37a0a242012-04-11 00:24:49 +00001324// This function takes a mutex locker as a parameter in case the GetSequenceMutex
Greg Clayton576d8832011-03-22 04:00:09 +00001325// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
1326// (the expected result), then it will send the halt packet. If it does succeed
1327// then the caller that requested the interrupt will want to keep the sequence
1328// locked down so that no one else can send packets while the caller has control.
1329// This function usually gets called when we are running and need to stop the
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001330// target. It can also be used when we are running and we need to do something
Greg Clayton576d8832011-03-22 04:00:09 +00001331// else (like read/write memory), so we need to interrupt the running process
1332// (gdb remote protocol requires this), and do what we need to do, then resume.
1333
1334bool
Greg Clayton2687cd12012-03-29 01:55:41 +00001335GDBRemoteCommunicationClient::SendInterrupt
Greg Clayton576d8832011-03-22 04:00:09 +00001336(
1337 Mutex::Locker& locker,
1338 uint32_t seconds_to_wait_for_stop,
Greg Clayton576d8832011-03-22 04:00:09 +00001339 bool &timed_out
1340)
1341{
Greg Clayton576d8832011-03-22 04:00:09 +00001342 timed_out = false;
Greg Clayton5160ce52013-03-27 23:08:40 +00001343 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Clayton576d8832011-03-22 04:00:09 +00001344
1345 if (IsRunning())
1346 {
1347 // Only send an interrupt if our debugserver is running...
Greg Claytonc3c0b0e2012-04-12 19:04:34 +00001348 if (GetSequenceMutex (locker))
Greg Clayton37a0a242012-04-11 00:24:49 +00001349 {
1350 if (log)
1351 log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
1352 }
1353 else
Greg Clayton576d8832011-03-22 04:00:09 +00001354 {
1355 // Someone has the mutex locked waiting for a response or for the
1356 // inferior to stop, so send the interrupt on the down low...
1357 char ctrl_c = '\x03';
1358 ConnectionStatus status = eConnectionStatusSuccess;
Greg Clayton576d8832011-03-22 04:00:09 +00001359 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
Greg Clayton2687cd12012-03-29 01:55:41 +00001360 if (log)
1361 log->PutCString("send packet: \\x03");
Greg Clayton576d8832011-03-22 04:00:09 +00001362 if (bytes_written > 0)
1363 {
Greg Clayton2687cd12012-03-29 01:55:41 +00001364 m_interrupt_sent = true;
Greg Clayton576d8832011-03-22 04:00:09 +00001365 if (seconds_to_wait_for_stop)
1366 {
Greg Clayton2687cd12012-03-29 01:55:41 +00001367 TimeValue timeout;
1368 if (seconds_to_wait_for_stop)
1369 {
1370 timeout = TimeValue::Now();
1371 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
1372 }
Greg Clayton576d8832011-03-22 04:00:09 +00001373 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
1374 {
1375 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +00001376 log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
Greg Clayton576d8832011-03-22 04:00:09 +00001377 return true;
1378 }
1379 else
1380 {
1381 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +00001382 log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
Greg Clayton576d8832011-03-22 04:00:09 +00001383 }
1384 }
1385 else
1386 {
1387 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +00001388 log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
Greg Clayton576d8832011-03-22 04:00:09 +00001389 return true;
1390 }
1391 }
1392 else
1393 {
1394 if (log)
Greg Clayton2687cd12012-03-29 01:55:41 +00001395 log->Printf ("SendInterrupt () - failed to write interrupt");
Greg Clayton576d8832011-03-22 04:00:09 +00001396 }
1397 return false;
1398 }
Greg Clayton576d8832011-03-22 04:00:09 +00001399 }
Greg Clayton2687cd12012-03-29 01:55:41 +00001400 else
1401 {
1402 if (log)
1403 log->Printf ("SendInterrupt () - not running");
1404 }
Greg Clayton576d8832011-03-22 04:00:09 +00001405 return true;
1406}
1407
1408lldb::pid_t
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001409GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy)
Greg Clayton576d8832011-03-22 04:00:09 +00001410{
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001411 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001412 return m_curr_pid;
1413
1414 // First try to retrieve the pid via the qProcessInfo request.
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001415 GetCurrentProcessInfo (allow_lazy);
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001416 if (m_curr_pid_is_valid == eLazyBoolYes)
Greg Clayton576d8832011-03-22 04:00:09 +00001417 {
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001418 // We really got it.
1419 return m_curr_pid;
Greg Clayton576d8832011-03-22 04:00:09 +00001420 }
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001421 else
1422 {
Todd Fialae24614f2014-05-14 00:15:32 +00001423 // If we don't get a response for qProcessInfo, check if $qC gives us a result.
1424 // $qC only returns a real process id on older debugserver and lldb-platform stubs.
1425 // The gdb remote protocol documents $qC as returning the thread id, which newer
1426 // debugserver and lldb-gdbserver stubs return correctly.
1427 StringExtractorGDBRemote response;
1428 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success)
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001429 {
Todd Fialae24614f2014-05-14 00:15:32 +00001430 if (response.GetChar() == 'Q')
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001431 {
Todd Fialae24614f2014-05-14 00:15:32 +00001432 if (response.GetChar() == 'C')
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001433 {
Todd Fialae24614f2014-05-14 00:15:32 +00001434 m_curr_pid = response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
1435 if (m_curr_pid != LLDB_INVALID_PROCESS_ID)
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001436 {
Todd Fialae24614f2014-05-14 00:15:32 +00001437 m_curr_pid_is_valid = eLazyBoolYes;
1438 return m_curr_pid;
Todd Fiala9f72b3a2014-05-07 19:28:21 +00001439 }
1440 }
1441 }
1442 }
1443 }
1444
Greg Clayton576d8832011-03-22 04:00:09 +00001445 return LLDB_INVALID_PROCESS_ID;
1446}
1447
1448bool
1449GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
1450{
1451 error_str.clear();
1452 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001453 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001454 {
1455 if (response.IsOKResponse())
1456 return true;
1457 if (response.GetChar() == 'E')
1458 {
1459 // A string the describes what failed when launching...
1460 error_str = response.GetStringRef().substr(1);
1461 }
1462 else
1463 {
1464 error_str.assign ("unknown error occurred launching process");
1465 }
1466 }
1467 else
1468 {
Jim Ingham98d6da52012-06-28 20:30:23 +00001469 error_str.assign ("timed out waiting for app to launch");
Greg Clayton576d8832011-03-22 04:00:09 +00001470 }
1471 return false;
1472}
1473
1474int
Greg Claytonfbb76342013-11-20 21:07:01 +00001475GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
Greg Clayton576d8832011-03-22 04:00:09 +00001476{
Greg Claytonfbb76342013-11-20 21:07:01 +00001477 // Since we don't get the send argv0 separate from the executable path, we need to
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001478 // make sure to use the actual executable path found in the launch_info...
Greg Claytonfbb76342013-11-20 21:07:01 +00001479 std::vector<const char *> argv;
1480 FileSpec exe_file = launch_info.GetExecutableFile();
1481 std::string exe_path;
1482 const char *arg = NULL;
1483 const Args &launch_args = launch_info.GetArguments();
1484 if (exe_file)
Chaoren Lind3173f32015-05-29 19:52:29 +00001485 exe_path = exe_file.GetPath(false);
Greg Claytonfbb76342013-11-20 21:07:01 +00001486 else
1487 {
1488 arg = launch_args.GetArgumentAtIndex(0);
1489 if (arg)
1490 exe_path = arg;
1491 }
1492 if (!exe_path.empty())
1493 {
1494 argv.push_back(exe_path.c_str());
1495 for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
1496 {
1497 if (arg)
1498 argv.push_back(arg);
1499 }
1500 }
1501 if (!argv.empty())
Greg Clayton576d8832011-03-22 04:00:09 +00001502 {
1503 StreamString packet;
1504 packet.PutChar('A');
Greg Claytonfbb76342013-11-20 21:07:01 +00001505 for (size_t i = 0, n = argv.size(); i < n; ++i)
Greg Clayton576d8832011-03-22 04:00:09 +00001506 {
Greg Claytonfbb76342013-11-20 21:07:01 +00001507 arg = argv[i];
Greg Clayton576d8832011-03-22 04:00:09 +00001508 const int arg_len = strlen(arg);
1509 if (i > 0)
1510 packet.PutChar(',');
Greg Claytonfbb76342013-11-20 21:07:01 +00001511 packet.Printf("%i,%i,", arg_len * 2, (int)i);
Greg Clayton576d8832011-03-22 04:00:09 +00001512 packet.PutBytesAsRawHex8 (arg, arg_len);
1513 }
1514
1515 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001516 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001517 {
1518 if (response.IsOKResponse())
1519 return 0;
1520 uint8_t error = response.GetError();
1521 if (error)
1522 return error;
1523 }
1524 }
1525 return -1;
1526}
1527
1528int
1529GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
1530{
1531 if (name_equal_value && name_equal_value[0])
1532 {
1533 StreamString packet;
Greg Clayton89600582013-10-10 17:53:50 +00001534 bool send_hex_encoding = false;
1535 for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p)
Greg Clayton576d8832011-03-22 04:00:09 +00001536 {
Greg Clayton89600582013-10-10 17:53:50 +00001537 if (isprint(*p))
1538 {
1539 switch (*p)
1540 {
1541 case '$':
1542 case '#':
1543 send_hex_encoding = true;
1544 break;
1545 default:
1546 break;
1547 }
1548 }
1549 else
1550 {
1551 // We have non printable characters, lets hex encode this...
1552 send_hex_encoding = true;
1553 }
1554 }
1555
1556 StringExtractorGDBRemote response;
1557 if (send_hex_encoding)
1558 {
1559 if (m_supports_QEnvironmentHexEncoded)
1560 {
1561 packet.PutCString("QEnvironmentHexEncoded:");
1562 packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
Greg Clayton3dedae12013-12-06 21:45:27 +00001563 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton89600582013-10-10 17:53:50 +00001564 {
1565 if (response.IsOKResponse())
1566 return 0;
1567 uint8_t error = response.GetError();
1568 if (error)
1569 return error;
1570 if (response.IsUnsupportedResponse())
1571 m_supports_QEnvironmentHexEncoded = false;
1572 }
1573 }
1574
1575 }
1576 else if (m_supports_QEnvironment)
1577 {
1578 packet.Printf("QEnvironment:%s", name_equal_value);
Greg Clayton3dedae12013-12-06 21:45:27 +00001579 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton89600582013-10-10 17:53:50 +00001580 {
1581 if (response.IsOKResponse())
1582 return 0;
1583 uint8_t error = response.GetError();
1584 if (error)
1585 return error;
1586 if (response.IsUnsupportedResponse())
1587 m_supports_QEnvironment = false;
1588 }
Greg Clayton576d8832011-03-22 04:00:09 +00001589 }
1590 }
1591 return -1;
1592}
1593
Greg Claytonc4103b32011-05-08 04:53:50 +00001594int
1595GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
1596{
1597 if (arch && arch[0])
1598 {
1599 StreamString packet;
1600 packet.Printf("QLaunchArch:%s", arch);
1601 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001602 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Claytonc4103b32011-05-08 04:53:50 +00001603 {
1604 if (response.IsOKResponse())
1605 return 0;
1606 uint8_t error = response.GetError();
1607 if (error)
1608 return error;
1609 }
1610 }
1611 return -1;
1612}
1613
Jason Molendaa3329782014-03-29 18:54:20 +00001614int
1615GDBRemoteCommunicationClient::SendLaunchEventDataPacket (char const *data, bool *was_supported)
1616{
1617 if (data && *data != '\0')
1618 {
1619 StreamString packet;
1620 packet.Printf("QSetProcessEvent:%s", data);
1621 StringExtractorGDBRemote response;
1622 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1623 {
1624 if (response.IsOKResponse())
1625 {
1626 if (was_supported)
1627 *was_supported = true;
1628 return 0;
1629 }
1630 else if (response.IsUnsupportedResponse())
1631 {
1632 if (was_supported)
1633 *was_supported = false;
1634 return -1;
1635 }
1636 else
1637 {
1638 uint8_t error = response.GetError();
1639 if (was_supported)
1640 *was_supported = true;
1641 if (error)
1642 return error;
1643 }
1644 }
1645 }
1646 return -1;
1647}
1648
Greg Clayton576d8832011-03-22 04:00:09 +00001649bool
Greg Clayton1cb64962011-03-24 04:28:38 +00001650GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
1651 uint32_t &minor,
1652 uint32_t &update)
1653{
1654 if (GetHostInfo ())
1655 {
1656 if (m_os_version_major != UINT32_MAX)
1657 {
1658 major = m_os_version_major;
1659 minor = m_os_version_minor;
1660 update = m_os_version_update;
1661 return true;
1662 }
1663 }
1664 return false;
1665}
1666
1667bool
1668GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
1669{
1670 if (GetHostInfo ())
1671 {
1672 if (!m_os_build.empty())
1673 {
1674 s = m_os_build;
1675 return true;
1676 }
1677 }
1678 s.clear();
1679 return false;
1680}
1681
1682
1683bool
1684GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
1685{
1686 if (GetHostInfo ())
1687 {
1688 if (!m_os_kernel.empty())
1689 {
1690 s = m_os_kernel;
1691 return true;
1692 }
1693 }
1694 s.clear();
1695 return false;
1696}
1697
1698bool
1699GDBRemoteCommunicationClient::GetHostname (std::string &s)
1700{
1701 if (GetHostInfo ())
1702 {
1703 if (!m_hostname.empty())
1704 {
1705 s = m_hostname;
1706 return true;
1707 }
1708 }
1709 s.clear();
1710 return false;
1711}
1712
1713ArchSpec
1714GDBRemoteCommunicationClient::GetSystemArchitecture ()
1715{
1716 if (GetHostInfo ())
1717 return m_host_arch;
1718 return ArchSpec();
1719}
1720
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001721const lldb_private::ArchSpec &
1722GDBRemoteCommunicationClient::GetProcessArchitecture ()
1723{
1724 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1725 GetCurrentProcessInfo ();
1726 return m_process_arch;
1727}
1728
Jason Molendaa3329782014-03-29 18:54:20 +00001729bool
1730GDBRemoteCommunicationClient::GetGDBServerVersion()
1731{
1732 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate)
1733 {
1734 m_gdb_server_name.clear();
1735 m_gdb_server_version = 0;
1736 m_qGDBServerVersion_is_valid = eLazyBoolNo;
1737
1738 StringExtractorGDBRemote response;
1739 if (SendPacketAndWaitForResponse ("qGDBServerVersion", response, false) == PacketResult::Success)
1740 {
1741 if (response.IsNormalResponse())
1742 {
1743 std::string name;
1744 std::string value;
1745 bool success = false;
1746 while (response.GetNameColonValue(name, value))
1747 {
1748 if (name.compare("name") == 0)
1749 {
1750 success = true;
1751 m_gdb_server_name.swap(value);
1752 }
1753 else if (name.compare("version") == 0)
1754 {
1755 size_t dot_pos = value.find('.');
1756 if (dot_pos != std::string::npos)
1757 value[dot_pos] = '\0';
Vince Harron5275aaa2015-01-15 20:08:35 +00001758 const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
Jason Molendaa3329782014-03-29 18:54:20 +00001759 if (version != UINT32_MAX)
1760 {
1761 success = true;
1762 m_gdb_server_version = version;
1763 }
1764 }
1765 }
1766 if (success)
1767 m_qGDBServerVersion_is_valid = eLazyBoolYes;
1768 }
1769 }
1770 }
1771 return m_qGDBServerVersion_is_valid == eLazyBoolYes;
1772}
1773
Jason Molenda91ffe0a2015-06-18 21:46:06 +00001774void
1775GDBRemoteCommunicationClient::MaybeEnableCompression (std::vector<std::string> supported_compressions)
1776{
1777 CompressionType avail_type = CompressionType::None;
1778 std::string avail_name;
1779
1780#if defined (HAVE_LIBCOMPRESSION)
1781 // libcompression is weak linked so test if compression_decode_buffer() is available
1782 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1783 {
1784 for (auto compression : supported_compressions)
1785 {
1786 if (compression == "lzfse")
1787 {
1788 avail_type = CompressionType::LZFSE;
1789 avail_name = compression;
1790 break;
1791 }
1792 }
1793 }
1794#endif
1795
1796#if defined (HAVE_LIBCOMPRESSION)
1797 // libcompression is weak linked so test if compression_decode_buffer() is available
1798 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1799 {
1800 for (auto compression : supported_compressions)
1801 {
1802 if (compression == "zlib-deflate")
1803 {
1804 avail_type = CompressionType::ZlibDeflate;
1805 avail_name = compression;
1806 break;
1807 }
1808 }
1809 }
1810#endif
1811
1812#if defined (HAVE_LIBZ)
1813 if (avail_type == CompressionType::None)
1814 {
1815 for (auto compression : supported_compressions)
1816 {
1817 if (compression == "zlib-deflate")
1818 {
1819 avail_type = CompressionType::ZlibDeflate;
1820 avail_name = compression;
1821 break;
1822 }
1823 }
1824 }
1825#endif
1826
1827#if defined (HAVE_LIBCOMPRESSION)
1828 // libcompression is weak linked so test if compression_decode_buffer() is available
1829 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1830 {
1831 for (auto compression : supported_compressions)
1832 {
1833 if (compression == "lz4")
1834 {
1835 avail_type = CompressionType::LZ4;
1836 avail_name = compression;
1837 break;
1838 }
1839 }
1840 }
1841#endif
1842
1843#if defined (HAVE_LIBCOMPRESSION)
1844 // libcompression is weak linked so test if compression_decode_buffer() is available
1845 if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
1846 {
1847 for (auto compression : supported_compressions)
1848 {
1849 if (compression == "lzma")
1850 {
1851 avail_type = CompressionType::LZMA;
1852 avail_name = compression;
1853 break;
1854 }
1855 }
1856 }
1857#endif
1858
1859 if (avail_type != CompressionType::None)
1860 {
1861 StringExtractorGDBRemote response;
1862 std::string packet = "QEnableCompression:type:" + avail_name + ";";
1863 if (SendPacketAndWaitForResponse (packet.c_str(), response, false) != PacketResult::Success)
1864 return;
1865
1866 if (response.IsOKResponse())
1867 {
1868 m_compression_type = avail_type;
1869 }
1870 }
1871}
1872
Jason Molendaa3329782014-03-29 18:54:20 +00001873const char *
1874GDBRemoteCommunicationClient::GetGDBServerProgramName()
1875{
1876 if (GetGDBServerVersion())
1877 {
1878 if (!m_gdb_server_name.empty())
1879 return m_gdb_server_name.c_str();
1880 }
1881 return NULL;
1882}
1883
1884uint32_t
1885GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
1886{
1887 if (GetGDBServerVersion())
1888 return m_gdb_server_version;
1889 return 0;
1890}
Greg Clayton1cb64962011-03-24 04:28:38 +00001891
1892bool
Ewan Crawford78baa192015-05-13 09:18:18 +00001893GDBRemoteCommunicationClient::GetDefaultThreadId (lldb::tid_t &tid)
1894{
1895 StringExtractorGDBRemote response;
1896 if (SendPacketAndWaitForResponse("qC",response,false) != PacketResult::Success)
1897 return false;
1898
1899 if (!response.IsNormalResponse())
1900 return false;
1901
1902 if (response.GetChar() == 'Q' && response.GetChar() == 'C')
1903 tid = response.GetHexMaxU32(true, -1);
1904
1905 return true;
1906}
1907
1908bool
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001909GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton576d8832011-03-22 04:00:09 +00001910{
Todd Fialaaf245d12014-06-30 21:05:18 +00001911 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));
1912
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00001913 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00001914 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001915 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +00001916 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00001917 if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00001918 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00001919 if (response.IsNormalResponse())
Greg Claytond314e812011-03-23 00:09:55 +00001920 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001921 std::string name;
1922 std::string value;
1923 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1924 uint32_t sub = 0;
1925 std::string arch_name;
1926 std::string os_name;
1927 std::string vendor_name;
1928 std::string triple;
Todd Fialaa9ddb0e2014-01-18 03:02:39 +00001929 std::string distribution_id;
Greg Clayton32e0a752011-03-30 18:16:51 +00001930 uint32_t pointer_byte_size = 0;
1931 StringExtractor extractor;
1932 ByteOrder byte_order = eByteOrderInvalid;
1933 uint32_t num_keys_decoded = 0;
1934 while (response.GetNameColonValue(name, value))
Greg Claytond314e812011-03-23 00:09:55 +00001935 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001936 if (name.compare("cputype") == 0)
Greg Clayton1cb64962011-03-24 04:28:38 +00001937 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001938 // exception type in big endian hex
Vince Harron5275aaa2015-01-15 20:08:35 +00001939 cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
Greg Clayton32e0a752011-03-30 18:16:51 +00001940 if (cpu != LLDB_INVALID_CPUTYPE)
1941 ++num_keys_decoded;
1942 }
1943 else if (name.compare("cpusubtype") == 0)
1944 {
1945 // exception count in big endian hex
Vince Harron5275aaa2015-01-15 20:08:35 +00001946 sub = StringConvert::ToUInt32 (value.c_str(), 0, 0);
Greg Clayton32e0a752011-03-30 18:16:51 +00001947 if (sub != 0)
1948 ++num_keys_decoded;
1949 }
1950 else if (name.compare("arch") == 0)
1951 {
1952 arch_name.swap (value);
1953 ++num_keys_decoded;
1954 }
1955 else if (name.compare("triple") == 0)
1956 {
Greg Clayton44272a42014-09-18 00:18:32 +00001957 extractor.GetStringRef ().swap (value);
1958 extractor.SetFilePos(0);
1959 extractor.GetHexByteString (triple);
Greg Clayton32e0a752011-03-30 18:16:51 +00001960 ++num_keys_decoded;
1961 }
Todd Fialaa9ddb0e2014-01-18 03:02:39 +00001962 else if (name.compare ("distribution_id") == 0)
1963 {
1964 extractor.GetStringRef ().swap (value);
1965 extractor.SetFilePos (0);
1966 extractor.GetHexByteString (distribution_id);
1967 ++num_keys_decoded;
1968 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001969 else if (name.compare("os_build") == 0)
1970 {
1971 extractor.GetStringRef().swap(value);
1972 extractor.SetFilePos(0);
1973 extractor.GetHexByteString (m_os_build);
1974 ++num_keys_decoded;
1975 }
1976 else if (name.compare("hostname") == 0)
1977 {
1978 extractor.GetStringRef().swap(value);
1979 extractor.SetFilePos(0);
1980 extractor.GetHexByteString (m_hostname);
1981 ++num_keys_decoded;
1982 }
1983 else if (name.compare("os_kernel") == 0)
1984 {
1985 extractor.GetStringRef().swap(value);
1986 extractor.SetFilePos(0);
1987 extractor.GetHexByteString (m_os_kernel);
1988 ++num_keys_decoded;
1989 }
1990 else if (name.compare("ostype") == 0)
1991 {
1992 os_name.swap (value);
1993 ++num_keys_decoded;
1994 }
1995 else if (name.compare("vendor") == 0)
1996 {
1997 vendor_name.swap(value);
1998 ++num_keys_decoded;
1999 }
2000 else if (name.compare("endian") == 0)
2001 {
2002 ++num_keys_decoded;
2003 if (value.compare("little") == 0)
2004 byte_order = eByteOrderLittle;
2005 else if (value.compare("big") == 0)
2006 byte_order = eByteOrderBig;
2007 else if (value.compare("pdp") == 0)
2008 byte_order = eByteOrderPDP;
2009 else
2010 --num_keys_decoded;
2011 }
2012 else if (name.compare("ptrsize") == 0)
2013 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002014 pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0);
Greg Clayton32e0a752011-03-30 18:16:51 +00002015 if (pointer_byte_size != 0)
2016 ++num_keys_decoded;
2017 }
2018 else if (name.compare("os_version") == 0)
2019 {
2020 Args::StringToVersion (value.c_str(),
2021 m_os_version_major,
2022 m_os_version_minor,
2023 m_os_version_update);
2024 if (m_os_version_major != UINT32_MAX)
2025 ++num_keys_decoded;
2026 }
Enrico Granataf04a2192012-07-13 23:18:48 +00002027 else if (name.compare("watchpoint_exceptions_received") == 0)
2028 {
2029 ++num_keys_decoded;
2030 if (strcmp(value.c_str(),"before") == 0)
2031 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
2032 else if (strcmp(value.c_str(),"after") == 0)
2033 m_watchpoints_trigger_after_instruction = eLazyBoolYes;
2034 else
2035 --num_keys_decoded;
2036 }
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00002037 else if (name.compare("default_packet_timeout") == 0)
2038 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002039 m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0);
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00002040 if (m_default_packet_timeout > 0)
2041 {
2042 SetPacketTimeout(m_default_packet_timeout);
2043 ++num_keys_decoded;
2044 }
2045 }
Enrico Granataf04a2192012-07-13 23:18:48 +00002046
Greg Clayton32e0a752011-03-30 18:16:51 +00002047 }
2048
2049 if (num_keys_decoded > 0)
2050 m_qHostInfo_is_valid = eLazyBoolYes;
2051
2052 if (triple.empty())
2053 {
2054 if (arch_name.empty())
2055 {
2056 if (cpu != LLDB_INVALID_CPUTYPE)
2057 {
2058 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
2059 if (pointer_byte_size)
2060 {
2061 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
2062 }
2063 if (byte_order != eByteOrderInvalid)
2064 {
2065 assert (byte_order == m_host_arch.GetByteOrder());
2066 }
Greg Clayton70512312012-05-08 01:45:38 +00002067
2068 if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0)
2069 {
2070 switch (m_host_arch.GetMachine())
2071 {
Todd Fialad8eaa172014-07-23 14:37:35 +00002072 case llvm::Triple::aarch64:
Greg Clayton70512312012-05-08 01:45:38 +00002073 case llvm::Triple::arm:
2074 case llvm::Triple::thumb:
2075 os_name = "ios";
2076 break;
2077 default:
2078 os_name = "macosx";
2079 break;
2080 }
2081 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002082 if (!vendor_name.empty())
2083 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
2084 if (!os_name.empty())
Greg Claytone1dadb82011-09-15 00:21:03 +00002085 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Greg Clayton32e0a752011-03-30 18:16:51 +00002086
2087 }
2088 }
2089 else
2090 {
2091 std::string triple;
2092 triple += arch_name;
Greg Clayton70512312012-05-08 01:45:38 +00002093 if (!vendor_name.empty() || !os_name.empty())
2094 {
2095 triple += '-';
2096 if (vendor_name.empty())
2097 triple += "unknown";
2098 else
2099 triple += vendor_name;
2100 triple += '-';
2101 if (os_name.empty())
2102 triple += "unknown";
2103 else
2104 triple += os_name;
2105 }
2106 m_host_arch.SetTriple (triple.c_str());
2107
2108 llvm::Triple &host_triple = m_host_arch.GetTriple();
2109 if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
2110 {
2111 switch (m_host_arch.GetMachine())
2112 {
Todd Fialad8eaa172014-07-23 14:37:35 +00002113 case llvm::Triple::aarch64:
Greg Clayton70512312012-05-08 01:45:38 +00002114 case llvm::Triple::arm:
2115 case llvm::Triple::thumb:
2116 host_triple.setOS(llvm::Triple::IOS);
2117 break;
2118 default:
2119 host_triple.setOS(llvm::Triple::MacOSX);
2120 break;
2121 }
2122 }
Greg Clayton1cb64962011-03-24 04:28:38 +00002123 if (pointer_byte_size)
2124 {
2125 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
2126 }
2127 if (byte_order != eByteOrderInvalid)
2128 {
2129 assert (byte_order == m_host_arch.GetByteOrder());
2130 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002131
Greg Clayton1cb64962011-03-24 04:28:38 +00002132 }
2133 }
2134 else
2135 {
Greg Clayton70512312012-05-08 01:45:38 +00002136 m_host_arch.SetTriple (triple.c_str());
Greg Claytond314e812011-03-23 00:09:55 +00002137 if (pointer_byte_size)
2138 {
2139 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
2140 }
2141 if (byte_order != eByteOrderInvalid)
2142 {
2143 assert (byte_order == m_host_arch.GetByteOrder());
2144 }
Todd Fialaaf245d12014-06-30 21:05:18 +00002145
2146 if (log)
2147 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 +00002148 }
2149 if (!distribution_id.empty ())
2150 m_host_arch.SetDistributionId (distribution_id.c_str ());
Greg Claytond314e812011-03-23 00:09:55 +00002151 }
Greg Clayton576d8832011-03-22 04:00:09 +00002152 }
2153 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002154 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00002155}
2156
2157int
2158GDBRemoteCommunicationClient::SendAttach
2159(
2160 lldb::pid_t pid,
2161 StringExtractorGDBRemote& response
2162)
2163{
2164 if (pid != LLDB_INVALID_PROCESS_ID)
2165 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002166 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00002167 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002168 assert (packet_len < (int)sizeof(packet));
Greg Clayton3dedae12013-12-06 21:45:27 +00002169 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00002170 {
2171 if (response.IsErrorResponse())
2172 return response.GetError();
2173 return 0;
2174 }
2175 }
2176 return -1;
2177}
2178
Vince Harrone0be4252015-02-06 18:32:57 +00002179int
2180GDBRemoteCommunicationClient::SendStdinNotification (const char* data, size_t data_len)
2181{
2182 StreamString packet;
2183 packet.PutCString("I");
2184 packet.PutBytesAsRawHex8(data, data_len);
2185 StringExtractorGDBRemote response;
2186 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
2187 {
2188 return 0;
2189 }
2190 return response.GetError();
2191
2192}
2193
Greg Clayton576d8832011-03-22 04:00:09 +00002194const lldb_private::ArchSpec &
2195GDBRemoteCommunicationClient::GetHostArchitecture ()
2196{
Greg Clayton32e0a752011-03-30 18:16:51 +00002197 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton576d8832011-03-22 04:00:09 +00002198 GetHostInfo ();
Greg Claytond314e812011-03-23 00:09:55 +00002199 return m_host_arch;
Greg Clayton576d8832011-03-22 04:00:09 +00002200}
2201
Greg Clayton9ac6d2d2013-10-25 18:13:17 +00002202uint32_t
2203GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
2204{
2205 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
2206 GetHostInfo ();
2207 return m_default_packet_timeout;
2208}
2209
Greg Clayton576d8832011-03-22 04:00:09 +00002210addr_t
2211GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
2212{
Greg Clayton70b57652011-05-15 01:25:55 +00002213 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00002214 {
Greg Clayton70b57652011-05-15 01:25:55 +00002215 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00002216 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00002217 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
Greg Clayton43e0af02012-09-18 18:04:04 +00002218 (uint64_t)size,
Greg Clayton2a48f522011-05-14 01:50:35 +00002219 permissions & lldb::ePermissionsReadable ? "r" : "",
2220 permissions & lldb::ePermissionsWritable ? "w" : "",
2221 permissions & lldb::ePermissionsExecutable ? "x" : "");
Andy Gibbsa297a972013-06-19 19:04:53 +00002222 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00002223 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002224 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton2a48f522011-05-14 01:50:35 +00002225 {
Todd Fialaf105f582014-06-21 00:48:09 +00002226 if (response.IsUnsupportedResponse())
2227 m_supports_alloc_dealloc_memory = eLazyBoolNo;
2228 else if (!response.IsErrorResponse())
Greg Clayton2a48f522011-05-14 01:50:35 +00002229 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2230 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002231 else
2232 {
2233 m_supports_alloc_dealloc_memory = eLazyBoolNo;
2234 }
Greg Clayton576d8832011-03-22 04:00:09 +00002235 }
2236 return LLDB_INVALID_ADDRESS;
2237}
2238
2239bool
2240GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
2241{
Greg Clayton70b57652011-05-15 01:25:55 +00002242 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton576d8832011-03-22 04:00:09 +00002243 {
Greg Clayton70b57652011-05-15 01:25:55 +00002244 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton2a48f522011-05-14 01:50:35 +00002245 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00002246 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00002247 assert (packet_len < (int)sizeof(packet));
Greg Clayton2a48f522011-05-14 01:50:35 +00002248 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002249 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton2a48f522011-05-14 01:50:35 +00002250 {
Todd Fialaf105f582014-06-21 00:48:09 +00002251 if (response.IsUnsupportedResponse())
2252 m_supports_alloc_dealloc_memory = eLazyBoolNo;
2253 else if (response.IsOKResponse())
Greg Clayton2a48f522011-05-14 01:50:35 +00002254 return true;
Greg Clayton17a0cb62011-05-15 23:46:54 +00002255 }
2256 else
2257 {
2258 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton2a48f522011-05-14 01:50:35 +00002259 }
Greg Clayton576d8832011-03-22 04:00:09 +00002260 }
2261 return false;
2262}
2263
Jim Inghamacff8952013-05-02 00:27:30 +00002264Error
2265GDBRemoteCommunicationClient::Detach (bool keep_stopped)
Greg Clayton37a0a242012-04-11 00:24:49 +00002266{
Jim Inghamacff8952013-05-02 00:27:30 +00002267 Error error;
2268
2269 if (keep_stopped)
2270 {
2271 if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
2272 {
2273 char packet[64];
2274 const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
Andy Gibbsa297a972013-06-19 19:04:53 +00002275 assert (packet_len < (int)sizeof(packet));
Jim Inghamacff8952013-05-02 00:27:30 +00002276 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002277 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00002278 {
2279 m_supports_detach_stay_stopped = eLazyBoolYes;
2280 }
2281 else
2282 {
2283 m_supports_detach_stay_stopped = eLazyBoolNo;
2284 }
2285 }
2286
2287 if (m_supports_detach_stay_stopped == eLazyBoolNo)
2288 {
2289 error.SetErrorString("Stays stopped not supported by this target.");
2290 return error;
2291 }
2292 else
2293 {
Jim Ingham6c8824d2014-03-28 20:00:07 +00002294 StringExtractorGDBRemote response;
2295 PacketResult packet_result = SendPacketAndWaitForResponse ("D1", 1, response, false);
Greg Clayton3dedae12013-12-06 21:45:27 +00002296 if (packet_result != PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00002297 error.SetErrorString ("Sending extended disconnect packet failed.");
2298 }
2299 }
2300 else
2301 {
Jim Ingham6c8824d2014-03-28 20:00:07 +00002302 StringExtractorGDBRemote response;
2303 PacketResult packet_result = SendPacketAndWaitForResponse ("D", 1, response, false);
Greg Clayton3dedae12013-12-06 21:45:27 +00002304 if (packet_result != PacketResult::Success)
Jim Inghamacff8952013-05-02 00:27:30 +00002305 error.SetErrorString ("Sending disconnect packet failed.");
2306 }
2307 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00002308}
2309
Greg Clayton46fb5582011-11-18 07:03:08 +00002310Error
2311GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
2312 lldb_private::MemoryRegionInfo &region_info)
2313{
2314 Error error;
2315 region_info.Clear();
2316
2317 if (m_supports_memory_region_info != eLazyBoolNo)
2318 {
2319 m_supports_memory_region_info = eLazyBoolYes;
2320 char packet[64];
Daniel Malead01b2952012-11-29 21:49:15 +00002321 const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
Andy Gibbsa297a972013-06-19 19:04:53 +00002322 assert (packet_len < (int)sizeof(packet));
Greg Clayton46fb5582011-11-18 07:03:08 +00002323 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002324 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton46fb5582011-11-18 07:03:08 +00002325 {
2326 std::string name;
2327 std::string value;
2328 addr_t addr_value;
2329 bool success = true;
Jason Molendacb349ee2011-12-13 05:39:38 +00002330 bool saw_permissions = false;
Greg Clayton46fb5582011-11-18 07:03:08 +00002331 while (success && response.GetNameColonValue(name, value))
2332 {
2333 if (name.compare ("start") == 0)
2334 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002335 addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
Greg Clayton46fb5582011-11-18 07:03:08 +00002336 if (success)
2337 region_info.GetRange().SetRangeBase(addr_value);
2338 }
2339 else if (name.compare ("size") == 0)
2340 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002341 addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success);
Greg Clayton46fb5582011-11-18 07:03:08 +00002342 if (success)
2343 region_info.GetRange().SetByteSize (addr_value);
2344 }
Jason Molendacb349ee2011-12-13 05:39:38 +00002345 else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
Greg Clayton46fb5582011-11-18 07:03:08 +00002346 {
Jason Molendacb349ee2011-12-13 05:39:38 +00002347 saw_permissions = true;
2348 if (region_info.GetRange().Contains (addr))
2349 {
2350 if (value.find('r') != std::string::npos)
2351 region_info.SetReadable (MemoryRegionInfo::eYes);
2352 else
2353 region_info.SetReadable (MemoryRegionInfo::eNo);
2354
2355 if (value.find('w') != std::string::npos)
2356 region_info.SetWritable (MemoryRegionInfo::eYes);
2357 else
2358 region_info.SetWritable (MemoryRegionInfo::eNo);
2359
2360 if (value.find('x') != std::string::npos)
2361 region_info.SetExecutable (MemoryRegionInfo::eYes);
2362 else
2363 region_info.SetExecutable (MemoryRegionInfo::eNo);
2364 }
2365 else
2366 {
2367 // The reported region does not contain this address -- we're looking at an unmapped page
2368 region_info.SetReadable (MemoryRegionInfo::eNo);
2369 region_info.SetWritable (MemoryRegionInfo::eNo);
2370 region_info.SetExecutable (MemoryRegionInfo::eNo);
2371 }
Greg Clayton46fb5582011-11-18 07:03:08 +00002372 }
2373 else if (name.compare ("error") == 0)
2374 {
2375 StringExtractorGDBRemote name_extractor;
2376 // Swap "value" over into "name_extractor"
2377 name_extractor.GetStringRef().swap(value);
2378 // Now convert the HEX bytes into a string value
2379 name_extractor.GetHexByteString (value);
2380 error.SetErrorString(value.c_str());
2381 }
2382 }
Jason Molendacb349ee2011-12-13 05:39:38 +00002383
2384 // We got a valid address range back but no permissions -- which means this is an unmapped page
2385 if (region_info.GetRange().IsValid() && saw_permissions == false)
2386 {
2387 region_info.SetReadable (MemoryRegionInfo::eNo);
2388 region_info.SetWritable (MemoryRegionInfo::eNo);
2389 region_info.SetExecutable (MemoryRegionInfo::eNo);
2390 }
Greg Clayton46fb5582011-11-18 07:03:08 +00002391 }
2392 else
2393 {
2394 m_supports_memory_region_info = eLazyBoolNo;
2395 }
2396 }
2397
2398 if (m_supports_memory_region_info == eLazyBoolNo)
2399 {
2400 error.SetErrorString("qMemoryRegionInfo is not supported");
2401 }
2402 if (error.Fail())
2403 region_info.Clear();
2404 return error;
2405
2406}
2407
Johnny Chen64637202012-05-23 21:09:52 +00002408Error
2409GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
2410{
2411 Error error;
2412
2413 if (m_supports_watchpoint_support_info == eLazyBoolYes)
2414 {
2415 num = m_num_supported_hardware_watchpoints;
2416 return error;
2417 }
2418
2419 // Set num to 0 first.
2420 num = 0;
2421 if (m_supports_watchpoint_support_info != eLazyBoolNo)
2422 {
2423 char packet[64];
2424 const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
Andy Gibbsa297a972013-06-19 19:04:53 +00002425 assert (packet_len < (int)sizeof(packet));
Johnny Chen64637202012-05-23 21:09:52 +00002426 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002427 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Johnny Chen64637202012-05-23 21:09:52 +00002428 {
2429 m_supports_watchpoint_support_info = eLazyBoolYes;
2430 std::string name;
2431 std::string value;
2432 while (response.GetNameColonValue(name, value))
2433 {
2434 if (name.compare ("num") == 0)
2435 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002436 num = StringConvert::ToUInt32(value.c_str(), 0, 0);
Johnny Chen64637202012-05-23 21:09:52 +00002437 m_num_supported_hardware_watchpoints = num;
2438 }
2439 }
2440 }
2441 else
2442 {
2443 m_supports_watchpoint_support_info = eLazyBoolNo;
2444 }
2445 }
2446
2447 if (m_supports_watchpoint_support_info == eLazyBoolNo)
2448 {
2449 error.SetErrorString("qWatchpointSupportInfo is not supported");
2450 }
2451 return error;
2452
2453}
Greg Clayton46fb5582011-11-18 07:03:08 +00002454
Enrico Granataf04a2192012-07-13 23:18:48 +00002455lldb_private::Error
2456GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after)
2457{
2458 Error error(GetWatchpointSupportInfo(num));
2459 if (error.Success())
2460 error = GetWatchpointsTriggerAfterInstruction(after);
2461 return error;
2462}
2463
2464lldb_private::Error
2465GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after)
2466{
2467 Error error;
2468
2469 // we assume watchpoints will happen after running the relevant opcode
2470 // and we only want to override this behavior if we have explicitly
2471 // received a qHostInfo telling us otherwise
2472 if (m_qHostInfo_is_valid != eLazyBoolYes)
2473 after = true;
2474 else
2475 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
2476 return error;
2477}
2478
Greg Clayton576d8832011-03-22 04:00:09 +00002479int
Chaoren Lind3173f32015-05-29 19:52:29 +00002480GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00002481{
Chaoren Lind3173f32015-05-29 19:52:29 +00002482 if (file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00002483 {
Chaoren Lind3173f32015-05-29 19:52:29 +00002484 std::string path{file_spec.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00002485 StreamString packet;
2486 packet.PutCString("QSetSTDIN:");
Chaoren Lind3173f32015-05-29 19:52:29 +00002487 packet.PutCStringAsRawHex8(path.c_str());
Greg Clayton576d8832011-03-22 04:00:09 +00002488
2489 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002490 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00002491 {
2492 if (response.IsOKResponse())
2493 return 0;
2494 uint8_t error = response.GetError();
2495 if (error)
2496 return error;
2497 }
2498 }
2499 return -1;
2500}
2501
2502int
Chaoren Lind3173f32015-05-29 19:52:29 +00002503GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00002504{
Chaoren Lind3173f32015-05-29 19:52:29 +00002505 if (file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00002506 {
Chaoren Lind3173f32015-05-29 19:52:29 +00002507 std::string path{file_spec.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00002508 StreamString packet;
2509 packet.PutCString("QSetSTDOUT:");
Chaoren Lind3173f32015-05-29 19:52:29 +00002510 packet.PutCStringAsRawHex8(path.c_str());
2511
Greg Clayton576d8832011-03-22 04:00:09 +00002512 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002513 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00002514 {
2515 if (response.IsOKResponse())
2516 return 0;
2517 uint8_t error = response.GetError();
2518 if (error)
2519 return error;
2520 }
2521 }
2522 return -1;
2523}
2524
2525int
Chaoren Lind3173f32015-05-29 19:52:29 +00002526GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00002527{
Chaoren Lind3173f32015-05-29 19:52:29 +00002528 if (file_spec)
Greg Clayton576d8832011-03-22 04:00:09 +00002529 {
Chaoren Lind3173f32015-05-29 19:52:29 +00002530 std::string path{file_spec.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00002531 StreamString packet;
2532 packet.PutCString("QSetSTDERR:");
Chaoren Lind3173f32015-05-29 19:52:29 +00002533 packet.PutCStringAsRawHex8(path.c_str());
2534
Greg Clayton576d8832011-03-22 04:00:09 +00002535 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002536 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00002537 {
2538 if (response.IsOKResponse())
2539 return 0;
2540 uint8_t error = response.GetError();
2541 if (error)
2542 return error;
2543 }
2544 }
2545 return -1;
2546}
2547
Greg Claytonfbb76342013-11-20 21:07:01 +00002548bool
Chaoren Lind3173f32015-05-29 19:52:29 +00002549GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir)
Greg Claytonfbb76342013-11-20 21:07:01 +00002550{
2551 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002552 if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00002553 {
2554 if (response.IsUnsupportedResponse())
2555 return false;
2556 if (response.IsErrorResponse())
2557 return false;
Chaoren Lind3173f32015-05-29 19:52:29 +00002558 std::string cwd;
2559 response.GetHexByteString(cwd);
Chaoren Lin44145d72015-05-29 19:52:37 +00002560 working_dir.SetFile(cwd, false, GetHostArchitecture());
Greg Claytonfbb76342013-11-20 21:07:01 +00002561 return !cwd.empty();
2562 }
2563 return false;
2564}
2565
Greg Clayton576d8832011-03-22 04:00:09 +00002566int
Chaoren Lind3173f32015-05-29 19:52:29 +00002567GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir)
Greg Clayton576d8832011-03-22 04:00:09 +00002568{
Chaoren Lind3173f32015-05-29 19:52:29 +00002569 if (working_dir)
Greg Clayton576d8832011-03-22 04:00:09 +00002570 {
Chaoren Lind3173f32015-05-29 19:52:29 +00002571 std::string path{working_dir.GetPath(false)};
Greg Clayton576d8832011-03-22 04:00:09 +00002572 StreamString packet;
2573 packet.PutCString("QSetWorkingDir:");
Chaoren Lind3173f32015-05-29 19:52:29 +00002574 packet.PutCStringAsRawHex8(path.c_str());
2575
Greg Clayton576d8832011-03-22 04:00:09 +00002576 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002577 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00002578 {
2579 if (response.IsOKResponse())
2580 return 0;
2581 uint8_t error = response.GetError();
2582 if (error)
2583 return error;
2584 }
2585 }
2586 return -1;
2587}
2588
2589int
2590GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
2591{
Greg Clayton32e0a752011-03-30 18:16:51 +00002592 char packet[32];
2593 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
Andy Gibbsa297a972013-06-19 19:04:53 +00002594 assert (packet_len < (int)sizeof(packet));
Greg Clayton576d8832011-03-22 04:00:09 +00002595 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002596 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton576d8832011-03-22 04:00:09 +00002597 {
2598 if (response.IsOKResponse())
2599 return 0;
2600 uint8_t error = response.GetError();
2601 if (error)
2602 return error;
2603 }
2604 return -1;
2605}
Greg Clayton32e0a752011-03-30 18:16:51 +00002606
Jim Ingham106d0282014-06-25 02:32:56 +00002607int
2608GDBRemoteCommunicationClient::SetDetachOnError (bool enable)
2609{
2610 char packet[32];
2611 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDetachOnError:%i", enable ? 1 : 0);
2612 assert (packet_len < (int)sizeof(packet));
2613 StringExtractorGDBRemote response;
2614 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
2615 {
2616 if (response.IsOKResponse())
2617 return 0;
2618 uint8_t error = response.GetError();
2619 if (error)
2620 return error;
2621 }
2622 return -1;
2623}
2624
2625
Greg Clayton32e0a752011-03-30 18:16:51 +00002626bool
Greg Clayton8b82f082011-04-12 05:54:46 +00002627GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00002628{
2629 if (response.IsNormalResponse())
2630 {
2631 std::string name;
2632 std::string value;
2633 StringExtractor extractor;
Jason Molenda89c37492014-01-27 22:23:20 +00002634
2635 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2636 uint32_t sub = 0;
2637 std::string vendor;
2638 std::string os_type;
Greg Clayton32e0a752011-03-30 18:16:51 +00002639
2640 while (response.GetNameColonValue(name, value))
2641 {
2642 if (name.compare("pid") == 0)
2643 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002644 process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002645 }
2646 else if (name.compare("ppid") == 0)
2647 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002648 process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002649 }
2650 else if (name.compare("uid") == 0)
2651 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002652 process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002653 }
2654 else if (name.compare("euid") == 0)
2655 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002656 process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002657 }
2658 else if (name.compare("gid") == 0)
2659 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002660 process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002661 }
2662 else if (name.compare("egid") == 0)
2663 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002664 process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton32e0a752011-03-30 18:16:51 +00002665 }
2666 else if (name.compare("triple") == 0)
2667 {
Greg Clayton44272a42014-09-18 00:18:32 +00002668 StringExtractor extractor;
2669 extractor.GetStringRef().swap(value);
2670 extractor.SetFilePos(0);
2671 extractor.GetHexByteString (value);
Greg Clayton70512312012-05-08 01:45:38 +00002672 process_info.GetArchitecture ().SetTriple (value.c_str());
Greg Clayton32e0a752011-03-30 18:16:51 +00002673 }
2674 else if (name.compare("name") == 0)
2675 {
2676 StringExtractor extractor;
Filipe Cabecinhasf86cf782012-05-07 09:30:51 +00002677 // The process name from ASCII hex bytes since we can't
Greg Clayton32e0a752011-03-30 18:16:51 +00002678 // control the characters in a process name
2679 extractor.GetStringRef().swap(value);
2680 extractor.SetFilePos(0);
2681 extractor.GetHexByteString (value);
Greg Clayton144f3a92011-11-15 03:53:30 +00002682 process_info.GetExecutableFile().SetFile (value.c_str(), false);
Greg Clayton32e0a752011-03-30 18:16:51 +00002683 }
Jason Molenda89c37492014-01-27 22:23:20 +00002684 else if (name.compare("cputype") == 0)
2685 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002686 cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
Jason Molenda89c37492014-01-27 22:23:20 +00002687 }
2688 else if (name.compare("cpusubtype") == 0)
2689 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002690 sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
Jason Molenda89c37492014-01-27 22:23:20 +00002691 }
2692 else if (name.compare("vendor") == 0)
2693 {
2694 vendor = value;
2695 }
2696 else if (name.compare("ostype") == 0)
2697 {
2698 os_type = value;
2699 }
2700 }
2701
2702 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty())
2703 {
2704 if (vendor == "apple")
2705 {
2706 process_info.GetArchitecture().SetArchitecture (eArchTypeMachO, cpu, sub);
2707 process_info.GetArchitecture().GetTriple().setVendorName (llvm::StringRef (vendor));
2708 process_info.GetArchitecture().GetTriple().setOSName (llvm::StringRef (os_type));
2709 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002710 }
2711
2712 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
2713 return true;
2714 }
2715 return false;
2716}
2717
2718bool
Greg Clayton8b82f082011-04-12 05:54:46 +00002719GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +00002720{
2721 process_info.Clear();
2722
2723 if (m_supports_qProcessInfoPID)
2724 {
2725 char packet[32];
Daniel Malead01b2952012-11-29 21:49:15 +00002726 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
Andy Gibbsa297a972013-06-19 19:04:53 +00002727 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00002728 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002729 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002730 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002731 return DecodeProcessInfoResponse (response, process_info);
2732 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002733 else
2734 {
2735 m_supports_qProcessInfoPID = false;
2736 return false;
2737 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002738 }
2739 return false;
2740}
2741
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002742bool
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00002743GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002744{
Todd Fiala3daa1762014-09-15 16:01:29 +00002745 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
2746
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00002747 if (allow_lazy)
2748 {
2749 if (m_qProcessInfo_is_valid == eLazyBoolYes)
2750 return true;
2751 if (m_qProcessInfo_is_valid == eLazyBoolNo)
2752 return false;
2753 }
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002754
2755 GetHostInfo ();
2756
2757 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00002758 if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success)
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002759 {
2760 if (response.IsNormalResponse())
2761 {
2762 std::string name;
2763 std::string value;
2764 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2765 uint32_t sub = 0;
2766 std::string arch_name;
2767 std::string os_name;
2768 std::string vendor_name;
2769 std::string triple;
2770 uint32_t pointer_byte_size = 0;
2771 StringExtractor extractor;
Todd Fiala5c9d5bf2014-09-15 15:31:11 +00002772 ByteOrder byte_order = eByteOrderInvalid;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002773 uint32_t num_keys_decoded = 0;
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002774 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002775 while (response.GetNameColonValue(name, value))
2776 {
2777 if (name.compare("cputype") == 0)
2778 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002779 cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002780 if (cpu != LLDB_INVALID_CPUTYPE)
2781 ++num_keys_decoded;
2782 }
2783 else if (name.compare("cpusubtype") == 0)
2784 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002785 sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002786 if (sub != 0)
2787 ++num_keys_decoded;
2788 }
Todd Fialac540dd02014-08-26 18:21:02 +00002789 else if (name.compare("triple") == 0)
2790 {
Greg Clayton44272a42014-09-18 00:18:32 +00002791 StringExtractor extractor;
2792 extractor.GetStringRef().swap(value);
2793 extractor.SetFilePos(0);
2794 extractor.GetHexByteString (triple);
Todd Fialac540dd02014-08-26 18:21:02 +00002795 ++num_keys_decoded;
2796 }
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002797 else if (name.compare("ostype") == 0)
2798 {
2799 os_name.swap (value);
2800 ++num_keys_decoded;
2801 }
2802 else if (name.compare("vendor") == 0)
2803 {
2804 vendor_name.swap(value);
2805 ++num_keys_decoded;
2806 }
2807 else if (name.compare("endian") == 0)
2808 {
Todd Fiala5c9d5bf2014-09-15 15:31:11 +00002809 ++num_keys_decoded;
2810 if (value.compare("little") == 0)
2811 byte_order = eByteOrderLittle;
2812 else if (value.compare("big") == 0)
2813 byte_order = eByteOrderBig;
2814 else if (value.compare("pdp") == 0)
2815 byte_order = eByteOrderPDP;
2816 else
2817 --num_keys_decoded;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002818 }
2819 else if (name.compare("ptrsize") == 0)
2820 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002821 pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16);
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002822 if (pointer_byte_size != 0)
2823 ++num_keys_decoded;
2824 }
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002825 else if (name.compare("pid") == 0)
2826 {
Vince Harron5275aaa2015-01-15 20:08:35 +00002827 pid = StringConvert::ToUInt64(value.c_str(), 0, 16);
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002828 if (pid != LLDB_INVALID_PROCESS_ID)
2829 ++num_keys_decoded;
2830 }
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002831 }
2832 if (num_keys_decoded > 0)
2833 m_qProcessInfo_is_valid = eLazyBoolYes;
Todd Fiala9f72b3a2014-05-07 19:28:21 +00002834 if (pid != LLDB_INVALID_PROCESS_ID)
2835 {
2836 m_curr_pid_is_valid = eLazyBoolYes;
2837 m_curr_pid = pid;
2838 }
Todd Fialac540dd02014-08-26 18:21:02 +00002839
2840 // Set the ArchSpec from the triple if we have it.
2841 if (!triple.empty ())
2842 {
2843 m_process_arch.SetTriple (triple.c_str ());
2844 if (pointer_byte_size)
2845 {
2846 assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
2847 }
2848 }
2849 else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002850 {
Todd Fiala3daa1762014-09-15 16:01:29 +00002851 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2852
2853 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2854 switch (triple.getObjectFormat()) {
2855 case llvm::Triple::MachO:
2856 m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
2857 break;
2858 case llvm::Triple::ELF:
2859 m_process_arch.SetArchitecture (eArchTypeELF, cpu, sub);
2860 break;
2861 case llvm::Triple::COFF:
2862 m_process_arch.SetArchitecture (eArchTypeCOFF, cpu, sub);
2863 break;
2864 case llvm::Triple::UnknownObjectFormat:
2865 if (log)
2866 log->Printf("error: failed to determine target architecture");
2867 return false;
2868 }
2869
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002870 if (pointer_byte_size)
2871 {
2872 assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
2873 }
Todd Fiala5c9d5bf2014-09-15 15:31:11 +00002874 if (byte_order != eByteOrderInvalid)
2875 {
2876 assert (byte_order == m_process_arch.GetByteOrder());
2877 }
Todd Fiala0cc371c2014-09-05 14:56:13 +00002878 m_process_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
Greg Clayton7ab7f892014-05-29 21:33:45 +00002879 m_process_arch.GetTriple().setOSName(llvm::StringRef (os_name));
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002880 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
2881 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002882 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00002883 return true;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00002884 }
2885 }
2886 else
2887 {
2888 m_qProcessInfo_is_valid = eLazyBoolNo;
2889 }
2890
2891 return false;
2892}
2893
2894
Greg Clayton32e0a752011-03-30 18:16:51 +00002895uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00002896GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
2897 ProcessInstanceInfoList &process_infos)
Greg Clayton32e0a752011-03-30 18:16:51 +00002898{
2899 process_infos.Clear();
2900
2901 if (m_supports_qfProcessInfo)
2902 {
2903 StreamString packet;
2904 packet.PutCString ("qfProcessInfo");
2905 if (!match_info.MatchAllProcesses())
2906 {
2907 packet.PutChar (':');
2908 const char *name = match_info.GetProcessInfo().GetName();
2909 bool has_name_match = false;
2910 if (name && name[0])
2911 {
2912 has_name_match = true;
2913 NameMatchType name_match_type = match_info.GetNameMatchType();
2914 switch (name_match_type)
2915 {
2916 case eNameMatchIgnore:
2917 has_name_match = false;
2918 break;
2919
2920 case eNameMatchEquals:
2921 packet.PutCString ("name_match:equals;");
2922 break;
2923
2924 case eNameMatchContains:
2925 packet.PutCString ("name_match:contains;");
2926 break;
2927
2928 case eNameMatchStartsWith:
2929 packet.PutCString ("name_match:starts_with;");
2930 break;
2931
2932 case eNameMatchEndsWith:
2933 packet.PutCString ("name_match:ends_with;");
2934 break;
2935
2936 case eNameMatchRegularExpression:
2937 packet.PutCString ("name_match:regex;");
2938 break;
2939 }
2940 if (has_name_match)
2941 {
2942 packet.PutCString ("name:");
2943 packet.PutBytesAsRawHex8(name, ::strlen(name));
2944 packet.PutChar (';');
2945 }
2946 }
2947
2948 if (match_info.GetProcessInfo().ProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002949 packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002950 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
Daniel Malead01b2952012-11-29 21:49:15 +00002951 packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
Greg Clayton8b82f082011-04-12 05:54:46 +00002952 if (match_info.GetProcessInfo().UserIDIsValid())
2953 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
2954 if (match_info.GetProcessInfo().GroupIDIsValid())
2955 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton32e0a752011-03-30 18:16:51 +00002956 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2957 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
2958 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2959 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
2960 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2961 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
2962 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
2963 {
2964 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
2965 const llvm::Triple &triple = match_arch.GetTriple();
2966 packet.PutCString("triple:");
Matthew Gardinerf39ebbe2014-08-01 05:12:23 +00002967 packet.PutCString(triple.getTriple().c_str());
Greg Clayton32e0a752011-03-30 18:16:51 +00002968 packet.PutChar (';');
2969 }
2970 }
2971 StringExtractorGDBRemote response;
Siva Chandra8fd94c92015-05-20 00:30:31 +00002972 // Increase timeout as the first qfProcessInfo packet takes a long time
2973 // on Android. The value of 1min was arrived at empirically.
2974 GDBRemoteCommunication::ScopedTimeout timeout (*this, 60);
Greg Clayton3dedae12013-12-06 21:45:27 +00002975 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00002976 {
Greg Clayton32e0a752011-03-30 18:16:51 +00002977 do
2978 {
Greg Clayton8b82f082011-04-12 05:54:46 +00002979 ProcessInstanceInfo process_info;
Greg Clayton32e0a752011-03-30 18:16:51 +00002980 if (!DecodeProcessInfoResponse (response, process_info))
2981 break;
2982 process_infos.Append(process_info);
2983 response.GetStringRef().clear();
2984 response.SetFilePos(0);
Greg Clayton3dedae12013-12-06 21:45:27 +00002985 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
Greg Clayton32e0a752011-03-30 18:16:51 +00002986 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00002987 else
2988 {
2989 m_supports_qfProcessInfo = false;
2990 return 0;
2991 }
Greg Clayton32e0a752011-03-30 18:16:51 +00002992 }
2993 return process_infos.GetSize();
2994
2995}
2996
2997bool
2998GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
2999{
3000 if (m_supports_qUserName)
3001 {
3002 char packet[32];
3003 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
Andy Gibbsa297a972013-06-19 19:04:53 +00003004 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00003005 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003006 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00003007 {
Greg Clayton32e0a752011-03-30 18:16:51 +00003008 if (response.IsNormalResponse())
3009 {
3010 // Make sure we parsed the right number of characters. The response is
3011 // the hex encoded user name and should make up the entire packet.
3012 // If there are any non-hex ASCII bytes, the length won't match below..
3013 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
3014 return true;
3015 }
3016 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00003017 else
3018 {
3019 m_supports_qUserName = false;
3020 return false;
3021 }
Greg Clayton32e0a752011-03-30 18:16:51 +00003022 }
3023 return false;
3024
3025}
3026
3027bool
3028GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
3029{
3030 if (m_supports_qGroupName)
3031 {
3032 char packet[32];
3033 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
Andy Gibbsa297a972013-06-19 19:04:53 +00003034 assert (packet_len < (int)sizeof(packet));
Greg Clayton32e0a752011-03-30 18:16:51 +00003035 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003036 if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton32e0a752011-03-30 18:16:51 +00003037 {
Greg Clayton32e0a752011-03-30 18:16:51 +00003038 if (response.IsNormalResponse())
3039 {
3040 // Make sure we parsed the right number of characters. The response is
3041 // the hex encoded group name and should make up the entire packet.
3042 // If there are any non-hex ASCII bytes, the length won't match below..
3043 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
3044 return true;
3045 }
3046 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00003047 else
3048 {
3049 m_supports_qGroupName = false;
3050 return false;
3051 }
Greg Clayton32e0a752011-03-30 18:16:51 +00003052 }
3053 return false;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003054}
Greg Clayton32e0a752011-03-30 18:16:51 +00003055
Ewan Crawford78baa192015-05-13 09:18:18 +00003056bool
3057GDBRemoteCommunicationClient::SetNonStopMode (const bool enable)
3058{
3059 // Form non-stop packet request
3060 char packet[32];
3061 const int packet_len = ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
3062 assert(packet_len < (int)sizeof(packet));
3063
3064 StringExtractorGDBRemote response;
3065 // Send to target
3066 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
3067 if (response.IsOKResponse())
3068 return true;
3069
3070 // Failed or not supported
3071 return false;
3072
3073}
3074
Greg Claytone034a042015-05-21 20:52:06 +00003075static void
3076MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
3077{
3078 packet.Clear();
3079 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
3080 uint32_t bytes_left = send_size;
3081 while (bytes_left > 0)
3082 {
3083 if (bytes_left >= 26)
3084 {
3085 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
3086 bytes_left -= 26;
3087 }
3088 else
3089 {
3090 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
3091 bytes_left = 0;
3092 }
3093 }
3094}
3095
3096template<typename T>
3097T calculate_standard_deviation(const std::vector<T> &v)
3098{
3099 T sum = std::accumulate(std::begin(v), std::end(v), T(0));
3100 T mean = sum / (T)v.size();
3101 T accum = T(0);
3102 std::for_each (std::begin(v), std::end(v), [&](const T d) {
3103 T delta = d - mean;
3104 accum += delta * delta;
3105 });
3106
3107 T stdev = sqrt(accum / (v.size()-1));
3108 return stdev;
3109}
3110
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003111void
Greg Claytone034a042015-05-21 20:52:06 +00003112GDBRemoteCommunicationClient::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 +00003113{
3114 uint32_t i;
3115 TimeValue start_time, end_time;
3116 uint64_t total_time_nsec;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003117 if (SendSpeedTestPacket (0, 0))
3118 {
Greg Claytone034a042015-05-21 20:52:06 +00003119 StreamString packet;
3120 if (json)
3121 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n \"results\" : [", num_packets);
3122 else
3123 strm.Printf("Testing sending %u packets of various sizes:\n", num_packets);
3124 strm.Flush();
Greg Clayton700e5082014-02-21 19:11:28 +00003125
Greg Claytone034a042015-05-21 20:52:06 +00003126 uint32_t result_idx = 0;
3127 uint32_t send_size;
3128 std::vector<float> packet_times;
3129
3130 for (send_size = 0; send_size <= max_send; send_size ? send_size *= 2 : send_size = 4)
3131 {
3132 for (uint32_t recv_size = 0; recv_size <= max_recv; recv_size ? recv_size *= 2 : recv_size = 4)
3133 {
3134 MakeSpeedTestPacket (packet, send_size, recv_size);
3135
3136 packet_times.clear();
3137 // Test how long it takes to send 'num_packets' packets
Greg Clayton700e5082014-02-21 19:11:28 +00003138 start_time = TimeValue::Now();
Greg Claytone034a042015-05-21 20:52:06 +00003139 for (i=0; i<num_packets; ++i)
Greg Clayton700e5082014-02-21 19:11:28 +00003140 {
Greg Claytone034a042015-05-21 20:52:06 +00003141 TimeValue packet_start_time = TimeValue::Now();
3142 StringExtractorGDBRemote response;
3143 SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
3144 TimeValue packet_end_time = TimeValue::Now();
3145 uint64_t packet_time_nsec = packet_end_time.GetAsNanoSecondsSinceJan1_1970() - packet_start_time.GetAsNanoSecondsSinceJan1_1970();
3146 packet_times.push_back((float)packet_time_nsec);
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003147 }
3148 end_time = TimeValue::Now();
3149 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Greg Claytone034a042015-05-21 20:52:06 +00003150
3151 float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
3152 float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
3153 float average_ms_per_packet = total_ms / num_packets;
3154 const float standard_deviation = calculate_standard_deviation<float>(packet_times);
3155 if (json)
Greg Clayton700e5082014-02-21 19:11:28 +00003156 {
Greg Claytone034a042015-05-21 20:52:06 +00003157 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);
3158 ++result_idx;
Greg Clayton700e5082014-02-21 19:11:28 +00003159 }
3160 else
3161 {
Greg Claytone034a042015-05-21 20:52:06 +00003162 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",
3163 send_size,
3164 recv_size,
3165 total_time_nsec / TimeValue::NanoSecPerSec,
3166 total_time_nsec % TimeValue::NanoSecPerSec,
3167 packets_per_second,
3168 average_ms_per_packet,
3169 standard_deviation/(float)TimeValue::NanoSecPerMilliSec);
Greg Clayton700e5082014-02-21 19:11:28 +00003170 }
Greg Claytone034a042015-05-21 20:52:06 +00003171 strm.Flush();
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003172 }
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003173 }
Greg Claytone034a042015-05-21 20:52:06 +00003174
3175 const uint64_t k_recv_amount = 4*1024*1024; // Receive amount in bytes
3176
3177 const float k_recv_amount_mb = (float)k_recv_amount/(1024.0f*1024.0f);
3178 if (json)
3179 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" : %" PRIu64 ",\n \"results\" : [", k_recv_amount);
3180 else
3181 strm.Printf("Testing receiving %2.1fMB of data using varying receive packet sizes:\n", k_recv_amount_mb);
3182 strm.Flush();
3183 send_size = 0;
3184 result_idx = 0;
3185 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2)
3186 {
3187 MakeSpeedTestPacket (packet, send_size, recv_size);
3188
3189 // If we have a receive size, test how long it takes to receive 4MB of data
3190 if (recv_size > 0)
3191 {
3192 start_time = TimeValue::Now();
3193 uint32_t bytes_read = 0;
3194 uint32_t packet_count = 0;
3195 while (bytes_read < k_recv_amount)
3196 {
3197 StringExtractorGDBRemote response;
3198 SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
3199 bytes_read += recv_size;
3200 ++packet_count;
3201 }
3202 end_time = TimeValue::Now();
3203 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
3204 float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
3205 float packets_per_second = (((float)packet_count)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
3206 float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
3207 float average_ms_per_packet = total_ms / packet_count;
3208
3209 if (json)
3210 {
3211 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);
3212 ++result_idx;
3213 }
3214 else
3215 {
3216 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",
3217 send_size,
3218 recv_size,
3219 packet_count,
3220 k_recv_amount_mb,
3221 total_time_nsec / TimeValue::NanoSecPerSec,
3222 total_time_nsec % TimeValue::NanoSecPerSec,
3223 mb_second,
3224 packets_per_second,
3225 average_ms_per_packet);
3226 }
3227 strm.Flush();
3228 }
3229 }
3230 if (json)
3231 strm.Printf("\n ]\n }\n}\n");
3232 else
3233 strm.EOL();
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003234 }
Greg Clayton9b1e1cd2011-04-04 18:18:57 +00003235}
3236
3237bool
3238GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
3239{
3240 StreamString packet;
3241 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
3242 uint32_t bytes_left = send_size;
3243 while (bytes_left > 0)
3244 {
3245 if (bytes_left >= 26)
3246 {
3247 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
3248 bytes_left -= 26;
3249 }
3250 else
3251 {
3252 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
3253 bytes_left = 0;
3254 }
3255 }
3256
3257 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003258 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
Greg Clayton32e0a752011-03-30 18:16:51 +00003259}
Greg Clayton8b82f082011-04-12 05:54:46 +00003260
3261uint16_t
Greg Claytondbf04572013-12-04 19:40:33 +00003262GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname)
Greg Clayton8b82f082011-04-12 05:54:46 +00003263{
Daniel Maleae0f8f572013-08-26 23:57:52 +00003264 pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton8b82f082011-04-12 05:54:46 +00003265 StringExtractorGDBRemote response;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003266 StreamString stream;
Greg Clayton29b8fc42013-11-21 01:44:58 +00003267 stream.PutCString("qLaunchGDBServer;");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003268 std::string hostname;
Greg Claytondbf04572013-12-04 19:40:33 +00003269 if (remote_accept_hostname && remote_accept_hostname[0])
3270 hostname = remote_accept_hostname;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003271 else
3272 {
Zachary Turner97a14e62014-08-19 17:18:29 +00003273 if (HostInfo::GetHostname(hostname))
Greg Claytondbf04572013-12-04 19:40:33 +00003274 {
3275 // Make the GDB server we launch only accept connections from this host
3276 stream.Printf("host:%s;", hostname.c_str());
3277 }
3278 else
3279 {
3280 // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
3281 stream.Printf("host:*;");
3282 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003283 }
3284 const char *packet = stream.GetData();
3285 int packet_len = stream.GetSize();
3286
Vince Harron1b5a74e2015-01-21 22:42:49 +00003287 // give the process a few seconds to startup
Tamas Berghammer912800c2015-02-24 10:23:39 +00003288 GDBRemoteCommunication::ScopedTimeout timeout (*this, 10);
3289
3290 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00003291 {
3292 std::string name;
3293 std::string value;
3294 uint16_t port = 0;
Greg Clayton8b82f082011-04-12 05:54:46 +00003295 while (response.GetNameColonValue(name, value))
3296 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00003297 if (name.compare("port") == 0)
Vince Harron5275aaa2015-01-15 20:08:35 +00003298 port = StringConvert::ToUInt32(value.c_str(), 0, 0);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003299 else if (name.compare("pid") == 0)
Vince Harron5275aaa2015-01-15 20:08:35 +00003300 pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
Greg Clayton8b82f082011-04-12 05:54:46 +00003301 }
3302 return port;
3303 }
3304 return 0;
3305}
3306
3307bool
Daniel Maleae0f8f572013-08-26 23:57:52 +00003308GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
3309{
3310 StreamString stream;
3311 stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
3312 const char *packet = stream.GetData();
3313 int packet_len = stream.GetSize();
Sylvestre Ledrufd654c42013-10-06 09:51:02 +00003314
Daniel Maleae0f8f572013-08-26 23:57:52 +00003315 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003316 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003317 {
3318 if (response.IsOKResponse())
3319 return true;
3320 }
3321 return false;
3322}
3323
3324bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00003325GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00003326{
3327 if (m_curr_tid == tid)
3328 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00003329
Greg Clayton8b82f082011-04-12 05:54:46 +00003330 char packet[32];
3331 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00003332 if (tid == UINT64_MAX)
3333 packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00003334 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00003335 packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00003336 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00003337 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003338 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00003339 {
3340 if (response.IsOKResponse())
3341 {
3342 m_curr_tid = tid;
3343 return true;
3344 }
3345 }
3346 return false;
3347}
3348
3349bool
Jason Molendae9ca4af2013-02-23 02:04:45 +00003350GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
Greg Clayton8b82f082011-04-12 05:54:46 +00003351{
3352 if (m_curr_tid_run == tid)
3353 return true;
Jason Molendae9ca4af2013-02-23 02:04:45 +00003354
Greg Clayton8b82f082011-04-12 05:54:46 +00003355 char packet[32];
3356 int packet_len;
Jason Molendae9ca4af2013-02-23 02:04:45 +00003357 if (tid == UINT64_MAX)
3358 packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
Greg Clayton8b82f082011-04-12 05:54:46 +00003359 else
Jason Molendae9ca4af2013-02-23 02:04:45 +00003360 packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
3361
Andy Gibbsa297a972013-06-19 19:04:53 +00003362 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00003363 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003364 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00003365 {
3366 if (response.IsOKResponse())
3367 {
3368 m_curr_tid_run = tid;
3369 return true;
3370 }
3371 }
3372 return false;
3373}
3374
3375bool
3376GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
3377{
Greg Clayton3dedae12013-12-06 21:45:27 +00003378 if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00003379 return response.IsNormalResponse();
3380 return false;
3381}
3382
3383bool
Greg Claytonf402f782012-10-13 02:11:55 +00003384GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
Greg Clayton8b82f082011-04-12 05:54:46 +00003385{
3386 if (m_supports_qThreadStopInfo)
3387 {
3388 char packet[256];
Daniel Malead01b2952012-11-29 21:49:15 +00003389 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
Andy Gibbsa297a972013-06-19 19:04:53 +00003390 assert (packet_len < (int)sizeof(packet));
Greg Clayton3dedae12013-12-06 21:45:27 +00003391 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00003392 {
Greg Claytonef8180a2013-10-15 00:14:28 +00003393 if (response.IsUnsupportedResponse())
3394 m_supports_qThreadStopInfo = false;
3395 else if (response.IsNormalResponse())
Greg Clayton8b82f082011-04-12 05:54:46 +00003396 return true;
3397 else
3398 return false;
3399 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00003400 else
3401 {
3402 m_supports_qThreadStopInfo = false;
3403 }
Greg Clayton8b82f082011-04-12 05:54:46 +00003404 }
Greg Clayton8b82f082011-04-12 05:54:46 +00003405 return false;
3406}
3407
3408
3409uint8_t
3410GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
3411{
Todd Fiala616b8272014-10-09 00:55:04 +00003412 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
3413 if (log)
3414 log->Printf ("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
3415 __FUNCTION__, insert ? "add" : "remove", addr);
3416
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00003417 // Check if the stub is known not to support this breakpoint type
3418 if (!SupportsGDBStoppointPacket(type))
3419 return UINT8_MAX;
3420 // Construct the breakpoint packet
Greg Clayton8b82f082011-04-12 05:54:46 +00003421 char packet[64];
3422 const int packet_len = ::snprintf (packet,
3423 sizeof(packet),
Daniel Malead01b2952012-11-29 21:49:15 +00003424 "%c%i,%" PRIx64 ",%x",
Greg Clayton8b82f082011-04-12 05:54:46 +00003425 insert ? 'Z' : 'z',
3426 type,
3427 addr,
3428 length);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003429 // Check we haven't overwritten the end of the packet buffer
Andy Gibbsa297a972013-06-19 19:04:53 +00003430 assert (packet_len + 1 < (int)sizeof(packet));
Greg Clayton8b82f082011-04-12 05:54:46 +00003431 StringExtractorGDBRemote response;
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00003432 // Try to send the breakpoint packet, and check that it was correctly sent
Greg Clayton3dedae12013-12-06 21:45:27 +00003433 if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
Greg Clayton8b82f082011-04-12 05:54:46 +00003434 {
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00003435 // Receive and OK packet when the breakpoint successfully placed
Greg Clayton8b82f082011-04-12 05:54:46 +00003436 if (response.IsOKResponse())
3437 return 0;
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00003438
3439 // Error while setting breakpoint, send back specific error
3440 if (response.IsErrorResponse())
Greg Clayton8b82f082011-04-12 05:54:46 +00003441 return response.GetError();
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00003442
3443 // Empty packet informs us that breakpoint is not supported
3444 if (response.IsUnsupportedResponse())
Greg Clayton17a0cb62011-05-15 23:46:54 +00003445 {
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00003446 // Disable this breakpoint type since it is unsupported
3447 switch (type)
3448 {
Greg Clayton17a0cb62011-05-15 23:46:54 +00003449 case eBreakpointSoftware: m_supports_z0 = false; break;
3450 case eBreakpointHardware: m_supports_z1 = false; break;
3451 case eWatchpointWrite: m_supports_z2 = false; break;
3452 case eWatchpointRead: m_supports_z3 = false; break;
3453 case eWatchpointReadWrite: m_supports_z4 = false; break;
Chaoren Lin0be9ebb2015-02-03 01:51:50 +00003454 case eStoppointInvalid: return UINT8_MAX;
Deepak Panickalb98a2bb2014-02-24 11:50:46 +00003455 }
Greg Clayton17a0cb62011-05-15 23:46:54 +00003456 }
3457 }
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003458 // Signal generic failure
Greg Clayton8b82f082011-04-12 05:54:46 +00003459 return UINT8_MAX;
3460}
Greg Claytonadc00cb2011-05-20 23:38:13 +00003461
3462size_t
3463GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
3464 bool &sequence_mutex_unavailable)
3465{
3466 Mutex::Locker locker;
3467 thread_ids.clear();
3468
Jim Ingham4ceb9282012-06-08 22:50:40 +00003469 if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
Greg Claytonadc00cb2011-05-20 23:38:13 +00003470 {
3471 sequence_mutex_unavailable = false;
3472 StringExtractorGDBRemote response;
3473
Greg Clayton3dedae12013-12-06 21:45:27 +00003474 PacketResult packet_result;
3475 for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response);
3476 packet_result == PacketResult::Success && response.IsNormalResponse();
3477 packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response))
Greg Claytonadc00cb2011-05-20 23:38:13 +00003478 {
3479 char ch = response.GetChar();
3480 if (ch == 'l')
3481 break;
3482 if (ch == 'm')
3483 {
3484 do
3485 {
Jason Molendae9ca4af2013-02-23 02:04:45 +00003486 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
Greg Claytonadc00cb2011-05-20 23:38:13 +00003487
3488 if (tid != LLDB_INVALID_THREAD_ID)
3489 {
3490 thread_ids.push_back (tid);
3491 }
3492 ch = response.GetChar(); // Skip the command separator
3493 } while (ch == ','); // Make sure we got a comma separator
3494 }
3495 }
3496 }
3497 else
3498 {
Jim Ingham4ceb9282012-06-08 22:50:40 +00003499#if defined (LLDB_CONFIGURATION_DEBUG)
3500 // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
3501#else
Greg Clayton5160ce52013-03-27 23:08:40 +00003502 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Greg Claytonc3c0b0e2012-04-12 19:04:34 +00003503 if (log)
3504 log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
Jim Ingham4ceb9282012-06-08 22:50:40 +00003505#endif
Greg Claytonadc00cb2011-05-20 23:38:13 +00003506 sequence_mutex_unavailable = true;
3507 }
3508 return thread_ids.size();
3509}
Greg Clayton37a0a242012-04-11 00:24:49 +00003510
3511lldb::addr_t
3512GDBRemoteCommunicationClient::GetShlibInfoAddr()
3513{
3514 if (!IsRunning())
3515 {
3516 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003517 if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false) == PacketResult::Success)
Greg Clayton37a0a242012-04-11 00:24:49 +00003518 {
3519 if (response.IsNormalResponse())
3520 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
3521 }
3522 }
3523 return LLDB_INVALID_ADDRESS;
3524}
3525
Daniel Maleae0f8f572013-08-26 23:57:52 +00003526lldb_private::Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003527GDBRemoteCommunicationClient::RunShellCommand(const char *command, // Shouldn't be NULL
3528 const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
3529 int *status_ptr, // Pass NULL if you don't want the process exit status
3530 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
3531 std::string *command_output, // Pass NULL if you don't want the command output
3532 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
Daniel Maleae0f8f572013-08-26 23:57:52 +00003533{
3534 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00003535 stream.PutCString("qPlatform_shell:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003536 stream.PutBytesAsRawHex8(command, strlen(command));
3537 stream.PutChar(',');
3538 stream.PutHex32(timeout_sec);
Chaoren Lind3173f32015-05-29 19:52:29 +00003539 if (working_dir)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003540 {
Chaoren Lind3173f32015-05-29 19:52:29 +00003541 std::string path{working_dir.GetPath(false)};
Daniel Maleae0f8f572013-08-26 23:57:52 +00003542 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003543 stream.PutCStringAsRawHex8(path.c_str());
Daniel Maleae0f8f572013-08-26 23:57:52 +00003544 }
3545 const char *packet = stream.GetData();
3546 int packet_len = stream.GetSize();
3547 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003548 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003549 {
3550 if (response.GetChar() != 'F')
3551 return Error("malformed reply");
3552 if (response.GetChar() != ',')
3553 return Error("malformed reply");
3554 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
3555 if (exitcode == UINT32_MAX)
3556 return Error("unable to run remote process");
3557 else if (status_ptr)
3558 *status_ptr = exitcode;
3559 if (response.GetChar() != ',')
3560 return Error("malformed reply");
3561 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
3562 if (signo_ptr)
3563 *signo_ptr = signo;
3564 if (response.GetChar() != ',')
3565 return Error("malformed reply");
3566 std::string output;
3567 response.GetEscapedBinaryData(output);
3568 if (command_output)
3569 command_output->assign(output);
3570 return Error();
3571 }
3572 return Error("unable to send packet");
3573}
3574
Greg Claytonfbb76342013-11-20 21:07:01 +00003575Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003576GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
3577 uint32_t file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003578{
Chaoren Lind3173f32015-05-29 19:52:29 +00003579 std::string path{file_spec.GetPath(false)};
Daniel Maleae0f8f572013-08-26 23:57:52 +00003580 lldb_private::StreamString stream;
Greg Claytonfbb76342013-11-20 21:07:01 +00003581 stream.PutCString("qPlatform_mkdir:");
3582 stream.PutHex32(file_permissions);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003583 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003584 stream.PutCStringAsRawHex8(path.c_str());
Daniel Maleae0f8f572013-08-26 23:57:52 +00003585 const char *packet = stream.GetData();
3586 int packet_len = stream.GetSize();
3587 StringExtractorGDBRemote response;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003588
Tamas Berghammer0f86b742015-02-23 11:03:08 +00003589 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
3590 return Error("failed to send '%s' packet", packet);
3591
3592 if (response.GetChar() != 'F')
3593 return Error("invalid response to '%s' packet", packet);
3594
3595 return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003596}
3597
Greg Claytonfbb76342013-11-20 21:07:01 +00003598Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003599GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
3600 uint32_t file_permissions)
Greg Claytonfbb76342013-11-20 21:07:01 +00003601{
Chaoren Lind3173f32015-05-29 19:52:29 +00003602 std::string path{file_spec.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003603 lldb_private::StreamString stream;
3604 stream.PutCString("qPlatform_chmod:");
3605 stream.PutHex32(file_permissions);
3606 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003607 stream.PutCStringAsRawHex8(path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003608 const char *packet = stream.GetData();
3609 int packet_len = stream.GetSize();
3610 StringExtractorGDBRemote response;
Tamas Berghammer0f86b742015-02-23 11:03:08 +00003611
3612 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
3613 return Error("failed to send '%s' packet", packet);
3614
3615 if (response.GetChar() != 'F')
3616 return Error("invalid response to '%s' packet", packet);
3617
Chaoren Lince36c4c2015-05-05 18:43:19 +00003618 return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Greg Claytonfbb76342013-11-20 21:07:01 +00003619}
3620
Daniel Maleae0f8f572013-08-26 23:57:52 +00003621static uint64_t
3622ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
3623 uint64_t fail_result,
3624 Error &error)
3625{
3626 response.SetFilePos(0);
3627 if (response.GetChar() != 'F')
3628 return fail_result;
3629 int32_t result = response.GetS32 (-2);
3630 if (result == -2)
3631 return fail_result;
3632 if (response.GetChar() == ',')
3633 {
3634 int result_errno = response.GetS32 (-2);
3635 if (result_errno != -2)
3636 error.SetError(result_errno, eErrorTypePOSIX);
3637 else
3638 error.SetError(-1, eErrorTypeGeneric);
3639 }
3640 else
3641 error.Clear();
3642 return result;
3643}
3644lldb::user_id_t
3645GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
3646 uint32_t flags,
3647 mode_t mode,
3648 Error &error)
3649{
Chaoren Lind3173f32015-05-29 19:52:29 +00003650 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003651 lldb_private::StreamString stream;
3652 stream.PutCString("vFile:open:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003653 if (path.empty())
3654 return UINT64_MAX;
3655 stream.PutCStringAsRawHex8(path.c_str());
3656 stream.PutChar(',');
Robert Flackebc56092015-03-18 13:55:48 +00003657 stream.PutHex32(flags);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003658 stream.PutChar(',');
3659 stream.PutHex32(mode);
3660 const char* packet = stream.GetData();
3661 int packet_len = stream.GetSize();
3662 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003663 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003664 {
3665 return ParseHostIOPacketResponse (response, UINT64_MAX, error);
3666 }
3667 return UINT64_MAX;
3668}
3669
3670bool
3671GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
3672 Error &error)
3673{
3674 lldb_private::StreamString stream;
3675 stream.Printf("vFile:close:%i", (int)fd);
3676 const char* packet = stream.GetData();
3677 int packet_len = stream.GetSize();
3678 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003679 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003680 {
3681 return ParseHostIOPacketResponse (response, -1, error) == 0;
3682 }
Deepak Panickald66b50c2013-10-22 12:27:43 +00003683 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003684}
3685
3686// Extension of host I/O packets to get the file size.
3687lldb::user_id_t
3688GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
3689{
Chaoren Lind3173f32015-05-29 19:52:29 +00003690 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003691 lldb_private::StreamString stream;
3692 stream.PutCString("vFile:size:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003693 stream.PutCStringAsRawHex8(path.c_str());
3694 const char* packet = stream.GetData();
3695 int packet_len = stream.GetSize();
3696 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003697 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003698 {
3699 if (response.GetChar() != 'F')
3700 return UINT64_MAX;
3701 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
3702 return retcode;
3703 }
3704 return UINT64_MAX;
3705}
3706
Greg Claytonfbb76342013-11-20 21:07:01 +00003707Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003708GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
3709 uint32_t &file_permissions)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003710{
Chaoren Lind3173f32015-05-29 19:52:29 +00003711 std::string path{file_spec.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003712 Error error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003713 lldb_private::StreamString stream;
3714 stream.PutCString("vFile:mode:");
Chaoren Lind3173f32015-05-29 19:52:29 +00003715 stream.PutCStringAsRawHex8(path.c_str());
Daniel Maleae0f8f572013-08-26 23:57:52 +00003716 const char* packet = stream.GetData();
3717 int packet_len = stream.GetSize();
3718 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003719 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003720 {
3721 if (response.GetChar() != 'F')
3722 {
3723 error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
Daniel Maleae0f8f572013-08-26 23:57:52 +00003724 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003725 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00003726 {
Greg Claytonfbb76342013-11-20 21:07:01 +00003727 const uint32_t mode = response.GetS32(-1);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00003728 if (static_cast<int32_t>(mode) == -1)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003729 {
Greg Claytonfbb76342013-11-20 21:07:01 +00003730 if (response.GetChar() == ',')
3731 {
3732 int response_errno = response.GetS32(-1);
3733 if (response_errno > 0)
3734 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3735 else
3736 error.SetErrorToGenericError();
3737 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003738 else
3739 error.SetErrorToGenericError();
3740 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003741 else
3742 {
3743 file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
3744 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003745 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003746 }
3747 else
3748 {
3749 error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
3750 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003751 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003752}
3753
3754uint64_t
3755GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
3756 uint64_t offset,
3757 void *dst,
3758 uint64_t dst_len,
3759 Error &error)
3760{
3761 lldb_private::StreamString stream;
3762 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
3763 const char* packet = stream.GetData();
3764 int packet_len = stream.GetSize();
3765 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003766 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003767 {
3768 if (response.GetChar() != 'F')
3769 return 0;
3770 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
3771 if (retcode == UINT32_MAX)
3772 return retcode;
3773 const char next = (response.Peek() ? *response.Peek() : 0);
3774 if (next == ',')
3775 return 0;
3776 if (next == ';')
3777 {
3778 response.GetChar(); // skip the semicolon
3779 std::string buffer;
3780 if (response.GetEscapedBinaryData(buffer))
3781 {
3782 const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
3783 if (data_to_write > 0)
3784 memcpy(dst, &buffer[0], data_to_write);
3785 return data_to_write;
3786 }
3787 }
3788 }
3789 return 0;
3790}
3791
3792uint64_t
3793GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
3794 uint64_t offset,
3795 const void* src,
3796 uint64_t src_len,
3797 Error &error)
3798{
3799 lldb_private::StreamGDBRemote stream;
3800 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3801 stream.PutEscapedBytes(src, src_len);
3802 const char* packet = stream.GetData();
3803 int packet_len = stream.GetSize();
3804 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003805 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003806 {
3807 if (response.GetChar() != 'F')
3808 {
3809 error.SetErrorStringWithFormat("write file failed");
3810 return 0;
3811 }
3812 uint64_t bytes_written = response.GetU64(UINT64_MAX);
3813 if (bytes_written == UINT64_MAX)
3814 {
3815 error.SetErrorToGenericError();
3816 if (response.GetChar() == ',')
3817 {
3818 int response_errno = response.GetS32(-1);
3819 if (response_errno > 0)
3820 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3821 }
3822 return 0;
3823 }
3824 return bytes_written;
3825 }
3826 else
3827 {
3828 error.SetErrorString ("failed to send vFile:pwrite packet");
3829 }
3830 return 0;
3831}
3832
Greg Claytonfbb76342013-11-20 21:07:01 +00003833Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003834GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, const FileSpec &dst)
Greg Claytonfbb76342013-11-20 21:07:01 +00003835{
Chaoren Lind3173f32015-05-29 19:52:29 +00003836 std::string src_path{src.GetPath(false)},
3837 dst_path{dst.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003838 Error error;
3839 lldb_private::StreamGDBRemote stream;
3840 stream.PutCString("vFile:symlink:");
3841 // the unix symlink() command reverses its parameters where the dst if first,
3842 // so we follow suit here
Chaoren Lind3173f32015-05-29 19:52:29 +00003843 stream.PutCStringAsRawHex8(dst_path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003844 stream.PutChar(',');
Chaoren Lind3173f32015-05-29 19:52:29 +00003845 stream.PutCStringAsRawHex8(src_path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003846 const char* packet = stream.GetData();
3847 int packet_len = stream.GetSize();
3848 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003849 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00003850 {
3851 if (response.GetChar() == 'F')
3852 {
3853 uint32_t result = response.GetU32(UINT32_MAX);
3854 if (result != 0)
3855 {
3856 error.SetErrorToGenericError();
3857 if (response.GetChar() == ',')
3858 {
3859 int response_errno = response.GetS32(-1);
3860 if (response_errno > 0)
3861 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3862 }
3863 }
3864 }
3865 else
3866 {
3867 // Should have returned with 'F<result>[,<errno>]'
3868 error.SetErrorStringWithFormat("symlink failed");
3869 }
3870 }
3871 else
3872 {
3873 error.SetErrorString ("failed to send vFile:symlink packet");
3874 }
3875 return error;
3876}
3877
3878Error
Chaoren Lind3173f32015-05-29 19:52:29 +00003879GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec)
Greg Claytonfbb76342013-11-20 21:07:01 +00003880{
Chaoren Lind3173f32015-05-29 19:52:29 +00003881 std::string path{file_spec.GetPath(false)};
Greg Claytonfbb76342013-11-20 21:07:01 +00003882 Error error;
3883 lldb_private::StreamGDBRemote stream;
3884 stream.PutCString("vFile:unlink:");
3885 // the unix symlink() command reverses its parameters where the dst if first,
3886 // so we follow suit here
Chaoren Lind3173f32015-05-29 19:52:29 +00003887 stream.PutCStringAsRawHex8(path.c_str());
Greg Claytonfbb76342013-11-20 21:07:01 +00003888 const char* packet = stream.GetData();
3889 int packet_len = stream.GetSize();
3890 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003891 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Greg Claytonfbb76342013-11-20 21:07:01 +00003892 {
3893 if (response.GetChar() == 'F')
3894 {
3895 uint32_t result = response.GetU32(UINT32_MAX);
3896 if (result != 0)
3897 {
3898 error.SetErrorToGenericError();
3899 if (response.GetChar() == ',')
3900 {
3901 int response_errno = response.GetS32(-1);
3902 if (response_errno > 0)
3903 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3904 }
3905 }
3906 }
3907 else
3908 {
3909 // Should have returned with 'F<result>[,<errno>]'
3910 error.SetErrorStringWithFormat("unlink failed");
3911 }
3912 }
3913 else
3914 {
3915 error.SetErrorString ("failed to send vFile:unlink packet");
3916 }
3917 return error;
3918}
3919
Daniel Maleae0f8f572013-08-26 23:57:52 +00003920// Extension of host I/O packets to get whether a file exists.
3921bool
3922GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
3923{
Chaoren Lind3173f32015-05-29 19:52:29 +00003924 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003925 lldb_private::StreamString stream;
3926 stream.PutCString("vFile:exists:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003927 stream.PutCStringAsRawHex8(path.c_str());
3928 const char* packet = stream.GetData();
3929 int packet_len = stream.GetSize();
3930 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003931 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003932 {
3933 if (response.GetChar() != 'F')
3934 return false;
3935 if (response.GetChar() != ',')
3936 return false;
3937 bool retcode = (response.GetChar() != '0');
3938 return retcode;
3939 }
3940 return false;
3941}
3942
3943bool
3944GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
3945 uint64_t &high,
3946 uint64_t &low)
3947{
Chaoren Lind3173f32015-05-29 19:52:29 +00003948 std::string path(file_spec.GetPath(false));
Daniel Maleae0f8f572013-08-26 23:57:52 +00003949 lldb_private::StreamString stream;
3950 stream.PutCString("vFile:MD5:");
Daniel Maleae0f8f572013-08-26 23:57:52 +00003951 stream.PutCStringAsRawHex8(path.c_str());
3952 const char* packet = stream.GetData();
3953 int packet_len = stream.GetSize();
3954 StringExtractorGDBRemote response;
Greg Clayton3dedae12013-12-06 21:45:27 +00003955 if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
Daniel Maleae0f8f572013-08-26 23:57:52 +00003956 {
3957 if (response.GetChar() != 'F')
3958 return false;
3959 if (response.GetChar() != ',')
3960 return false;
3961 if (response.Peek() && *response.Peek() == 'x')
3962 return false;
3963 low = response.GetHexMaxU64(false, UINT64_MAX);
3964 high = response.GetHexMaxU64(false, UINT64_MAX);
3965 return true;
3966 }
3967 return false;
3968}
Greg Claytonf74cf862013-11-13 23:28:31 +00003969
3970bool
Jason Molendaa3329782014-03-29 18:54:20 +00003971GDBRemoteCommunicationClient::AvoidGPackets (ProcessGDBRemote *process)
3972{
3973 // Some targets have issues with g/G packets and we need to avoid using them
3974 if (m_avoid_g_packets == eLazyBoolCalculate)
3975 {
3976 if (process)
3977 {
3978 m_avoid_g_packets = eLazyBoolNo;
3979 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3980 if (arch.IsValid()
3981 && arch.GetTriple().getVendor() == llvm::Triple::Apple
3982 && arch.GetTriple().getOS() == llvm::Triple::IOS
Todd Fialad8eaa172014-07-23 14:37:35 +00003983 && arch.GetTriple().getArch() == llvm::Triple::aarch64)
Jason Molendaa3329782014-03-29 18:54:20 +00003984 {
3985 m_avoid_g_packets = eLazyBoolYes;
3986 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3987 if (gdb_server_version != 0)
3988 {
3989 const char *gdb_server_name = GetGDBServerProgramName();
3990 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0)
3991 {
3992 if (gdb_server_version >= 310)
3993 m_avoid_g_packets = eLazyBoolNo;
3994 }
3995 }
3996 }
3997 }
3998 }
3999 return m_avoid_g_packets == eLazyBoolYes;
4000}
4001
4002bool
Greg Claytonf74cf862013-11-13 23:28:31 +00004003GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
4004{
4005 Mutex::Locker locker;
4006 if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet."))
4007 {
4008 const bool thread_suffix_supported = GetThreadSuffixSupported();
4009
4010 if (thread_suffix_supported || SetCurrentThread(tid))
4011 {
4012 char packet[64];
4013 int packet_len = 0;
4014 if (thread_suffix_supported)
4015 packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid);
4016 else
4017 packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
4018 assert (packet_len < ((int)sizeof(packet) - 1));
Greg Clayton3dedae12013-12-06 21:45:27 +00004019 return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
Greg Claytonf74cf862013-11-13 23:28:31 +00004020 }
4021 }
4022 return false;
4023
4024}
4025
4026
4027bool
4028GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response)
4029{
4030 Mutex::Locker locker;
4031 if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet."))
4032 {
4033 const bool thread_suffix_supported = GetThreadSuffixSupported();
4034
4035 if (thread_suffix_supported || SetCurrentThread(tid))
4036 {
4037 char packet[64];
4038 int packet_len = 0;
4039 // Get all registers in one packet
4040 if (thread_suffix_supported)
4041 packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid);
4042 else
4043 packet_len = ::snprintf (packet, sizeof(packet), "g");
4044 assert (packet_len < ((int)sizeof(packet) - 1));
Greg Clayton3dedae12013-12-06 21:45:27 +00004045 return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
Greg Claytonf74cf862013-11-13 23:28:31 +00004046 }
4047 }
4048 return false;
4049}
4050bool
4051GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
4052{
4053 save_id = 0; // Set to invalid save ID
4054 if (m_supports_QSaveRegisterState == eLazyBoolNo)
4055 return false;
4056
4057 m_supports_QSaveRegisterState = eLazyBoolYes;
4058 Mutex::Locker locker;
4059 if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState."))
4060 {
4061 const bool thread_suffix_supported = GetThreadSuffixSupported();
4062 if (thread_suffix_supported || SetCurrentThread(tid))
4063 {
4064 char packet[256];
4065 if (thread_suffix_supported)
4066 ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid);
4067 else
Ilia K686b1fe2015-02-27 19:43:08 +00004068 ::snprintf(packet, sizeof(packet), "QSaveRegisterState");
Greg Claytonf74cf862013-11-13 23:28:31 +00004069
4070 StringExtractorGDBRemote response;
4071
Greg Clayton3dedae12013-12-06 21:45:27 +00004072 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
Greg Claytonf74cf862013-11-13 23:28:31 +00004073 {
4074 if (response.IsUnsupportedResponse())
4075 {
4076 // This packet isn't supported, don't try calling it again
4077 m_supports_QSaveRegisterState = eLazyBoolNo;
4078 }
4079
4080 const uint32_t response_save_id = response.GetU32(0);
4081 if (response_save_id != 0)
4082 {
4083 save_id = response_save_id;
4084 return true;
4085 }
4086 }
4087 }
4088 }
4089 return false;
4090}
4091
4092bool
4093GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
4094{
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004095 // We use the "m_supports_QSaveRegisterState" variable here because the
Greg Claytonf74cf862013-11-13 23:28:31 +00004096 // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
4097 // order to be useful
4098 if (m_supports_QSaveRegisterState == eLazyBoolNo)
4099 return false;
4100
4101 Mutex::Locker locker;
4102 if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState."))
4103 {
4104 const bool thread_suffix_supported = GetThreadSuffixSupported();
4105 if (thread_suffix_supported || SetCurrentThread(tid))
4106 {
4107 char packet[256];
4108 if (thread_suffix_supported)
4109 ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid);
4110 else
4111 ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id);
4112
4113 StringExtractorGDBRemote response;
4114
Greg Clayton3dedae12013-12-06 21:45:27 +00004115 if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
Greg Claytonf74cf862013-11-13 23:28:31 +00004116 {
4117 if (response.IsOKResponse())
4118 {
4119 return true;
4120 }
4121 else if (response.IsUnsupportedResponse())
4122 {
4123 // This packet isn't supported, don't try calling this packet or
4124 // QSaveRegisterState again...
4125 m_supports_QSaveRegisterState = eLazyBoolNo;
4126 }
4127 }
4128 }
4129 }
4130 return false;
4131}
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00004132
4133bool
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00004134GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec,
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00004135 const lldb_private::ArchSpec& arch_spec,
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00004136 ModuleSpec &module_spec)
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00004137{
Oleksiy Vyalov7d9d9412015-04-16 07:02:56 +00004138 std::string module_path = module_file_spec.GetPath (false);
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00004139 if (module_path.empty ())
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00004140 return false;
4141
4142 StreamString packet;
4143 packet.PutCString("qModuleInfo:");
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00004144 packet.PutCStringAsRawHex8(module_path.c_str());
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00004145 packet.PutCString(";");
Chaoren Linf34f4102015-05-09 01:21:32 +00004146 const auto& triple = arch_spec.GetTriple().getTriple();
Chaoren Lind3173f32015-05-29 19:52:29 +00004147 packet.PutCStringAsRawHex8(triple.c_str());
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00004148
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00004149 StringExtractorGDBRemote response;
4150 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success)
4151 return false;
4152
Aidan Doddsdf627e72015-05-05 08:31:55 +00004153 if (response.IsErrorResponse () || response.IsUnsupportedResponse ())
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00004154 return false;
4155
4156 std::string name;
4157 std::string value;
4158 bool success;
4159 StringExtractor extractor;
4160
4161 module_spec.Clear ();
4162 module_spec.GetFileSpec () = module_file_spec;
4163
4164 while (response.GetNameColonValue (name, value))
4165 {
4166 if (name == "uuid" || name == "md5")
4167 {
4168 extractor.GetStringRef ().swap (value);
4169 extractor.SetFilePos (0);
4170 extractor.GetHexByteString (value);
4171 module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2);
4172 }
4173 else if (name == "triple")
4174 {
4175 extractor.GetStringRef ().swap (value);
4176 extractor.SetFilePos (0);
4177 extractor.GetHexByteString (value);
4178 module_spec.GetArchitecture().SetTriple (value.c_str ());
4179 }
4180 else if (name == "file_offset")
4181 {
4182 const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
4183 if (success)
4184 module_spec.SetObjectOffset (ival);
4185 }
4186 else if (name == "file_size")
4187 {
4188 const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
4189 if (success)
4190 module_spec.SetObjectSize (ival);
4191 }
4192 else if (name == "file_path")
4193 {
4194 extractor.GetStringRef ().swap (value);
4195 extractor.SetFilePos (0);
4196 extractor.GetHexByteString (value);
Chaoren Linf34f4102015-05-09 01:21:32 +00004197 module_spec.GetFileSpec() = FileSpec(value.c_str(), false, arch_spec);
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00004198 }
4199 }
4200
4201 return true;
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00004202}
Colin Rileyc3c95b22015-04-16 15:51:33 +00004203
4204// query the target remote for extended information using the qXfer packet
4205//
4206// example: object='features', annex='target.xml', out=<xml output>
4207// return: 'true' on success
4208// 'false' on failure (err set)
4209bool
4210GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString object,
4211 const lldb_private::ConstString annex,
4212 std::string & out,
4213 lldb_private::Error & err) {
4214
4215 std::stringstream output;
4216 StringExtractorGDBRemote chunk;
4217
Greg Claytond04f0ed2015-05-26 18:00:51 +00004218 uint64_t size = GetRemoteMaxPacketSize();
4219 if (size == 0)
4220 size = 0x1000;
4221 size = size - 1; // Leave space for the 'm' or 'l' character in the response
4222 int offset = 0;
4223 bool active = true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00004224
4225 // loop until all data has been read
4226 while ( active ) {
4227
4228 // send query extended feature packet
4229 std::stringstream packet;
4230 packet << "qXfer:"
Ewan Crawford682e8422015-06-26 09:38:27 +00004231 << object.AsCString("") << ":read:"
4232 << annex.AsCString("") << ":"
Colin Rileyc3c95b22015-04-16 15:51:33 +00004233 << std::hex << offset << ","
4234 << std::hex << size;
4235
4236 GDBRemoteCommunication::PacketResult res =
4237 SendPacketAndWaitForResponse( packet.str().c_str(),
4238 chunk,
4239 false );
4240
4241 if ( res != GDBRemoteCommunication::PacketResult::Success ) {
4242 err.SetErrorString( "Error sending $qXfer packet" );
4243 return false;
4244 }
4245
4246 const std::string & str = chunk.GetStringRef( );
4247 if ( str.length() == 0 ) {
4248 // should have some data in chunk
4249 err.SetErrorString( "Empty response from $qXfer packet" );
4250 return false;
4251 }
4252
4253 // check packet code
4254 switch ( str[0] ) {
4255 // last chunk
4256 case ( 'l' ):
4257 active = false;
Aidan Doddsed9f6122015-04-29 10:08:17 +00004258 // fall through intentional
Colin Rileyc3c95b22015-04-16 15:51:33 +00004259
4260 // more chunks
4261 case ( 'm' ) :
4262 if ( str.length() > 1 )
4263 output << &str[1];
Aidan Doddsed9f6122015-04-29 10:08:17 +00004264 offset += size;
Colin Rileyc3c95b22015-04-16 15:51:33 +00004265 break;
4266
4267 // unknown chunk
4268 default:
4269 err.SetErrorString( "Invalid continuation code from $qXfer packet" );
4270 return false;
4271 }
4272 }
4273
4274 out = output.str( );
4275 err.Success( );
4276 return true;
4277}
Greg Clayton0b90be12015-06-23 21:27:50 +00004278
4279// Notify the target that gdb is prepared to serve symbol lookup requests.
4280// packet: "qSymbol::"
4281// reply:
4282// OK The target does not need to look up any (more) symbols.
4283// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex encoded).
4284// LLDB may provide the value by sending another qSymbol packet
4285// in the form of"qSymbol:<sym_value>:<sym_name>".
4286
4287void
4288GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
4289{
4290 if (m_supports_qSymbol)
4291 {
4292 Mutex::Locker locker;
4293 if (GetSequenceMutex(locker, "GDBRemoteCommunicationClient::ServeSymbolLookups() failed due to not getting the sequence mutex"))
4294 {
4295 StreamString packet;
4296 packet.PutCString ("qSymbol::");
4297 while (1)
4298 {
4299 StringExtractorGDBRemote response;
4300 if (SendPacketAndWaitForResponseNoLock(packet.GetData(), packet.GetSize(), response) == PacketResult::Success)
4301 {
4302 if (response.IsOKResponse())
4303 {
4304 // We are done serving symbols requests
4305 return;
4306 }
4307
4308 if (response.IsUnsupportedResponse())
4309 {
4310 // qSymbol is not supported by the current GDB server we are connected to
4311 m_supports_qSymbol = false;
4312 return;
4313 }
4314 else
4315 {
4316 llvm::StringRef response_str(response.GetStringRef());
4317 if (response_str.startswith("qSymbol:"))
4318 {
4319 response.SetFilePos(strlen("qSymbol:"));
4320 std::string symbol_name;
4321 if (response.GetHexByteString(symbol_name))
4322 {
4323 if (symbol_name.empty())
4324 return;
4325
4326 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
4327 lldb_private::SymbolContextList sc_list;
4328 if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list))
4329 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004330 const size_t num_scs = sc_list.GetSize();
4331 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 +00004332 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004333 SymbolContext sc;
4334 if (sc_list.GetContextAtIndex(sc_idx, sc))
4335 {
4336 if (sc.symbol)
4337 {
4338 switch (sc.symbol->GetType())
4339 {
4340 case eSymbolTypeInvalid:
4341 case eSymbolTypeAbsolute:
4342 case eSymbolTypeUndefined:
4343 case eSymbolTypeSourceFile:
4344 case eSymbolTypeHeaderFile:
4345 case eSymbolTypeObjectFile:
4346 case eSymbolTypeCommonBlock:
4347 case eSymbolTypeBlock:
4348 case eSymbolTypeLocal:
4349 case eSymbolTypeParam:
4350 case eSymbolTypeVariable:
4351 case eSymbolTypeVariableType:
4352 case eSymbolTypeLineEntry:
4353 case eSymbolTypeLineHeader:
4354 case eSymbolTypeScopeBegin:
4355 case eSymbolTypeScopeEnd:
4356 case eSymbolTypeAdditional:
4357 case eSymbolTypeCompiler:
4358 case eSymbolTypeInstrumentation:
4359 case eSymbolTypeTrampoline:
4360 break;
4361
4362 case eSymbolTypeCode:
4363 case eSymbolTypeResolver:
4364 case eSymbolTypeData:
4365 case eSymbolTypeRuntime:
4366 case eSymbolTypeException:
4367 case eSymbolTypeObjCClass:
4368 case eSymbolTypeObjCMetaClass:
4369 case eSymbolTypeObjCIVar:
4370 case eSymbolTypeReExported:
4371 symbol_load_addr = sc.symbol->GetLoadAddress(&process->GetTarget());
4372 break;
4373 }
4374 }
4375 }
Greg Clayton0b90be12015-06-23 21:27:50 +00004376 }
4377 }
4378 // This is the normal path where our symbol lookup was successful and we want
4379 // to send a packet with the new symbol value and see if another lookup needs to be
4380 // done.
4381
4382 // Change "packet" to contain the requested symbol value and name
4383 packet.Clear();
4384 packet.PutCString("qSymbol:");
4385 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
4386 packet.Printf("%" PRIx64, symbol_load_addr);
4387 packet.PutCString(":");
4388 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
4389 continue; // go back to the while loop and send "packet" and wait for another response
4390 }
4391 }
4392 }
4393 }
4394 }
4395 // If we make it here, the symbol request packet response wasn't valid or
4396 // our symbol lookup failed so we must abort
4397 return;
4398
4399 }
4400 }
4401}
4402