blob: 30db5583ac87cb9168b588ee8bc98d196496d03f [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
Greg Clayton576d8832011-03-22 04:00:09 +000010#include "GDBRemoteCommunicationClient.h"
11
12// C Includes
Greg Claytone034a042015-05-21 20:52:06 +000013#include <math.h>
Daniel Maleab89d0492013-08-28 16:06:16 +000014#include <sys/stat.h>
15
Greg Clayton576d8832011-03-22 04:00:09 +000016// C++ Includes
Greg Claytone034a042015-05-21 20:52:06 +000017#include <numeric>
Kate Stoneb9c1b512016-09-06 20:57:50 +000018#include <sstream>
Han Ming Ong4b6459f2013-01-18 23:11:53 +000019
Greg Clayton576d8832011-03-22 04:00:09 +000020// Other libraries and framework includes
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +000021#include "lldb/Core/ModuleSpec.h"
Greg Clayton576d8832011-03-22 04:00:09 +000022#include "lldb/Core/State.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000023#include "lldb/Host/HostInfo.h"
Pavel Labath16064d32018-03-20 11:56:24 +000024#include "lldb/Host/XML.h"
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000025#include "lldb/Interpreter/Args.h"
Greg Clayton0b90be12015-06-23 21:27:50 +000026#include "lldb/Symbol/Symbol.h"
Pavel Labath4cb69922016-07-29 15:41:52 +000027#include "lldb/Target/MemoryRegionInfo.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000028#include "lldb/Target/Target.h"
Todd Fiala75930012016-08-19 04:21:48 +000029#include "lldb/Target/UnixSignals.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000030#include "lldb/Utility/DataBufferHeap.h"
Pavel Labath2f1fbae2016-09-08 10:07:04 +000031#include "lldb/Utility/JSON.h"
Todd Fiala75930012016-08-19 04:21:48 +000032#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000033#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000034#include "lldb/Utility/StreamString.h"
Greg Clayton576d8832011-03-22 04:00:09 +000035
36// Project includes
Greg Clayton576d8832011-03-22 04:00:09 +000037#include "ProcessGDBRemote.h"
38#include "ProcessGDBRemoteLog.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000039#include "Utility/StringExtractorGDBRemote.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000040#include "lldb/Host/Config.h"
Greg Clayton576d8832011-03-22 04:00:09 +000041
Zachary Turner54695a32016-08-29 19:58:14 +000042#include "llvm/ADT/StringSwitch.h"
43
Kate Stoneb9c1b512016-09-06 20:57:50 +000044#if defined(HAVE_LIBCOMPRESSION)
Jason Molenda91ffe0a2015-06-18 21:46:06 +000045#include <compression.h>
46#endif
47
Greg Clayton576d8832011-03-22 04:00:09 +000048using namespace lldb;
49using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000050using namespace lldb_private::process_gdb_remote;
Pavel Labath1eff73c2016-11-24 10:54:49 +000051using namespace std::chrono;
Greg Clayton576d8832011-03-22 04:00:09 +000052
53//----------------------------------------------------------------------
54// GDBRemoteCommunicationClient constructor
55//----------------------------------------------------------------------
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000056GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000057 : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000058 m_supports_not_sending_acks(eLazyBoolCalculate),
59 m_supports_thread_suffix(eLazyBoolCalculate),
60 m_supports_threads_in_stop_reply(eLazyBoolCalculate),
61 m_supports_vCont_all(eLazyBoolCalculate),
62 m_supports_vCont_any(eLazyBoolCalculate),
63 m_supports_vCont_c(eLazyBoolCalculate),
64 m_supports_vCont_C(eLazyBoolCalculate),
65 m_supports_vCont_s(eLazyBoolCalculate),
66 m_supports_vCont_S(eLazyBoolCalculate),
67 m_qHostInfo_is_valid(eLazyBoolCalculate),
68 m_curr_pid_is_valid(eLazyBoolCalculate),
69 m_qProcessInfo_is_valid(eLazyBoolCalculate),
70 m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
71 m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
72 m_supports_memory_region_info(eLazyBoolCalculate),
73 m_supports_watchpoint_support_info(eLazyBoolCalculate),
74 m_supports_detach_stay_stopped(eLazyBoolCalculate),
75 m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
76 m_attach_or_wait_reply(eLazyBoolCalculate),
77 m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000079 m_avoid_g_packets(eLazyBoolCalculate),
80 m_supports_QSaveRegisterState(eLazyBoolCalculate),
81 m_supports_qXfer_auxv_read(eLazyBoolCalculate),
82 m_supports_qXfer_libraries_read(eLazyBoolCalculate),
83 m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
84 m_supports_qXfer_features_read(eLazyBoolCalculate),
Pavel Labath16064d32018-03-20 11:56:24 +000085 m_supports_qXfer_memory_map_read(eLazyBoolCalculate),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000086 m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
87 m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
88 m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000089 m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
Eugene Zemtsov7993cc52017-03-07 21:34:40 +000090 m_supports_QPassSignals(eLazyBoolCalculate),
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +000091 m_supports_error_string_reply(eLazyBoolCalculate),
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
93 m_supports_qUserName(true), m_supports_qGroupName(true),
94 m_supports_qThreadStopInfo(true), m_supports_z0(true),
95 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
96 m_supports_z4(true), m_supports_QEnvironment(true),
97 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
98 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
Pavel Labath2f1fbae2016-09-08 10:07:04 +000099 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
100 m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000101 m_curr_tid_run(LLDB_INVALID_THREAD_ID),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102 m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
103 m_os_version_major(UINT32_MAX), m_os_version_minor(UINT32_MAX),
104 m_os_version_update(UINT32_MAX), m_os_build(), m_os_kernel(),
105 m_hostname(), m_gdb_server_name(), m_gdb_server_version(UINT32_MAX),
106 m_default_packet_timeout(0), m_max_packet_size(0),
107 m_qSupported_response(), m_supported_async_json_packets_is_valid(false),
Pavel Labath16064d32018-03-20 11:56:24 +0000108 m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
109 m_qXfer_memory_map_loaded(false) {}
Greg Clayton576d8832011-03-22 04:00:09 +0000110
111//----------------------------------------------------------------------
112// Destructor
113//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
115 if (IsConnected())
116 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000117}
118
Zachary Turner97206d52017-05-12 04:51:55 +0000119bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 ResetDiscoverableSettings(false);
Greg Claytonfb909312013-11-23 01:58:15 +0000121
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122 // Start the read thread after we send the handshake ack since if we
123 // fail to send the handshake ack, there is no reason to continue...
124 if (SendAck()) {
125 // Wait for any responses that might have been queued up in the remote
126 // GDB server and flush them all
127 StringExtractorGDBRemote response;
128 PacketResult packet_result = PacketResult::Success;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 while (packet_result == PacketResult::Success)
Pavel Labath1eff73c2016-11-24 10:54:49 +0000130 packet_result = ReadPacket(response, milliseconds(10), false);
Ed Maste48f986f2013-12-18 15:31:45 +0000131
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 // The return value from QueryNoAckModeSupported() is true if the packet
133 // was sent and _any_ response (including UNIMPLEMENTED) was received),
134 // or false if no response was received. This quickly tells us if we have
135 // a live connection to a remote GDB server...
136 if (QueryNoAckModeSupported()) {
137 return true;
138 } else {
139 if (error_ptr)
140 error_ptr->SetErrorString("failed to get reply to handshake packet");
Greg Claytonfb909312013-11-23 01:58:15 +0000141 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 } else {
143 if (error_ptr)
144 error_ptr->SetErrorString("failed to send the handshake ack");
145 }
146 return false;
Greg Clayton1cb64962011-03-24 04:28:38 +0000147}
148
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149bool GDBRemoteCommunicationClient::GetEchoSupported() {
150 if (m_supports_qEcho == eLazyBoolCalculate) {
151 GetRemoteQSupported();
152 }
153 return m_supports_qEcho == eLazyBoolYes;
Greg Claytonb30c50c2015-05-29 00:01:55 +0000154}
155
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000156bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
157 if (m_supports_QPassSignals == eLazyBoolCalculate) {
158 GetRemoteQSupported();
159 }
160 return m_supports_QPassSignals == eLazyBoolYes;
161}
162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
164 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
165 GetRemoteQSupported();
166 }
167 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000168}
169
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
171 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
172 GetRemoteQSupported();
173 }
174 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000175}
176
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
178 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
179 GetRemoteQSupported();
180 }
181 return m_supports_qXfer_libraries_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000182}
183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
185 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
186 GetRemoteQSupported();
187 }
188 return m_supports_qXfer_auxv_read == eLazyBoolYes;
Steve Pucci03904ac2014-03-04 23:18:46 +0000189}
190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
192 if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
193 GetRemoteQSupported();
194 }
195 return m_supports_qXfer_features_read == eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000196}
197
Pavel Labath16064d32018-03-20 11:56:24 +0000198bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
199 if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
200 GetRemoteQSupported();
201 }
202 return m_supports_qXfer_memory_map_read == eLazyBoolYes;
203}
204
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
206 if (m_max_packet_size == 0) {
207 GetRemoteQSupported();
208 }
209 return m_max_packet_size;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000210}
211
Kate Stoneb9c1b512016-09-06 20:57:50 +0000212bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
213 if (m_supports_not_sending_acks == eLazyBoolCalculate) {
214 m_send_acks = true;
215 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000216
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217 // This is the first real packet that we'll send in a debug session and it
218 // may take a little
219 // longer than normal to receive a reply. Wait at least 6 seconds for a
220 // reply to this packet.
Jason Molenda36a216e2014-07-24 01:36:24 +0000221
Pavel Labath1eff73c2016-11-24 10:54:49 +0000222 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
Colin Rileyc3c95b22015-04-16 15:51:33 +0000223
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000224 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
226 PacketResult::Success) {
227 if (response.IsOKResponse()) {
228 m_send_acks = false;
229 m_supports_not_sending_acks = eLazyBoolYes;
230 }
231 return true;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000232 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 }
234 return false;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000235}
Greg Clayton576d8832011-03-22 04:00:09 +0000236
Kate Stoneb9c1b512016-09-06 20:57:50 +0000237void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
238 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
239 m_supports_threads_in_stop_reply = eLazyBoolNo;
240
241 StringExtractorGDBRemote response;
242 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
243 false) == PacketResult::Success) {
244 if (response.IsOKResponse())
245 m_supports_threads_in_stop_reply = eLazyBoolYes;
Pavel Labath5c95ee42016-08-30 13:56:11 +0000246 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247 }
Pavel Labath0faf3732016-08-25 08:34:57 +0000248}
Greg Clayton576d8832011-03-22 04:00:09 +0000249
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
251 if (m_attach_or_wait_reply == eLazyBoolCalculate) {
252 m_attach_or_wait_reply = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +0000253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 StringExtractorGDBRemote response;
255 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
256 false) == PacketResult::Success) {
257 if (response.IsOKResponse())
258 m_attach_or_wait_reply = eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +0000259 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260 }
261 if (m_attach_or_wait_reply == eLazyBoolYes)
262 return true;
263 else
Greg Clayton576d8832011-03-22 04:00:09 +0000264 return false;
265}
266
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
268 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
269 m_prepare_for_reg_writing_reply = eLazyBoolNo;
270
271 StringExtractorGDBRemote response;
272 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
273 false) == PacketResult::Success) {
274 if (response.IsOKResponse())
275 m_prepare_for_reg_writing_reply = eLazyBoolYes;
276 }
277 }
278 if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
279 return true;
280 else
281 return false;
282}
283
284void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
285 if (did_exec == false) {
286 // Hard reset everything, this is when we first connect to a GDB server
287 m_supports_not_sending_acks = eLazyBoolCalculate;
288 m_supports_thread_suffix = eLazyBoolCalculate;
289 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
290 m_supports_vCont_c = eLazyBoolCalculate;
291 m_supports_vCont_C = eLazyBoolCalculate;
292 m_supports_vCont_s = eLazyBoolCalculate;
293 m_supports_vCont_S = eLazyBoolCalculate;
294 m_supports_p = eLazyBoolCalculate;
295 m_supports_x = eLazyBoolCalculate;
296 m_supports_QSaveRegisterState = eLazyBoolCalculate;
297 m_qHostInfo_is_valid = eLazyBoolCalculate;
298 m_curr_pid_is_valid = eLazyBoolCalculate;
299 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
300 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
301 m_supports_memory_region_info = eLazyBoolCalculate;
302 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
303 m_attach_or_wait_reply = eLazyBoolCalculate;
304 m_avoid_g_packets = eLazyBoolCalculate;
305 m_supports_qXfer_auxv_read = eLazyBoolCalculate;
306 m_supports_qXfer_libraries_read = eLazyBoolCalculate;
307 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
308 m_supports_qXfer_features_read = eLazyBoolCalculate;
Pavel Labath16064d32018-03-20 11:56:24 +0000309 m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000310 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
311 m_supports_qProcessInfoPID = true;
312 m_supports_qfProcessInfo = true;
313 m_supports_qUserName = true;
314 m_supports_qGroupName = true;
315 m_supports_qThreadStopInfo = true;
316 m_supports_z0 = true;
317 m_supports_z1 = true;
318 m_supports_z2 = true;
319 m_supports_z3 = true;
320 m_supports_z4 = true;
321 m_supports_QEnvironment = true;
322 m_supports_QEnvironmentHexEncoded = true;
323 m_supports_qSymbol = true;
324 m_qSymbol_requests_done = false;
325 m_supports_qModuleInfo = true;
326 m_host_arch.Clear();
327 m_os_version_major = UINT32_MAX;
328 m_os_version_minor = UINT32_MAX;
329 m_os_version_update = UINT32_MAX;
330 m_os_build.clear();
331 m_os_kernel.clear();
332 m_hostname.clear();
333 m_gdb_server_name.clear();
334 m_gdb_server_version = UINT32_MAX;
Pavel Labath1eff73c2016-11-24 10:54:49 +0000335 m_default_packet_timeout = seconds(0);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336 m_max_packet_size = 0;
337 m_qSupported_response.clear();
338 m_supported_async_json_packets_is_valid = false;
339 m_supported_async_json_packets_sp.reset();
Pavel Labath2f1fbae2016-09-08 10:07:04 +0000340 m_supports_jModulesInfo = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 }
342
343 // These flags should be reset when we first connect to a GDB server
344 // and when our inferior process execs
345 m_qProcessInfo_is_valid = eLazyBoolCalculate;
346 m_process_arch.Clear();
347}
348
349void GDBRemoteCommunicationClient::GetRemoteQSupported() {
350 // Clear out any capabilities we expect to see in the qSupported response
351 m_supports_qXfer_auxv_read = eLazyBoolNo;
352 m_supports_qXfer_libraries_read = eLazyBoolNo;
353 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
354 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
355 m_supports_qXfer_features_read = eLazyBoolNo;
Pavel Labath16064d32018-03-20 11:56:24 +0000356 m_supports_qXfer_memory_map_read = eLazyBoolNo;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000357 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
358 // not, we assume no limit
359
360 // build the qSupported packet
361 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
362 StreamString packet;
363 packet.PutCString("qSupported");
364 for (uint32_t i = 0; i < features.size(); ++i) {
365 packet.PutCString(i == 0 ? ":" : ";");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000366 packet.PutCString(features[i]);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367 }
368
369 StringExtractorGDBRemote response;
Zachary Turnerc1564272016-11-16 21:15:24 +0000370 if (SendPacketAndWaitForResponse(packet.GetString(), response,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000371 /*send_async=*/false) ==
372 PacketResult::Success) {
373 const char *response_cstr = response.GetStringRef().c_str();
374
375 // Hang on to the qSupported packet, so that platforms can do custom
376 // configuration of the transport before attaching/launching the
377 // process.
378 m_qSupported_response = response_cstr;
379
380 if (::strstr(response_cstr, "qXfer:auxv:read+"))
381 m_supports_qXfer_auxv_read = eLazyBoolYes;
382 if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
383 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
384 if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
385 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
386 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
387 }
388 if (::strstr(response_cstr, "qXfer:libraries:read+"))
389 m_supports_qXfer_libraries_read = eLazyBoolYes;
390 if (::strstr(response_cstr, "qXfer:features:read+"))
391 m_supports_qXfer_features_read = eLazyBoolYes;
Pavel Labath16064d32018-03-20 11:56:24 +0000392 if (::strstr(response_cstr, "qXfer:memory-map:read+"))
393 m_supports_qXfer_memory_map_read = eLazyBoolYes;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394
395 // Look for a list of compressions in the features list e.g.
396 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
397 const char *features_list = ::strstr(response_cstr, "qXfer:features:");
398 if (features_list) {
399 const char *compressions =
400 ::strstr(features_list, "SupportedCompressions=");
401 if (compressions) {
402 std::vector<std::string> supported_compressions;
403 compressions += sizeof("SupportedCompressions=") - 1;
404 const char *end_of_compressions = strchr(compressions, ';');
405 if (end_of_compressions == NULL) {
406 end_of_compressions = strchr(compressions, '\0');
407 }
408 const char *current_compression = compressions;
409 while (current_compression < end_of_compressions) {
410 const char *next_compression_name = strchr(current_compression, ',');
411 const char *end_of_this_word = next_compression_name;
412 if (next_compression_name == NULL ||
413 end_of_compressions < next_compression_name) {
414 end_of_this_word = end_of_compressions;
415 }
416
417 if (end_of_this_word) {
418 if (end_of_this_word == current_compression) {
419 current_compression++;
420 } else {
421 std::string this_compression(
422 current_compression, end_of_this_word - current_compression);
423 supported_compressions.push_back(this_compression);
424 current_compression = end_of_this_word + 1;
425 }
426 } else {
427 supported_compressions.push_back(current_compression);
428 current_compression = end_of_compressions;
429 }
430 }
431
432 if (supported_compressions.size() > 0) {
433 MaybeEnableCompression(supported_compressions);
434 }
435 }
436 }
437
438 if (::strstr(response_cstr, "qEcho"))
439 m_supports_qEcho = eLazyBoolYes;
440 else
441 m_supports_qEcho = eLazyBoolNo;
442
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000443 if (::strstr(response_cstr, "QPassSignals+"))
444 m_supports_QPassSignals = eLazyBoolYes;
445 else
446 m_supports_QPassSignals = eLazyBoolNo;
447
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448 const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
449 if (packet_size_str) {
450 StringExtractorGDBRemote packet_response(packet_size_str +
451 strlen("PacketSize="));
452 m_max_packet_size =
453 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
454 if (m_max_packet_size == 0) {
455 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
456 Log *log(
457 ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
458 if (log)
459 log->Printf("Garbled PacketSize spec in qSupported response");
460 }
461 }
462 }
463}
464
465bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
466 if (m_supports_thread_suffix == eLazyBoolCalculate) {
467 StringExtractorGDBRemote response;
468 m_supports_thread_suffix = eLazyBoolNo;
469 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
470 false) == PacketResult::Success) {
471 if (response.IsOKResponse())
472 m_supports_thread_suffix = eLazyBoolYes;
473 }
474 }
475 return m_supports_thread_suffix;
476}
477bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
478 if (m_supports_vCont_c == eLazyBoolCalculate) {
479 StringExtractorGDBRemote response;
480 m_supports_vCont_any = eLazyBoolNo;
481 m_supports_vCont_all = eLazyBoolNo;
482 m_supports_vCont_c = eLazyBoolNo;
483 m_supports_vCont_C = eLazyBoolNo;
484 m_supports_vCont_s = eLazyBoolNo;
485 m_supports_vCont_S = eLazyBoolNo;
486 if (SendPacketAndWaitForResponse("vCont?", response, false) ==
487 PacketResult::Success) {
488 const char *response_cstr = response.GetStringRef().c_str();
489 if (::strstr(response_cstr, ";c"))
490 m_supports_vCont_c = eLazyBoolYes;
491
492 if (::strstr(response_cstr, ";C"))
493 m_supports_vCont_C = eLazyBoolYes;
494
495 if (::strstr(response_cstr, ";s"))
496 m_supports_vCont_s = eLazyBoolYes;
497
498 if (::strstr(response_cstr, ";S"))
499 m_supports_vCont_S = eLazyBoolYes;
500
501 if (m_supports_vCont_c == eLazyBoolYes &&
502 m_supports_vCont_C == eLazyBoolYes &&
503 m_supports_vCont_s == eLazyBoolYes &&
504 m_supports_vCont_S == eLazyBoolYes) {
505 m_supports_vCont_all = eLazyBoolYes;
506 }
507
508 if (m_supports_vCont_c == eLazyBoolYes ||
509 m_supports_vCont_C == eLazyBoolYes ||
510 m_supports_vCont_s == eLazyBoolYes ||
511 m_supports_vCont_S == eLazyBoolYes) {
512 m_supports_vCont_any = eLazyBoolYes;
513 }
514 }
515 }
516
517 switch (flavor) {
518 case 'a':
519 return m_supports_vCont_any;
520 case 'A':
521 return m_supports_vCont_all;
522 case 'c':
523 return m_supports_vCont_c;
524 case 'C':
525 return m_supports_vCont_C;
526 case 's':
527 return m_supports_vCont_s;
528 case 'S':
529 return m_supports_vCont_S;
530 default:
531 break;
532 }
533 return false;
534}
535
Pavel Labath4b6f9592016-08-18 08:30:03 +0000536GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
538 lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
539 bool send_async) {
540 Lock lock(*this, send_async);
541 if (!lock) {
542 if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
543 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
544 log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
545 "for %s packet.",
Zachary Turnerc1564272016-11-16 21:15:24 +0000546 __FUNCTION__, payload.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 return PacketResult::ErrorNoSequenceLock;
548 }
Pavel Labath5c95ee42016-08-30 13:56:11 +0000549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550 if (GetThreadSuffixSupported())
551 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
552 else {
553 if (!SetCurrentThread(tid))
554 return PacketResult::ErrorSendFailed;
555 }
Pavel Labath4b6f9592016-08-18 08:30:03 +0000556
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
Pavel Labath4b6f9592016-08-18 08:30:03 +0000558}
559
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000560// Check if the target supports 'p' packet. It sends out a 'p'
561// packet and checks the response. A normal packet will tell us
562// that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000563//
564// Takes a valid thread ID because p needs to apply to a thread.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000565bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
566 if (m_supports_p == eLazyBoolCalculate) {
567 m_supports_p = eLazyBoolNo;
568 StreamString payload;
569 payload.PutCString("p0");
570 StringExtractorGDBRemote response;
571 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
572 response, false) ==
573 PacketResult::Success &&
574 response.IsNormalResponse()) {
575 m_supports_p = eLazyBoolYes;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000576 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577 }
578 return m_supports_p;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000579}
Greg Clayton576d8832011-03-22 04:00:09 +0000580
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
582 // Get information on all threads at one using the "jThreadsInfo" packet
583 StructuredData::ObjectSP object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000584
Kate Stoneb9c1b512016-09-06 20:57:50 +0000585 if (m_supports_jThreadsInfo) {
586 StringExtractorGDBRemote response;
587 response.SetResponseValidatorToJSON();
588 if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
589 PacketResult::Success) {
590 if (response.IsUnsupportedResponse()) {
591 m_supports_jThreadsInfo = false;
592 } else if (!response.Empty()) {
593 object_sp = StructuredData::ParseJSON(response.GetStringRef());
594 }
Greg Clayton358cf1e2015-06-25 21:46:34 +0000595 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 }
597 return object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000598}
599
Kate Stoneb9c1b512016-09-06 20:57:50 +0000600bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
601 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
602 StringExtractorGDBRemote response;
603 m_supports_jThreadExtendedInfo = eLazyBoolNo;
604 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
605 PacketResult::Success) {
606 if (response.IsOKResponse()) {
607 m_supports_jThreadExtendedInfo = eLazyBoolYes;
608 }
Jason Molenda705b1802014-06-13 02:37:02 +0000609 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 }
611 return m_supports_jThreadExtendedInfo;
Jason Molenda705b1802014-06-13 02:37:02 +0000612}
613
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000614void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
615 if (m_supports_error_string_reply == eLazyBoolCalculate) {
616 StringExtractorGDBRemote response;
617 // We try to enable error strings in remote packets
618 // but if we fail, we just work in the older way.
619 m_supports_error_string_reply = eLazyBoolNo;
620 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
621 PacketResult::Success) {
622 if (response.IsOKResponse()) {
623 m_supports_error_string_reply = eLazyBoolYes;
624 }
625 }
626 }
627}
628
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
630 if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
631 StringExtractorGDBRemote response;
632 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
633 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
634 response,
635 false) == PacketResult::Success) {
636 if (response.IsOKResponse()) {
637 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
638 }
Jason Molenda20ee21b2015-07-10 23:15:22 +0000639 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640 }
641 return m_supports_jLoadedDynamicLibrariesInfos;
Jason Molenda20ee21b2015-07-10 23:15:22 +0000642}
643
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
645 if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
646 StringExtractorGDBRemote response;
647 m_supports_jGetSharedCacheInfo = eLazyBoolNo;
648 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
649 PacketResult::Success) {
650 if (response.IsOKResponse()) {
651 m_supports_jGetSharedCacheInfo = eLazyBoolYes;
652 }
Jason Molenda37397352016-07-22 00:17:55 +0000653 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654 }
655 return m_supports_jGetSharedCacheInfo;
Jason Molenda37397352016-07-22 00:17:55 +0000656}
657
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658bool GDBRemoteCommunicationClient::GetxPacketSupported() {
659 if (m_supports_x == eLazyBoolCalculate) {
660 StringExtractorGDBRemote response;
661 m_supports_x = eLazyBoolNo;
662 char packet[256];
663 snprintf(packet, sizeof(packet), "x0,0");
664 if (SendPacketAndWaitForResponse(packet, response, false) ==
665 PacketResult::Success) {
666 if (response.IsOKResponse())
667 m_supports_x = eLazyBoolYes;
Jason Molendabdc4f122014-05-06 02:59:39 +0000668 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000669 }
670 return m_supports_x;
Jason Molendabdc4f122014-05-06 02:59:39 +0000671}
672
Greg Clayton3dedae12013-12-06 21:45:27 +0000673GDBRemoteCommunicationClient::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
675 const char *payload_prefix, std::string &response_string) {
676 Lock lock(*this, false);
677 if (!lock) {
678 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
679 GDBR_LOG_PACKETS));
680 if (log)
681 log->Printf("error: failed to get packet sequence mutex, not sending "
682 "packets with prefix '%s'",
683 payload_prefix);
684 return PacketResult::ErrorNoSequenceLock;
685 }
686
687 response_string = "";
688 std::string payload_prefix_str(payload_prefix);
689 unsigned int response_size = 0x1000;
690 if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
691 response_size = GetRemoteMaxPacketSize();
692 }
693
694 for (unsigned int offset = 0; true; offset += response_size) {
695 StringExtractorGDBRemote this_response;
696 // Construct payload
697 char sizeDescriptor[128];
698 snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
699 response_size);
700 PacketResult result = SendPacketAndWaitForResponseNoLock(
701 payload_prefix_str + sizeDescriptor, this_response);
702 if (result != PacketResult::Success)
703 return result;
704
705 const std::string &this_string = this_response.GetStringRef();
706
707 // Check for m or l as first character; l seems to mean this is the last
708 // chunk
709 char first_char = *this_string.c_str();
710 if (first_char != 'm' && first_char != 'l') {
711 return PacketResult::ErrorReplyInvalid;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000712 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000713 // Concatenate the result so far (skipping 'm' or 'l')
714 response_string.append(this_string, 1, std::string::npos);
715 if (first_char == 'l')
716 // We're done
717 return PacketResult::Success;
718 }
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000719}
720
Kate Stoneb9c1b512016-09-06 20:57:50 +0000721lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
722 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
723 return m_curr_pid;
Jaydeep Patil1142f832015-08-13 03:46:36 +0000724
Kate Stoneb9c1b512016-09-06 20:57:50 +0000725 // First try to retrieve the pid via the qProcessInfo request.
726 GetCurrentProcessInfo(allow_lazy);
727 if (m_curr_pid_is_valid == eLazyBoolYes) {
728 // We really got it.
729 return m_curr_pid;
730 } else {
731 // If we don't get a response for qProcessInfo, check if $qC gives us a
732 // result.
733 // $qC only returns a real process id on older debugserver and lldb-platform
734 // stubs.
735 // The gdb remote protocol documents $qC as returning the thread id, which
736 // newer
737 // debugserver and lldb-gdbserver stubs return correctly.
Greg Clayton576d8832011-03-22 04:00:09 +0000738 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000739 if (SendPacketAndWaitForResponse("qC", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +0000740 PacketResult::Success) {
741 if (response.GetChar() == 'Q') {
742 if (response.GetChar() == 'C') {
743 m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
744 if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
745 m_curr_pid_is_valid = eLazyBoolYes;
746 return m_curr_pid;
747 }
Greg Clayton576d8832011-03-22 04:00:09 +0000748 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749 }
Greg Clayton576d8832011-03-22 04:00:09 +0000750 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000751
752 // If we don't get a response for $qC, check if $qfThreadID gives us a
753 // result.
754 if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
755 std::vector<lldb::tid_t> thread_ids;
756 bool sequence_mutex_unavailable;
757 size_t size;
758 size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
759 if (size && sequence_mutex_unavailable == false) {
760 m_curr_pid = thread_ids.front();
761 m_curr_pid_is_valid = eLazyBoolYes;
762 return m_curr_pid;
763 }
Greg Clayton576d8832011-03-22 04:00:09 +0000764 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000765 }
766
767 return LLDB_INVALID_PROCESS_ID;
Greg Clayton576d8832011-03-22 04:00:09 +0000768}
769
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
771 error_str.clear();
772 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000773 if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
774 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 if (response.IsOKResponse())
776 return true;
777 if (response.GetChar() == 'E') {
778 // A string the describes what failed when launching...
779 error_str = response.GetStringRef().substr(1);
780 } else {
781 error_str.assign("unknown error occurred launching process");
Greg Claytonfbb76342013-11-20 21:07:01 +0000782 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783 } else {
784 error_str.assign("timed out waiting for app to launch");
785 }
786 return false;
Greg Clayton576d8832011-03-22 04:00:09 +0000787}
788
Kate Stoneb9c1b512016-09-06 20:57:50 +0000789int GDBRemoteCommunicationClient::SendArgumentsPacket(
790 const ProcessLaunchInfo &launch_info) {
791 // Since we don't get the send argv0 separate from the executable path, we
792 // need to
793 // make sure to use the actual executable path found in the launch_info...
794 std::vector<const char *> argv;
795 FileSpec exe_file = launch_info.GetExecutableFile();
796 std::string exe_path;
797 const char *arg = NULL;
798 const Args &launch_args = launch_info.GetArguments();
799 if (exe_file)
800 exe_path = exe_file.GetPath(false);
801 else {
802 arg = launch_args.GetArgumentAtIndex(0);
803 if (arg)
804 exe_path = arg;
805 }
806 if (!exe_path.empty()) {
807 argv.push_back(exe_path.c_str());
808 for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL;
809 ++i) {
810 if (arg)
811 argv.push_back(arg);
Greg Clayton576d8832011-03-22 04:00:09 +0000812 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 }
814 if (!argv.empty()) {
Vince Harrone0be4252015-02-06 18:32:57 +0000815 StreamString packet;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816 packet.PutChar('A');
817 for (size_t i = 0, n = argv.size(); i < n; ++i) {
818 arg = argv[i];
819 const int arg_len = strlen(arg);
820 if (i > 0)
821 packet.PutChar(',');
822 packet.Printf("%i,%i,", arg_len * 2, (int)i);
823 packet.PutBytesAsRawHex8(arg, arg_len);
824 }
825
Vince Harrone0be4252015-02-06 18:32:57 +0000826 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000827 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
828 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000829 if (response.IsOKResponse())
Vince Harrone0be4252015-02-06 18:32:57 +0000830 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831 uint8_t error = response.GetError();
832 if (error)
Johnny Chen64637202012-05-23 21:09:52 +0000833 return error;
834 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000835 }
836 return -1;
837}
Johnny Chen64637202012-05-23 21:09:52 +0000838
Pavel Labath62930e52018-01-10 11:57:31 +0000839int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
840 for (const auto &KV : env) {
841 int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
842 if (r != 0)
843 return r;
844 }
845 return 0;
846}
847
Kate Stoneb9c1b512016-09-06 20:57:50 +0000848int GDBRemoteCommunicationClient::SendEnvironmentPacket(
849 char const *name_equal_value) {
850 if (name_equal_value && name_equal_value[0]) {
851 StreamString packet;
852 bool send_hex_encoding = false;
853 for (const char *p = name_equal_value;
854 *p != '\0' && send_hex_encoding == false; ++p) {
855 if (isprint(*p)) {
856 switch (*p) {
857 case '$':
858 case '#':
859 case '*':
860 case '}':
861 send_hex_encoding = true;
862 break;
863 default:
864 break;
Johnny Chen64637202012-05-23 21:09:52 +0000865 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000866 } else {
867 // We have non printable characters, lets hex encode this...
868 send_hex_encoding = true;
869 }
Johnny Chen64637202012-05-23 21:09:52 +0000870 }
871
Greg Claytonfbb76342013-11-20 21:07:01 +0000872 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000873 if (send_hex_encoding) {
874 if (m_supports_QEnvironmentHexEncoded) {
875 packet.PutCString("QEnvironmentHexEncoded:");
876 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000877 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
878 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879 if (response.IsOKResponse())
880 return 0;
881 uint8_t error = response.GetError();
882 if (error)
883 return error;
884 if (response.IsUnsupportedResponse())
885 m_supports_QEnvironmentHexEncoded = false;
886 }
887 }
888
889 } else if (m_supports_QEnvironment) {
890 packet.Printf("QEnvironment:%s", name_equal_value);
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000891 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
892 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000893 if (response.IsOKResponse())
894 return 0;
895 uint8_t error = response.GetError();
896 if (error)
897 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000898 if (response.IsUnsupportedResponse())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000899 m_supports_QEnvironment = false;
900 }
Greg Claytonfbb76342013-11-20 21:07:01 +0000901 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000902 }
903 return -1;
Greg Claytonfbb76342013-11-20 21:07:01 +0000904}
905
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
907 if (arch && arch[0]) {
908 StreamString packet;
909 packet.Printf("QLaunchArch:%s", arch);
910 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000911 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
912 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000913 if (response.IsOKResponse())
914 return 0;
915 uint8_t error = response.GetError();
916 if (error)
917 return error;
918 }
919 }
920 return -1;
921}
Chaoren Lind3173f32015-05-29 19:52:29 +0000922
Kate Stoneb9c1b512016-09-06 20:57:50 +0000923int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
924 char const *data, bool *was_supported) {
925 if (data && *data != '\0') {
926 StreamString packet;
927 packet.Printf("QSetProcessEvent:%s", data);
928 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000929 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
930 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000931 if (response.IsOKResponse()) {
932 if (was_supported)
933 *was_supported = true;
934 return 0;
935 } else if (response.IsUnsupportedResponse()) {
936 if (was_supported)
937 *was_supported = false;
938 return -1;
939 } else {
940 uint8_t error = response.GetError();
941 if (was_supported)
942 *was_supported = true;
943 if (error)
944 return error;
945 }
946 }
947 }
948 return -1;
949}
950
951bool GDBRemoteCommunicationClient::GetOSVersion(uint32_t &major,
952 uint32_t &minor,
953 uint32_t &update) {
954 if (GetHostInfo()) {
955 if (m_os_version_major != UINT32_MAX) {
956 major = m_os_version_major;
957 minor = m_os_version_minor;
958 update = m_os_version_update;
959 return true;
960 }
961 }
962 return false;
963}
964
965bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
966 if (GetHostInfo()) {
967 if (!m_os_build.empty()) {
968 s = m_os_build;
969 return true;
970 }
971 }
972 s.clear();
973 return false;
974}
975
976bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
977 if (GetHostInfo()) {
978 if (!m_os_kernel.empty()) {
979 s = m_os_kernel;
980 return true;
981 }
982 }
983 s.clear();
984 return false;
985}
986
987bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
988 if (GetHostInfo()) {
989 if (!m_hostname.empty()) {
990 s = m_hostname;
991 return true;
992 }
993 }
994 s.clear();
995 return false;
996}
997
998ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
999 if (GetHostInfo())
1000 return m_host_arch;
1001 return ArchSpec();
1002}
1003
1004const lldb_private::ArchSpec &
1005GDBRemoteCommunicationClient::GetProcessArchitecture() {
1006 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1007 GetCurrentProcessInfo();
1008 return m_process_arch;
1009}
1010
1011bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
1012 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
1013 m_gdb_server_name.clear();
1014 m_gdb_server_version = 0;
1015 m_qGDBServerVersion_is_valid = eLazyBoolNo;
1016
1017 StringExtractorGDBRemote response;
1018 if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
1019 PacketResult::Success) {
1020 if (response.IsNormalResponse()) {
1021 llvm::StringRef name, value;
1022 bool success = false;
1023 while (response.GetNameColonValue(name, value)) {
1024 if (name.equals("name")) {
1025 success = true;
1026 m_gdb_server_name = value;
1027 } else if (name.equals("version")) {
1028 llvm::StringRef major, minor;
1029 std::tie(major, minor) = value.split('.');
1030 if (!major.getAsInteger(0, m_gdb_server_version))
1031 success = true;
1032 }
Greg Clayton576d8832011-03-22 04:00:09 +00001033 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001034 if (success)
1035 m_qGDBServerVersion_is_valid = eLazyBoolYes;
1036 }
Greg Clayton576d8832011-03-22 04:00:09 +00001037 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001038 }
1039 return m_qGDBServerVersion_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001040}
1041
Kate Stoneb9c1b512016-09-06 20:57:50 +00001042void GDBRemoteCommunicationClient::MaybeEnableCompression(
1043 std::vector<std::string> supported_compressions) {
1044 CompressionType avail_type = CompressionType::None;
1045 std::string avail_name;
1046
1047#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001048 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001049 for (auto compression : supported_compressions) {
1050 if (compression == "lzfse") {
1051 avail_type = CompressionType::LZFSE;
1052 avail_name = compression;
1053 break;
1054 }
1055 }
1056 }
1057#endif
1058
1059#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001060 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061 for (auto compression : supported_compressions) {
1062 if (compression == "zlib-deflate") {
1063 avail_type = CompressionType::ZlibDeflate;
1064 avail_name = compression;
1065 break;
1066 }
1067 }
1068 }
1069#endif
1070
1071#if defined(HAVE_LIBZ)
1072 if (avail_type == CompressionType::None) {
1073 for (auto compression : supported_compressions) {
1074 if (compression == "zlib-deflate") {
1075 avail_type = CompressionType::ZlibDeflate;
1076 avail_name = compression;
1077 break;
1078 }
1079 }
1080 }
1081#endif
1082
1083#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001084 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085 for (auto compression : supported_compressions) {
1086 if (compression == "lz4") {
1087 avail_type = CompressionType::LZ4;
1088 avail_name = compression;
1089 break;
1090 }
1091 }
1092 }
1093#endif
1094
1095#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001096 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001097 for (auto compression : supported_compressions) {
1098 if (compression == "lzma") {
1099 avail_type = CompressionType::LZMA;
1100 avail_name = compression;
1101 break;
1102 }
1103 }
1104 }
1105#endif
1106
1107 if (avail_type != CompressionType::None) {
Greg Clayton576d8832011-03-22 04:00:09 +00001108 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 std::string packet = "QEnableCompression:type:" + avail_name + ";";
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001110 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111 PacketResult::Success)
1112 return;
1113
1114 if (response.IsOKResponse()) {
1115 m_compression_type = avail_type;
Greg Clayton576d8832011-03-22 04:00:09 +00001116 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 }
Greg Clayton576d8832011-03-22 04:00:09 +00001118}
Greg Clayton32e0a752011-03-30 18:16:51 +00001119
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
1121 if (GetGDBServerVersion()) {
1122 if (!m_gdb_server_name.empty())
1123 return m_gdb_server_name.c_str();
1124 }
1125 return NULL;
1126}
1127
1128uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1129 if (GetGDBServerVersion())
1130 return m_gdb_server_version;
1131 return 0;
1132}
1133
1134bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
1135 StringExtractorGDBRemote response;
1136 if (SendPacketAndWaitForResponse("qC", response, false) !=
1137 PacketResult::Success)
1138 return false;
1139
1140 if (!response.IsNormalResponse())
1141 return false;
1142
1143 if (response.GetChar() == 'Q' && response.GetChar() == 'C')
1144 tid = response.GetHexMaxU32(true, -1);
1145
1146 return true;
1147}
1148
1149bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
1150 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
1151
1152 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
1153 m_qHostInfo_is_valid = eLazyBoolNo;
Jim Ingham106d0282014-06-25 02:32:56 +00001154 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001155 if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
1156 PacketResult::Success) {
1157 if (response.IsNormalResponse()) {
Zachary Turner54695a32016-08-29 19:58:14 +00001158 llvm::StringRef name;
1159 llvm::StringRef value;
Jason Molenda89c37492014-01-27 22:23:20 +00001160 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1161 uint32_t sub = 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162 std::string arch_name;
1163 std::string os_name;
1164 std::string vendor_name;
1165 std::string triple;
1166 std::string distribution_id;
1167 uint32_t pointer_byte_size = 0;
1168 ByteOrder byte_order = eByteOrderInvalid;
1169 uint32_t num_keys_decoded = 0;
1170 while (response.GetNameColonValue(name, value)) {
1171 if (name.equals("cputype")) {
1172 // exception type in big endian hex
1173 if (!value.getAsInteger(0, cpu))
1174 ++num_keys_decoded;
1175 } else if (name.equals("cpusubtype")) {
1176 // exception count in big endian hex
1177 if (!value.getAsInteger(0, sub))
1178 ++num_keys_decoded;
1179 } else if (name.equals("arch")) {
1180 arch_name = value;
1181 ++num_keys_decoded;
1182 } else if (name.equals("triple")) {
1183 StringExtractor extractor(value);
1184 extractor.GetHexByteString(triple);
1185 ++num_keys_decoded;
1186 } else if (name.equals("distribution_id")) {
1187 StringExtractor extractor(value);
1188 extractor.GetHexByteString(distribution_id);
1189 ++num_keys_decoded;
1190 } else if (name.equals("os_build")) {
1191 StringExtractor extractor(value);
1192 extractor.GetHexByteString(m_os_build);
1193 ++num_keys_decoded;
1194 } else if (name.equals("hostname")) {
1195 StringExtractor extractor(value);
1196 extractor.GetHexByteString(m_hostname);
1197 ++num_keys_decoded;
1198 } else if (name.equals("os_kernel")) {
1199 StringExtractor extractor(value);
1200 extractor.GetHexByteString(m_os_kernel);
1201 ++num_keys_decoded;
1202 } else if (name.equals("ostype")) {
1203 os_name = value;
1204 ++num_keys_decoded;
1205 } else if (name.equals("vendor")) {
1206 vendor_name = value;
1207 ++num_keys_decoded;
1208 } else if (name.equals("endian")) {
1209 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1210 .Case("little", eByteOrderLittle)
1211 .Case("big", eByteOrderBig)
1212 .Case("pdp", eByteOrderPDP)
1213 .Default(eByteOrderInvalid);
1214 if (byte_order != eByteOrderInvalid)
1215 ++num_keys_decoded;
1216 } else if (name.equals("ptrsize")) {
1217 if (!value.getAsInteger(0, pointer_byte_size))
1218 ++num_keys_decoded;
1219 } else if (name.equals("os_version") ||
1220 name.equals(
1221 "version")) // Older debugserver binaries used the
1222 // "version" key instead of
1223 // "os_version"...
1224 {
Zachary Turner6fa7681b2016-09-17 02:00:02 +00001225 Args::StringToVersion(value, m_os_version_major, m_os_version_minor,
1226 m_os_version_update);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227 if (m_os_version_major != UINT32_MAX)
1228 ++num_keys_decoded;
1229 } else if (name.equals("watchpoint_exceptions_received")) {
1230 m_watchpoints_trigger_after_instruction =
1231 llvm::StringSwitch<LazyBool>(value)
1232 .Case("before", eLazyBoolNo)
1233 .Case("after", eLazyBoolYes)
1234 .Default(eLazyBoolCalculate);
1235 if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
1236 ++num_keys_decoded;
1237 } else if (name.equals("default_packet_timeout")) {
Pavel Labath3aa04912016-10-31 17:19:42 +00001238 uint32_t timeout_seconds;
1239 if (!value.getAsInteger(0, timeout_seconds)) {
Pavel Labath1eff73c2016-11-24 10:54:49 +00001240 m_default_packet_timeout = seconds(timeout_seconds);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001241 SetPacketTimeout(m_default_packet_timeout);
1242 ++num_keys_decoded;
Greg Clayton32e0a752011-03-30 18:16:51 +00001243 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244 }
Jason Molenda89c37492014-01-27 22:23:20 +00001245 }
1246
Kate Stoneb9c1b512016-09-06 20:57:50 +00001247 if (num_keys_decoded > 0)
1248 m_qHostInfo_is_valid = eLazyBoolYes;
1249
1250 if (triple.empty()) {
1251 if (arch_name.empty()) {
1252 if (cpu != LLDB_INVALID_CPUTYPE) {
1253 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1254 if (pointer_byte_size) {
1255 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1256 }
1257 if (byte_order != eByteOrderInvalid) {
1258 assert(byte_order == m_host_arch.GetByteOrder());
1259 }
1260
1261 if (!vendor_name.empty())
1262 m_host_arch.GetTriple().setVendorName(
1263 llvm::StringRef(vendor_name));
1264 if (!os_name.empty())
1265 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
Jason Molenda89c37492014-01-27 22:23:20 +00001266 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001267 } else {
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001268 std::string triple;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001269 triple += arch_name;
1270 if (!vendor_name.empty() || !os_name.empty()) {
1271 triple += '-';
1272 if (vendor_name.empty())
1273 triple += "unknown";
1274 else
1275 triple += vendor_name;
1276 triple += '-';
1277 if (os_name.empty())
1278 triple += "unknown";
1279 else
1280 triple += os_name;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001281 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001282 m_host_arch.SetTriple(triple.c_str());
Todd Fialac540dd02014-08-26 18:21:02 +00001283
Kate Stoneb9c1b512016-09-06 20:57:50 +00001284 llvm::Triple &host_triple = m_host_arch.GetTriple();
1285 if (host_triple.getVendor() == llvm::Triple::Apple &&
1286 host_triple.getOS() == llvm::Triple::Darwin) {
1287 switch (m_host_arch.GetMachine()) {
1288 case llvm::Triple::aarch64:
1289 case llvm::Triple::arm:
1290 case llvm::Triple::thumb:
1291 host_triple.setOS(llvm::Triple::IOS);
Greg Claytonadc00cb2011-05-20 23:38:13 +00001292 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001293 default:
1294 host_triple.setOS(llvm::Triple::MacOSX);
1295 break;
1296 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001297 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001298 if (pointer_byte_size) {
1299 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1300 }
1301 if (byte_order != eByteOrderInvalid) {
1302 assert(byte_order == m_host_arch.GetByteOrder());
1303 }
1304 }
1305 } else {
1306 m_host_arch.SetTriple(triple.c_str());
1307 if (pointer_byte_size) {
1308 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1309 }
1310 if (byte_order != eByteOrderInvalid) {
1311 assert(byte_order == m_host_arch.GetByteOrder());
1312 }
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001313
Kate Stoneb9c1b512016-09-06 20:57:50 +00001314 if (log)
1315 log->Printf("GDBRemoteCommunicationClient::%s parsed host "
1316 "architecture as %s, triple as %s from triple text %s",
1317 __FUNCTION__, m_host_arch.GetArchitectureName()
1318 ? m_host_arch.GetArchitectureName()
1319 : "<null-arch-name>",
1320 m_host_arch.GetTriple().getTriple().c_str(),
1321 triple.c_str());
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001322 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001323 if (!distribution_id.empty())
1324 m_host_arch.SetDistributionId(distribution_id.c_str());
1325 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001326 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001327 }
1328 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Claytonadc00cb2011-05-20 23:38:13 +00001329}
Greg Clayton37a0a242012-04-11 00:24:49 +00001330
Kate Stoneb9c1b512016-09-06 20:57:50 +00001331int GDBRemoteCommunicationClient::SendAttach(
1332 lldb::pid_t pid, StringExtractorGDBRemote &response) {
1333 if (pid != LLDB_INVALID_PROCESS_ID) {
1334 char packet[64];
1335 const int packet_len =
1336 ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001337 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001338 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001339 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001340 PacketResult::Success) {
1341 if (response.IsErrorResponse())
1342 return response.GetError();
1343 return 0;
1344 }
1345 }
1346 return -1;
1347}
1348
1349int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
1350 size_t data_len) {
1351 StreamString packet;
1352 packet.PutCString("I");
1353 packet.PutBytesAsRawHex8(data, data_len);
1354 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001355 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1356 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001357 return 0;
1358 }
1359 return response.GetError();
1360}
1361
1362const lldb_private::ArchSpec &
1363GDBRemoteCommunicationClient::GetHostArchitecture() {
1364 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1365 GetHostInfo();
1366 return m_host_arch;
1367}
1368
Pavel Labath1eff73c2016-11-24 10:54:49 +00001369seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001370 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1371 GetHostInfo();
1372 return m_default_packet_timeout;
1373}
1374
1375addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
1376 uint32_t permissions) {
1377 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1378 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1379 char packet[64];
1380 const int packet_len = ::snprintf(
1381 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1382 permissions & lldb::ePermissionsReadable ? "r" : "",
1383 permissions & lldb::ePermissionsWritable ? "w" : "",
1384 permissions & lldb::ePermissionsExecutable ? "x" : "");
1385 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001386 UNUSED_IF_ASSERT_DISABLED(packet_len);
Pavel Labath83082a02016-08-18 14:33:55 +00001387 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001388 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001389 PacketResult::Success) {
1390 if (response.IsUnsupportedResponse())
1391 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1392 else if (!response.IsErrorResponse())
1393 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1394 } else {
1395 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1396 }
1397 }
1398 return LLDB_INVALID_ADDRESS;
1399}
1400
1401bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
1402 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1403 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1404 char packet[64];
1405 const int packet_len =
1406 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1407 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001408 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001409 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001410 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001411 PacketResult::Success) {
1412 if (response.IsUnsupportedResponse())
1413 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1414 else if (response.IsOKResponse())
1415 return true;
1416 } else {
1417 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1418 }
1419 }
1420 return false;
1421}
1422
Zachary Turner97206d52017-05-12 04:51:55 +00001423Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
1424 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001425
1426 if (keep_stopped) {
1427 if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
1428 char packet[64];
1429 const int packet_len =
1430 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1431 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001432 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001434 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001435 PacketResult::Success &&
1436 response.IsOKResponse()) {
1437 m_supports_detach_stay_stopped = eLazyBoolYes;
1438 } else {
1439 m_supports_detach_stay_stopped = eLazyBoolNo;
1440 }
1441 }
1442
1443 if (m_supports_detach_stay_stopped == eLazyBoolNo) {
1444 error.SetErrorString("Stays stopped not supported by this target.");
1445 return error;
1446 } else {
1447 StringExtractorGDBRemote response;
1448 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001449 SendPacketAndWaitForResponse("D1", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001450 if (packet_result != PacketResult::Success)
1451 error.SetErrorString("Sending extended disconnect packet failed.");
1452 }
1453 } else {
1454 StringExtractorGDBRemote response;
1455 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001456 SendPacketAndWaitForResponse("D", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001457 if (packet_result != PacketResult::Success)
1458 error.SetErrorString("Sending disconnect packet failed.");
1459 }
1460 return error;
1461}
1462
Zachary Turner97206d52017-05-12 04:51:55 +00001463Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001464 lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
Zachary Turner97206d52017-05-12 04:51:55 +00001465 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001466 region_info.Clear();
1467
1468 if (m_supports_memory_region_info != eLazyBoolNo) {
1469 m_supports_memory_region_info = eLazyBoolYes;
1470 char packet[64];
1471 const int packet_len = ::snprintf(
1472 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1473 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001474 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001475 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001476 if (SendPacketAndWaitForResponse(packet, response, false) ==
Pavel Labath16064d32018-03-20 11:56:24 +00001477 PacketResult::Success &&
1478 response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001479 llvm::StringRef name;
1480 llvm::StringRef value;
1481 addr_t addr_value = LLDB_INVALID_ADDRESS;
1482 bool success = true;
1483 bool saw_permissions = false;
1484 while (success && response.GetNameColonValue(name, value)) {
1485 if (name.equals("start")) {
1486 if (!value.getAsInteger(16, addr_value))
1487 region_info.GetRange().SetRangeBase(addr_value);
1488 } else if (name.equals("size")) {
1489 if (!value.getAsInteger(16, addr_value))
1490 region_info.GetRange().SetByteSize(addr_value);
1491 } else if (name.equals("permissions") &&
1492 region_info.GetRange().IsValid()) {
1493 saw_permissions = true;
1494 if (region_info.GetRange().Contains(addr)) {
1495 if (value.find('r') != llvm::StringRef::npos)
1496 region_info.SetReadable(MemoryRegionInfo::eYes);
1497 else
1498 region_info.SetReadable(MemoryRegionInfo::eNo);
1499
1500 if (value.find('w') != llvm::StringRef::npos)
1501 region_info.SetWritable(MemoryRegionInfo::eYes);
1502 else
1503 region_info.SetWritable(MemoryRegionInfo::eNo);
1504
1505 if (value.find('x') != llvm::StringRef::npos)
1506 region_info.SetExecutable(MemoryRegionInfo::eYes);
1507 else
1508 region_info.SetExecutable(MemoryRegionInfo::eNo);
1509
1510 region_info.SetMapped(MemoryRegionInfo::eYes);
1511 } else {
1512 // The reported region does not contain this address -- we're
1513 // looking at an unmapped page
1514 region_info.SetReadable(MemoryRegionInfo::eNo);
1515 region_info.SetWritable(MemoryRegionInfo::eNo);
1516 region_info.SetExecutable(MemoryRegionInfo::eNo);
1517 region_info.SetMapped(MemoryRegionInfo::eNo);
1518 }
1519 } else if (name.equals("name")) {
1520 StringExtractorGDBRemote name_extractor(value);
1521 std::string name;
1522 name_extractor.GetHexByteString(name);
1523 region_info.SetName(name.c_str());
1524 } else if (name.equals("error")) {
1525 StringExtractorGDBRemote error_extractor(value);
1526 std::string error_string;
1527 // Now convert the HEX bytes into a string value
1528 error_extractor.GetHexByteString(error_string);
1529 error.SetErrorString(error_string.c_str());
1530 }
1531 }
1532
Stephane Sezer48d14272017-03-31 18:00:48 +00001533 if (region_info.GetRange().IsValid()) {
1534 // We got a valid address range back but no permissions -- which means
1535 // this is an unmapped page
1536 if (!saw_permissions) {
1537 region_info.SetReadable(MemoryRegionInfo::eNo);
1538 region_info.SetWritable(MemoryRegionInfo::eNo);
1539 region_info.SetExecutable(MemoryRegionInfo::eNo);
1540 region_info.SetMapped(MemoryRegionInfo::eNo);
1541 }
1542 } else {
1543 // We got an invalid address range back
1544 error.SetErrorString("Server returned invalid range");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001545 }
1546 } else {
1547 m_supports_memory_region_info = eLazyBoolNo;
1548 }
1549 }
1550
1551 if (m_supports_memory_region_info == eLazyBoolNo) {
1552 error.SetErrorString("qMemoryRegionInfo is not supported");
1553 }
Pavel Labath16064d32018-03-20 11:56:24 +00001554
1555 // Try qXfer:memory-map:read to get region information not included in
1556 // qMemoryRegionInfo
1557 MemoryRegionInfo qXfer_region_info;
1558 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1559
1560 if (error.Fail()) {
1561 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded,
1562 // use the qXfer result as a fallback
1563 if (qXfer_error.Success()) {
1564 region_info = qXfer_region_info;
1565 error.Clear();
1566 } else {
1567 region_info.Clear();
1568 }
1569 } else if (qXfer_error.Success()) {
1570 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
1571 // both regions are the same range, update the result to include the
1572 // flash-memory information that is specific to the qXfer result.
1573 if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1574 region_info.SetFlash(qXfer_region_info.GetFlash());
1575 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1576 }
1577 }
1578 return error;
1579}
1580
1581Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1582 lldb::addr_t addr, MemoryRegionInfo &region) {
1583 Status error = LoadQXferMemoryMap();
1584 if (!error.Success())
1585 return error;
1586 for (const auto &map_region : m_qXfer_memory_map) {
1587 if (map_region.GetRange().Contains(addr)) {
1588 region = map_region;
1589 return error;
1590 }
1591 }
1592 error.SetErrorString("Region not found");
1593 return error;
1594}
1595
1596Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
1597
1598 Status error;
1599
1600 if (m_qXfer_memory_map_loaded)
1601 // Already loaded, return success
1602 return error;
1603
1604 if (!XMLDocument::XMLEnabled()) {
1605 error.SetErrorString("XML is not supported");
1606 return error;
1607 }
1608
1609 if (!GetQXferMemoryMapReadSupported()) {
1610 error.SetErrorString("Memory map is not supported");
1611 return error;
1612 }
1613
1614 std::string xml;
1615 lldb_private::Status lldberr;
1616 if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
1617 lldberr)) {
1618 error.SetErrorString("Failed to read memory map");
1619 return error;
1620 }
1621
1622 XMLDocument xml_document;
1623
1624 if (!xml_document.ParseMemory(xml.c_str(), xml.size())) {
1625 error.SetErrorString("Failed to parse memory map xml");
1626 return error;
1627 }
1628
1629 XMLNode map_node = xml_document.GetRootElement("memory-map");
1630 if (!map_node) {
1631 error.SetErrorString("Invalid root node in memory map xml");
1632 return error;
1633 }
1634
1635 m_qXfer_memory_map.clear();
1636
1637 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1638 if (!memory_node.IsElement())
1639 return true;
1640 if (memory_node.GetName() != "memory")
1641 return true;
1642 auto type = memory_node.GetAttributeValue("type", "");
1643 uint64_t start;
1644 uint64_t length;
1645 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1646 return true;
1647 if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1648 return true;
1649 MemoryRegionInfo region;
1650 region.GetRange().SetRangeBase(start);
1651 region.GetRange().SetByteSize(length);
1652 if (type == "rom") {
1653 region.SetReadable(MemoryRegionInfo::eYes);
1654 this->m_qXfer_memory_map.push_back(region);
1655 } else if (type == "ram") {
1656 region.SetReadable(MemoryRegionInfo::eYes);
1657 region.SetWritable(MemoryRegionInfo::eYes);
1658 this->m_qXfer_memory_map.push_back(region);
1659 } else if (type == "flash") {
1660 region.SetFlash(MemoryRegionInfo::eYes);
1661 memory_node.ForEachChildElement(
1662 [&region](const XMLNode &prop_node) -> bool {
1663 if (!prop_node.IsElement())
1664 return true;
1665 if (prop_node.GetName() != "property")
1666 return true;
1667 auto propname = prop_node.GetAttributeValue("name", "");
1668 if (propname == "blocksize") {
1669 uint64_t blocksize;
1670 if (prop_node.GetElementTextAsUnsigned(blocksize))
1671 region.SetBlocksize(blocksize);
1672 }
1673 return true;
1674 });
1675 this->m_qXfer_memory_map.push_back(region);
1676 }
1677 return true;
1678 });
1679
1680 m_qXfer_memory_map_loaded = true;
1681
Kate Stoneb9c1b512016-09-06 20:57:50 +00001682 return error;
1683}
1684
Zachary Turner97206d52017-05-12 04:51:55 +00001685Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
1686 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001687
1688 if (m_supports_watchpoint_support_info == eLazyBoolYes) {
1689 num = m_num_supported_hardware_watchpoints;
1690 return error;
1691 }
1692
1693 // Set num to 0 first.
1694 num = 0;
1695 if (m_supports_watchpoint_support_info != eLazyBoolNo) {
1696 char packet[64];
1697 const int packet_len =
1698 ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
1699 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001700 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001701 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001702 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001703 PacketResult::Success) {
1704 m_supports_watchpoint_support_info = eLazyBoolYes;
1705 llvm::StringRef name;
1706 llvm::StringRef value;
1707 while (response.GetNameColonValue(name, value)) {
1708 if (name.equals("num")) {
1709 value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1710 num = m_num_supported_hardware_watchpoints;
1711 }
1712 }
1713 } else {
1714 m_supports_watchpoint_support_info = eLazyBoolNo;
1715 }
1716 }
1717
1718 if (m_supports_watchpoint_support_info == eLazyBoolNo) {
1719 error.SetErrorString("qWatchpointSupportInfo is not supported");
1720 }
1721 return error;
1722}
1723
Zachary Turner97206d52017-05-12 04:51:55 +00001724lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001725 uint32_t &num, bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001726 Status error(GetWatchpointSupportInfo(num));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001727 if (error.Success())
1728 error = GetWatchpointsTriggerAfterInstruction(after, arch);
1729 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001730}
1731
Zachary Turner97206d52017-05-12 04:51:55 +00001732lldb_private::Status
Kate Stoneb9c1b512016-09-06 20:57:50 +00001733GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
1734 bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001735 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001736 llvm::Triple::ArchType atype = arch.GetMachine();
Daniel Maleae0f8f572013-08-26 23:57:52 +00001737
Kate Stoneb9c1b512016-09-06 20:57:50 +00001738 // we assume watchpoints will happen after running the relevant opcode
1739 // and we only want to override this behavior if we have explicitly
1740 // received a qHostInfo telling us otherwise
1741 if (m_qHostInfo_is_valid != eLazyBoolYes) {
Pavel Labathc51ad482017-10-27 17:02:32 +00001742 // On targets like MIPS and ppc64le, watchpoint exceptions are always
1743 // generated before the instruction is executed. The connected target
1744 // may not support qHostInfo or qWatchpointSupportInfo packets.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001745 if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
Pavel Labathc51ad482017-10-27 17:02:32 +00001746 atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
1747 atype == llvm::Triple::ppc64le)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001748 after = false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00001749 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001750 after = true;
1751 } else {
Pavel Labathc51ad482017-10-27 17:02:32 +00001752 // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to
1753 // eLazyBoolNo if it is not calculated before.
1754 if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
1755 (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
1756 atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) ||
1757 atype == llvm::Triple::ppc64le) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001758 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
Pavel Labathc51ad482017-10-27 17:02:32 +00001759 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001760
1761 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1762 }
1763 return error;
1764}
1765
1766int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
1767 if (file_spec) {
1768 std::string path{file_spec.GetPath(false)};
1769 StreamString packet;
1770 packet.PutCString("QSetSTDIN:");
1771 packet.PutCStringAsRawHex8(path.c_str());
1772
1773 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001774 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1775 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001776 if (response.IsOKResponse())
1777 return 0;
1778 uint8_t error = response.GetError();
1779 if (error)
1780 return error;
1781 }
1782 }
1783 return -1;
1784}
1785
1786int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
1787 if (file_spec) {
1788 std::string path{file_spec.GetPath(false)};
1789 StreamString packet;
1790 packet.PutCString("QSetSTDOUT:");
1791 packet.PutCStringAsRawHex8(path.c_str());
1792
1793 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001794 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1795 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001796 if (response.IsOKResponse())
1797 return 0;
1798 uint8_t error = response.GetError();
1799 if (error)
1800 return error;
1801 }
1802 }
1803 return -1;
1804}
1805
1806int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
1807 if (file_spec) {
1808 std::string path{file_spec.GetPath(false)};
1809 StreamString packet;
1810 packet.PutCString("QSetSTDERR:");
1811 packet.PutCStringAsRawHex8(path.c_str());
1812
1813 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001814 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1815 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001816 if (response.IsOKResponse())
1817 return 0;
1818 uint8_t error = response.GetError();
1819 if (error)
1820 return error;
1821 }
1822 }
1823 return -1;
1824}
1825
1826bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
1827 StringExtractorGDBRemote response;
1828 if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
1829 PacketResult::Success) {
1830 if (response.IsUnsupportedResponse())
1831 return false;
1832 if (response.IsErrorResponse())
1833 return false;
1834 std::string cwd;
1835 response.GetHexByteString(cwd);
Zachary Turner8c6b5462017-03-06 23:42:44 +00001836 working_dir.SetFile(cwd, false, GetHostArchitecture().GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001837 return !cwd.empty();
1838 }
1839 return false;
1840}
1841
1842int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
1843 if (working_dir) {
1844 std::string path{working_dir.GetPath(false)};
1845 StreamString packet;
1846 packet.PutCString("QSetWorkingDir:");
1847 packet.PutCStringAsRawHex8(path.c_str());
1848
1849 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001850 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1851 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001852 if (response.IsOKResponse())
1853 return 0;
1854 uint8_t error = response.GetError();
1855 if (error)
1856 return error;
1857 }
1858 }
1859 return -1;
1860}
1861
1862int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
1863 char packet[32];
1864 const int packet_len =
1865 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1866 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001867 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001868 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001869 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001870 PacketResult::Success) {
1871 if (response.IsOKResponse())
1872 return 0;
1873 uint8_t error = response.GetError();
1874 if (error)
1875 return error;
1876 }
1877 return -1;
1878}
1879
1880int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
1881 char packet[32];
1882 const int packet_len = ::snprintf(packet, sizeof(packet),
1883 "QSetDetachOnError:%i", enable ? 1 : 0);
1884 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001885 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001886 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001887 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001888 PacketResult::Success) {
1889 if (response.IsOKResponse())
1890 return 0;
1891 uint8_t error = response.GetError();
1892 if (error)
1893 return error;
1894 }
1895 return -1;
1896}
1897
1898bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
1899 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
1900 if (response.IsNormalResponse()) {
1901 llvm::StringRef name;
1902 llvm::StringRef value;
1903 StringExtractor extractor;
1904
1905 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1906 uint32_t sub = 0;
1907 std::string vendor;
1908 std::string os_type;
1909
1910 while (response.GetNameColonValue(name, value)) {
1911 if (name.equals("pid")) {
1912 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1913 value.getAsInteger(0, pid);
1914 process_info.SetProcessID(pid);
1915 } else if (name.equals("ppid")) {
1916 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1917 value.getAsInteger(0, pid);
1918 process_info.SetParentProcessID(pid);
1919 } else if (name.equals("uid")) {
1920 uint32_t uid = UINT32_MAX;
1921 value.getAsInteger(0, uid);
1922 process_info.SetUserID(uid);
1923 } else if (name.equals("euid")) {
1924 uint32_t uid = UINT32_MAX;
1925 value.getAsInteger(0, uid);
1926 process_info.SetEffectiveGroupID(uid);
1927 } else if (name.equals("gid")) {
1928 uint32_t gid = UINT32_MAX;
1929 value.getAsInteger(0, gid);
1930 process_info.SetGroupID(gid);
1931 } else if (name.equals("egid")) {
1932 uint32_t gid = UINT32_MAX;
1933 value.getAsInteger(0, gid);
1934 process_info.SetEffectiveGroupID(gid);
1935 } else if (name.equals("triple")) {
1936 StringExtractor extractor(value);
1937 std::string triple;
1938 extractor.GetHexByteString(triple);
1939 process_info.GetArchitecture().SetTriple(triple.c_str());
1940 } else if (name.equals("name")) {
1941 StringExtractor extractor(value);
1942 // The process name from ASCII hex bytes since we can't
1943 // control the characters in a process name
1944 std::string name;
1945 extractor.GetHexByteString(name);
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001946 process_info.GetExecutableFile().SetFile(name, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001947 } else if (name.equals("cputype")) {
1948 value.getAsInteger(0, cpu);
1949 } else if (name.equals("cpusubtype")) {
1950 value.getAsInteger(0, sub);
1951 } else if (name.equals("vendor")) {
1952 vendor = value;
1953 } else if (name.equals("ostype")) {
1954 os_type = value;
1955 }
1956 }
1957
1958 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
1959 if (vendor == "apple") {
1960 process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
1961 sub);
1962 process_info.GetArchitecture().GetTriple().setVendorName(
1963 llvm::StringRef(vendor));
1964 process_info.GetArchitecture().GetTriple().setOSName(
1965 llvm::StringRef(os_type));
1966 }
1967 }
1968
1969 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1970 return true;
1971 }
1972 return false;
1973}
1974
1975bool GDBRemoteCommunicationClient::GetProcessInfo(
1976 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
1977 process_info.Clear();
1978
1979 if (m_supports_qProcessInfoPID) {
1980 char packet[32];
1981 const int packet_len =
1982 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
1983 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001984 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001985 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001986 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001987 PacketResult::Success) {
1988 return DecodeProcessInfoResponse(response, process_info);
1989 } else {
1990 m_supports_qProcessInfoPID = false;
1991 return false;
1992 }
1993 }
1994 return false;
1995}
1996
1997bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
1998 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
1999 GDBR_LOG_PACKETS));
2000
2001 if (allow_lazy) {
2002 if (m_qProcessInfo_is_valid == eLazyBoolYes)
2003 return true;
2004 if (m_qProcessInfo_is_valid == eLazyBoolNo)
2005 return false;
2006 }
2007
2008 GetHostInfo();
2009
2010 StringExtractorGDBRemote response;
2011 if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
2012 PacketResult::Success) {
2013 if (response.IsNormalResponse()) {
2014 llvm::StringRef name;
2015 llvm::StringRef value;
2016 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2017 uint32_t sub = 0;
2018 std::string arch_name;
2019 std::string os_name;
2020 std::string vendor_name;
2021 std::string triple;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002022 std::string elf_abi;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002023 uint32_t pointer_byte_size = 0;
2024 StringExtractor extractor;
2025 ByteOrder byte_order = eByteOrderInvalid;
2026 uint32_t num_keys_decoded = 0;
2027 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
2028 while (response.GetNameColonValue(name, value)) {
2029 if (name.equals("cputype")) {
2030 if (!value.getAsInteger(16, cpu))
2031 ++num_keys_decoded;
2032 } else if (name.equals("cpusubtype")) {
2033 if (!value.getAsInteger(16, sub))
2034 ++num_keys_decoded;
2035 } else if (name.equals("triple")) {
2036 StringExtractor extractor(value);
2037 extractor.GetHexByteString(triple);
2038 ++num_keys_decoded;
2039 } else if (name.equals("ostype")) {
2040 os_name = value;
2041 ++num_keys_decoded;
2042 } else if (name.equals("vendor")) {
2043 vendor_name = value;
2044 ++num_keys_decoded;
2045 } else if (name.equals("endian")) {
2046 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2047 .Case("little", eByteOrderLittle)
2048 .Case("big", eByteOrderBig)
2049 .Case("pdp", eByteOrderPDP)
2050 .Default(eByteOrderInvalid);
2051 if (byte_order != eByteOrderInvalid)
2052 ++num_keys_decoded;
2053 } else if (name.equals("ptrsize")) {
2054 if (!value.getAsInteger(16, pointer_byte_size))
2055 ++num_keys_decoded;
2056 } else if (name.equals("pid")) {
2057 if (!value.getAsInteger(16, pid))
2058 ++num_keys_decoded;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002059 } else if (name.equals("elf_abi")) {
2060 elf_abi = value;
2061 ++num_keys_decoded;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002062 }
2063 }
2064 if (num_keys_decoded > 0)
2065 m_qProcessInfo_is_valid = eLazyBoolYes;
2066 if (pid != LLDB_INVALID_PROCESS_ID) {
2067 m_curr_pid_is_valid = eLazyBoolYes;
2068 m_curr_pid = pid;
2069 }
2070
2071 // Set the ArchSpec from the triple if we have it.
2072 if (!triple.empty()) {
2073 m_process_arch.SetTriple(triple.c_str());
Nitesh Jain8999edf2016-10-12 10:21:09 +00002074 m_process_arch.SetFlags(elf_abi);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002075 if (pointer_byte_size) {
2076 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2077 }
2078 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2079 !vendor_name.empty()) {
2080 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2081
2082 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
Pavel Labath4f19fce22017-02-17 13:39:50 +00002083 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002084 switch (triple.getObjectFormat()) {
2085 case llvm::Triple::MachO:
2086 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2087 break;
2088 case llvm::Triple::ELF:
2089 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2090 break;
2091 case llvm::Triple::COFF:
2092 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2093 break;
Pavel Labath4f19fce22017-02-17 13:39:50 +00002094 case llvm::Triple::Wasm:
2095 if (log)
2096 log->Printf("error: not supported target architecture");
2097 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002098 case llvm::Triple::UnknownObjectFormat:
2099 if (log)
2100 log->Printf("error: failed to determine target architecture");
2101 return false;
2102 }
2103
2104 if (pointer_byte_size) {
2105 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2106 }
2107 if (byte_order != eByteOrderInvalid) {
2108 assert(byte_order == m_process_arch.GetByteOrder());
2109 }
2110 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2111 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2112 m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2113 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2114 }
2115 return true;
2116 }
2117 } else {
2118 m_qProcessInfo_is_valid = eLazyBoolNo;
2119 }
2120
2121 return false;
2122}
2123
2124uint32_t GDBRemoteCommunicationClient::FindProcesses(
2125 const ProcessInstanceInfoMatch &match_info,
2126 ProcessInstanceInfoList &process_infos) {
2127 process_infos.Clear();
2128
2129 if (m_supports_qfProcessInfo) {
2130 StreamString packet;
2131 packet.PutCString("qfProcessInfo");
2132 if (!match_info.MatchAllProcesses()) {
2133 packet.PutChar(':');
2134 const char *name = match_info.GetProcessInfo().GetName();
2135 bool has_name_match = false;
2136 if (name && name[0]) {
2137 has_name_match = true;
Pavel Labathc4a33952017-02-20 11:35:33 +00002138 NameMatch name_match_type = match_info.GetNameMatchType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002139 switch (name_match_type) {
Pavel Labathc4a33952017-02-20 11:35:33 +00002140 case NameMatch::Ignore:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002141 has_name_match = false;
2142 break;
2143
Pavel Labathc4a33952017-02-20 11:35:33 +00002144 case NameMatch::Equals:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002145 packet.PutCString("name_match:equals;");
2146 break;
2147
Pavel Labathc4a33952017-02-20 11:35:33 +00002148 case NameMatch::Contains:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002149 packet.PutCString("name_match:contains;");
2150 break;
2151
Pavel Labathc4a33952017-02-20 11:35:33 +00002152 case NameMatch::StartsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002153 packet.PutCString("name_match:starts_with;");
2154 break;
2155
Pavel Labathc4a33952017-02-20 11:35:33 +00002156 case NameMatch::EndsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002157 packet.PutCString("name_match:ends_with;");
2158 break;
2159
Pavel Labathc4a33952017-02-20 11:35:33 +00002160 case NameMatch::RegularExpression:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002161 packet.PutCString("name_match:regex;");
2162 break;
2163 }
2164 if (has_name_match) {
2165 packet.PutCString("name:");
2166 packet.PutBytesAsRawHex8(name, ::strlen(name));
2167 packet.PutChar(';');
2168 }
2169 }
2170
2171 if (match_info.GetProcessInfo().ProcessIDIsValid())
2172 packet.Printf("pid:%" PRIu64 ";",
2173 match_info.GetProcessInfo().GetProcessID());
2174 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2175 packet.Printf("parent_pid:%" PRIu64 ";",
2176 match_info.GetProcessInfo().GetParentProcessID());
2177 if (match_info.GetProcessInfo().UserIDIsValid())
2178 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2179 if (match_info.GetProcessInfo().GroupIDIsValid())
2180 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2181 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2182 packet.Printf("euid:%u;",
2183 match_info.GetProcessInfo().GetEffectiveUserID());
2184 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2185 packet.Printf("egid:%u;",
2186 match_info.GetProcessInfo().GetEffectiveGroupID());
2187 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2188 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
2189 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2190 const ArchSpec &match_arch =
2191 match_info.GetProcessInfo().GetArchitecture();
2192 const llvm::Triple &triple = match_arch.GetTriple();
2193 packet.PutCString("triple:");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00002194 packet.PutCString(triple.getTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002195 packet.PutChar(';');
2196 }
2197 }
2198 StringExtractorGDBRemote response;
2199 // Increase timeout as the first qfProcessInfo packet takes a long time
2200 // on Android. The value of 1min was arrived at empirically.
Pavel Labath1eff73c2016-11-24 10:54:49 +00002201 ScopedTimeout timeout(*this, minutes(1));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002202 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2203 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002204 do {
2205 ProcessInstanceInfo process_info;
2206 if (!DecodeProcessInfoResponse(response, process_info))
2207 break;
2208 process_infos.Append(process_info);
2209 response.GetStringRef().clear();
2210 response.SetFilePos(0);
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002211 } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
2212 PacketResult::Success);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002213 } else {
2214 m_supports_qfProcessInfo = false;
2215 return 0;
2216 }
2217 }
2218 return process_infos.GetSize();
2219}
2220
2221bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
2222 std::string &name) {
2223 if (m_supports_qUserName) {
2224 char packet[32];
2225 const int packet_len =
2226 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2227 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002228 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002229 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002230 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002231 PacketResult::Success) {
2232 if (response.IsNormalResponse()) {
2233 // Make sure we parsed the right number of characters. The response is
2234 // the hex encoded user name and should make up the entire packet.
2235 // If there are any non-hex ASCII bytes, the length won't match below..
2236 if (response.GetHexByteString(name) * 2 ==
2237 response.GetStringRef().size())
2238 return true;
2239 }
2240 } else {
2241 m_supports_qUserName = false;
2242 return false;
2243 }
2244 }
2245 return false;
2246}
2247
2248bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
2249 std::string &name) {
2250 if (m_supports_qGroupName) {
2251 char packet[32];
2252 const int packet_len =
2253 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2254 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002255 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002256 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002257 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002258 PacketResult::Success) {
2259 if (response.IsNormalResponse()) {
2260 // Make sure we parsed the right number of characters. The response is
2261 // the hex encoded group name and should make up the entire packet.
2262 // If there are any non-hex ASCII bytes, the length won't match below..
2263 if (response.GetHexByteString(name) * 2 ==
2264 response.GetStringRef().size())
2265 return true;
2266 }
2267 } else {
2268 m_supports_qGroupName = false;
2269 return false;
2270 }
2271 }
2272 return false;
2273}
2274
2275bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
2276 // Form non-stop packet request
2277 char packet[32];
2278 const int packet_len =
2279 ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
2280 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002281 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002282
2283 StringExtractorGDBRemote response;
2284 // Send to target
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002285 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002286 PacketResult::Success)
2287 if (response.IsOKResponse())
2288 return true;
2289
2290 // Failed or not supported
2291 return false;
2292}
2293
2294static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2295 uint32_t recv_size) {
2296 packet.Clear();
2297 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2298 uint32_t bytes_left = send_size;
2299 while (bytes_left > 0) {
2300 if (bytes_left >= 26) {
2301 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2302 bytes_left -= 26;
2303 } else {
2304 packet.Printf("%*.*s;", bytes_left, bytes_left,
2305 "abcdefghijklmnopqrstuvwxyz");
2306 bytes_left = 0;
2307 }
2308 }
2309}
2310
Pavel Labath1eff73c2016-11-24 10:54:49 +00002311duration<float>
2312calculate_standard_deviation(const std::vector<duration<float>> &v) {
2313 using Dur = duration<float>;
Pavel Labath3aa04912016-10-31 17:19:42 +00002314 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2315 Dur mean = sum / v.size();
2316 float accum = 0;
2317 for (auto d : v) {
2318 float delta = (d - mean).count();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002319 accum += delta * delta;
Pavel Labath3aa04912016-10-31 17:19:42 +00002320 };
Kate Stoneb9c1b512016-09-06 20:57:50 +00002321
Pavel Labath3aa04912016-10-31 17:19:42 +00002322 return Dur(sqrtf(accum / (v.size() - 1)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002323}
2324
2325void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
2326 uint32_t max_send,
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002327 uint32_t max_recv,
2328 uint64_t recv_amount,
2329 bool json, Stream &strm) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002330 uint32_t i;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002331 if (SendSpeedTestPacket(0, 0)) {
2332 StreamString packet;
2333 if (json)
2334 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2335 "\"results\" : [",
2336 num_packets);
2337 else
2338 strm.Printf("Testing sending %u packets of various sizes:\n",
2339 num_packets);
2340 strm.Flush();
2341
2342 uint32_t result_idx = 0;
2343 uint32_t send_size;
Pavel Labath3aa04912016-10-31 17:19:42 +00002344 std::vector<duration<float>> packet_times;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002345
2346 for (send_size = 0; send_size <= max_send;
2347 send_size ? send_size *= 2 : send_size = 4) {
2348 for (uint32_t recv_size = 0; recv_size <= max_recv;
2349 recv_size ? recv_size *= 2 : recv_size = 4) {
2350 MakeSpeedTestPacket(packet, send_size, recv_size);
2351
2352 packet_times.clear();
2353 // Test how long it takes to send 'num_packets' packets
Pavel Labath3aa04912016-10-31 17:19:42 +00002354 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002355 for (i = 0; i < num_packets; ++i) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002356 const auto packet_start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002357 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002358 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Pavel Labath3aa04912016-10-31 17:19:42 +00002359 const auto packet_end_time = steady_clock::now();
2360 packet_times.push_back(packet_end_time - packet_start_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002361 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002362 const auto end_time = steady_clock::now();
2363 const auto total_time = end_time - start_time;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002364
2365 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002366 ((float)num_packets) / duration<float>(total_time).count();
2367 auto average_per_packet = total_time / num_packets;
2368 const duration<float> standard_deviation =
2369 calculate_standard_deviation(packet_times);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002370 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002371 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2372 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2373 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002374 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002375 total_time, standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002376 ++result_idx;
2377 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002378 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2379 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2380 "standard deviation of {5,10:ms+f6}\n",
2381 send_size, recv_size, duration<float>(total_time),
2382 packets_per_second, duration<float>(average_per_packet),
2383 standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002384 }
2385 strm.Flush();
2386 }
2387 }
2388
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002389 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002390 if (json)
2391 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2392 ": %" PRIu64 ",\n \"results\" : [",
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002393 recv_amount);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002394 else
2395 strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2396 "packet sizes:\n",
2397 k_recv_amount_mb);
2398 strm.Flush();
2399 send_size = 0;
2400 result_idx = 0;
2401 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2402 MakeSpeedTestPacket(packet, send_size, recv_size);
2403
2404 // If we have a receive size, test how long it takes to receive 4MB of
2405 // data
2406 if (recv_size > 0) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002407 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002408 uint32_t bytes_read = 0;
2409 uint32_t packet_count = 0;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002410 while (bytes_read < recv_amount) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002411 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002412 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002413 bytes_read += recv_size;
2414 ++packet_count;
2415 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002416 const auto end_time = steady_clock::now();
2417 const auto total_time = end_time - start_time;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002418 float mb_second = ((float)recv_amount) /
Pavel Labath3aa04912016-10-31 17:19:42 +00002419 duration<float>(total_time).count() /
Kate Stoneb9c1b512016-09-06 20:57:50 +00002420 (1024.0 * 1024.0);
2421 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002422 ((float)packet_count) / duration<float>(total_time).count();
2423 const auto average_per_packet = total_time / packet_count;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002424
2425 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002426 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2427 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002428 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002429 total_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002430 ++result_idx;
2431 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002432 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2433 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2434 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002435 send_size, recv_size, packet_count, k_recv_amount_mb,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002436 duration<float>(total_time), mb_second,
2437 packets_per_second, duration<float>(average_per_packet));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002438 }
2439 strm.Flush();
2440 }
2441 }
2442 if (json)
2443 strm.Printf("\n ]\n }\n}\n");
2444 else
2445 strm.EOL();
2446 }
2447}
2448
2449bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
2450 uint32_t recv_size) {
2451 StreamString packet;
2452 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2453 uint32_t bytes_left = send_size;
2454 while (bytes_left > 0) {
2455 if (bytes_left >= 26) {
2456 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2457 bytes_left -= 26;
2458 } else {
2459 packet.Printf("%*.*s;", bytes_left, bytes_left,
2460 "abcdefghijklmnopqrstuvwxyz");
2461 bytes_left = 0;
2462 }
2463 }
2464
2465 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002466 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2467 PacketResult::Success;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002468}
2469
2470bool GDBRemoteCommunicationClient::LaunchGDBServer(
2471 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2472 std::string &socket_name) {
2473 pid = LLDB_INVALID_PROCESS_ID;
2474 port = 0;
2475 socket_name.clear();
2476
2477 StringExtractorGDBRemote response;
2478 StreamString stream;
2479 stream.PutCString("qLaunchGDBServer;");
2480 std::string hostname;
2481 if (remote_accept_hostname && remote_accept_hostname[0])
2482 hostname = remote_accept_hostname;
2483 else {
2484 if (HostInfo::GetHostname(hostname)) {
2485 // Make the GDB server we launch only accept connections from this host
2486 stream.Printf("host:%s;", hostname.c_str());
2487 } else {
2488 // Make the GDB server we launch accept connections from any host since we
2489 // can't figure out the hostname
2490 stream.Printf("host:*;");
2491 }
2492 }
2493 // give the process a few seconds to startup
Pavel Labath1eff73c2016-11-24 10:54:49 +00002494 ScopedTimeout timeout(*this, seconds(10));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002495
2496 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2497 PacketResult::Success) {
2498 llvm::StringRef name;
2499 llvm::StringRef value;
2500 while (response.GetNameColonValue(name, value)) {
2501 if (name.equals("port"))
2502 value.getAsInteger(0, port);
2503 else if (name.equals("pid"))
2504 value.getAsInteger(0, pid);
2505 else if (name.compare("socket_name") == 0) {
2506 StringExtractor extractor(value);
2507 extractor.GetHexByteString(socket_name);
2508 }
2509 }
2510 return true;
2511 }
2512 return false;
2513}
2514
2515size_t GDBRemoteCommunicationClient::QueryGDBServer(
2516 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2517 connection_urls.clear();
2518
2519 StringExtractorGDBRemote response;
2520 if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
2521 PacketResult::Success)
2522 return 0;
2523
2524 StructuredData::ObjectSP data =
2525 StructuredData::ParseJSON(response.GetStringRef());
2526 if (!data)
2527 return 0;
2528
2529 StructuredData::Array *array = data->GetAsArray();
2530 if (!array)
2531 return 0;
2532
2533 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2534 StructuredData::Dictionary *element = nullptr;
2535 if (!array->GetItemAtIndexAsDictionary(i, element))
2536 continue;
2537
2538 uint16_t port = 0;
2539 if (StructuredData::ObjectSP port_osp =
2540 element->GetValueForKey(llvm::StringRef("port")))
2541 port = port_osp->GetIntegerValue(0);
2542
2543 std::string socket_name;
2544 if (StructuredData::ObjectSP socket_name_osp =
2545 element->GetValueForKey(llvm::StringRef("socket_name")))
2546 socket_name = socket_name_osp->GetStringValue();
2547
2548 if (port != 0 || !socket_name.empty())
2549 connection_urls.emplace_back(port, socket_name);
2550 }
2551 return connection_urls.size();
2552}
2553
2554bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
2555 StreamString stream;
2556 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002557
2558 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002559 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002560 PacketResult::Success) {
2561 if (response.IsOKResponse())
2562 return true;
2563 }
2564 return false;
2565}
2566
2567bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
2568 if (m_curr_tid == tid)
2569 return true;
2570
2571 char packet[32];
2572 int packet_len;
2573 if (tid == UINT64_MAX)
2574 packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
2575 else
2576 packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
2577 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002578 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002579 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002580 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002581 PacketResult::Success) {
2582 if (response.IsOKResponse()) {
2583 m_curr_tid = tid;
2584 return true;
2585 }
2586
2587 /*
2588 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2589 * Hg packet.
2590 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2591 * which can
2592 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2593 */
2594 if (response.IsUnsupportedResponse() && IsConnected()) {
2595 m_curr_tid = 1;
2596 return true;
2597 }
2598 }
2599 return false;
2600}
2601
2602bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
2603 if (m_curr_tid_run == tid)
2604 return true;
2605
2606 char packet[32];
2607 int packet_len;
2608 if (tid == UINT64_MAX)
2609 packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
2610 else
2611 packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
2612
2613 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002614 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002615 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002616 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002617 PacketResult::Success) {
2618 if (response.IsOKResponse()) {
2619 m_curr_tid_run = tid;
2620 return true;
2621 }
2622
2623 /*
2624 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2625 * Hc packet.
2626 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2627 * which can
2628 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2629 */
2630 if (response.IsUnsupportedResponse() && IsConnected()) {
2631 m_curr_tid_run = 1;
2632 return true;
2633 }
2634 }
2635 return false;
2636}
2637
2638bool GDBRemoteCommunicationClient::GetStopReply(
2639 StringExtractorGDBRemote &response) {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002640 if (SendPacketAndWaitForResponse("?", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002641 PacketResult::Success)
2642 return response.IsNormalResponse();
2643 return false;
2644}
2645
2646bool GDBRemoteCommunicationClient::GetThreadStopInfo(
2647 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2648 if (m_supports_qThreadStopInfo) {
2649 char packet[256];
2650 int packet_len =
2651 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2652 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002653 UNUSED_IF_ASSERT_DISABLED(packet_len);
2654 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002655 PacketResult::Success) {
2656 if (response.IsUnsupportedResponse())
2657 m_supports_qThreadStopInfo = false;
2658 else if (response.IsNormalResponse())
2659 return true;
2660 else
2661 return false;
2662 } else {
2663 m_supports_qThreadStopInfo = false;
2664 }
2665 }
2666 return false;
2667}
2668
2669uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2670 GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
2671 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
2672 if (log)
2673 log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2674 __FUNCTION__, insert ? "add" : "remove", addr);
2675
2676 // Check if the stub is known not to support this breakpoint type
2677 if (!SupportsGDBStoppointPacket(type))
2678 return UINT8_MAX;
2679 // Construct the breakpoint packet
2680 char packet[64];
2681 const int packet_len =
2682 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
2683 insert ? 'Z' : 'z', type, addr, length);
2684 // Check we haven't overwritten the end of the packet buffer
2685 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002686 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002687 StringExtractorGDBRemote response;
2688 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2689 // or "" (unsupported)
2690 response.SetResponseValidatorToOKErrorNotSupported();
2691 // Try to send the breakpoint packet, and check that it was correctly sent
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002692 if (SendPacketAndWaitForResponse(packet, response, true) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002693 PacketResult::Success) {
2694 // Receive and OK packet when the breakpoint successfully placed
2695 if (response.IsOKResponse())
2696 return 0;
2697
Zachary Turner97206d52017-05-12 04:51:55 +00002698 // Status while setting breakpoint, send back specific error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002699 if (response.IsErrorResponse())
2700 return response.GetError();
2701
2702 // Empty packet informs us that breakpoint is not supported
2703 if (response.IsUnsupportedResponse()) {
2704 // Disable this breakpoint type since it is unsupported
2705 switch (type) {
2706 case eBreakpointSoftware:
2707 m_supports_z0 = false;
2708 break;
2709 case eBreakpointHardware:
2710 m_supports_z1 = false;
2711 break;
2712 case eWatchpointWrite:
2713 m_supports_z2 = false;
2714 break;
2715 case eWatchpointRead:
2716 m_supports_z3 = false;
2717 break;
2718 case eWatchpointReadWrite:
2719 m_supports_z4 = false;
2720 break;
2721 case eStoppointInvalid:
2722 return UINT8_MAX;
2723 }
2724 }
2725 }
2726 // Signal generic failure
2727 return UINT8_MAX;
2728}
2729
2730size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2731 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
2732 thread_ids.clear();
2733
2734 Lock lock(*this, false);
2735 if (lock) {
2736 sequence_mutex_unavailable = false;
2737 StringExtractorGDBRemote response;
2738
2739 PacketResult packet_result;
2740 for (packet_result =
2741 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
2742 packet_result == PacketResult::Success && response.IsNormalResponse();
2743 packet_result =
2744 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
2745 char ch = response.GetChar();
2746 if (ch == 'l')
2747 break;
2748 if (ch == 'm') {
2749 do {
2750 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
2751
2752 if (tid != LLDB_INVALID_THREAD_ID) {
2753 thread_ids.push_back(tid);
2754 }
2755 ch = response.GetChar(); // Skip the command separator
2756 } while (ch == ','); // Make sure we got a comma separator
2757 }
2758 }
2759
2760 /*
2761 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2762 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2763 * could
2764 * be as simple as 'S05'. There is no packet which can give us pid and/or
2765 * tid.
2766 * Assume pid=tid=1 in such cases.
2767 */
Tamas Berghammer1492cb82017-09-18 10:24:48 +00002768 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
2769 thread_ids.size() == 0 && IsConnected()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002770 thread_ids.push_back(1);
2771 }
2772 } else {
David Blaikiea322f362017-01-06 00:38:06 +00002773#if !defined(LLDB_CONFIGURATION_DEBUG)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002774 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2775 GDBR_LOG_PACKETS));
2776 if (log)
2777 log->Printf("error: failed to get packet sequence mutex, not sending "
2778 "packet 'qfThreadInfo'");
2779#endif
2780 sequence_mutex_unavailable = true;
2781 }
2782 return thread_ids.size();
2783}
2784
2785lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
2786 StringExtractorGDBRemote response;
2787 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
2788 PacketResult::Success ||
2789 !response.IsNormalResponse())
2790 return LLDB_INVALID_ADDRESS;
2791 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2792}
2793
Zachary Turner97206d52017-05-12 04:51:55 +00002794lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002795 const char *command, // Shouldn't be NULL
2796 const FileSpec &
2797 working_dir, // Pass empty FileSpec to use the current working directory
2798 int *status_ptr, // Pass NULL if you don't want the process exit status
2799 int *signo_ptr, // Pass NULL if you don't want the signal that caused the
2800 // process to exit
2801 std::string
2802 *command_output, // Pass NULL if you don't want the command output
2803 uint32_t
2804 timeout_sec) // Timeout in seconds to wait for shell program to finish
2805{
2806 lldb_private::StreamString stream;
2807 stream.PutCString("qPlatform_shell:");
2808 stream.PutBytesAsRawHex8(command, strlen(command));
2809 stream.PutChar(',');
2810 stream.PutHex32(timeout_sec);
2811 if (working_dir) {
2812 std::string path{working_dir.GetPath(false)};
2813 stream.PutChar(',');
2814 stream.PutCStringAsRawHex8(path.c_str());
2815 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002816 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002817 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002818 PacketResult::Success) {
2819 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002820 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002821 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002822 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002823 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2824 if (exitcode == UINT32_MAX)
Zachary Turner97206d52017-05-12 04:51:55 +00002825 return Status("unable to run remote process");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002826 else if (status_ptr)
2827 *status_ptr = exitcode;
2828 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002829 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002830 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2831 if (signo_ptr)
2832 *signo_ptr = signo;
2833 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002834 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002835 std::string output;
2836 response.GetEscapedBinaryData(output);
2837 if (command_output)
2838 command_output->assign(output);
Zachary Turner97206d52017-05-12 04:51:55 +00002839 return Status();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002840 }
Zachary Turner97206d52017-05-12 04:51:55 +00002841 return Status("unable to send packet");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002842}
2843
Zachary Turner97206d52017-05-12 04:51:55 +00002844Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
2845 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002846 std::string path{file_spec.GetPath(false)};
2847 lldb_private::StreamString stream;
2848 stream.PutCString("qPlatform_mkdir:");
2849 stream.PutHex32(file_permissions);
2850 stream.PutChar(',');
2851 stream.PutCStringAsRawHex8(path.c_str());
Zachary Turnerc1564272016-11-16 21:15:24 +00002852 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002853 StringExtractorGDBRemote response;
2854
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002855 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002856 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002857 return Status("failed to send '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002858
2859 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002860 return Status("invalid response to '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002861
Zachary Turner97206d52017-05-12 04:51:55 +00002862 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002863}
2864
Zachary Turner97206d52017-05-12 04:51:55 +00002865Status
2866GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
2867 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002868 std::string path{file_spec.GetPath(false)};
2869 lldb_private::StreamString stream;
2870 stream.PutCString("qPlatform_chmod:");
2871 stream.PutHex32(file_permissions);
2872 stream.PutChar(',');
2873 stream.PutCStringAsRawHex8(path.c_str());
Zachary Turnerc1564272016-11-16 21:15:24 +00002874 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002875 StringExtractorGDBRemote response;
2876
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002877 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002878 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002879 return Status("failed to send '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002880
2881 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002882 return Status("invalid response to '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002883
Zachary Turner97206d52017-05-12 04:51:55 +00002884 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002885}
2886
2887static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
Zachary Turner97206d52017-05-12 04:51:55 +00002888 uint64_t fail_result, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002889 response.SetFilePos(0);
2890 if (response.GetChar() != 'F')
2891 return fail_result;
2892 int32_t result = response.GetS32(-2);
2893 if (result == -2)
2894 return fail_result;
2895 if (response.GetChar() == ',') {
2896 int result_errno = response.GetS32(-2);
2897 if (result_errno != -2)
2898 error.SetError(result_errno, eErrorTypePOSIX);
2899 else
2900 error.SetError(-1, eErrorTypeGeneric);
2901 } else
2902 error.Clear();
2903 return result;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002904}
2905lldb::user_id_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00002906GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
2907 uint32_t flags, mode_t mode,
Zachary Turner97206d52017-05-12 04:51:55 +00002908 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002909 std::string path(file_spec.GetPath(false));
2910 lldb_private::StreamString stream;
2911 stream.PutCString("vFile:open:");
2912 if (path.empty())
Daniel Maleae0f8f572013-08-26 23:57:52 +00002913 return UINT64_MAX;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002914 stream.PutCStringAsRawHex8(path.c_str());
2915 stream.PutChar(',');
2916 stream.PutHex32(flags);
2917 stream.PutChar(',');
2918 stream.PutHex32(mode);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002919 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002920 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002921 PacketResult::Success) {
2922 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
2923 }
2924 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002925}
2926
Zachary Turner97206d52017-05-12 04:51:55 +00002927bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
2928 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002929 lldb_private::StreamString stream;
2930 stream.Printf("vFile:close:%i", (int)fd);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002931 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002932 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002933 PacketResult::Success) {
2934 return ParseHostIOPacketResponse(response, -1, error) == 0;
2935 }
2936 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002937}
2938
2939// Extension of host I/O packets to get the file size.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002940lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
2941 const lldb_private::FileSpec &file_spec) {
2942 std::string path(file_spec.GetPath(false));
2943 lldb_private::StreamString stream;
2944 stream.PutCString("vFile:size:");
2945 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002946 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002947 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002948 PacketResult::Success) {
2949 if (response.GetChar() != 'F')
2950 return UINT64_MAX;
2951 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2952 return retcode;
2953 }
2954 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002955}
2956
Zachary Turner97206d52017-05-12 04:51:55 +00002957Status
2958GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
2959 uint32_t &file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002960 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00002961 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002962 lldb_private::StreamString stream;
2963 stream.PutCString("vFile:mode:");
2964 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002965 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002966 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002967 PacketResult::Success) {
2968 if (response.GetChar() != 'F') {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002969 error.SetErrorStringWithFormat("invalid response to '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00002970 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002971 } else {
2972 const uint32_t mode = response.GetS32(-1);
2973 if (static_cast<int32_t>(mode) == -1) {
2974 if (response.GetChar() == ',') {
2975 int response_errno = response.GetS32(-1);
2976 if (response_errno > 0)
2977 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2978 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00002979 error.SetErrorToGenericError();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002980 } else
2981 error.SetErrorToGenericError();
2982 } else {
2983 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
2984 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002985 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002986 } else {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002987 error.SetErrorStringWithFormat("failed to send '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00002988 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002989 }
2990 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002991}
2992
Kate Stoneb9c1b512016-09-06 20:57:50 +00002993uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
2994 uint64_t offset, void *dst,
2995 uint64_t dst_len,
Zachary Turner97206d52017-05-12 04:51:55 +00002996 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002997 lldb_private::StreamString stream;
2998 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
2999 offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003000 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003001 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003002 PacketResult::Success) {
3003 if (response.GetChar() != 'F')
3004 return 0;
3005 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
3006 if (retcode == UINT32_MAX)
3007 return retcode;
3008 const char next = (response.Peek() ? *response.Peek() : 0);
3009 if (next == ',')
3010 return 0;
3011 if (next == ';') {
3012 response.GetChar(); // skip the semicolon
3013 std::string buffer;
3014 if (response.GetEscapedBinaryData(buffer)) {
3015 const uint64_t data_to_write =
3016 std::min<uint64_t>(dst_len, buffer.size());
3017 if (data_to_write > 0)
3018 memcpy(dst, &buffer[0], data_to_write);
3019 return data_to_write;
3020 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003021 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003022 }
3023 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003024}
3025
Kate Stoneb9c1b512016-09-06 20:57:50 +00003026uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
3027 uint64_t offset,
3028 const void *src,
3029 uint64_t src_len,
Zachary Turner97206d52017-05-12 04:51:55 +00003030 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003031 lldb_private::StreamGDBRemote stream;
3032 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3033 stream.PutEscapedBytes(src, src_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003034 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003035 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003036 PacketResult::Success) {
3037 if (response.GetChar() != 'F') {
3038 error.SetErrorStringWithFormat("write file failed");
3039 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003040 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003041 uint64_t bytes_written = response.GetU64(UINT64_MAX);
3042 if (bytes_written == UINT64_MAX) {
3043 error.SetErrorToGenericError();
3044 if (response.GetChar() == ',') {
3045 int response_errno = response.GetS32(-1);
3046 if (response_errno > 0)
3047 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3048 }
3049 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003050 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003051 return bytes_written;
3052 } else {
3053 error.SetErrorString("failed to send vFile:pwrite packet");
3054 }
3055 return 0;
3056}
3057
Zachary Turner97206d52017-05-12 04:51:55 +00003058Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
3059 const FileSpec &dst) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003060 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00003061 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003062 lldb_private::StreamGDBRemote stream;
3063 stream.PutCString("vFile:symlink:");
3064 // the unix symlink() command reverses its parameters where the dst if first,
3065 // so we follow suit here
3066 stream.PutCStringAsRawHex8(dst_path.c_str());
3067 stream.PutChar(',');
3068 stream.PutCStringAsRawHex8(src_path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003069 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003070 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003071 PacketResult::Success) {
3072 if (response.GetChar() == 'F') {
3073 uint32_t result = response.GetU32(UINT32_MAX);
3074 if (result != 0) {
3075 error.SetErrorToGenericError();
3076 if (response.GetChar() == ',') {
3077 int response_errno = response.GetS32(-1);
3078 if (response_errno > 0)
3079 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3080 }
3081 }
3082 } else {
3083 // Should have returned with 'F<result>[,<errno>]'
3084 error.SetErrorStringWithFormat("symlink failed");
3085 }
3086 } else {
3087 error.SetErrorString("failed to send vFile:symlink packet");
3088 }
3089 return error;
3090}
3091
Zachary Turner97206d52017-05-12 04:51:55 +00003092Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003093 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00003094 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003095 lldb_private::StreamGDBRemote stream;
3096 stream.PutCString("vFile:unlink:");
3097 // the unix symlink() command reverses its parameters where the dst if first,
3098 // so we follow suit here
3099 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003100 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003101 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003102 PacketResult::Success) {
3103 if (response.GetChar() == 'F') {
3104 uint32_t result = response.GetU32(UINT32_MAX);
3105 if (result != 0) {
3106 error.SetErrorToGenericError();
3107 if (response.GetChar() == ',') {
3108 int response_errno = response.GetS32(-1);
3109 if (response_errno > 0)
3110 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3111 }
3112 }
3113 } else {
3114 // Should have returned with 'F<result>[,<errno>]'
3115 error.SetErrorStringWithFormat("unlink failed");
3116 }
3117 } else {
3118 error.SetErrorString("failed to send vFile:unlink packet");
3119 }
3120 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +00003121}
3122
Daniel Maleae0f8f572013-08-26 23:57:52 +00003123// Extension of host I/O packets to get whether a file exists.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003124bool GDBRemoteCommunicationClient::GetFileExists(
3125 const lldb_private::FileSpec &file_spec) {
3126 std::string path(file_spec.GetPath(false));
3127 lldb_private::StreamString stream;
3128 stream.PutCString("vFile:exists:");
3129 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003130 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003131 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003132 PacketResult::Success) {
3133 if (response.GetChar() != 'F')
3134 return false;
3135 if (response.GetChar() != ',')
3136 return false;
3137 bool retcode = (response.GetChar() != '0');
3138 return retcode;
3139 }
3140 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003141}
3142
Kate Stoneb9c1b512016-09-06 20:57:50 +00003143bool GDBRemoteCommunicationClient::CalculateMD5(
3144 const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
3145 std::string path(file_spec.GetPath(false));
3146 lldb_private::StreamString stream;
3147 stream.PutCString("vFile:MD5:");
3148 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003149 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003150 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003151 PacketResult::Success) {
3152 if (response.GetChar() != 'F')
3153 return false;
3154 if (response.GetChar() != ',')
3155 return false;
3156 if (response.Peek() && *response.Peek() == 'x')
3157 return false;
3158 low = response.GetHexMaxU64(false, UINT64_MAX);
3159 high = response.GetHexMaxU64(false, UINT64_MAX);
Pavel Labath4b6f9592016-08-18 08:30:03 +00003160 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003161 }
3162 return false;
Greg Claytonf74cf862013-11-13 23:28:31 +00003163}
3164
Kate Stoneb9c1b512016-09-06 20:57:50 +00003165bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
3166 // Some targets have issues with g/G packets and we need to avoid using them
3167 if (m_avoid_g_packets == eLazyBoolCalculate) {
3168 if (process) {
3169 m_avoid_g_packets = eLazyBoolNo;
3170 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3171 if (arch.IsValid() &&
3172 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3173 arch.GetTriple().getOS() == llvm::Triple::IOS &&
3174 arch.GetTriple().getArch() == llvm::Triple::aarch64) {
3175 m_avoid_g_packets = eLazyBoolYes;
3176 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3177 if (gdb_server_version != 0) {
3178 const char *gdb_server_name = GetGDBServerProgramName();
3179 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3180 if (gdb_server_version >= 310)
3181 m_avoid_g_packets = eLazyBoolNo;
3182 }
3183 }
3184 }
3185 }
3186 }
3187 return m_avoid_g_packets == eLazyBoolYes;
3188}
Saleem Abdulrasool2d6a9ec2016-07-28 17:32:20 +00003189
Kate Stoneb9c1b512016-09-06 20:57:50 +00003190DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
3191 uint32_t reg) {
3192 StreamString payload;
3193 payload.Printf("p%x", reg);
3194 StringExtractorGDBRemote response;
3195 if (SendThreadSpecificPacketAndWaitForResponse(
3196 tid, std::move(payload), response, false) != PacketResult::Success ||
3197 !response.IsNormalResponse())
3198 return nullptr;
Pavel Labath4b6f9592016-08-18 08:30:03 +00003199
Kate Stoneb9c1b512016-09-06 20:57:50 +00003200 DataBufferSP buffer_sp(
3201 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3202 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3203 return buffer_sp;
3204}
Pavel Labath4b6f9592016-08-18 08:30:03 +00003205
Kate Stoneb9c1b512016-09-06 20:57:50 +00003206DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
3207 StreamString payload;
3208 payload.PutChar('g');
3209 StringExtractorGDBRemote response;
3210 if (SendThreadSpecificPacketAndWaitForResponse(
3211 tid, std::move(payload), response, false) != PacketResult::Success ||
3212 !response.IsNormalResponse())
3213 return nullptr;
3214
3215 DataBufferSP buffer_sp(
3216 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3217 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3218 return buffer_sp;
3219}
3220
3221bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
3222 uint32_t reg_num,
3223 llvm::ArrayRef<uint8_t> data) {
3224 StreamString payload;
3225 payload.Printf("P%x=", reg_num);
3226 payload.PutBytesAsRawHex8(data.data(), data.size(),
3227 endian::InlHostByteOrder(),
3228 endian::InlHostByteOrder());
3229 StringExtractorGDBRemote response;
3230 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3231 response, false) ==
3232 PacketResult::Success &&
3233 response.IsOKResponse();
3234}
3235
3236bool GDBRemoteCommunicationClient::WriteAllRegisters(
3237 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3238 StreamString payload;
3239 payload.PutChar('G');
3240 payload.PutBytesAsRawHex8(data.data(), data.size(),
3241 endian::InlHostByteOrder(),
3242 endian::InlHostByteOrder());
3243 StringExtractorGDBRemote response;
3244 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3245 response, false) ==
3246 PacketResult::Success &&
3247 response.IsOKResponse();
3248}
3249
3250bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
3251 uint32_t &save_id) {
3252 save_id = 0; // Set to invalid save ID
3253 if (m_supports_QSaveRegisterState == eLazyBoolNo)
Greg Claytonf74cf862013-11-13 23:28:31 +00003254 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003255
3256 m_supports_QSaveRegisterState = eLazyBoolYes;
3257 StreamString payload;
3258 payload.PutCString("QSaveRegisterState");
3259 StringExtractorGDBRemote response;
3260 if (SendThreadSpecificPacketAndWaitForResponse(
3261 tid, std::move(payload), response, false) != PacketResult::Success)
3262 return false;
3263
3264 if (response.IsUnsupportedResponse())
3265 m_supports_QSaveRegisterState = eLazyBoolNo;
3266
3267 const uint32_t response_save_id = response.GetU32(0);
3268 if (response_save_id == 0)
3269 return false;
3270
3271 save_id = response_save_id;
3272 return true;
Greg Claytonf74cf862013-11-13 23:28:31 +00003273}
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003274
Kate Stoneb9c1b512016-09-06 20:57:50 +00003275bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
3276 uint32_t save_id) {
3277 // We use the "m_supports_QSaveRegisterState" variable here because the
3278 // QSaveRegisterState and QRestoreRegisterState packets must both be supported
3279 // in
3280 // order to be useful
3281 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3282 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003283
Kate Stoneb9c1b512016-09-06 20:57:50 +00003284 StreamString payload;
3285 payload.Printf("QRestoreRegisterState:%u", save_id);
3286 StringExtractorGDBRemote response;
3287 if (SendThreadSpecificPacketAndWaitForResponse(
3288 tid, std::move(payload), response, false) != PacketResult::Success)
3289 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003290
Kate Stoneb9c1b512016-09-06 20:57:50 +00003291 if (response.IsOKResponse())
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003292 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003293
3294 if (response.IsUnsupportedResponse())
3295 m_supports_QSaveRegisterState = eLazyBoolNo;
3296 return false;
3297}
3298
3299bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
3300 if (!GetSyncThreadStateSupported())
3301 return false;
3302
3303 StreamString packet;
3304 StringExtractorGDBRemote response;
3305 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3306 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
3307 GDBRemoteCommunication::PacketResult::Success &&
3308 response.IsOKResponse();
3309}
3310
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003311lldb::user_id_t
3312GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
3313 Status &error) {
3314 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3315 lldb::user_id_t ret_uid = LLDB_INVALID_UID;
3316
3317 StreamGDBRemote escaped_packet;
3318 escaped_packet.PutCString("jTraceStart:");
3319
3320 StructuredData::Dictionary json_packet;
3321 json_packet.AddIntegerItem("type", options.getType());
3322 json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
3323 json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
3324
3325 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3326 json_packet.AddIntegerItem("threadid", options.getThreadID());
3327
3328 StructuredData::DictionarySP custom_params = options.getTraceParams();
3329 if (custom_params)
3330 json_packet.AddItem("params", custom_params);
3331
3332 StreamString json_string;
3333 json_packet.Dump(json_string, false);
3334 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3335
3336 StringExtractorGDBRemote response;
3337 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3338 true) ==
3339 GDBRemoteCommunication::PacketResult::Success) {
3340 if (!response.IsNormalResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003341 error = response.GetStatus();
3342 LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003343 } else {
3344 ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
3345 }
3346 } else {
3347 LLDB_LOG(log, "failed to send packet");
3348 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3349 escaped_packet.GetData());
3350 }
3351 return ret_uid;
3352}
3353
3354Status
3355GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
3356 lldb::tid_t thread_id) {
3357 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3358 StringExtractorGDBRemote response;
3359 Status error;
3360
3361 StructuredData::Dictionary json_packet;
3362 StreamGDBRemote escaped_packet;
3363 StreamString json_string;
3364 escaped_packet.PutCString("jTraceStop:");
3365
3366 json_packet.AddIntegerItem("traceid", uid);
3367
3368 if (thread_id != LLDB_INVALID_THREAD_ID)
3369 json_packet.AddIntegerItem("threadid", thread_id);
3370
3371 json_packet.Dump(json_string, false);
3372
3373 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3374
3375 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3376 true) ==
3377 GDBRemoteCommunication::PacketResult::Success) {
3378 if (!response.IsOKResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003379 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003380 LLDB_LOG(log, "stop tracing failed");
3381 }
3382 } else {
3383 LLDB_LOG(log, "failed to send packet");
3384 error.SetErrorStringWithFormat(
3385 "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
3386 response.GetError());
3387 }
3388 return error;
3389}
3390
3391Status GDBRemoteCommunicationClient::SendGetDataPacket(
3392 lldb::user_id_t uid, lldb::tid_t thread_id,
3393 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003394
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003395 StreamGDBRemote escaped_packet;
3396 escaped_packet.PutCString("jTraceBufferRead:");
3397 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3398}
3399
3400Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
3401 lldb::user_id_t uid, lldb::tid_t thread_id,
3402 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003403
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003404 StreamGDBRemote escaped_packet;
3405 escaped_packet.PutCString("jTraceMetaRead:");
3406 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3407}
3408
3409Status
3410GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
3411 TraceOptions &options) {
3412 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3413 StringExtractorGDBRemote response;
3414 Status error;
3415
3416 StreamString json_string;
3417 StreamGDBRemote escaped_packet;
3418 escaped_packet.PutCString("jTraceConfigRead:");
3419
3420 StructuredData::Dictionary json_packet;
3421 json_packet.AddIntegerItem("traceid", uid);
3422
3423 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3424 json_packet.AddIntegerItem("threadid", options.getThreadID());
3425
3426 json_packet.Dump(json_string, false);
3427 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3428
3429 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3430 true) ==
3431 GDBRemoteCommunication::PacketResult::Success) {
3432 if (response.IsNormalResponse()) {
3433 uint64_t type = std::numeric_limits<uint64_t>::max();
3434 uint64_t buffersize = std::numeric_limits<uint64_t>::max();
3435 uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
3436
3437 auto json_object = StructuredData::ParseJSON(response.Peek());
3438
3439 if (!json_object ||
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003440 json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003441 error.SetErrorString("Invalid Configuration obtained");
3442 return error;
3443 }
3444
3445 auto json_dict = json_object->GetAsDictionary();
3446
3447 json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
3448 metabuffersize);
3449 options.setMetaDataBufferSize(metabuffersize);
3450
3451 json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
3452 options.setTraceBufferSize(buffersize);
3453
3454 json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
3455 options.setType(static_cast<lldb::TraceType>(type));
3456
3457 StructuredData::ObjectSP custom_params_sp =
3458 json_dict->GetValueForKey("params");
3459 if (custom_params_sp) {
3460 if (custom_params_sp->GetType() !=
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003461 lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003462 error.SetErrorString("Invalid Configuration obtained");
3463 return error;
3464 } else
3465 options.setTraceParams(
3466 static_pointer_cast<StructuredData::Dictionary>(
3467 custom_params_sp));
3468 }
3469 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003470 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003471 }
3472 } else {
3473 LLDB_LOG(log, "failed to send packet");
3474 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3475 escaped_packet.GetData());
3476 }
3477 return error;
3478}
3479
3480Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
3481 StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
3482 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
3483 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3484 Status error;
3485
3486 StructuredData::Dictionary json_packet;
3487
3488 json_packet.AddIntegerItem("traceid", uid);
3489 json_packet.AddIntegerItem("offset", offset);
3490 json_packet.AddIntegerItem("buffersize", buffer.size());
3491
3492 if (thread_id != LLDB_INVALID_THREAD_ID)
3493 json_packet.AddIntegerItem("threadid", thread_id);
3494
3495 StreamString json_string;
3496 json_packet.Dump(json_string, false);
3497
3498 packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3499 StringExtractorGDBRemote response;
3500 if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
3501 GDBRemoteCommunication::PacketResult::Success) {
3502 if (response.IsNormalResponse()) {
3503 size_t filled_size = response.GetHexBytesAvail(buffer);
3504 buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
3505 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003506 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003507 buffer = buffer.slice(buffer.size());
3508 }
3509 } else {
3510 LLDB_LOG(log, "failed to send packet");
3511 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3512 packet.GetData());
3513 buffer = buffer.slice(buffer.size());
3514 }
3515 return error;
3516}
3517
Kate Stoneb9c1b512016-09-06 20:57:50 +00003518bool GDBRemoteCommunicationClient::GetModuleInfo(
3519 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3520 ModuleSpec &module_spec) {
3521 if (!m_supports_qModuleInfo)
3522 return false;
3523
3524 std::string module_path = module_file_spec.GetPath(false);
3525 if (module_path.empty())
3526 return false;
3527
3528 StreamString packet;
3529 packet.PutCString("qModuleInfo:");
3530 packet.PutCStringAsRawHex8(module_path.c_str());
3531 packet.PutCString(";");
3532 const auto &triple = arch_spec.GetTriple().getTriple();
3533 packet.PutCStringAsRawHex8(triple.c_str());
3534
3535 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003536 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
3537 PacketResult::Success)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003538 return false;
3539
3540 if (response.IsErrorResponse())
3541 return false;
3542
3543 if (response.IsUnsupportedResponse()) {
3544 m_supports_qModuleInfo = false;
3545 return false;
3546 }
3547
3548 llvm::StringRef name;
3549 llvm::StringRef value;
3550
3551 module_spec.Clear();
3552 module_spec.GetFileSpec() = module_file_spec;
3553
3554 while (response.GetNameColonValue(name, value)) {
3555 if (name == "uuid" || name == "md5") {
3556 StringExtractor extractor(value);
3557 std::string uuid;
3558 extractor.GetHexByteString(uuid);
3559 module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2);
3560 } else if (name == "triple") {
3561 StringExtractor extractor(value);
3562 std::string triple;
3563 extractor.GetHexByteString(triple);
3564 module_spec.GetArchitecture().SetTriple(triple.c_str());
3565 } else if (name == "file_offset") {
3566 uint64_t ival = 0;
3567 if (!value.getAsInteger(16, ival))
3568 module_spec.SetObjectOffset(ival);
3569 } else if (name == "file_size") {
3570 uint64_t ival = 0;
3571 if (!value.getAsInteger(16, ival))
3572 module_spec.SetObjectSize(ival);
3573 } else if (name == "file_path") {
3574 StringExtractor extractor(value);
3575 std::string path;
3576 extractor.GetHexByteString(path);
Zachary Turner8c6b5462017-03-06 23:42:44 +00003577 module_spec.GetFileSpec() = FileSpec(path, false, arch_spec.GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003578 }
3579 }
3580
3581 return true;
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003582}
Colin Rileyc3c95b22015-04-16 15:51:33 +00003583
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003584static llvm::Optional<ModuleSpec>
3585ParseModuleSpec(StructuredData::Dictionary *dict) {
3586 ModuleSpec result;
3587 if (!dict)
3588 return llvm::None;
3589
Zachary Turner28333212017-05-12 05:49:54 +00003590 llvm::StringRef string;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003591 uint64_t integer;
3592
3593 if (!dict->GetValueForKeyAsString("uuid", string))
3594 return llvm::None;
Pavel Labath8c92c892017-12-18 14:31:44 +00003595 if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
3596 string.size())
3597 return llvm::None;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003598
3599 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3600 return llvm::None;
3601 result.SetObjectOffset(integer);
3602
3603 if (!dict->GetValueForKeyAsInteger("file_size", integer))
3604 return llvm::None;
3605 result.SetObjectSize(integer);
3606
3607 if (!dict->GetValueForKeyAsString("triple", string))
3608 return llvm::None;
Zachary Turner28333212017-05-12 05:49:54 +00003609 result.GetArchitecture().SetTriple(string);
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003610
3611 if (!dict->GetValueForKeyAsString("file_path", string))
3612 return llvm::None;
Zachary Turner8c6b5462017-03-06 23:42:44 +00003613 result.GetFileSpec() =
3614 FileSpec(string, false, result.GetArchitecture().GetTriple());
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003615
3616 return result;
3617}
3618
3619llvm::Optional<std::vector<ModuleSpec>>
3620GDBRemoteCommunicationClient::GetModulesInfo(
3621 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
3622 if (!m_supports_jModulesInfo)
3623 return llvm::None;
3624
3625 JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
3626 for (const FileSpec &module_file_spec : module_file_specs) {
3627 JSONObject::SP module_sp = std::make_shared<JSONObject>();
3628 module_array_sp->AppendObject(module_sp);
3629 module_sp->SetObject(
Pavel Labath763f1c42017-01-05 13:18:46 +00003630 "file", std::make_shared<JSONString>(module_file_spec.GetPath(false)));
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003631 module_sp->SetObject("triple",
3632 std::make_shared<JSONString>(triple.getTriple()));
3633 }
3634 StreamString unescaped_payload;
3635 unescaped_payload.PutCString("jModulesInfo:");
3636 module_array_sp->Write(unescaped_payload);
3637 StreamGDBRemote payload;
Zachary Turnerc1564272016-11-16 21:15:24 +00003638 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003639 unescaped_payload.GetSize());
3640
Greg Clayton70a9f512017-04-14 17:10:04 +00003641 // Increase the timeout for jModulesInfo since this packet can take longer.
3642 ScopedTimeout timeout(*this, std::chrono::seconds(10));
3643
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003644 StringExtractorGDBRemote response;
3645 if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
3646 PacketResult::Success ||
3647 response.IsErrorResponse())
3648 return llvm::None;
3649
3650 if (response.IsUnsupportedResponse()) {
3651 m_supports_jModulesInfo = false;
3652 return llvm::None;
3653 }
3654
3655 StructuredData::ObjectSP response_object_sp =
3656 StructuredData::ParseJSON(response.GetStringRef());
3657 if (!response_object_sp)
3658 return llvm::None;
3659
3660 StructuredData::Array *response_array = response_object_sp->GetAsArray();
3661 if (!response_array)
3662 return llvm::None;
3663
3664 std::vector<ModuleSpec> result;
3665 for (size_t i = 0; i < response_array->GetSize(); ++i) {
3666 if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
3667 response_array->GetItemAtIndex(i)->GetAsDictionary()))
3668 result.push_back(*module_spec);
3669 }
3670
3671 return result;
3672}
3673
Colin Rileyc3c95b22015-04-16 15:51:33 +00003674// query the target remote for extended information using the qXfer packet
3675//
3676// example: object='features', annex='target.xml', out=<xml output>
3677// return: 'true' on success
3678// 'false' on failure (err set)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003679bool GDBRemoteCommunicationClient::ReadExtFeature(
3680 const lldb_private::ConstString object,
3681 const lldb_private::ConstString annex, std::string &out,
Zachary Turner97206d52017-05-12 04:51:55 +00003682 lldb_private::Status &err) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003683
Kate Stoneb9c1b512016-09-06 20:57:50 +00003684 std::stringstream output;
3685 StringExtractorGDBRemote chunk;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003686
Kate Stoneb9c1b512016-09-06 20:57:50 +00003687 uint64_t size = GetRemoteMaxPacketSize();
3688 if (size == 0)
3689 size = 0x1000;
3690 size = size - 1; // Leave space for the 'm' or 'l' character in the response
3691 int offset = 0;
3692 bool active = true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003693
Kate Stoneb9c1b512016-09-06 20:57:50 +00003694 // loop until all data has been read
3695 while (active) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003696
Kate Stoneb9c1b512016-09-06 20:57:50 +00003697 // send query extended feature packet
3698 std::stringstream packet;
3699 packet << "qXfer:" << object.AsCString("")
3700 << ":read:" << annex.AsCString("") << ":" << std::hex << offset
3701 << "," << std::hex << size;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003702
Kate Stoneb9c1b512016-09-06 20:57:50 +00003703 GDBRemoteCommunication::PacketResult res =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00003704 SendPacketAndWaitForResponse(packet.str(), chunk, false);
Colin Rileyc3c95b22015-04-16 15:51:33 +00003705
Kate Stoneb9c1b512016-09-06 20:57:50 +00003706 if (res != GDBRemoteCommunication::PacketResult::Success) {
3707 err.SetErrorString("Error sending $qXfer packet");
3708 return false;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003709 }
3710
Kate Stoneb9c1b512016-09-06 20:57:50 +00003711 const std::string &str = chunk.GetStringRef();
3712 if (str.length() == 0) {
3713 // should have some data in chunk
3714 err.SetErrorString("Empty response from $qXfer packet");
3715 return false;
3716 }
3717
3718 // check packet code
3719 switch (str[0]) {
3720 // last chunk
3721 case ('l'):
3722 active = false;
3723 LLVM_FALLTHROUGH;
3724
3725 // more chunks
3726 case ('m'):
3727 if (str.length() > 1)
3728 output << &str[1];
3729 offset += size;
3730 break;
3731
3732 // unknown chunk
3733 default:
3734 err.SetErrorString("Invalid continuation code from $qXfer packet");
3735 return false;
3736 }
3737 }
3738
3739 out = output.str();
3740 err.Success();
3741 return true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003742}
Greg Clayton0b90be12015-06-23 21:27:50 +00003743
3744// Notify the target that gdb is prepared to serve symbol lookup requests.
3745// packet: "qSymbol::"
3746// reply:
3747// OK The target does not need to look up any (more) symbols.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003748// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
3749// encoded).
3750// LLDB may provide the value by sending another qSymbol
3751// packet
Greg Clayton0b90be12015-06-23 21:27:50 +00003752// in the form of"qSymbol:<sym_value>:<sym_name>".
Jason Molenda50018d32016-01-13 04:08:10 +00003753//
3754// Three examples:
3755//
3756// lldb sends: qSymbol::
3757// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003758// Remote gdb stub does not need to know the addresses of any symbols, lldb
3759// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003760// need to ask again in this session.
3761//
3762// lldb sends: qSymbol::
3763// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3764// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
3765// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003766// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
3767// not know
3768// the address at this time. lldb needs to send qSymbol:: again when it has
3769// more
Jason Molenda50018d32016-01-13 04:08:10 +00003770// solibs loaded.
3771//
3772// lldb sends: qSymbol::
3773// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3774// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
3775// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003776// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
3777// that it
3778// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
3779// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003780// need any more symbols. lldb does not need to ask again in this session.
Greg Clayton0b90be12015-06-23 21:27:50 +00003781
Kate Stoneb9c1b512016-09-06 20:57:50 +00003782void GDBRemoteCommunicationClient::ServeSymbolLookups(
3783 lldb_private::Process *process) {
3784 // Set to true once we've resolved a symbol to an address for the remote stub.
3785 // If we get an 'OK' response after this, the remote stub doesn't need any
3786 // more
3787 // symbols and we can stop asking.
3788 bool symbol_response_provided = false;
Jason Molenda50018d32016-01-13 04:08:10 +00003789
Kate Stoneb9c1b512016-09-06 20:57:50 +00003790 // Is this the initial qSymbol:: packet?
3791 bool first_qsymbol_query = true;
Jason Molenda50018d32016-01-13 04:08:10 +00003792
Kate Stoneb9c1b512016-09-06 20:57:50 +00003793 if (m_supports_qSymbol && m_qSymbol_requests_done == false) {
3794 Lock lock(*this, false);
3795 if (lock) {
3796 StreamString packet;
3797 packet.PutCString("qSymbol::");
3798 StringExtractorGDBRemote response;
3799 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
3800 PacketResult::Success) {
3801 if (response.IsOKResponse()) {
3802 if (symbol_response_provided || first_qsymbol_query) {
3803 m_qSymbol_requests_done = true;
3804 }
3805
3806 // We are done serving symbols requests
3807 return;
3808 }
3809 first_qsymbol_query = false;
3810
3811 if (response.IsUnsupportedResponse()) {
3812 // qSymbol is not supported by the current GDB server we are connected
3813 // to
3814 m_supports_qSymbol = false;
3815 return;
3816 } else {
3817 llvm::StringRef response_str(response.GetStringRef());
3818 if (response_str.startswith("qSymbol:")) {
3819 response.SetFilePos(strlen("qSymbol:"));
3820 std::string symbol_name;
3821 if (response.GetHexByteString(symbol_name)) {
3822 if (symbol_name.empty())
3823 return;
3824
3825 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
3826 lldb_private::SymbolContextList sc_list;
3827 if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(
3828 ConstString(symbol_name), eSymbolTypeAny, sc_list)) {
3829 const size_t num_scs = sc_list.GetSize();
3830 for (size_t sc_idx = 0;
3831 sc_idx < num_scs &&
3832 symbol_load_addr == LLDB_INVALID_ADDRESS;
3833 ++sc_idx) {
3834 SymbolContext sc;
3835 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
3836 if (sc.symbol) {
3837 switch (sc.symbol->GetType()) {
3838 case eSymbolTypeInvalid:
3839 case eSymbolTypeAbsolute:
3840 case eSymbolTypeUndefined:
3841 case eSymbolTypeSourceFile:
3842 case eSymbolTypeHeaderFile:
3843 case eSymbolTypeObjectFile:
3844 case eSymbolTypeCommonBlock:
3845 case eSymbolTypeBlock:
3846 case eSymbolTypeLocal:
3847 case eSymbolTypeParam:
3848 case eSymbolTypeVariable:
3849 case eSymbolTypeVariableType:
3850 case eSymbolTypeLineEntry:
3851 case eSymbolTypeLineHeader:
3852 case eSymbolTypeScopeBegin:
3853 case eSymbolTypeScopeEnd:
3854 case eSymbolTypeAdditional:
3855 case eSymbolTypeCompiler:
3856 case eSymbolTypeInstrumentation:
3857 case eSymbolTypeTrampoline:
3858 break;
3859
3860 case eSymbolTypeCode:
3861 case eSymbolTypeResolver:
3862 case eSymbolTypeData:
3863 case eSymbolTypeRuntime:
3864 case eSymbolTypeException:
3865 case eSymbolTypeObjCClass:
3866 case eSymbolTypeObjCMetaClass:
3867 case eSymbolTypeObjCIVar:
3868 case eSymbolTypeReExported:
3869 symbol_load_addr =
3870 sc.symbol->GetLoadAddress(&process->GetTarget());
3871 break;
3872 }
Jason Molenda50018d32016-01-13 04:08:10 +00003873 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003874 }
Greg Clayton42b01482015-08-11 22:07:46 +00003875 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003876 }
3877 // This is the normal path where our symbol lookup was successful
3878 // and we want
3879 // to send a packet with the new symbol value and see if another
3880 // lookup needs to be
3881 // done.
Greg Clayton0b90be12015-06-23 21:27:50 +00003882
Kate Stoneb9c1b512016-09-06 20:57:50 +00003883 // Change "packet" to contain the requested symbol value and name
3884 packet.Clear();
3885 packet.PutCString("qSymbol:");
3886 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
3887 packet.Printf("%" PRIx64, symbol_load_addr);
3888 symbol_response_provided = true;
3889 } else {
3890 symbol_response_provided = false;
3891 }
3892 packet.PutCString(":");
3893 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
3894 continue; // go back to the while loop and send "packet" and wait
3895 // for another response
Greg Clayton0b90be12015-06-23 21:27:50 +00003896 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003897 }
3898 }
3899 }
3900 // If we make it here, the symbol request packet response wasn't valid or
3901 // our symbol lookup failed so we must abort
3902 return;
Greg Clayton0b90be12015-06-23 21:27:50 +00003903
Kate Stoneb9c1b512016-09-06 20:57:50 +00003904 } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
3905 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
3906 log->Printf(
3907 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
3908 __FUNCTION__);
Greg Clayton0b90be12015-06-23 21:27:50 +00003909 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003910 }
Greg Clayton0b90be12015-06-23 21:27:50 +00003911}
3912
Kate Stoneb9c1b512016-09-06 20:57:50 +00003913StructuredData::Array *
3914GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
3915 if (!m_supported_async_json_packets_is_valid) {
3916 // Query the server for the array of supported asynchronous JSON
3917 // packets.
3918 m_supported_async_json_packets_is_valid = true;
Todd Fiala75930012016-08-19 04:21:48 +00003919
Kate Stoneb9c1b512016-09-06 20:57:50 +00003920 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Todd Fiala75930012016-08-19 04:21:48 +00003921
Kate Stoneb9c1b512016-09-06 20:57:50 +00003922 // Poll it now.
Todd Fiala75930012016-08-19 04:21:48 +00003923 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003924 const bool send_async = false;
3925 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
3926 send_async) == PacketResult::Success) {
3927 m_supported_async_json_packets_sp =
3928 StructuredData::ParseJSON(response.GetStringRef());
3929 if (m_supported_async_json_packets_sp &&
3930 !m_supported_async_json_packets_sp->GetAsArray()) {
3931 // We were returned something other than a JSON array. This
3932 // is invalid. Clear it out.
3933 if (log)
3934 log->Printf("GDBRemoteCommunicationClient::%s(): "
3935 "QSupportedAsyncJSONPackets returned invalid "
3936 "result: %s",
3937 __FUNCTION__, response.GetStringRef().c_str());
3938 m_supported_async_json_packets_sp.reset();
3939 }
3940 } else {
3941 if (log)
3942 log->Printf("GDBRemoteCommunicationClient::%s(): "
3943 "QSupportedAsyncJSONPackets unsupported",
3944 __FUNCTION__);
Todd Fiala75930012016-08-19 04:21:48 +00003945 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003946
3947 if (log && m_supported_async_json_packets_sp) {
3948 StreamString stream;
3949 m_supported_async_json_packets_sp->Dump(stream);
3950 log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
3951 "JSON packets: %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00003952 __FUNCTION__, stream.GetData());
Todd Fiala75930012016-08-19 04:21:48 +00003953 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003954 }
3955
3956 return m_supported_async_json_packets_sp
3957 ? m_supported_async_json_packets_sp->GetAsArray()
3958 : nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00003959}
3960
Zachary Turner97206d52017-05-12 04:51:55 +00003961Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003962 llvm::ArrayRef<int32_t> signals) {
3963 // Format packet:
3964 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
3965 auto range = llvm::make_range(signals.begin(), signals.end());
3966 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
3967
3968 StringExtractorGDBRemote response;
3969 auto send_status = SendPacketAndWaitForResponse(packet, response, false);
3970
3971 if (send_status != GDBRemoteCommunication::PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00003972 return Status("Sending QPassSignals packet failed");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003973
3974 if (response.IsOKResponse()) {
Zachary Turner97206d52017-05-12 04:51:55 +00003975 return Status();
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003976 } else {
Zachary Turner97206d52017-05-12 04:51:55 +00003977 return Status("Unknown error happened during sending QPassSignals packet.");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003978 }
3979}
3980
Zachary Turner97206d52017-05-12 04:51:55 +00003981Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
Kate Stoneb9c1b512016-09-06 20:57:50 +00003982 const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
Zachary Turner97206d52017-05-12 04:51:55 +00003983 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003984
3985 if (type_name.GetLength() == 0) {
3986 error.SetErrorString("invalid type_name argument");
3987 return error;
3988 }
3989
3990 // Build command: Configure{type_name}: serialized config
3991 // data.
3992 StreamGDBRemote stream;
3993 stream.PutCString("QConfigure");
3994 stream.PutCString(type_name.AsCString());
3995 stream.PutChar(':');
3996 if (config_sp) {
3997 // Gather the plain-text version of the configuration data.
3998 StreamString unescaped_stream;
3999 config_sp->Dump(unescaped_stream);
4000 unescaped_stream.Flush();
4001
4002 // Add it to the stream in escaped fashion.
Zachary Turnerc1564272016-11-16 21:15:24 +00004003 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00004004 unescaped_stream.GetSize());
4005 }
4006 stream.Flush();
4007
4008 // Send the packet.
4009 const bool send_async = false;
4010 StringExtractorGDBRemote response;
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00004011 auto result =
4012 SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004013 if (result == PacketResult::Success) {
4014 // We failed if the config result comes back other than OK.
4015 if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
4016 // Okay!
4017 error.Clear();
4018 } else {
4019 error.SetErrorStringWithFormat("configuring StructuredData feature "
4020 "%s failed with error %s",
4021 type_name.AsCString(),
4022 response.GetStringRef().c_str());
4023 }
4024 } else {
4025 // Can we get more data here on the failure?
4026 error.SetErrorStringWithFormat("configuring StructuredData feature %s "
4027 "failed when sending packet: "
4028 "PacketResult=%d",
Ilia K4f730dc2016-09-12 05:25:33 +00004029 type_name.AsCString(), (int)result);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004030 }
4031 return error;
4032}
4033
4034void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
4035 GDBRemoteClientBase::OnRunPacketSent(first);
4036 m_curr_tid = LLDB_INVALID_THREAD_ID;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00004037}