blob: f7551f342f61bd9ad1a26087024837dcef0d9d1f [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"
Zachary Turner97a14e62014-08-19 17:18:29 +000022#include "lldb/Host/HostInfo.h"
Pavel Labath16064d32018-03-20 11:56:24 +000023#include "lldb/Host/XML.h"
Greg Clayton0b90be12015-06-23 21:27:50 +000024#include "lldb/Symbol/Symbol.h"
Pavel Labath4cb69922016-07-29 15:41:52 +000025#include "lldb/Target/MemoryRegionInfo.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000026#include "lldb/Target/Target.h"
Todd Fiala75930012016-08-19 04:21:48 +000027#include "lldb/Target/UnixSignals.h"
Pavel Labath145d95c2018-04-17 18:53:35 +000028#include "lldb/Utility/Args.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000029#include "lldb/Utility/DataBufferHeap.h"
Pavel Labath2f1fbae2016-09-08 10:07:04 +000030#include "lldb/Utility/JSON.h"
Todd Fiala75930012016-08-19 04:21:48 +000031#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000032#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000033#include "lldb/Utility/State.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"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000039#include "lldb/Host/Config.h"
Pavel Labath9af71b32018-03-20 16:14:00 +000040#include "lldb/Utility/StringExtractorGDBRemote.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(),
Pavel Labath2272c482018-06-18 15:02:23 +0000103 m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
104 m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
105 m_max_packet_size(0), m_qSupported_response(),
106 m_supported_async_json_packets_is_valid(false),
Pavel Labath16064d32018-03-20 11:56:24 +0000107 m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
108 m_qXfer_memory_map_loaded(false) {}
Greg Clayton576d8832011-03-22 04:00:09 +0000109
110//----------------------------------------------------------------------
111// Destructor
112//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
114 if (IsConnected())
115 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000116}
117
Zachary Turner97206d52017-05-12 04:51:55 +0000118bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 ResetDiscoverableSettings(false);
Greg Claytonfb909312013-11-23 01:58:15 +0000120
Adrian Prantl05097242018-04-30 16:49:04 +0000121 // Start the read thread after we send the handshake ack since if we fail to
122 // send the handshake ack, there is no reason to continue...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 if (SendAck()) {
124 // Wait for any responses that might have been queued up in the remote
125 // GDB server and flush them all
126 StringExtractorGDBRemote response;
127 PacketResult packet_result = PacketResult::Success;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128 while (packet_result == PacketResult::Success)
Pavel Labath1eff73c2016-11-24 10:54:49 +0000129 packet_result = ReadPacket(response, milliseconds(10), false);
Ed Maste48f986f2013-12-18 15:31:45 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 // The return value from QueryNoAckModeSupported() is true if the packet
Adrian Prantl05097242018-04-30 16:49:04 +0000132 // was sent and _any_ response (including UNIMPLEMENTED) was received), or
133 // false if no response was received. This quickly tells us if we have a
134 // live connection to a remote GDB server...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 if (QueryNoAckModeSupported()) {
136 return true;
137 } else {
138 if (error_ptr)
139 error_ptr->SetErrorString("failed to get reply to handshake packet");
Greg Claytonfb909312013-11-23 01:58:15 +0000140 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 } else {
142 if (error_ptr)
143 error_ptr->SetErrorString("failed to send the handshake ack");
144 }
145 return false;
Greg Clayton1cb64962011-03-24 04:28:38 +0000146}
147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148bool GDBRemoteCommunicationClient::GetEchoSupported() {
149 if (m_supports_qEcho == eLazyBoolCalculate) {
150 GetRemoteQSupported();
151 }
152 return m_supports_qEcho == eLazyBoolYes;
Greg Claytonb30c50c2015-05-29 00:01:55 +0000153}
154
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000155bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
156 if (m_supports_QPassSignals == eLazyBoolCalculate) {
157 GetRemoteQSupported();
158 }
159 return m_supports_QPassSignals == eLazyBoolYes;
160}
161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
163 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
164 GetRemoteQSupported();
165 }
166 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000167}
168
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
170 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
171 GetRemoteQSupported();
172 }
173 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000174}
175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
177 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
178 GetRemoteQSupported();
179 }
180 return m_supports_qXfer_libraries_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000181}
182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
184 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
185 GetRemoteQSupported();
186 }
187 return m_supports_qXfer_auxv_read == eLazyBoolYes;
Steve Pucci03904ac2014-03-04 23:18:46 +0000188}
189
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
191 if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
192 GetRemoteQSupported();
193 }
194 return m_supports_qXfer_features_read == eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000195}
196
Pavel Labath16064d32018-03-20 11:56:24 +0000197bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
198 if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
199 GetRemoteQSupported();
200 }
201 return m_supports_qXfer_memory_map_read == eLazyBoolYes;
202}
203
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
205 if (m_max_packet_size == 0) {
206 GetRemoteQSupported();
207 }
208 return m_max_packet_size;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000209}
210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
212 if (m_supports_not_sending_acks == eLazyBoolCalculate) {
213 m_send_acks = true;
214 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000215
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 // This is the first real packet that we'll send in a debug session and it
Adrian Prantl05097242018-04-30 16:49:04 +0000217 // may take a little longer than normal to receive a reply. Wait at least
218 // 6 seconds for a reply to this packet.
Jason Molenda36a216e2014-07-24 01:36:24 +0000219
Pavel Labath1eff73c2016-11-24 10:54:49 +0000220 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
Colin Rileyc3c95b22015-04-16 15:51:33 +0000221
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000222 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
224 PacketResult::Success) {
225 if (response.IsOKResponse()) {
226 m_send_acks = false;
227 m_supports_not_sending_acks = eLazyBoolYes;
228 }
229 return true;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000230 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231 }
232 return false;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000233}
Greg Clayton576d8832011-03-22 04:00:09 +0000234
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
236 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
237 m_supports_threads_in_stop_reply = eLazyBoolNo;
238
239 StringExtractorGDBRemote response;
240 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
241 false) == PacketResult::Success) {
242 if (response.IsOKResponse())
243 m_supports_threads_in_stop_reply = eLazyBoolYes;
Pavel Labath5c95ee42016-08-30 13:56:11 +0000244 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245 }
Pavel Labath0faf3732016-08-25 08:34:57 +0000246}
Greg Clayton576d8832011-03-22 04:00:09 +0000247
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
249 if (m_attach_or_wait_reply == eLazyBoolCalculate) {
250 m_attach_or_wait_reply = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +0000251
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 StringExtractorGDBRemote response;
253 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
254 false) == PacketResult::Success) {
255 if (response.IsOKResponse())
256 m_attach_or_wait_reply = eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +0000257 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 }
259 if (m_attach_or_wait_reply == eLazyBoolYes)
260 return true;
261 else
Greg Clayton576d8832011-03-22 04:00:09 +0000262 return false;
263}
264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
266 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
267 m_prepare_for_reg_writing_reply = eLazyBoolNo;
268
269 StringExtractorGDBRemote response;
270 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
271 false) == PacketResult::Success) {
272 if (response.IsOKResponse())
273 m_prepare_for_reg_writing_reply = eLazyBoolYes;
274 }
275 }
276 if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
277 return true;
278 else
279 return false;
280}
281
282void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
283 if (did_exec == false) {
284 // Hard reset everything, this is when we first connect to a GDB server
285 m_supports_not_sending_acks = eLazyBoolCalculate;
286 m_supports_thread_suffix = eLazyBoolCalculate;
287 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
288 m_supports_vCont_c = eLazyBoolCalculate;
289 m_supports_vCont_C = eLazyBoolCalculate;
290 m_supports_vCont_s = eLazyBoolCalculate;
291 m_supports_vCont_S = eLazyBoolCalculate;
292 m_supports_p = eLazyBoolCalculate;
293 m_supports_x = eLazyBoolCalculate;
294 m_supports_QSaveRegisterState = eLazyBoolCalculate;
295 m_qHostInfo_is_valid = eLazyBoolCalculate;
296 m_curr_pid_is_valid = eLazyBoolCalculate;
297 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
298 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
299 m_supports_memory_region_info = eLazyBoolCalculate;
300 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
301 m_attach_or_wait_reply = eLazyBoolCalculate;
302 m_avoid_g_packets = eLazyBoolCalculate;
303 m_supports_qXfer_auxv_read = eLazyBoolCalculate;
304 m_supports_qXfer_libraries_read = eLazyBoolCalculate;
305 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
306 m_supports_qXfer_features_read = eLazyBoolCalculate;
Pavel Labath16064d32018-03-20 11:56:24 +0000307 m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000308 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
309 m_supports_qProcessInfoPID = true;
310 m_supports_qfProcessInfo = true;
311 m_supports_qUserName = true;
312 m_supports_qGroupName = true;
313 m_supports_qThreadStopInfo = true;
314 m_supports_z0 = true;
315 m_supports_z1 = true;
316 m_supports_z2 = true;
317 m_supports_z3 = true;
318 m_supports_z4 = true;
319 m_supports_QEnvironment = true;
320 m_supports_QEnvironmentHexEncoded = true;
321 m_supports_qSymbol = true;
322 m_qSymbol_requests_done = false;
323 m_supports_qModuleInfo = true;
324 m_host_arch.Clear();
Pavel Labath2272c482018-06-18 15:02:23 +0000325 m_os_version = llvm::VersionTuple();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 m_os_build.clear();
327 m_os_kernel.clear();
328 m_hostname.clear();
329 m_gdb_server_name.clear();
330 m_gdb_server_version = UINT32_MAX;
Pavel Labath1eff73c2016-11-24 10:54:49 +0000331 m_default_packet_timeout = seconds(0);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000332 m_max_packet_size = 0;
333 m_qSupported_response.clear();
334 m_supported_async_json_packets_is_valid = false;
335 m_supported_async_json_packets_sp.reset();
Pavel Labath2f1fbae2016-09-08 10:07:04 +0000336 m_supports_jModulesInfo = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 }
338
Adrian Prantl05097242018-04-30 16:49:04 +0000339 // These flags should be reset when we first connect to a GDB server and when
340 // our inferior process execs
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 m_qProcessInfo_is_valid = eLazyBoolCalculate;
342 m_process_arch.Clear();
343}
344
345void GDBRemoteCommunicationClient::GetRemoteQSupported() {
346 // Clear out any capabilities we expect to see in the qSupported response
347 m_supports_qXfer_auxv_read = eLazyBoolNo;
348 m_supports_qXfer_libraries_read = eLazyBoolNo;
349 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
350 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
351 m_supports_qXfer_features_read = eLazyBoolNo;
Pavel Labath16064d32018-03-20 11:56:24 +0000352 m_supports_qXfer_memory_map_read = eLazyBoolNo;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
354 // not, we assume no limit
355
356 // build the qSupported packet
357 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
358 StreamString packet;
359 packet.PutCString("qSupported");
360 for (uint32_t i = 0; i < features.size(); ++i) {
361 packet.PutCString(i == 0 ? ":" : ";");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000362 packet.PutCString(features[i]);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363 }
364
365 StringExtractorGDBRemote response;
Zachary Turnerc1564272016-11-16 21:15:24 +0000366 if (SendPacketAndWaitForResponse(packet.GetString(), response,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367 /*send_async=*/false) ==
368 PacketResult::Success) {
369 const char *response_cstr = response.GetStringRef().c_str();
370
371 // Hang on to the qSupported packet, so that platforms can do custom
Adrian Prantl05097242018-04-30 16:49:04 +0000372 // configuration of the transport before attaching/launching the process.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000373 m_qSupported_response = response_cstr;
374
375 if (::strstr(response_cstr, "qXfer:auxv:read+"))
376 m_supports_qXfer_auxv_read = eLazyBoolYes;
377 if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
378 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
379 if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
380 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
381 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
382 }
383 if (::strstr(response_cstr, "qXfer:libraries:read+"))
384 m_supports_qXfer_libraries_read = eLazyBoolYes;
385 if (::strstr(response_cstr, "qXfer:features:read+"))
386 m_supports_qXfer_features_read = eLazyBoolYes;
Pavel Labath16064d32018-03-20 11:56:24 +0000387 if (::strstr(response_cstr, "qXfer:memory-map:read+"))
388 m_supports_qXfer_memory_map_read = eLazyBoolYes;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389
390 // Look for a list of compressions in the features list e.g.
Adrian Prantl05097242018-04-30 16:49:04 +0000391 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
392 // deflate,lzma
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393 const char *features_list = ::strstr(response_cstr, "qXfer:features:");
394 if (features_list) {
395 const char *compressions =
396 ::strstr(features_list, "SupportedCompressions=");
397 if (compressions) {
398 std::vector<std::string> supported_compressions;
399 compressions += sizeof("SupportedCompressions=") - 1;
400 const char *end_of_compressions = strchr(compressions, ';');
401 if (end_of_compressions == NULL) {
402 end_of_compressions = strchr(compressions, '\0');
403 }
404 const char *current_compression = compressions;
405 while (current_compression < end_of_compressions) {
406 const char *next_compression_name = strchr(current_compression, ',');
407 const char *end_of_this_word = next_compression_name;
408 if (next_compression_name == NULL ||
409 end_of_compressions < next_compression_name) {
410 end_of_this_word = end_of_compressions;
411 }
412
413 if (end_of_this_word) {
414 if (end_of_this_word == current_compression) {
415 current_compression++;
416 } else {
417 std::string this_compression(
418 current_compression, end_of_this_word - current_compression);
419 supported_compressions.push_back(this_compression);
420 current_compression = end_of_this_word + 1;
421 }
422 } else {
423 supported_compressions.push_back(current_compression);
424 current_compression = end_of_compressions;
425 }
426 }
427
428 if (supported_compressions.size() > 0) {
429 MaybeEnableCompression(supported_compressions);
430 }
431 }
432 }
433
434 if (::strstr(response_cstr, "qEcho"))
435 m_supports_qEcho = eLazyBoolYes;
436 else
437 m_supports_qEcho = eLazyBoolNo;
438
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000439 if (::strstr(response_cstr, "QPassSignals+"))
440 m_supports_QPassSignals = eLazyBoolYes;
441 else
442 m_supports_QPassSignals = eLazyBoolNo;
443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
445 if (packet_size_str) {
446 StringExtractorGDBRemote packet_response(packet_size_str +
447 strlen("PacketSize="));
448 m_max_packet_size =
449 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
450 if (m_max_packet_size == 0) {
451 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
452 Log *log(
453 ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
454 if (log)
455 log->Printf("Garbled PacketSize spec in qSupported response");
456 }
457 }
458 }
459}
460
461bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
462 if (m_supports_thread_suffix == eLazyBoolCalculate) {
463 StringExtractorGDBRemote response;
464 m_supports_thread_suffix = eLazyBoolNo;
465 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
466 false) == PacketResult::Success) {
467 if (response.IsOKResponse())
468 m_supports_thread_suffix = eLazyBoolYes;
469 }
470 }
471 return m_supports_thread_suffix;
472}
473bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
474 if (m_supports_vCont_c == eLazyBoolCalculate) {
475 StringExtractorGDBRemote response;
476 m_supports_vCont_any = eLazyBoolNo;
477 m_supports_vCont_all = eLazyBoolNo;
478 m_supports_vCont_c = eLazyBoolNo;
479 m_supports_vCont_C = eLazyBoolNo;
480 m_supports_vCont_s = eLazyBoolNo;
481 m_supports_vCont_S = eLazyBoolNo;
482 if (SendPacketAndWaitForResponse("vCont?", response, false) ==
483 PacketResult::Success) {
484 const char *response_cstr = response.GetStringRef().c_str();
485 if (::strstr(response_cstr, ";c"))
486 m_supports_vCont_c = eLazyBoolYes;
487
488 if (::strstr(response_cstr, ";C"))
489 m_supports_vCont_C = eLazyBoolYes;
490
491 if (::strstr(response_cstr, ";s"))
492 m_supports_vCont_s = eLazyBoolYes;
493
494 if (::strstr(response_cstr, ";S"))
495 m_supports_vCont_S = eLazyBoolYes;
496
497 if (m_supports_vCont_c == eLazyBoolYes &&
498 m_supports_vCont_C == eLazyBoolYes &&
499 m_supports_vCont_s == eLazyBoolYes &&
500 m_supports_vCont_S == eLazyBoolYes) {
501 m_supports_vCont_all = eLazyBoolYes;
502 }
503
504 if (m_supports_vCont_c == eLazyBoolYes ||
505 m_supports_vCont_C == eLazyBoolYes ||
506 m_supports_vCont_s == eLazyBoolYes ||
507 m_supports_vCont_S == eLazyBoolYes) {
508 m_supports_vCont_any = eLazyBoolYes;
509 }
510 }
511 }
512
513 switch (flavor) {
514 case 'a':
515 return m_supports_vCont_any;
516 case 'A':
517 return m_supports_vCont_all;
518 case 'c':
519 return m_supports_vCont_c;
520 case 'C':
521 return m_supports_vCont_C;
522 case 's':
523 return m_supports_vCont_s;
524 case 'S':
525 return m_supports_vCont_S;
526 default:
527 break;
528 }
529 return false;
530}
531
Pavel Labath4b6f9592016-08-18 08:30:03 +0000532GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
534 lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
535 bool send_async) {
536 Lock lock(*this, send_async);
537 if (!lock) {
538 if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
539 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
540 log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
541 "for %s packet.",
Zachary Turnerc1564272016-11-16 21:15:24 +0000542 __FUNCTION__, payload.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 return PacketResult::ErrorNoSequenceLock;
544 }
Pavel Labath5c95ee42016-08-30 13:56:11 +0000545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546 if (GetThreadSuffixSupported())
547 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
548 else {
549 if (!SetCurrentThread(tid))
550 return PacketResult::ErrorSendFailed;
551 }
Pavel Labath4b6f9592016-08-18 08:30:03 +0000552
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
Pavel Labath4b6f9592016-08-18 08:30:03 +0000554}
555
Adrian Prantl05097242018-04-30 16:49:04 +0000556// Check if the target supports 'p' packet. It sends out a 'p' packet and
557// checks the response. A normal packet will tell us that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000558//
559// Takes a valid thread ID because p needs to apply to a thread.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
561 if (m_supports_p == eLazyBoolCalculate) {
562 m_supports_p = eLazyBoolNo;
563 StreamString payload;
564 payload.PutCString("p0");
565 StringExtractorGDBRemote response;
566 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
567 response, false) ==
568 PacketResult::Success &&
569 response.IsNormalResponse()) {
570 m_supports_p = eLazyBoolYes;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000571 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000572 }
573 return m_supports_p;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000574}
Greg Clayton576d8832011-03-22 04:00:09 +0000575
Kate Stoneb9c1b512016-09-06 20:57:50 +0000576StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
577 // Get information on all threads at one using the "jThreadsInfo" packet
578 StructuredData::ObjectSP object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000579
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580 if (m_supports_jThreadsInfo) {
581 StringExtractorGDBRemote response;
582 response.SetResponseValidatorToJSON();
583 if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
584 PacketResult::Success) {
585 if (response.IsUnsupportedResponse()) {
586 m_supports_jThreadsInfo = false;
587 } else if (!response.Empty()) {
588 object_sp = StructuredData::ParseJSON(response.GetStringRef());
589 }
Greg Clayton358cf1e2015-06-25 21:46:34 +0000590 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591 }
592 return object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000593}
594
Kate Stoneb9c1b512016-09-06 20:57:50 +0000595bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
596 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
597 StringExtractorGDBRemote response;
598 m_supports_jThreadExtendedInfo = eLazyBoolNo;
599 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
600 PacketResult::Success) {
601 if (response.IsOKResponse()) {
602 m_supports_jThreadExtendedInfo = eLazyBoolYes;
603 }
Jason Molenda705b1802014-06-13 02:37:02 +0000604 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605 }
606 return m_supports_jThreadExtendedInfo;
Jason Molenda705b1802014-06-13 02:37:02 +0000607}
608
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000609void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
610 if (m_supports_error_string_reply == eLazyBoolCalculate) {
611 StringExtractorGDBRemote response;
Adrian Prantl05097242018-04-30 16:49:04 +0000612 // We try to enable error strings in remote packets but if we fail, we just
613 // work in the older way.
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000614 m_supports_error_string_reply = eLazyBoolNo;
615 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
616 PacketResult::Success) {
617 if (response.IsOKResponse()) {
618 m_supports_error_string_reply = eLazyBoolYes;
619 }
620 }
621 }
622}
623
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
625 if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
626 StringExtractorGDBRemote response;
627 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
628 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
629 response,
630 false) == PacketResult::Success) {
631 if (response.IsOKResponse()) {
632 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
633 }
Jason Molenda20ee21b2015-07-10 23:15:22 +0000634 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635 }
636 return m_supports_jLoadedDynamicLibrariesInfos;
Jason Molenda20ee21b2015-07-10 23:15:22 +0000637}
638
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
640 if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
641 StringExtractorGDBRemote response;
642 m_supports_jGetSharedCacheInfo = eLazyBoolNo;
643 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
644 PacketResult::Success) {
645 if (response.IsOKResponse()) {
646 m_supports_jGetSharedCacheInfo = eLazyBoolYes;
647 }
Jason Molenda37397352016-07-22 00:17:55 +0000648 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000649 }
650 return m_supports_jGetSharedCacheInfo;
Jason Molenda37397352016-07-22 00:17:55 +0000651}
652
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653bool GDBRemoteCommunicationClient::GetxPacketSupported() {
654 if (m_supports_x == eLazyBoolCalculate) {
655 StringExtractorGDBRemote response;
656 m_supports_x = eLazyBoolNo;
657 char packet[256];
658 snprintf(packet, sizeof(packet), "x0,0");
659 if (SendPacketAndWaitForResponse(packet, response, false) ==
660 PacketResult::Success) {
661 if (response.IsOKResponse())
662 m_supports_x = eLazyBoolYes;
Jason Molendabdc4f122014-05-06 02:59:39 +0000663 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664 }
665 return m_supports_x;
Jason Molendabdc4f122014-05-06 02:59:39 +0000666}
667
Greg Clayton3dedae12013-12-06 21:45:27 +0000668GDBRemoteCommunicationClient::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000669GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
670 const char *payload_prefix, std::string &response_string) {
671 Lock lock(*this, false);
672 if (!lock) {
673 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
674 GDBR_LOG_PACKETS));
675 if (log)
676 log->Printf("error: failed to get packet sequence mutex, not sending "
677 "packets with prefix '%s'",
678 payload_prefix);
679 return PacketResult::ErrorNoSequenceLock;
680 }
681
682 response_string = "";
683 std::string payload_prefix_str(payload_prefix);
684 unsigned int response_size = 0x1000;
685 if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
686 response_size = GetRemoteMaxPacketSize();
687 }
688
689 for (unsigned int offset = 0; true; offset += response_size) {
690 StringExtractorGDBRemote this_response;
691 // Construct payload
692 char sizeDescriptor[128];
693 snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
694 response_size);
695 PacketResult result = SendPacketAndWaitForResponseNoLock(
696 payload_prefix_str + sizeDescriptor, this_response);
697 if (result != PacketResult::Success)
698 return result;
699
700 const std::string &this_string = this_response.GetStringRef();
701
702 // Check for m or l as first character; l seems to mean this is the last
703 // chunk
704 char first_char = *this_string.c_str();
705 if (first_char != 'm' && first_char != 'l') {
706 return PacketResult::ErrorReplyInvalid;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000707 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000708 // Concatenate the result so far (skipping 'm' or 'l')
709 response_string.append(this_string, 1, std::string::npos);
710 if (first_char == 'l')
711 // We're done
712 return PacketResult::Success;
713 }
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000714}
715
Kate Stoneb9c1b512016-09-06 20:57:50 +0000716lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
717 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
718 return m_curr_pid;
Jaydeep Patil1142f832015-08-13 03:46:36 +0000719
Kate Stoneb9c1b512016-09-06 20:57:50 +0000720 // First try to retrieve the pid via the qProcessInfo request.
721 GetCurrentProcessInfo(allow_lazy);
722 if (m_curr_pid_is_valid == eLazyBoolYes) {
723 // We really got it.
724 return m_curr_pid;
725 } else {
726 // If we don't get a response for qProcessInfo, check if $qC gives us a
Adrian Prantl05097242018-04-30 16:49:04 +0000727 // result. $qC only returns a real process id on older debugserver and
728 // lldb-platform stubs. The gdb remote protocol documents $qC as returning
729 // the thread id, which newer debugserver and lldb-gdbserver stubs return
730 // correctly.
Greg Clayton576d8832011-03-22 04:00:09 +0000731 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000732 if (SendPacketAndWaitForResponse("qC", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733 PacketResult::Success) {
734 if (response.GetChar() == 'Q') {
735 if (response.GetChar() == 'C') {
736 m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
737 if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
738 m_curr_pid_is_valid = eLazyBoolYes;
739 return m_curr_pid;
740 }
Greg Clayton576d8832011-03-22 04:00:09 +0000741 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742 }
Greg Clayton576d8832011-03-22 04:00:09 +0000743 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744
745 // If we don't get a response for $qC, check if $qfThreadID gives us a
746 // result.
747 if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
748 std::vector<lldb::tid_t> thread_ids;
749 bool sequence_mutex_unavailable;
750 size_t size;
751 size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
752 if (size && sequence_mutex_unavailable == false) {
753 m_curr_pid = thread_ids.front();
754 m_curr_pid_is_valid = eLazyBoolYes;
755 return m_curr_pid;
756 }
Greg Clayton576d8832011-03-22 04:00:09 +0000757 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758 }
759
760 return LLDB_INVALID_PROCESS_ID;
Greg Clayton576d8832011-03-22 04:00:09 +0000761}
762
Kate Stoneb9c1b512016-09-06 20:57:50 +0000763bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
764 error_str.clear();
765 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000766 if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
767 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 if (response.IsOKResponse())
769 return true;
770 if (response.GetChar() == 'E') {
771 // A string the describes what failed when launching...
772 error_str = response.GetStringRef().substr(1);
773 } else {
774 error_str.assign("unknown error occurred launching process");
Greg Claytonfbb76342013-11-20 21:07:01 +0000775 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776 } else {
777 error_str.assign("timed out waiting for app to launch");
778 }
779 return false;
Greg Clayton576d8832011-03-22 04:00:09 +0000780}
781
Kate Stoneb9c1b512016-09-06 20:57:50 +0000782int GDBRemoteCommunicationClient::SendArgumentsPacket(
783 const ProcessLaunchInfo &launch_info) {
784 // Since we don't get the send argv0 separate from the executable path, we
Adrian Prantl05097242018-04-30 16:49:04 +0000785 // need to make sure to use the actual executable path found in the
786 // launch_info...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787 std::vector<const char *> argv;
788 FileSpec exe_file = launch_info.GetExecutableFile();
789 std::string exe_path;
790 const char *arg = NULL;
791 const Args &launch_args = launch_info.GetArguments();
792 if (exe_file)
793 exe_path = exe_file.GetPath(false);
794 else {
795 arg = launch_args.GetArgumentAtIndex(0);
796 if (arg)
797 exe_path = arg;
798 }
799 if (!exe_path.empty()) {
800 argv.push_back(exe_path.c_str());
801 for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL;
802 ++i) {
803 if (arg)
804 argv.push_back(arg);
Greg Clayton576d8832011-03-22 04:00:09 +0000805 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000806 }
807 if (!argv.empty()) {
Vince Harrone0be4252015-02-06 18:32:57 +0000808 StreamString packet;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000809 packet.PutChar('A');
810 for (size_t i = 0, n = argv.size(); i < n; ++i) {
811 arg = argv[i];
812 const int arg_len = strlen(arg);
813 if (i > 0)
814 packet.PutChar(',');
815 packet.Printf("%i,%i,", arg_len * 2, (int)i);
816 packet.PutBytesAsRawHex8(arg, arg_len);
817 }
818
Vince Harrone0be4252015-02-06 18:32:57 +0000819 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000820 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
821 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000822 if (response.IsOKResponse())
Vince Harrone0be4252015-02-06 18:32:57 +0000823 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824 uint8_t error = response.GetError();
825 if (error)
Johnny Chen64637202012-05-23 21:09:52 +0000826 return error;
827 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 }
829 return -1;
830}
Johnny Chen64637202012-05-23 21:09:52 +0000831
Pavel Labath62930e52018-01-10 11:57:31 +0000832int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
833 for (const auto &KV : env) {
834 int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
835 if (r != 0)
836 return r;
837 }
838 return 0;
839}
840
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841int GDBRemoteCommunicationClient::SendEnvironmentPacket(
842 char const *name_equal_value) {
843 if (name_equal_value && name_equal_value[0]) {
844 StreamString packet;
845 bool send_hex_encoding = false;
846 for (const char *p = name_equal_value;
847 *p != '\0' && send_hex_encoding == false; ++p) {
848 if (isprint(*p)) {
849 switch (*p) {
850 case '$':
851 case '#':
852 case '*':
853 case '}':
854 send_hex_encoding = true;
855 break;
856 default:
857 break;
Johnny Chen64637202012-05-23 21:09:52 +0000858 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000859 } else {
860 // We have non printable characters, lets hex encode this...
861 send_hex_encoding = true;
862 }
Johnny Chen64637202012-05-23 21:09:52 +0000863 }
864
Greg Claytonfbb76342013-11-20 21:07:01 +0000865 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000866 if (send_hex_encoding) {
867 if (m_supports_QEnvironmentHexEncoded) {
868 packet.PutCString("QEnvironmentHexEncoded:");
869 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000870 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
871 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 if (response.IsOKResponse())
873 return 0;
874 uint8_t error = response.GetError();
875 if (error)
876 return error;
877 if (response.IsUnsupportedResponse())
878 m_supports_QEnvironmentHexEncoded = false;
879 }
880 }
881
882 } else if (m_supports_QEnvironment) {
883 packet.Printf("QEnvironment:%s", name_equal_value);
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000884 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
885 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000886 if (response.IsOKResponse())
887 return 0;
888 uint8_t error = response.GetError();
889 if (error)
890 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000891 if (response.IsUnsupportedResponse())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000892 m_supports_QEnvironment = false;
893 }
Greg Claytonfbb76342013-11-20 21:07:01 +0000894 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000895 }
896 return -1;
Greg Claytonfbb76342013-11-20 21:07:01 +0000897}
898
Kate Stoneb9c1b512016-09-06 20:57:50 +0000899int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
900 if (arch && arch[0]) {
901 StreamString packet;
902 packet.Printf("QLaunchArch:%s", arch);
903 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000904 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
905 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906 if (response.IsOKResponse())
907 return 0;
908 uint8_t error = response.GetError();
909 if (error)
910 return error;
911 }
912 }
913 return -1;
914}
Chaoren Lind3173f32015-05-29 19:52:29 +0000915
Kate Stoneb9c1b512016-09-06 20:57:50 +0000916int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
917 char const *data, bool *was_supported) {
918 if (data && *data != '\0') {
919 StreamString packet;
920 packet.Printf("QSetProcessEvent:%s", data);
921 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000922 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
923 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924 if (response.IsOKResponse()) {
925 if (was_supported)
926 *was_supported = true;
927 return 0;
928 } else if (response.IsUnsupportedResponse()) {
929 if (was_supported)
930 *was_supported = false;
931 return -1;
932 } else {
933 uint8_t error = response.GetError();
934 if (was_supported)
935 *was_supported = true;
936 if (error)
937 return error;
938 }
939 }
940 }
941 return -1;
942}
943
Pavel Labath2272c482018-06-18 15:02:23 +0000944llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
945 GetHostInfo();
946 return m_os_version;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947}
948
949bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
950 if (GetHostInfo()) {
951 if (!m_os_build.empty()) {
952 s = m_os_build;
953 return true;
954 }
955 }
956 s.clear();
957 return false;
958}
959
960bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
961 if (GetHostInfo()) {
962 if (!m_os_kernel.empty()) {
963 s = m_os_kernel;
964 return true;
965 }
966 }
967 s.clear();
968 return false;
969}
970
971bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
972 if (GetHostInfo()) {
973 if (!m_hostname.empty()) {
974 s = m_hostname;
975 return true;
976 }
977 }
978 s.clear();
979 return false;
980}
981
982ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
983 if (GetHostInfo())
984 return m_host_arch;
985 return ArchSpec();
986}
987
988const lldb_private::ArchSpec &
989GDBRemoteCommunicationClient::GetProcessArchitecture() {
990 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
991 GetCurrentProcessInfo();
992 return m_process_arch;
993}
994
995bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
996 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
997 m_gdb_server_name.clear();
998 m_gdb_server_version = 0;
999 m_qGDBServerVersion_is_valid = eLazyBoolNo;
1000
1001 StringExtractorGDBRemote response;
1002 if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
1003 PacketResult::Success) {
1004 if (response.IsNormalResponse()) {
1005 llvm::StringRef name, value;
1006 bool success = false;
1007 while (response.GetNameColonValue(name, value)) {
1008 if (name.equals("name")) {
1009 success = true;
1010 m_gdb_server_name = value;
1011 } else if (name.equals("version")) {
1012 llvm::StringRef major, minor;
1013 std::tie(major, minor) = value.split('.');
1014 if (!major.getAsInteger(0, m_gdb_server_version))
1015 success = true;
1016 }
Greg Clayton576d8832011-03-22 04:00:09 +00001017 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018 if (success)
1019 m_qGDBServerVersion_is_valid = eLazyBoolYes;
1020 }
Greg Clayton576d8832011-03-22 04:00:09 +00001021 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 }
1023 return m_qGDBServerVersion_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001024}
1025
Kate Stoneb9c1b512016-09-06 20:57:50 +00001026void GDBRemoteCommunicationClient::MaybeEnableCompression(
1027 std::vector<std::string> supported_compressions) {
1028 CompressionType avail_type = CompressionType::None;
1029 std::string avail_name;
1030
1031#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001032 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001033 for (auto compression : supported_compressions) {
1034 if (compression == "lzfse") {
1035 avail_type = CompressionType::LZFSE;
1036 avail_name = compression;
1037 break;
1038 }
1039 }
1040 }
1041#endif
1042
1043#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001044 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001045 for (auto compression : supported_compressions) {
1046 if (compression == "zlib-deflate") {
1047 avail_type = CompressionType::ZlibDeflate;
1048 avail_name = compression;
1049 break;
1050 }
1051 }
1052 }
1053#endif
1054
1055#if defined(HAVE_LIBZ)
1056 if (avail_type == CompressionType::None) {
1057 for (auto compression : supported_compressions) {
1058 if (compression == "zlib-deflate") {
1059 avail_type = CompressionType::ZlibDeflate;
1060 avail_name = compression;
1061 break;
1062 }
1063 }
1064 }
1065#endif
1066
1067#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001068 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001069 for (auto compression : supported_compressions) {
1070 if (compression == "lz4") {
1071 avail_type = CompressionType::LZ4;
1072 avail_name = compression;
1073 break;
1074 }
1075 }
1076 }
1077#endif
1078
1079#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001080 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081 for (auto compression : supported_compressions) {
1082 if (compression == "lzma") {
1083 avail_type = CompressionType::LZMA;
1084 avail_name = compression;
1085 break;
1086 }
1087 }
1088 }
1089#endif
1090
1091 if (avail_type != CompressionType::None) {
Greg Clayton576d8832011-03-22 04:00:09 +00001092 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 std::string packet = "QEnableCompression:type:" + avail_name + ";";
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001094 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00001095 PacketResult::Success)
1096 return;
1097
1098 if (response.IsOKResponse()) {
1099 m_compression_type = avail_type;
Greg Clayton576d8832011-03-22 04:00:09 +00001100 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 }
Greg Clayton576d8832011-03-22 04:00:09 +00001102}
Greg Clayton32e0a752011-03-30 18:16:51 +00001103
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
1105 if (GetGDBServerVersion()) {
1106 if (!m_gdb_server_name.empty())
1107 return m_gdb_server_name.c_str();
1108 }
1109 return NULL;
1110}
1111
1112uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1113 if (GetGDBServerVersion())
1114 return m_gdb_server_version;
1115 return 0;
1116}
1117
1118bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
1119 StringExtractorGDBRemote response;
1120 if (SendPacketAndWaitForResponse("qC", response, false) !=
1121 PacketResult::Success)
1122 return false;
1123
1124 if (!response.IsNormalResponse())
1125 return false;
1126
1127 if (response.GetChar() == 'Q' && response.GetChar() == 'C')
1128 tid = response.GetHexMaxU32(true, -1);
1129
1130 return true;
1131}
1132
1133bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
1134 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
1135
1136 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
Pavel Labathe7ec0832018-08-31 05:34:03 +00001137 // host info computation can require DNS traffic and shelling out to external processes.
1138 // Increase the timeout to account for that.
1139 ScopedTimeout timeout(*this, seconds(10));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001140 m_qHostInfo_is_valid = eLazyBoolNo;
Jim Ingham106d0282014-06-25 02:32:56 +00001141 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001142 if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
1143 PacketResult::Success) {
1144 if (response.IsNormalResponse()) {
Zachary Turner54695a32016-08-29 19:58:14 +00001145 llvm::StringRef name;
1146 llvm::StringRef value;
Jason Molenda89c37492014-01-27 22:23:20 +00001147 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1148 uint32_t sub = 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001149 std::string arch_name;
1150 std::string os_name;
1151 std::string vendor_name;
1152 std::string triple;
1153 std::string distribution_id;
1154 uint32_t pointer_byte_size = 0;
1155 ByteOrder byte_order = eByteOrderInvalid;
1156 uint32_t num_keys_decoded = 0;
1157 while (response.GetNameColonValue(name, value)) {
1158 if (name.equals("cputype")) {
1159 // exception type in big endian hex
1160 if (!value.getAsInteger(0, cpu))
1161 ++num_keys_decoded;
1162 } else if (name.equals("cpusubtype")) {
1163 // exception count in big endian hex
1164 if (!value.getAsInteger(0, sub))
1165 ++num_keys_decoded;
1166 } else if (name.equals("arch")) {
1167 arch_name = value;
1168 ++num_keys_decoded;
1169 } else if (name.equals("triple")) {
1170 StringExtractor extractor(value);
1171 extractor.GetHexByteString(triple);
1172 ++num_keys_decoded;
1173 } else if (name.equals("distribution_id")) {
1174 StringExtractor extractor(value);
1175 extractor.GetHexByteString(distribution_id);
1176 ++num_keys_decoded;
1177 } else if (name.equals("os_build")) {
1178 StringExtractor extractor(value);
1179 extractor.GetHexByteString(m_os_build);
1180 ++num_keys_decoded;
1181 } else if (name.equals("hostname")) {
1182 StringExtractor extractor(value);
1183 extractor.GetHexByteString(m_hostname);
1184 ++num_keys_decoded;
1185 } else if (name.equals("os_kernel")) {
1186 StringExtractor extractor(value);
1187 extractor.GetHexByteString(m_os_kernel);
1188 ++num_keys_decoded;
1189 } else if (name.equals("ostype")) {
1190 os_name = value;
1191 ++num_keys_decoded;
1192 } else if (name.equals("vendor")) {
1193 vendor_name = value;
1194 ++num_keys_decoded;
1195 } else if (name.equals("endian")) {
1196 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1197 .Case("little", eByteOrderLittle)
1198 .Case("big", eByteOrderBig)
1199 .Case("pdp", eByteOrderPDP)
1200 .Default(eByteOrderInvalid);
1201 if (byte_order != eByteOrderInvalid)
1202 ++num_keys_decoded;
1203 } else if (name.equals("ptrsize")) {
1204 if (!value.getAsInteger(0, pointer_byte_size))
1205 ++num_keys_decoded;
1206 } else if (name.equals("os_version") ||
1207 name.equals(
1208 "version")) // Older debugserver binaries used the
1209 // "version" key instead of
1210 // "os_version"...
1211 {
Pavel Labath2272c482018-06-18 15:02:23 +00001212 if (!m_os_version.tryParse(value))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213 ++num_keys_decoded;
1214 } else if (name.equals("watchpoint_exceptions_received")) {
1215 m_watchpoints_trigger_after_instruction =
1216 llvm::StringSwitch<LazyBool>(value)
1217 .Case("before", eLazyBoolNo)
1218 .Case("after", eLazyBoolYes)
1219 .Default(eLazyBoolCalculate);
1220 if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
1221 ++num_keys_decoded;
1222 } else if (name.equals("default_packet_timeout")) {
Pavel Labath3aa04912016-10-31 17:19:42 +00001223 uint32_t timeout_seconds;
1224 if (!value.getAsInteger(0, timeout_seconds)) {
Pavel Labath1eff73c2016-11-24 10:54:49 +00001225 m_default_packet_timeout = seconds(timeout_seconds);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001226 SetPacketTimeout(m_default_packet_timeout);
1227 ++num_keys_decoded;
Greg Clayton32e0a752011-03-30 18:16:51 +00001228 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001229 }
Jason Molenda89c37492014-01-27 22:23:20 +00001230 }
1231
Kate Stoneb9c1b512016-09-06 20:57:50 +00001232 if (num_keys_decoded > 0)
1233 m_qHostInfo_is_valid = eLazyBoolYes;
1234
1235 if (triple.empty()) {
1236 if (arch_name.empty()) {
1237 if (cpu != LLDB_INVALID_CPUTYPE) {
1238 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1239 if (pointer_byte_size) {
1240 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1241 }
1242 if (byte_order != eByteOrderInvalid) {
1243 assert(byte_order == m_host_arch.GetByteOrder());
1244 }
1245
1246 if (!vendor_name.empty())
1247 m_host_arch.GetTriple().setVendorName(
1248 llvm::StringRef(vendor_name));
1249 if (!os_name.empty())
1250 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
Jason Molenda89c37492014-01-27 22:23:20 +00001251 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001252 } else {
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001253 std::string triple;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001254 triple += arch_name;
1255 if (!vendor_name.empty() || !os_name.empty()) {
1256 triple += '-';
1257 if (vendor_name.empty())
1258 triple += "unknown";
1259 else
1260 triple += vendor_name;
1261 triple += '-';
1262 if (os_name.empty())
1263 triple += "unknown";
1264 else
1265 triple += os_name;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001266 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001267 m_host_arch.SetTriple(triple.c_str());
Todd Fialac540dd02014-08-26 18:21:02 +00001268
Kate Stoneb9c1b512016-09-06 20:57:50 +00001269 llvm::Triple &host_triple = m_host_arch.GetTriple();
1270 if (host_triple.getVendor() == llvm::Triple::Apple &&
1271 host_triple.getOS() == llvm::Triple::Darwin) {
1272 switch (m_host_arch.GetMachine()) {
1273 case llvm::Triple::aarch64:
1274 case llvm::Triple::arm:
1275 case llvm::Triple::thumb:
1276 host_triple.setOS(llvm::Triple::IOS);
Greg Claytonadc00cb2011-05-20 23:38:13 +00001277 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001278 default:
1279 host_triple.setOS(llvm::Triple::MacOSX);
1280 break;
1281 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001282 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001283 if (pointer_byte_size) {
1284 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1285 }
1286 if (byte_order != eByteOrderInvalid) {
1287 assert(byte_order == m_host_arch.GetByteOrder());
1288 }
1289 }
1290 } else {
1291 m_host_arch.SetTriple(triple.c_str());
1292 if (pointer_byte_size) {
1293 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1294 }
1295 if (byte_order != eByteOrderInvalid) {
1296 assert(byte_order == m_host_arch.GetByteOrder());
1297 }
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001298
Kate Stoneb9c1b512016-09-06 20:57:50 +00001299 if (log)
1300 log->Printf("GDBRemoteCommunicationClient::%s parsed host "
1301 "architecture as %s, triple as %s from triple text %s",
1302 __FUNCTION__, m_host_arch.GetArchitectureName()
1303 ? m_host_arch.GetArchitectureName()
1304 : "<null-arch-name>",
1305 m_host_arch.GetTriple().getTriple().c_str(),
1306 triple.c_str());
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001307 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001308 if (!distribution_id.empty())
1309 m_host_arch.SetDistributionId(distribution_id.c_str());
1310 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001311 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001312 }
1313 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Claytonadc00cb2011-05-20 23:38:13 +00001314}
Greg Clayton37a0a242012-04-11 00:24:49 +00001315
Kate Stoneb9c1b512016-09-06 20:57:50 +00001316int GDBRemoteCommunicationClient::SendAttach(
1317 lldb::pid_t pid, StringExtractorGDBRemote &response) {
1318 if (pid != LLDB_INVALID_PROCESS_ID) {
1319 char packet[64];
1320 const int packet_len =
1321 ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001322 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001323 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001324 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001325 PacketResult::Success) {
1326 if (response.IsErrorResponse())
1327 return response.GetError();
1328 return 0;
1329 }
1330 }
1331 return -1;
1332}
1333
1334int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
1335 size_t data_len) {
1336 StreamString packet;
1337 packet.PutCString("I");
1338 packet.PutBytesAsRawHex8(data, data_len);
1339 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001340 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1341 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001342 return 0;
1343 }
1344 return response.GetError();
1345}
1346
1347const lldb_private::ArchSpec &
1348GDBRemoteCommunicationClient::GetHostArchitecture() {
1349 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1350 GetHostInfo();
1351 return m_host_arch;
1352}
1353
Pavel Labath1eff73c2016-11-24 10:54:49 +00001354seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001355 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1356 GetHostInfo();
1357 return m_default_packet_timeout;
1358}
1359
1360addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
1361 uint32_t permissions) {
1362 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1363 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1364 char packet[64];
1365 const int packet_len = ::snprintf(
1366 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1367 permissions & lldb::ePermissionsReadable ? "r" : "",
1368 permissions & lldb::ePermissionsWritable ? "w" : "",
1369 permissions & lldb::ePermissionsExecutable ? "x" : "");
1370 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001371 UNUSED_IF_ASSERT_DISABLED(packet_len);
Pavel Labath83082a02016-08-18 14:33:55 +00001372 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001373 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001374 PacketResult::Success) {
1375 if (response.IsUnsupportedResponse())
1376 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1377 else if (!response.IsErrorResponse())
1378 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1379 } else {
1380 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1381 }
1382 }
1383 return LLDB_INVALID_ADDRESS;
1384}
1385
1386bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
1387 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1388 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1389 char packet[64];
1390 const int packet_len =
1391 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1392 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001393 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001394 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001395 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001396 PacketResult::Success) {
1397 if (response.IsUnsupportedResponse())
1398 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1399 else if (response.IsOKResponse())
1400 return true;
1401 } else {
1402 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1403 }
1404 }
1405 return false;
1406}
1407
Zachary Turner97206d52017-05-12 04:51:55 +00001408Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
1409 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001410
1411 if (keep_stopped) {
1412 if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
1413 char packet[64];
1414 const int packet_len =
1415 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1416 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001417 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001418 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001419 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001420 PacketResult::Success &&
1421 response.IsOKResponse()) {
1422 m_supports_detach_stay_stopped = eLazyBoolYes;
1423 } else {
1424 m_supports_detach_stay_stopped = eLazyBoolNo;
1425 }
1426 }
1427
1428 if (m_supports_detach_stay_stopped == eLazyBoolNo) {
1429 error.SetErrorString("Stays stopped not supported by this target.");
1430 return error;
1431 } else {
1432 StringExtractorGDBRemote response;
1433 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001434 SendPacketAndWaitForResponse("D1", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001435 if (packet_result != PacketResult::Success)
1436 error.SetErrorString("Sending extended disconnect packet failed.");
1437 }
1438 } else {
1439 StringExtractorGDBRemote response;
1440 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001441 SendPacketAndWaitForResponse("D", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001442 if (packet_result != PacketResult::Success)
1443 error.SetErrorString("Sending disconnect packet failed.");
1444 }
1445 return error;
1446}
1447
Zachary Turner97206d52017-05-12 04:51:55 +00001448Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001449 lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
Zachary Turner97206d52017-05-12 04:51:55 +00001450 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001451 region_info.Clear();
1452
1453 if (m_supports_memory_region_info != eLazyBoolNo) {
1454 m_supports_memory_region_info = eLazyBoolYes;
1455 char packet[64];
1456 const int packet_len = ::snprintf(
1457 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1458 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001459 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001460 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001461 if (SendPacketAndWaitForResponse(packet, response, false) ==
Pavel Labath16064d32018-03-20 11:56:24 +00001462 PacketResult::Success &&
1463 response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001464 llvm::StringRef name;
1465 llvm::StringRef value;
1466 addr_t addr_value = LLDB_INVALID_ADDRESS;
1467 bool success = true;
1468 bool saw_permissions = false;
1469 while (success && response.GetNameColonValue(name, value)) {
1470 if (name.equals("start")) {
1471 if (!value.getAsInteger(16, addr_value))
1472 region_info.GetRange().SetRangeBase(addr_value);
1473 } else if (name.equals("size")) {
1474 if (!value.getAsInteger(16, addr_value))
1475 region_info.GetRange().SetByteSize(addr_value);
1476 } else if (name.equals("permissions") &&
1477 region_info.GetRange().IsValid()) {
1478 saw_permissions = true;
1479 if (region_info.GetRange().Contains(addr)) {
1480 if (value.find('r') != llvm::StringRef::npos)
1481 region_info.SetReadable(MemoryRegionInfo::eYes);
1482 else
1483 region_info.SetReadable(MemoryRegionInfo::eNo);
1484
1485 if (value.find('w') != llvm::StringRef::npos)
1486 region_info.SetWritable(MemoryRegionInfo::eYes);
1487 else
1488 region_info.SetWritable(MemoryRegionInfo::eNo);
1489
1490 if (value.find('x') != llvm::StringRef::npos)
1491 region_info.SetExecutable(MemoryRegionInfo::eYes);
1492 else
1493 region_info.SetExecutable(MemoryRegionInfo::eNo);
1494
1495 region_info.SetMapped(MemoryRegionInfo::eYes);
1496 } else {
1497 // The reported region does not contain this address -- we're
1498 // looking at an unmapped page
1499 region_info.SetReadable(MemoryRegionInfo::eNo);
1500 region_info.SetWritable(MemoryRegionInfo::eNo);
1501 region_info.SetExecutable(MemoryRegionInfo::eNo);
1502 region_info.SetMapped(MemoryRegionInfo::eNo);
1503 }
1504 } else if (name.equals("name")) {
1505 StringExtractorGDBRemote name_extractor(value);
1506 std::string name;
1507 name_extractor.GetHexByteString(name);
1508 region_info.SetName(name.c_str());
1509 } else if (name.equals("error")) {
1510 StringExtractorGDBRemote error_extractor(value);
1511 std::string error_string;
1512 // Now convert the HEX bytes into a string value
1513 error_extractor.GetHexByteString(error_string);
1514 error.SetErrorString(error_string.c_str());
1515 }
1516 }
1517
Stephane Sezer48d14272017-03-31 18:00:48 +00001518 if (region_info.GetRange().IsValid()) {
1519 // We got a valid address range back but no permissions -- which means
1520 // this is an unmapped page
1521 if (!saw_permissions) {
1522 region_info.SetReadable(MemoryRegionInfo::eNo);
1523 region_info.SetWritable(MemoryRegionInfo::eNo);
1524 region_info.SetExecutable(MemoryRegionInfo::eNo);
1525 region_info.SetMapped(MemoryRegionInfo::eNo);
1526 }
1527 } else {
1528 // We got an invalid address range back
1529 error.SetErrorString("Server returned invalid range");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001530 }
1531 } else {
1532 m_supports_memory_region_info = eLazyBoolNo;
1533 }
1534 }
1535
1536 if (m_supports_memory_region_info == eLazyBoolNo) {
1537 error.SetErrorString("qMemoryRegionInfo is not supported");
1538 }
Pavel Labath16064d32018-03-20 11:56:24 +00001539
1540 // Try qXfer:memory-map:read to get region information not included in
1541 // qMemoryRegionInfo
1542 MemoryRegionInfo qXfer_region_info;
1543 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1544
1545 if (error.Fail()) {
Adrian Prantl05097242018-04-30 16:49:04 +00001546 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1547 // the qXfer result as a fallback
Pavel Labath16064d32018-03-20 11:56:24 +00001548 if (qXfer_error.Success()) {
1549 region_info = qXfer_region_info;
1550 error.Clear();
1551 } else {
1552 region_info.Clear();
1553 }
1554 } else if (qXfer_error.Success()) {
1555 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
Adrian Prantl05097242018-04-30 16:49:04 +00001556 // both regions are the same range, update the result to include the flash-
1557 // memory information that is specific to the qXfer result.
Pavel Labath16064d32018-03-20 11:56:24 +00001558 if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1559 region_info.SetFlash(qXfer_region_info.GetFlash());
1560 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1561 }
1562 }
1563 return error;
1564}
1565
1566Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1567 lldb::addr_t addr, MemoryRegionInfo &region) {
1568 Status error = LoadQXferMemoryMap();
1569 if (!error.Success())
1570 return error;
1571 for (const auto &map_region : m_qXfer_memory_map) {
1572 if (map_region.GetRange().Contains(addr)) {
1573 region = map_region;
1574 return error;
1575 }
1576 }
1577 error.SetErrorString("Region not found");
1578 return error;
1579}
1580
1581Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
1582
1583 Status error;
1584
1585 if (m_qXfer_memory_map_loaded)
1586 // Already loaded, return success
1587 return error;
1588
1589 if (!XMLDocument::XMLEnabled()) {
1590 error.SetErrorString("XML is not supported");
1591 return error;
1592 }
1593
1594 if (!GetQXferMemoryMapReadSupported()) {
1595 error.SetErrorString("Memory map is not supported");
1596 return error;
1597 }
1598
1599 std::string xml;
1600 lldb_private::Status lldberr;
1601 if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
1602 lldberr)) {
1603 error.SetErrorString("Failed to read memory map");
1604 return error;
1605 }
1606
1607 XMLDocument xml_document;
1608
1609 if (!xml_document.ParseMemory(xml.c_str(), xml.size())) {
1610 error.SetErrorString("Failed to parse memory map xml");
1611 return error;
1612 }
1613
1614 XMLNode map_node = xml_document.GetRootElement("memory-map");
1615 if (!map_node) {
1616 error.SetErrorString("Invalid root node in memory map xml");
1617 return error;
1618 }
1619
1620 m_qXfer_memory_map.clear();
1621
1622 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1623 if (!memory_node.IsElement())
1624 return true;
1625 if (memory_node.GetName() != "memory")
1626 return true;
1627 auto type = memory_node.GetAttributeValue("type", "");
1628 uint64_t start;
1629 uint64_t length;
1630 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1631 return true;
1632 if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1633 return true;
1634 MemoryRegionInfo region;
1635 region.GetRange().SetRangeBase(start);
1636 region.GetRange().SetByteSize(length);
1637 if (type == "rom") {
1638 region.SetReadable(MemoryRegionInfo::eYes);
1639 this->m_qXfer_memory_map.push_back(region);
1640 } else if (type == "ram") {
1641 region.SetReadable(MemoryRegionInfo::eYes);
1642 region.SetWritable(MemoryRegionInfo::eYes);
1643 this->m_qXfer_memory_map.push_back(region);
1644 } else if (type == "flash") {
1645 region.SetFlash(MemoryRegionInfo::eYes);
1646 memory_node.ForEachChildElement(
1647 [&region](const XMLNode &prop_node) -> bool {
1648 if (!prop_node.IsElement())
1649 return true;
1650 if (prop_node.GetName() != "property")
1651 return true;
1652 auto propname = prop_node.GetAttributeValue("name", "");
1653 if (propname == "blocksize") {
1654 uint64_t blocksize;
1655 if (prop_node.GetElementTextAsUnsigned(blocksize))
1656 region.SetBlocksize(blocksize);
1657 }
1658 return true;
1659 });
1660 this->m_qXfer_memory_map.push_back(region);
1661 }
1662 return true;
1663 });
1664
1665 m_qXfer_memory_map_loaded = true;
1666
Kate Stoneb9c1b512016-09-06 20:57:50 +00001667 return error;
1668}
1669
Zachary Turner97206d52017-05-12 04:51:55 +00001670Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
1671 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001672
1673 if (m_supports_watchpoint_support_info == eLazyBoolYes) {
1674 num = m_num_supported_hardware_watchpoints;
1675 return error;
1676 }
1677
1678 // Set num to 0 first.
1679 num = 0;
1680 if (m_supports_watchpoint_support_info != eLazyBoolNo) {
1681 char packet[64];
1682 const int packet_len =
1683 ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
1684 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001685 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001686 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001687 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001688 PacketResult::Success) {
1689 m_supports_watchpoint_support_info = eLazyBoolYes;
1690 llvm::StringRef name;
1691 llvm::StringRef value;
1692 while (response.GetNameColonValue(name, value)) {
1693 if (name.equals("num")) {
1694 value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1695 num = m_num_supported_hardware_watchpoints;
1696 }
1697 }
1698 } else {
1699 m_supports_watchpoint_support_info = eLazyBoolNo;
1700 }
1701 }
1702
1703 if (m_supports_watchpoint_support_info == eLazyBoolNo) {
1704 error.SetErrorString("qWatchpointSupportInfo is not supported");
1705 }
1706 return error;
1707}
1708
Zachary Turner97206d52017-05-12 04:51:55 +00001709lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001710 uint32_t &num, bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001711 Status error(GetWatchpointSupportInfo(num));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001712 if (error.Success())
1713 error = GetWatchpointsTriggerAfterInstruction(after, arch);
1714 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001715}
1716
Zachary Turner97206d52017-05-12 04:51:55 +00001717lldb_private::Status
Kate Stoneb9c1b512016-09-06 20:57:50 +00001718GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
1719 bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001720 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001721 llvm::Triple::ArchType atype = arch.GetMachine();
Daniel Maleae0f8f572013-08-26 23:57:52 +00001722
Adrian Prantl05097242018-04-30 16:49:04 +00001723 // we assume watchpoints will happen after running the relevant opcode and we
1724 // only want to override this behavior if we have explicitly received a
1725 // qHostInfo telling us otherwise
Kate Stoneb9c1b512016-09-06 20:57:50 +00001726 if (m_qHostInfo_is_valid != eLazyBoolYes) {
Pavel Labathc51ad482017-10-27 17:02:32 +00001727 // On targets like MIPS and ppc64le, watchpoint exceptions are always
Adrian Prantl05097242018-04-30 16:49:04 +00001728 // generated before the instruction is executed. The connected target may
1729 // not support qHostInfo or qWatchpointSupportInfo packets.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001730 if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
Pavel Labathc51ad482017-10-27 17:02:32 +00001731 atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
1732 atype == llvm::Triple::ppc64le)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001733 after = false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00001734 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001735 after = true;
1736 } else {
Pavel Labathc51ad482017-10-27 17:02:32 +00001737 // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to
1738 // eLazyBoolNo if it is not calculated before.
1739 if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
1740 (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
1741 atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) ||
1742 atype == llvm::Triple::ppc64le) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001743 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
Pavel Labathc51ad482017-10-27 17:02:32 +00001744 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001745
1746 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1747 }
1748 return error;
1749}
1750
1751int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
1752 if (file_spec) {
1753 std::string path{file_spec.GetPath(false)};
1754 StreamString packet;
1755 packet.PutCString("QSetSTDIN:");
1756 packet.PutCStringAsRawHex8(path.c_str());
1757
1758 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001759 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1760 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001761 if (response.IsOKResponse())
1762 return 0;
1763 uint8_t error = response.GetError();
1764 if (error)
1765 return error;
1766 }
1767 }
1768 return -1;
1769}
1770
1771int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
1772 if (file_spec) {
1773 std::string path{file_spec.GetPath(false)};
1774 StreamString packet;
1775 packet.PutCString("QSetSTDOUT:");
1776 packet.PutCStringAsRawHex8(path.c_str());
1777
1778 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001779 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1780 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001781 if (response.IsOKResponse())
1782 return 0;
1783 uint8_t error = response.GetError();
1784 if (error)
1785 return error;
1786 }
1787 }
1788 return -1;
1789}
1790
1791int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
1792 if (file_spec) {
1793 std::string path{file_spec.GetPath(false)};
1794 StreamString packet;
1795 packet.PutCString("QSetSTDERR:");
1796 packet.PutCStringAsRawHex8(path.c_str());
1797
1798 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001799 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1800 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001801 if (response.IsOKResponse())
1802 return 0;
1803 uint8_t error = response.GetError();
1804 if (error)
1805 return error;
1806 }
1807 }
1808 return -1;
1809}
1810
1811bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
1812 StringExtractorGDBRemote response;
1813 if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
1814 PacketResult::Success) {
1815 if (response.IsUnsupportedResponse())
1816 return false;
1817 if (response.IsErrorResponse())
1818 return false;
1819 std::string cwd;
1820 response.GetHexByteString(cwd);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00001821 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001822 return !cwd.empty();
1823 }
1824 return false;
1825}
1826
1827int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
1828 if (working_dir) {
1829 std::string path{working_dir.GetPath(false)};
1830 StreamString packet;
1831 packet.PutCString("QSetWorkingDir:");
1832 packet.PutCStringAsRawHex8(path.c_str());
1833
1834 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001835 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1836 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001837 if (response.IsOKResponse())
1838 return 0;
1839 uint8_t error = response.GetError();
1840 if (error)
1841 return error;
1842 }
1843 }
1844 return -1;
1845}
1846
1847int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
1848 char packet[32];
1849 const int packet_len =
1850 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1851 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001852 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001853 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001854 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001855 PacketResult::Success) {
1856 if (response.IsOKResponse())
1857 return 0;
1858 uint8_t error = response.GetError();
1859 if (error)
1860 return error;
1861 }
1862 return -1;
1863}
1864
1865int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
1866 char packet[32];
1867 const int packet_len = ::snprintf(packet, sizeof(packet),
1868 "QSetDetachOnError:%i", enable ? 1 : 0);
1869 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001870 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001871 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001872 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001873 PacketResult::Success) {
1874 if (response.IsOKResponse())
1875 return 0;
1876 uint8_t error = response.GetError();
1877 if (error)
1878 return error;
1879 }
1880 return -1;
1881}
1882
1883bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
1884 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
1885 if (response.IsNormalResponse()) {
1886 llvm::StringRef name;
1887 llvm::StringRef value;
1888 StringExtractor extractor;
1889
1890 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1891 uint32_t sub = 0;
1892 std::string vendor;
1893 std::string os_type;
1894
1895 while (response.GetNameColonValue(name, value)) {
1896 if (name.equals("pid")) {
1897 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1898 value.getAsInteger(0, pid);
1899 process_info.SetProcessID(pid);
1900 } else if (name.equals("ppid")) {
1901 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1902 value.getAsInteger(0, pid);
1903 process_info.SetParentProcessID(pid);
1904 } else if (name.equals("uid")) {
1905 uint32_t uid = UINT32_MAX;
1906 value.getAsInteger(0, uid);
1907 process_info.SetUserID(uid);
1908 } else if (name.equals("euid")) {
1909 uint32_t uid = UINT32_MAX;
1910 value.getAsInteger(0, uid);
1911 process_info.SetEffectiveGroupID(uid);
1912 } else if (name.equals("gid")) {
1913 uint32_t gid = UINT32_MAX;
1914 value.getAsInteger(0, gid);
1915 process_info.SetGroupID(gid);
1916 } else if (name.equals("egid")) {
1917 uint32_t gid = UINT32_MAX;
1918 value.getAsInteger(0, gid);
1919 process_info.SetEffectiveGroupID(gid);
1920 } else if (name.equals("triple")) {
1921 StringExtractor extractor(value);
1922 std::string triple;
1923 extractor.GetHexByteString(triple);
1924 process_info.GetArchitecture().SetTriple(triple.c_str());
1925 } else if (name.equals("name")) {
1926 StringExtractor extractor(value);
Adrian Prantl05097242018-04-30 16:49:04 +00001927 // The process name from ASCII hex bytes since we can't control the
1928 // characters in a process name
Kate Stoneb9c1b512016-09-06 20:57:50 +00001929 std::string name;
1930 extractor.GetHexByteString(name);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00001931 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001932 } else if (name.equals("cputype")) {
1933 value.getAsInteger(0, cpu);
1934 } else if (name.equals("cpusubtype")) {
1935 value.getAsInteger(0, sub);
1936 } else if (name.equals("vendor")) {
1937 vendor = value;
1938 } else if (name.equals("ostype")) {
1939 os_type = value;
1940 }
1941 }
1942
1943 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
1944 if (vendor == "apple") {
1945 process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
1946 sub);
1947 process_info.GetArchitecture().GetTriple().setVendorName(
1948 llvm::StringRef(vendor));
1949 process_info.GetArchitecture().GetTriple().setOSName(
1950 llvm::StringRef(os_type));
1951 }
1952 }
1953
1954 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1955 return true;
1956 }
1957 return false;
1958}
1959
1960bool GDBRemoteCommunicationClient::GetProcessInfo(
1961 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
1962 process_info.Clear();
1963
1964 if (m_supports_qProcessInfoPID) {
1965 char packet[32];
1966 const int packet_len =
1967 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
1968 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001969 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001970 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001971 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001972 PacketResult::Success) {
1973 return DecodeProcessInfoResponse(response, process_info);
1974 } else {
1975 m_supports_qProcessInfoPID = false;
1976 return false;
1977 }
1978 }
1979 return false;
1980}
1981
1982bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
1983 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
1984 GDBR_LOG_PACKETS));
1985
1986 if (allow_lazy) {
1987 if (m_qProcessInfo_is_valid == eLazyBoolYes)
1988 return true;
1989 if (m_qProcessInfo_is_valid == eLazyBoolNo)
1990 return false;
1991 }
1992
1993 GetHostInfo();
1994
1995 StringExtractorGDBRemote response;
1996 if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
1997 PacketResult::Success) {
1998 if (response.IsNormalResponse()) {
1999 llvm::StringRef name;
2000 llvm::StringRef value;
2001 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2002 uint32_t sub = 0;
2003 std::string arch_name;
2004 std::string os_name;
2005 std::string vendor_name;
2006 std::string triple;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002007 std::string elf_abi;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002008 uint32_t pointer_byte_size = 0;
2009 StringExtractor extractor;
2010 ByteOrder byte_order = eByteOrderInvalid;
2011 uint32_t num_keys_decoded = 0;
2012 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
2013 while (response.GetNameColonValue(name, value)) {
2014 if (name.equals("cputype")) {
2015 if (!value.getAsInteger(16, cpu))
2016 ++num_keys_decoded;
2017 } else if (name.equals("cpusubtype")) {
2018 if (!value.getAsInteger(16, sub))
2019 ++num_keys_decoded;
2020 } else if (name.equals("triple")) {
2021 StringExtractor extractor(value);
2022 extractor.GetHexByteString(triple);
2023 ++num_keys_decoded;
2024 } else if (name.equals("ostype")) {
2025 os_name = value;
2026 ++num_keys_decoded;
2027 } else if (name.equals("vendor")) {
2028 vendor_name = value;
2029 ++num_keys_decoded;
2030 } else if (name.equals("endian")) {
2031 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2032 .Case("little", eByteOrderLittle)
2033 .Case("big", eByteOrderBig)
2034 .Case("pdp", eByteOrderPDP)
2035 .Default(eByteOrderInvalid);
2036 if (byte_order != eByteOrderInvalid)
2037 ++num_keys_decoded;
2038 } else if (name.equals("ptrsize")) {
2039 if (!value.getAsInteger(16, pointer_byte_size))
2040 ++num_keys_decoded;
2041 } else if (name.equals("pid")) {
2042 if (!value.getAsInteger(16, pid))
2043 ++num_keys_decoded;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002044 } else if (name.equals("elf_abi")) {
2045 elf_abi = value;
2046 ++num_keys_decoded;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002047 }
2048 }
2049 if (num_keys_decoded > 0)
2050 m_qProcessInfo_is_valid = eLazyBoolYes;
2051 if (pid != LLDB_INVALID_PROCESS_ID) {
2052 m_curr_pid_is_valid = eLazyBoolYes;
2053 m_curr_pid = pid;
2054 }
2055
2056 // Set the ArchSpec from the triple if we have it.
2057 if (!triple.empty()) {
2058 m_process_arch.SetTriple(triple.c_str());
Nitesh Jain8999edf2016-10-12 10:21:09 +00002059 m_process_arch.SetFlags(elf_abi);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002060 if (pointer_byte_size) {
2061 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2062 }
2063 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2064 !vendor_name.empty()) {
2065 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2066
2067 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
Pavel Labath4f19fce22017-02-17 13:39:50 +00002068 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002069 switch (triple.getObjectFormat()) {
2070 case llvm::Triple::MachO:
2071 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2072 break;
2073 case llvm::Triple::ELF:
2074 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2075 break;
2076 case llvm::Triple::COFF:
2077 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2078 break;
Pavel Labath4f19fce22017-02-17 13:39:50 +00002079 case llvm::Triple::Wasm:
2080 if (log)
2081 log->Printf("error: not supported target architecture");
2082 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002083 case llvm::Triple::UnknownObjectFormat:
2084 if (log)
2085 log->Printf("error: failed to determine target architecture");
2086 return false;
2087 }
2088
2089 if (pointer_byte_size) {
2090 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2091 }
2092 if (byte_order != eByteOrderInvalid) {
2093 assert(byte_order == m_process_arch.GetByteOrder());
2094 }
2095 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2096 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2097 m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2098 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2099 }
2100 return true;
2101 }
2102 } else {
2103 m_qProcessInfo_is_valid = eLazyBoolNo;
2104 }
2105
2106 return false;
2107}
2108
2109uint32_t GDBRemoteCommunicationClient::FindProcesses(
2110 const ProcessInstanceInfoMatch &match_info,
2111 ProcessInstanceInfoList &process_infos) {
2112 process_infos.Clear();
2113
2114 if (m_supports_qfProcessInfo) {
2115 StreamString packet;
2116 packet.PutCString("qfProcessInfo");
2117 if (!match_info.MatchAllProcesses()) {
2118 packet.PutChar(':');
2119 const char *name = match_info.GetProcessInfo().GetName();
2120 bool has_name_match = false;
2121 if (name && name[0]) {
2122 has_name_match = true;
Pavel Labathc4a33952017-02-20 11:35:33 +00002123 NameMatch name_match_type = match_info.GetNameMatchType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002124 switch (name_match_type) {
Pavel Labathc4a33952017-02-20 11:35:33 +00002125 case NameMatch::Ignore:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002126 has_name_match = false;
2127 break;
2128
Pavel Labathc4a33952017-02-20 11:35:33 +00002129 case NameMatch::Equals:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002130 packet.PutCString("name_match:equals;");
2131 break;
2132
Pavel Labathc4a33952017-02-20 11:35:33 +00002133 case NameMatch::Contains:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002134 packet.PutCString("name_match:contains;");
2135 break;
2136
Pavel Labathc4a33952017-02-20 11:35:33 +00002137 case NameMatch::StartsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002138 packet.PutCString("name_match:starts_with;");
2139 break;
2140
Pavel Labathc4a33952017-02-20 11:35:33 +00002141 case NameMatch::EndsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002142 packet.PutCString("name_match:ends_with;");
2143 break;
2144
Pavel Labathc4a33952017-02-20 11:35:33 +00002145 case NameMatch::RegularExpression:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002146 packet.PutCString("name_match:regex;");
2147 break;
2148 }
2149 if (has_name_match) {
2150 packet.PutCString("name:");
2151 packet.PutBytesAsRawHex8(name, ::strlen(name));
2152 packet.PutChar(';');
2153 }
2154 }
2155
2156 if (match_info.GetProcessInfo().ProcessIDIsValid())
2157 packet.Printf("pid:%" PRIu64 ";",
2158 match_info.GetProcessInfo().GetProcessID());
2159 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2160 packet.Printf("parent_pid:%" PRIu64 ";",
2161 match_info.GetProcessInfo().GetParentProcessID());
2162 if (match_info.GetProcessInfo().UserIDIsValid())
2163 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2164 if (match_info.GetProcessInfo().GroupIDIsValid())
2165 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2166 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2167 packet.Printf("euid:%u;",
2168 match_info.GetProcessInfo().GetEffectiveUserID());
2169 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2170 packet.Printf("egid:%u;",
2171 match_info.GetProcessInfo().GetEffectiveGroupID());
2172 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2173 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
2174 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2175 const ArchSpec &match_arch =
2176 match_info.GetProcessInfo().GetArchitecture();
2177 const llvm::Triple &triple = match_arch.GetTriple();
2178 packet.PutCString("triple:");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00002179 packet.PutCString(triple.getTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002180 packet.PutChar(';');
2181 }
2182 }
2183 StringExtractorGDBRemote response;
Adrian Prantl05097242018-04-30 16:49:04 +00002184 // Increase timeout as the first qfProcessInfo packet takes a long time on
2185 // Android. The value of 1min was arrived at empirically.
Pavel Labath1eff73c2016-11-24 10:54:49 +00002186 ScopedTimeout timeout(*this, minutes(1));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002187 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2188 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002189 do {
2190 ProcessInstanceInfo process_info;
2191 if (!DecodeProcessInfoResponse(response, process_info))
2192 break;
2193 process_infos.Append(process_info);
2194 response.GetStringRef().clear();
2195 response.SetFilePos(0);
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002196 } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
2197 PacketResult::Success);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002198 } else {
2199 m_supports_qfProcessInfo = false;
2200 return 0;
2201 }
2202 }
2203 return process_infos.GetSize();
2204}
2205
2206bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
2207 std::string &name) {
2208 if (m_supports_qUserName) {
2209 char packet[32];
2210 const int packet_len =
2211 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2212 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002213 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002214 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002215 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002216 PacketResult::Success) {
2217 if (response.IsNormalResponse()) {
2218 // Make sure we parsed the right number of characters. The response is
Adrian Prantl05097242018-04-30 16:49:04 +00002219 // the hex encoded user name and should make up the entire packet. If
2220 // there are any non-hex ASCII bytes, the length won't match below..
Kate Stoneb9c1b512016-09-06 20:57:50 +00002221 if (response.GetHexByteString(name) * 2 ==
2222 response.GetStringRef().size())
2223 return true;
2224 }
2225 } else {
2226 m_supports_qUserName = false;
2227 return false;
2228 }
2229 }
2230 return false;
2231}
2232
2233bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
2234 std::string &name) {
2235 if (m_supports_qGroupName) {
2236 char packet[32];
2237 const int packet_len =
2238 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2239 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002240 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002241 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002242 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002243 PacketResult::Success) {
2244 if (response.IsNormalResponse()) {
2245 // Make sure we parsed the right number of characters. The response is
Adrian Prantl05097242018-04-30 16:49:04 +00002246 // the hex encoded group name and should make up the entire packet. If
2247 // there are any non-hex ASCII bytes, the length won't match below..
Kate Stoneb9c1b512016-09-06 20:57:50 +00002248 if (response.GetHexByteString(name) * 2 ==
2249 response.GetStringRef().size())
2250 return true;
2251 }
2252 } else {
2253 m_supports_qGroupName = false;
2254 return false;
2255 }
2256 }
2257 return false;
2258}
2259
2260bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
2261 // Form non-stop packet request
2262 char packet[32];
2263 const int packet_len =
2264 ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
2265 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002266 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002267
2268 StringExtractorGDBRemote response;
2269 // Send to target
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002270 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002271 PacketResult::Success)
2272 if (response.IsOKResponse())
2273 return true;
2274
2275 // Failed or not supported
2276 return false;
2277}
2278
2279static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2280 uint32_t recv_size) {
2281 packet.Clear();
2282 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2283 uint32_t bytes_left = send_size;
2284 while (bytes_left > 0) {
2285 if (bytes_left >= 26) {
2286 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2287 bytes_left -= 26;
2288 } else {
2289 packet.Printf("%*.*s;", bytes_left, bytes_left,
2290 "abcdefghijklmnopqrstuvwxyz");
2291 bytes_left = 0;
2292 }
2293 }
2294}
2295
Pavel Labath1eff73c2016-11-24 10:54:49 +00002296duration<float>
2297calculate_standard_deviation(const std::vector<duration<float>> &v) {
2298 using Dur = duration<float>;
Pavel Labath3aa04912016-10-31 17:19:42 +00002299 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2300 Dur mean = sum / v.size();
2301 float accum = 0;
2302 for (auto d : v) {
2303 float delta = (d - mean).count();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002304 accum += delta * delta;
Pavel Labath3aa04912016-10-31 17:19:42 +00002305 };
Kate Stoneb9c1b512016-09-06 20:57:50 +00002306
Pavel Labath3aa04912016-10-31 17:19:42 +00002307 return Dur(sqrtf(accum / (v.size() - 1)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002308}
2309
2310void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
2311 uint32_t max_send,
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002312 uint32_t max_recv,
2313 uint64_t recv_amount,
2314 bool json, Stream &strm) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002315 uint32_t i;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002316 if (SendSpeedTestPacket(0, 0)) {
2317 StreamString packet;
2318 if (json)
2319 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2320 "\"results\" : [",
2321 num_packets);
2322 else
2323 strm.Printf("Testing sending %u packets of various sizes:\n",
2324 num_packets);
2325 strm.Flush();
2326
2327 uint32_t result_idx = 0;
2328 uint32_t send_size;
Pavel Labath3aa04912016-10-31 17:19:42 +00002329 std::vector<duration<float>> packet_times;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002330
2331 for (send_size = 0; send_size <= max_send;
2332 send_size ? send_size *= 2 : send_size = 4) {
2333 for (uint32_t recv_size = 0; recv_size <= max_recv;
2334 recv_size ? recv_size *= 2 : recv_size = 4) {
2335 MakeSpeedTestPacket(packet, send_size, recv_size);
2336
2337 packet_times.clear();
2338 // Test how long it takes to send 'num_packets' packets
Pavel Labath3aa04912016-10-31 17:19:42 +00002339 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002340 for (i = 0; i < num_packets; ++i) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002341 const auto packet_start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002342 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002343 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Pavel Labath3aa04912016-10-31 17:19:42 +00002344 const auto packet_end_time = steady_clock::now();
2345 packet_times.push_back(packet_end_time - packet_start_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002346 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002347 const auto end_time = steady_clock::now();
2348 const auto total_time = end_time - start_time;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002349
2350 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002351 ((float)num_packets) / duration<float>(total_time).count();
2352 auto average_per_packet = total_time / num_packets;
2353 const duration<float> standard_deviation =
2354 calculate_standard_deviation(packet_times);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002355 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002356 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2357 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2358 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002359 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002360 total_time, standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002361 ++result_idx;
2362 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002363 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2364 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2365 "standard deviation of {5,10:ms+f6}\n",
2366 send_size, recv_size, duration<float>(total_time),
2367 packets_per_second, duration<float>(average_per_packet),
2368 standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002369 }
2370 strm.Flush();
2371 }
2372 }
2373
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002374 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002375 if (json)
2376 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2377 ": %" PRIu64 ",\n \"results\" : [",
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002378 recv_amount);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002379 else
2380 strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2381 "packet sizes:\n",
2382 k_recv_amount_mb);
2383 strm.Flush();
2384 send_size = 0;
2385 result_idx = 0;
2386 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2387 MakeSpeedTestPacket(packet, send_size, recv_size);
2388
2389 // If we have a receive size, test how long it takes to receive 4MB of
2390 // data
2391 if (recv_size > 0) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002392 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393 uint32_t bytes_read = 0;
2394 uint32_t packet_count = 0;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002395 while (bytes_read < recv_amount) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002396 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002397 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002398 bytes_read += recv_size;
2399 ++packet_count;
2400 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002401 const auto end_time = steady_clock::now();
2402 const auto total_time = end_time - start_time;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002403 float mb_second = ((float)recv_amount) /
Pavel Labath3aa04912016-10-31 17:19:42 +00002404 duration<float>(total_time).count() /
Kate Stoneb9c1b512016-09-06 20:57:50 +00002405 (1024.0 * 1024.0);
2406 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002407 ((float)packet_count) / duration<float>(total_time).count();
2408 const auto average_per_packet = total_time / packet_count;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002409
2410 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002411 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2412 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002413 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002414 total_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002415 ++result_idx;
2416 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002417 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2418 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2419 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002420 send_size, recv_size, packet_count, k_recv_amount_mb,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002421 duration<float>(total_time), mb_second,
2422 packets_per_second, duration<float>(average_per_packet));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002423 }
2424 strm.Flush();
2425 }
2426 }
2427 if (json)
2428 strm.Printf("\n ]\n }\n}\n");
2429 else
2430 strm.EOL();
2431 }
2432}
2433
2434bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
2435 uint32_t recv_size) {
2436 StreamString packet;
2437 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2438 uint32_t bytes_left = send_size;
2439 while (bytes_left > 0) {
2440 if (bytes_left >= 26) {
2441 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2442 bytes_left -= 26;
2443 } else {
2444 packet.Printf("%*.*s;", bytes_left, bytes_left,
2445 "abcdefghijklmnopqrstuvwxyz");
2446 bytes_left = 0;
2447 }
2448 }
2449
2450 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002451 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2452 PacketResult::Success;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002453}
2454
2455bool GDBRemoteCommunicationClient::LaunchGDBServer(
2456 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2457 std::string &socket_name) {
2458 pid = LLDB_INVALID_PROCESS_ID;
2459 port = 0;
2460 socket_name.clear();
2461
2462 StringExtractorGDBRemote response;
2463 StreamString stream;
2464 stream.PutCString("qLaunchGDBServer;");
2465 std::string hostname;
2466 if (remote_accept_hostname && remote_accept_hostname[0])
2467 hostname = remote_accept_hostname;
2468 else {
2469 if (HostInfo::GetHostname(hostname)) {
2470 // Make the GDB server we launch only accept connections from this host
2471 stream.Printf("host:%s;", hostname.c_str());
2472 } else {
Adrian Prantl05097242018-04-30 16:49:04 +00002473 // Make the GDB server we launch accept connections from any host since
2474 // we can't figure out the hostname
Kate Stoneb9c1b512016-09-06 20:57:50 +00002475 stream.Printf("host:*;");
2476 }
2477 }
2478 // give the process a few seconds to startup
Pavel Labath1eff73c2016-11-24 10:54:49 +00002479 ScopedTimeout timeout(*this, seconds(10));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002480
2481 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2482 PacketResult::Success) {
2483 llvm::StringRef name;
2484 llvm::StringRef value;
2485 while (response.GetNameColonValue(name, value)) {
2486 if (name.equals("port"))
2487 value.getAsInteger(0, port);
2488 else if (name.equals("pid"))
2489 value.getAsInteger(0, pid);
2490 else if (name.compare("socket_name") == 0) {
2491 StringExtractor extractor(value);
2492 extractor.GetHexByteString(socket_name);
2493 }
2494 }
2495 return true;
2496 }
2497 return false;
2498}
2499
2500size_t GDBRemoteCommunicationClient::QueryGDBServer(
2501 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2502 connection_urls.clear();
2503
2504 StringExtractorGDBRemote response;
2505 if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
2506 PacketResult::Success)
2507 return 0;
2508
2509 StructuredData::ObjectSP data =
2510 StructuredData::ParseJSON(response.GetStringRef());
2511 if (!data)
2512 return 0;
2513
2514 StructuredData::Array *array = data->GetAsArray();
2515 if (!array)
2516 return 0;
2517
2518 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2519 StructuredData::Dictionary *element = nullptr;
2520 if (!array->GetItemAtIndexAsDictionary(i, element))
2521 continue;
2522
2523 uint16_t port = 0;
2524 if (StructuredData::ObjectSP port_osp =
2525 element->GetValueForKey(llvm::StringRef("port")))
2526 port = port_osp->GetIntegerValue(0);
2527
2528 std::string socket_name;
2529 if (StructuredData::ObjectSP socket_name_osp =
2530 element->GetValueForKey(llvm::StringRef("socket_name")))
2531 socket_name = socket_name_osp->GetStringValue();
2532
2533 if (port != 0 || !socket_name.empty())
2534 connection_urls.emplace_back(port, socket_name);
2535 }
2536 return connection_urls.size();
2537}
2538
2539bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
2540 StreamString stream;
2541 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002542
2543 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002544 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002545 PacketResult::Success) {
2546 if (response.IsOKResponse())
2547 return true;
2548 }
2549 return false;
2550}
2551
2552bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
2553 if (m_curr_tid == tid)
2554 return true;
2555
2556 char packet[32];
2557 int packet_len;
2558 if (tid == UINT64_MAX)
2559 packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
2560 else
2561 packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
2562 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002563 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002564 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002565 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002566 PacketResult::Success) {
2567 if (response.IsOKResponse()) {
2568 m_curr_tid = tid;
2569 return true;
2570 }
2571
2572 /*
2573 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2574 * Hg packet.
2575 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2576 * which can
2577 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2578 */
2579 if (response.IsUnsupportedResponse() && IsConnected()) {
2580 m_curr_tid = 1;
2581 return true;
2582 }
2583 }
2584 return false;
2585}
2586
2587bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
2588 if (m_curr_tid_run == tid)
2589 return true;
2590
2591 char packet[32];
2592 int packet_len;
2593 if (tid == UINT64_MAX)
2594 packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
2595 else
2596 packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
2597
2598 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002599 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002600 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002601 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002602 PacketResult::Success) {
2603 if (response.IsOKResponse()) {
2604 m_curr_tid_run = tid;
2605 return true;
2606 }
2607
2608 /*
2609 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2610 * Hc packet.
2611 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2612 * which can
2613 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2614 */
2615 if (response.IsUnsupportedResponse() && IsConnected()) {
2616 m_curr_tid_run = 1;
2617 return true;
2618 }
2619 }
2620 return false;
2621}
2622
2623bool GDBRemoteCommunicationClient::GetStopReply(
2624 StringExtractorGDBRemote &response) {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002625 if (SendPacketAndWaitForResponse("?", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002626 PacketResult::Success)
2627 return response.IsNormalResponse();
2628 return false;
2629}
2630
2631bool GDBRemoteCommunicationClient::GetThreadStopInfo(
2632 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2633 if (m_supports_qThreadStopInfo) {
2634 char packet[256];
2635 int packet_len =
2636 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2637 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002638 UNUSED_IF_ASSERT_DISABLED(packet_len);
2639 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002640 PacketResult::Success) {
2641 if (response.IsUnsupportedResponse())
2642 m_supports_qThreadStopInfo = false;
2643 else if (response.IsNormalResponse())
2644 return true;
2645 else
2646 return false;
2647 } else {
2648 m_supports_qThreadStopInfo = false;
2649 }
2650 }
2651 return false;
2652}
2653
2654uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2655 GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
2656 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
2657 if (log)
2658 log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2659 __FUNCTION__, insert ? "add" : "remove", addr);
2660
2661 // Check if the stub is known not to support this breakpoint type
2662 if (!SupportsGDBStoppointPacket(type))
2663 return UINT8_MAX;
2664 // Construct the breakpoint packet
2665 char packet[64];
2666 const int packet_len =
2667 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
2668 insert ? 'Z' : 'z', type, addr, length);
2669 // Check we haven't overwritten the end of the packet buffer
2670 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002671 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002672 StringExtractorGDBRemote response;
2673 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2674 // or "" (unsupported)
2675 response.SetResponseValidatorToOKErrorNotSupported();
2676 // Try to send the breakpoint packet, and check that it was correctly sent
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002677 if (SendPacketAndWaitForResponse(packet, response, true) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002678 PacketResult::Success) {
2679 // Receive and OK packet when the breakpoint successfully placed
2680 if (response.IsOKResponse())
2681 return 0;
2682
Zachary Turner97206d52017-05-12 04:51:55 +00002683 // Status while setting breakpoint, send back specific error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002684 if (response.IsErrorResponse())
2685 return response.GetError();
2686
2687 // Empty packet informs us that breakpoint is not supported
2688 if (response.IsUnsupportedResponse()) {
2689 // Disable this breakpoint type since it is unsupported
2690 switch (type) {
2691 case eBreakpointSoftware:
2692 m_supports_z0 = false;
2693 break;
2694 case eBreakpointHardware:
2695 m_supports_z1 = false;
2696 break;
2697 case eWatchpointWrite:
2698 m_supports_z2 = false;
2699 break;
2700 case eWatchpointRead:
2701 m_supports_z3 = false;
2702 break;
2703 case eWatchpointReadWrite:
2704 m_supports_z4 = false;
2705 break;
2706 case eStoppointInvalid:
2707 return UINT8_MAX;
2708 }
2709 }
2710 }
2711 // Signal generic failure
2712 return UINT8_MAX;
2713}
2714
2715size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2716 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
2717 thread_ids.clear();
2718
2719 Lock lock(*this, false);
2720 if (lock) {
2721 sequence_mutex_unavailable = false;
2722 StringExtractorGDBRemote response;
2723
2724 PacketResult packet_result;
2725 for (packet_result =
2726 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
2727 packet_result == PacketResult::Success && response.IsNormalResponse();
2728 packet_result =
2729 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
2730 char ch = response.GetChar();
2731 if (ch == 'l')
2732 break;
2733 if (ch == 'm') {
2734 do {
2735 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
2736
2737 if (tid != LLDB_INVALID_THREAD_ID) {
2738 thread_ids.push_back(tid);
2739 }
2740 ch = response.GetChar(); // Skip the command separator
2741 } while (ch == ','); // Make sure we got a comma separator
2742 }
2743 }
2744
2745 /*
2746 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2747 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2748 * could
2749 * be as simple as 'S05'. There is no packet which can give us pid and/or
2750 * tid.
2751 * Assume pid=tid=1 in such cases.
2752 */
Tamas Berghammer1492cb82017-09-18 10:24:48 +00002753 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
2754 thread_ids.size() == 0 && IsConnected()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002755 thread_ids.push_back(1);
2756 }
2757 } else {
David Blaikiea322f362017-01-06 00:38:06 +00002758#if !defined(LLDB_CONFIGURATION_DEBUG)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002759 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2760 GDBR_LOG_PACKETS));
2761 if (log)
2762 log->Printf("error: failed to get packet sequence mutex, not sending "
2763 "packet 'qfThreadInfo'");
2764#endif
2765 sequence_mutex_unavailable = true;
2766 }
2767 return thread_ids.size();
2768}
2769
2770lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
2771 StringExtractorGDBRemote response;
2772 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
2773 PacketResult::Success ||
2774 !response.IsNormalResponse())
2775 return LLDB_INVALID_ADDRESS;
2776 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2777}
2778
Zachary Turner97206d52017-05-12 04:51:55 +00002779lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002780 const char *command, // Shouldn't be NULL
2781 const FileSpec &
2782 working_dir, // Pass empty FileSpec to use the current working directory
2783 int *status_ptr, // Pass NULL if you don't want the process exit status
2784 int *signo_ptr, // Pass NULL if you don't want the signal that caused the
2785 // process to exit
2786 std::string
2787 *command_output, // Pass NULL if you don't want the command output
Pavel Labath19dd1a02018-05-10 10:46:03 +00002788 const Timeout<std::micro> &timeout) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002789 lldb_private::StreamString stream;
2790 stream.PutCString("qPlatform_shell:");
2791 stream.PutBytesAsRawHex8(command, strlen(command));
2792 stream.PutChar(',');
Pavel Labath19dd1a02018-05-10 10:46:03 +00002793 uint32_t timeout_sec = UINT32_MAX;
2794 if (timeout) {
2795 // TODO: Use chrono version of std::ceil once c++17 is available.
2796 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2797 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002798 stream.PutHex32(timeout_sec);
2799 if (working_dir) {
2800 std::string path{working_dir.GetPath(false)};
2801 stream.PutChar(',');
2802 stream.PutCStringAsRawHex8(path.c_str());
2803 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002804 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002805 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002806 PacketResult::Success) {
2807 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002808 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002809 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002810 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002811 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2812 if (exitcode == UINT32_MAX)
Zachary Turner97206d52017-05-12 04:51:55 +00002813 return Status("unable to run remote process");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002814 else if (status_ptr)
2815 *status_ptr = exitcode;
2816 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002817 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002818 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2819 if (signo_ptr)
2820 *signo_ptr = signo;
2821 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002822 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002823 std::string output;
2824 response.GetEscapedBinaryData(output);
2825 if (command_output)
2826 command_output->assign(output);
Zachary Turner97206d52017-05-12 04:51:55 +00002827 return Status();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002828 }
Zachary Turner97206d52017-05-12 04:51:55 +00002829 return Status("unable to send packet");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002830}
2831
Zachary Turner97206d52017-05-12 04:51:55 +00002832Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
2833 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002834 std::string path{file_spec.GetPath(false)};
2835 lldb_private::StreamString stream;
2836 stream.PutCString("qPlatform_mkdir:");
2837 stream.PutHex32(file_permissions);
2838 stream.PutChar(',');
2839 stream.PutCStringAsRawHex8(path.c_str());
Zachary Turnerc1564272016-11-16 21:15:24 +00002840 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002841 StringExtractorGDBRemote response;
2842
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002843 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002844 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002845 return Status("failed to send '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002846
2847 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002848 return Status("invalid response to '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002849
Zachary Turner97206d52017-05-12 04:51:55 +00002850 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002851}
2852
Zachary Turner97206d52017-05-12 04:51:55 +00002853Status
2854GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
2855 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002856 std::string path{file_spec.GetPath(false)};
2857 lldb_private::StreamString stream;
2858 stream.PutCString("qPlatform_chmod:");
2859 stream.PutHex32(file_permissions);
2860 stream.PutChar(',');
2861 stream.PutCStringAsRawHex8(path.c_str());
Zachary Turnerc1564272016-11-16 21:15:24 +00002862 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002863 StringExtractorGDBRemote response;
2864
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002865 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002866 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002867 return Status("failed to send '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002868
2869 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002870 return Status("invalid response to '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002871
Zachary Turner97206d52017-05-12 04:51:55 +00002872 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002873}
2874
2875static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
Zachary Turner97206d52017-05-12 04:51:55 +00002876 uint64_t fail_result, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002877 response.SetFilePos(0);
2878 if (response.GetChar() != 'F')
2879 return fail_result;
2880 int32_t result = response.GetS32(-2);
2881 if (result == -2)
2882 return fail_result;
2883 if (response.GetChar() == ',') {
2884 int result_errno = response.GetS32(-2);
2885 if (result_errno != -2)
2886 error.SetError(result_errno, eErrorTypePOSIX);
2887 else
2888 error.SetError(-1, eErrorTypeGeneric);
2889 } else
2890 error.Clear();
2891 return result;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002892}
2893lldb::user_id_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00002894GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
2895 uint32_t flags, mode_t mode,
Zachary Turner97206d52017-05-12 04:51:55 +00002896 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002897 std::string path(file_spec.GetPath(false));
2898 lldb_private::StreamString stream;
2899 stream.PutCString("vFile:open:");
2900 if (path.empty())
Daniel Maleae0f8f572013-08-26 23:57:52 +00002901 return UINT64_MAX;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002902 stream.PutCStringAsRawHex8(path.c_str());
2903 stream.PutChar(',');
2904 stream.PutHex32(flags);
2905 stream.PutChar(',');
2906 stream.PutHex32(mode);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002907 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002908 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002909 PacketResult::Success) {
2910 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
2911 }
2912 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002913}
2914
Zachary Turner97206d52017-05-12 04:51:55 +00002915bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
2916 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002917 lldb_private::StreamString stream;
2918 stream.Printf("vFile:close:%i", (int)fd);
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, -1, error) == 0;
2923 }
2924 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002925}
2926
2927// Extension of host I/O packets to get the file size.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002928lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
2929 const lldb_private::FileSpec &file_spec) {
2930 std::string path(file_spec.GetPath(false));
2931 lldb_private::StreamString stream;
2932 stream.PutCString("vFile:size:");
2933 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002934 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002935 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002936 PacketResult::Success) {
2937 if (response.GetChar() != 'F')
2938 return UINT64_MAX;
2939 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2940 return retcode;
2941 }
2942 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002943}
2944
Zachary Turner97206d52017-05-12 04:51:55 +00002945Status
2946GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
2947 uint32_t &file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002948 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00002949 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002950 lldb_private::StreamString stream;
2951 stream.PutCString("vFile:mode:");
2952 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002953 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002954 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002955 PacketResult::Success) {
2956 if (response.GetChar() != 'F') {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002957 error.SetErrorStringWithFormat("invalid response to '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00002958 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002959 } else {
2960 const uint32_t mode = response.GetS32(-1);
2961 if (static_cast<int32_t>(mode) == -1) {
2962 if (response.GetChar() == ',') {
2963 int response_errno = response.GetS32(-1);
2964 if (response_errno > 0)
2965 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2966 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00002967 error.SetErrorToGenericError();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002968 } else
2969 error.SetErrorToGenericError();
2970 } else {
2971 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
2972 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002973 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002974 } else {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002975 error.SetErrorStringWithFormat("failed to send '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00002976 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002977 }
2978 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002979}
2980
Kate Stoneb9c1b512016-09-06 20:57:50 +00002981uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
2982 uint64_t offset, void *dst,
2983 uint64_t dst_len,
Zachary Turner97206d52017-05-12 04:51:55 +00002984 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002985 lldb_private::StreamString stream;
2986 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
2987 offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002988 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002989 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002990 PacketResult::Success) {
2991 if (response.GetChar() != 'F')
2992 return 0;
2993 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
2994 if (retcode == UINT32_MAX)
2995 return retcode;
2996 const char next = (response.Peek() ? *response.Peek() : 0);
2997 if (next == ',')
2998 return 0;
2999 if (next == ';') {
3000 response.GetChar(); // skip the semicolon
3001 std::string buffer;
3002 if (response.GetEscapedBinaryData(buffer)) {
3003 const uint64_t data_to_write =
3004 std::min<uint64_t>(dst_len, buffer.size());
3005 if (data_to_write > 0)
3006 memcpy(dst, &buffer[0], data_to_write);
3007 return data_to_write;
3008 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003009 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003010 }
3011 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003012}
3013
Kate Stoneb9c1b512016-09-06 20:57:50 +00003014uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
3015 uint64_t offset,
3016 const void *src,
3017 uint64_t src_len,
Zachary Turner97206d52017-05-12 04:51:55 +00003018 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003019 lldb_private::StreamGDBRemote stream;
3020 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3021 stream.PutEscapedBytes(src, src_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003022 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003023 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003024 PacketResult::Success) {
3025 if (response.GetChar() != 'F') {
3026 error.SetErrorStringWithFormat("write file failed");
3027 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003028 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003029 uint64_t bytes_written = response.GetU64(UINT64_MAX);
3030 if (bytes_written == UINT64_MAX) {
3031 error.SetErrorToGenericError();
3032 if (response.GetChar() == ',') {
3033 int response_errno = response.GetS32(-1);
3034 if (response_errno > 0)
3035 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3036 }
3037 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003038 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003039 return bytes_written;
3040 } else {
3041 error.SetErrorString("failed to send vFile:pwrite packet");
3042 }
3043 return 0;
3044}
3045
Zachary Turner97206d52017-05-12 04:51:55 +00003046Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
3047 const FileSpec &dst) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003048 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00003049 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003050 lldb_private::StreamGDBRemote stream;
3051 stream.PutCString("vFile:symlink:");
3052 // the unix symlink() command reverses its parameters where the dst if first,
3053 // so we follow suit here
3054 stream.PutCStringAsRawHex8(dst_path.c_str());
3055 stream.PutChar(',');
3056 stream.PutCStringAsRawHex8(src_path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003057 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003058 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003059 PacketResult::Success) {
3060 if (response.GetChar() == 'F') {
3061 uint32_t result = response.GetU32(UINT32_MAX);
3062 if (result != 0) {
3063 error.SetErrorToGenericError();
3064 if (response.GetChar() == ',') {
3065 int response_errno = response.GetS32(-1);
3066 if (response_errno > 0)
3067 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3068 }
3069 }
3070 } else {
3071 // Should have returned with 'F<result>[,<errno>]'
3072 error.SetErrorStringWithFormat("symlink failed");
3073 }
3074 } else {
3075 error.SetErrorString("failed to send vFile:symlink packet");
3076 }
3077 return error;
3078}
3079
Zachary Turner97206d52017-05-12 04:51:55 +00003080Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003081 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00003082 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003083 lldb_private::StreamGDBRemote stream;
3084 stream.PutCString("vFile:unlink:");
3085 // the unix symlink() command reverses its parameters where the dst if first,
3086 // so we follow suit here
3087 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003088 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003089 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003090 PacketResult::Success) {
3091 if (response.GetChar() == 'F') {
3092 uint32_t result = response.GetU32(UINT32_MAX);
3093 if (result != 0) {
3094 error.SetErrorToGenericError();
3095 if (response.GetChar() == ',') {
3096 int response_errno = response.GetS32(-1);
3097 if (response_errno > 0)
3098 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3099 }
3100 }
3101 } else {
3102 // Should have returned with 'F<result>[,<errno>]'
3103 error.SetErrorStringWithFormat("unlink failed");
3104 }
3105 } else {
3106 error.SetErrorString("failed to send vFile:unlink packet");
3107 }
3108 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +00003109}
3110
Daniel Maleae0f8f572013-08-26 23:57:52 +00003111// Extension of host I/O packets to get whether a file exists.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003112bool GDBRemoteCommunicationClient::GetFileExists(
3113 const lldb_private::FileSpec &file_spec) {
3114 std::string path(file_spec.GetPath(false));
3115 lldb_private::StreamString stream;
3116 stream.PutCString("vFile:exists:");
3117 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003118 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003119 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003120 PacketResult::Success) {
3121 if (response.GetChar() != 'F')
3122 return false;
3123 if (response.GetChar() != ',')
3124 return false;
3125 bool retcode = (response.GetChar() != '0');
3126 return retcode;
3127 }
3128 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003129}
3130
Kate Stoneb9c1b512016-09-06 20:57:50 +00003131bool GDBRemoteCommunicationClient::CalculateMD5(
3132 const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
3133 std::string path(file_spec.GetPath(false));
3134 lldb_private::StreamString stream;
3135 stream.PutCString("vFile:MD5:");
3136 stream.PutCStringAsRawHex8(path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003137 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003138 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003139 PacketResult::Success) {
3140 if (response.GetChar() != 'F')
3141 return false;
3142 if (response.GetChar() != ',')
3143 return false;
3144 if (response.Peek() && *response.Peek() == 'x')
3145 return false;
3146 low = response.GetHexMaxU64(false, UINT64_MAX);
3147 high = response.GetHexMaxU64(false, UINT64_MAX);
Pavel Labath4b6f9592016-08-18 08:30:03 +00003148 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003149 }
3150 return false;
Greg Claytonf74cf862013-11-13 23:28:31 +00003151}
3152
Kate Stoneb9c1b512016-09-06 20:57:50 +00003153bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
3154 // Some targets have issues with g/G packets and we need to avoid using them
3155 if (m_avoid_g_packets == eLazyBoolCalculate) {
3156 if (process) {
3157 m_avoid_g_packets = eLazyBoolNo;
3158 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3159 if (arch.IsValid() &&
3160 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3161 arch.GetTriple().getOS() == llvm::Triple::IOS &&
3162 arch.GetTriple().getArch() == llvm::Triple::aarch64) {
3163 m_avoid_g_packets = eLazyBoolYes;
3164 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3165 if (gdb_server_version != 0) {
3166 const char *gdb_server_name = GetGDBServerProgramName();
3167 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3168 if (gdb_server_version >= 310)
3169 m_avoid_g_packets = eLazyBoolNo;
3170 }
3171 }
3172 }
3173 }
3174 }
3175 return m_avoid_g_packets == eLazyBoolYes;
3176}
Saleem Abdulrasool2d6a9ec2016-07-28 17:32:20 +00003177
Kate Stoneb9c1b512016-09-06 20:57:50 +00003178DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
3179 uint32_t reg) {
3180 StreamString payload;
3181 payload.Printf("p%x", reg);
3182 StringExtractorGDBRemote response;
3183 if (SendThreadSpecificPacketAndWaitForResponse(
3184 tid, std::move(payload), response, false) != PacketResult::Success ||
3185 !response.IsNormalResponse())
3186 return nullptr;
Pavel Labath4b6f9592016-08-18 08:30:03 +00003187
Kate Stoneb9c1b512016-09-06 20:57:50 +00003188 DataBufferSP buffer_sp(
3189 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3190 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3191 return buffer_sp;
3192}
Pavel Labath4b6f9592016-08-18 08:30:03 +00003193
Kate Stoneb9c1b512016-09-06 20:57:50 +00003194DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
3195 StreamString payload;
3196 payload.PutChar('g');
3197 StringExtractorGDBRemote response;
3198 if (SendThreadSpecificPacketAndWaitForResponse(
3199 tid, std::move(payload), response, false) != PacketResult::Success ||
3200 !response.IsNormalResponse())
3201 return nullptr;
3202
3203 DataBufferSP buffer_sp(
3204 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3205 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3206 return buffer_sp;
3207}
3208
3209bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
3210 uint32_t reg_num,
3211 llvm::ArrayRef<uint8_t> data) {
3212 StreamString payload;
3213 payload.Printf("P%x=", reg_num);
3214 payload.PutBytesAsRawHex8(data.data(), data.size(),
3215 endian::InlHostByteOrder(),
3216 endian::InlHostByteOrder());
3217 StringExtractorGDBRemote response;
3218 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3219 response, false) ==
3220 PacketResult::Success &&
3221 response.IsOKResponse();
3222}
3223
3224bool GDBRemoteCommunicationClient::WriteAllRegisters(
3225 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3226 StreamString payload;
3227 payload.PutChar('G');
3228 payload.PutBytesAsRawHex8(data.data(), data.size(),
3229 endian::InlHostByteOrder(),
3230 endian::InlHostByteOrder());
3231 StringExtractorGDBRemote response;
3232 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3233 response, false) ==
3234 PacketResult::Success &&
3235 response.IsOKResponse();
3236}
3237
3238bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
3239 uint32_t &save_id) {
3240 save_id = 0; // Set to invalid save ID
3241 if (m_supports_QSaveRegisterState == eLazyBoolNo)
Greg Claytonf74cf862013-11-13 23:28:31 +00003242 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003243
3244 m_supports_QSaveRegisterState = eLazyBoolYes;
3245 StreamString payload;
3246 payload.PutCString("QSaveRegisterState");
3247 StringExtractorGDBRemote response;
3248 if (SendThreadSpecificPacketAndWaitForResponse(
3249 tid, std::move(payload), response, false) != PacketResult::Success)
3250 return false;
3251
3252 if (response.IsUnsupportedResponse())
3253 m_supports_QSaveRegisterState = eLazyBoolNo;
3254
3255 const uint32_t response_save_id = response.GetU32(0);
3256 if (response_save_id == 0)
3257 return false;
3258
3259 save_id = response_save_id;
3260 return true;
Greg Claytonf74cf862013-11-13 23:28:31 +00003261}
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003262
Kate Stoneb9c1b512016-09-06 20:57:50 +00003263bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
3264 uint32_t save_id) {
3265 // We use the "m_supports_QSaveRegisterState" variable here because the
Adrian Prantl05097242018-04-30 16:49:04 +00003266 // QSaveRegisterState and QRestoreRegisterState packets must both be
3267 // supported in order to be useful
Kate Stoneb9c1b512016-09-06 20:57:50 +00003268 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3269 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003270
Kate Stoneb9c1b512016-09-06 20:57:50 +00003271 StreamString payload;
3272 payload.Printf("QRestoreRegisterState:%u", save_id);
3273 StringExtractorGDBRemote response;
3274 if (SendThreadSpecificPacketAndWaitForResponse(
3275 tid, std::move(payload), response, false) != PacketResult::Success)
3276 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003277
Kate Stoneb9c1b512016-09-06 20:57:50 +00003278 if (response.IsOKResponse())
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003279 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003280
3281 if (response.IsUnsupportedResponse())
3282 m_supports_QSaveRegisterState = eLazyBoolNo;
3283 return false;
3284}
3285
3286bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
3287 if (!GetSyncThreadStateSupported())
3288 return false;
3289
3290 StreamString packet;
3291 StringExtractorGDBRemote response;
3292 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3293 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
3294 GDBRemoteCommunication::PacketResult::Success &&
3295 response.IsOKResponse();
3296}
3297
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003298lldb::user_id_t
3299GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
3300 Status &error) {
3301 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3302 lldb::user_id_t ret_uid = LLDB_INVALID_UID;
3303
3304 StreamGDBRemote escaped_packet;
3305 escaped_packet.PutCString("jTraceStart:");
3306
3307 StructuredData::Dictionary json_packet;
3308 json_packet.AddIntegerItem("type", options.getType());
3309 json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
3310 json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
3311
3312 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3313 json_packet.AddIntegerItem("threadid", options.getThreadID());
3314
3315 StructuredData::DictionarySP custom_params = options.getTraceParams();
3316 if (custom_params)
3317 json_packet.AddItem("params", custom_params);
3318
3319 StreamString json_string;
3320 json_packet.Dump(json_string, false);
3321 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3322
3323 StringExtractorGDBRemote response;
3324 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3325 true) ==
3326 GDBRemoteCommunication::PacketResult::Success) {
3327 if (!response.IsNormalResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003328 error = response.GetStatus();
3329 LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003330 } else {
3331 ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
3332 }
3333 } else {
3334 LLDB_LOG(log, "failed to send packet");
3335 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3336 escaped_packet.GetData());
3337 }
3338 return ret_uid;
3339}
3340
3341Status
3342GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
3343 lldb::tid_t thread_id) {
3344 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3345 StringExtractorGDBRemote response;
3346 Status error;
3347
3348 StructuredData::Dictionary json_packet;
3349 StreamGDBRemote escaped_packet;
3350 StreamString json_string;
3351 escaped_packet.PutCString("jTraceStop:");
3352
3353 json_packet.AddIntegerItem("traceid", uid);
3354
3355 if (thread_id != LLDB_INVALID_THREAD_ID)
3356 json_packet.AddIntegerItem("threadid", thread_id);
3357
3358 json_packet.Dump(json_string, false);
3359
3360 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3361
3362 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3363 true) ==
3364 GDBRemoteCommunication::PacketResult::Success) {
3365 if (!response.IsOKResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003366 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003367 LLDB_LOG(log, "stop tracing failed");
3368 }
3369 } else {
3370 LLDB_LOG(log, "failed to send packet");
3371 error.SetErrorStringWithFormat(
3372 "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
3373 response.GetError());
3374 }
3375 return error;
3376}
3377
3378Status GDBRemoteCommunicationClient::SendGetDataPacket(
3379 lldb::user_id_t uid, lldb::tid_t thread_id,
3380 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003381
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003382 StreamGDBRemote escaped_packet;
3383 escaped_packet.PutCString("jTraceBufferRead:");
3384 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3385}
3386
3387Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
3388 lldb::user_id_t uid, lldb::tid_t thread_id,
3389 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003390
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003391 StreamGDBRemote escaped_packet;
3392 escaped_packet.PutCString("jTraceMetaRead:");
3393 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3394}
3395
3396Status
3397GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
3398 TraceOptions &options) {
3399 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3400 StringExtractorGDBRemote response;
3401 Status error;
3402
3403 StreamString json_string;
3404 StreamGDBRemote escaped_packet;
3405 escaped_packet.PutCString("jTraceConfigRead:");
3406
3407 StructuredData::Dictionary json_packet;
3408 json_packet.AddIntegerItem("traceid", uid);
3409
3410 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3411 json_packet.AddIntegerItem("threadid", options.getThreadID());
3412
3413 json_packet.Dump(json_string, false);
3414 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3415
3416 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3417 true) ==
3418 GDBRemoteCommunication::PacketResult::Success) {
3419 if (response.IsNormalResponse()) {
3420 uint64_t type = std::numeric_limits<uint64_t>::max();
3421 uint64_t buffersize = std::numeric_limits<uint64_t>::max();
3422 uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
3423
3424 auto json_object = StructuredData::ParseJSON(response.Peek());
3425
3426 if (!json_object ||
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003427 json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003428 error.SetErrorString("Invalid Configuration obtained");
3429 return error;
3430 }
3431
3432 auto json_dict = json_object->GetAsDictionary();
3433
3434 json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
3435 metabuffersize);
3436 options.setMetaDataBufferSize(metabuffersize);
3437
3438 json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
3439 options.setTraceBufferSize(buffersize);
3440
3441 json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
3442 options.setType(static_cast<lldb::TraceType>(type));
3443
3444 StructuredData::ObjectSP custom_params_sp =
3445 json_dict->GetValueForKey("params");
3446 if (custom_params_sp) {
3447 if (custom_params_sp->GetType() !=
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003448 lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003449 error.SetErrorString("Invalid Configuration obtained");
3450 return error;
3451 } else
3452 options.setTraceParams(
3453 static_pointer_cast<StructuredData::Dictionary>(
3454 custom_params_sp));
3455 }
3456 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003457 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003458 }
3459 } else {
3460 LLDB_LOG(log, "failed to send packet");
3461 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3462 escaped_packet.GetData());
3463 }
3464 return error;
3465}
3466
3467Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
3468 StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
3469 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
3470 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3471 Status error;
3472
3473 StructuredData::Dictionary json_packet;
3474
3475 json_packet.AddIntegerItem("traceid", uid);
3476 json_packet.AddIntegerItem("offset", offset);
3477 json_packet.AddIntegerItem("buffersize", buffer.size());
3478
3479 if (thread_id != LLDB_INVALID_THREAD_ID)
3480 json_packet.AddIntegerItem("threadid", thread_id);
3481
3482 StreamString json_string;
3483 json_packet.Dump(json_string, false);
3484
3485 packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3486 StringExtractorGDBRemote response;
3487 if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
3488 GDBRemoteCommunication::PacketResult::Success) {
3489 if (response.IsNormalResponse()) {
3490 size_t filled_size = response.GetHexBytesAvail(buffer);
3491 buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
3492 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003493 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003494 buffer = buffer.slice(buffer.size());
3495 }
3496 } else {
3497 LLDB_LOG(log, "failed to send packet");
3498 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3499 packet.GetData());
3500 buffer = buffer.slice(buffer.size());
3501 }
3502 return error;
3503}
3504
Kate Stoneb9c1b512016-09-06 20:57:50 +00003505bool GDBRemoteCommunicationClient::GetModuleInfo(
3506 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3507 ModuleSpec &module_spec) {
3508 if (!m_supports_qModuleInfo)
3509 return false;
3510
3511 std::string module_path = module_file_spec.GetPath(false);
3512 if (module_path.empty())
3513 return false;
3514
3515 StreamString packet;
3516 packet.PutCString("qModuleInfo:");
3517 packet.PutCStringAsRawHex8(module_path.c_str());
3518 packet.PutCString(";");
3519 const auto &triple = arch_spec.GetTriple().getTriple();
3520 packet.PutCStringAsRawHex8(triple.c_str());
3521
3522 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003523 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
3524 PacketResult::Success)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003525 return false;
3526
3527 if (response.IsErrorResponse())
3528 return false;
3529
3530 if (response.IsUnsupportedResponse()) {
3531 m_supports_qModuleInfo = false;
3532 return false;
3533 }
3534
3535 llvm::StringRef name;
3536 llvm::StringRef value;
3537
3538 module_spec.Clear();
3539 module_spec.GetFileSpec() = module_file_spec;
3540
3541 while (response.GetNameColonValue(name, value)) {
3542 if (name == "uuid" || name == "md5") {
3543 StringExtractor extractor(value);
3544 std::string uuid;
3545 extractor.GetHexByteString(uuid);
Pavel Labatha174bcb2018-06-21 15:24:39 +00003546 module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003547 } else if (name == "triple") {
3548 StringExtractor extractor(value);
3549 std::string triple;
3550 extractor.GetHexByteString(triple);
3551 module_spec.GetArchitecture().SetTriple(triple.c_str());
3552 } else if (name == "file_offset") {
3553 uint64_t ival = 0;
3554 if (!value.getAsInteger(16, ival))
3555 module_spec.SetObjectOffset(ival);
3556 } else if (name == "file_size") {
3557 uint64_t ival = 0;
3558 if (!value.getAsInteger(16, ival))
3559 module_spec.SetObjectSize(ival);
3560 } else if (name == "file_path") {
3561 StringExtractor extractor(value);
3562 std::string path;
3563 extractor.GetHexByteString(path);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00003564 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003565 }
3566 }
3567
3568 return true;
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003569}
Colin Rileyc3c95b22015-04-16 15:51:33 +00003570
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003571static llvm::Optional<ModuleSpec>
3572ParseModuleSpec(StructuredData::Dictionary *dict) {
3573 ModuleSpec result;
3574 if (!dict)
3575 return llvm::None;
3576
Zachary Turner28333212017-05-12 05:49:54 +00003577 llvm::StringRef string;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003578 uint64_t integer;
3579
3580 if (!dict->GetValueForKeyAsString("uuid", string))
3581 return llvm::None;
Pavel Labath8c92c892017-12-18 14:31:44 +00003582 if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
3583 string.size())
3584 return llvm::None;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003585
3586 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3587 return llvm::None;
3588 result.SetObjectOffset(integer);
3589
3590 if (!dict->GetValueForKeyAsInteger("file_size", integer))
3591 return llvm::None;
3592 result.SetObjectSize(integer);
3593
3594 if (!dict->GetValueForKeyAsString("triple", string))
3595 return llvm::None;
Zachary Turner28333212017-05-12 05:49:54 +00003596 result.GetArchitecture().SetTriple(string);
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003597
3598 if (!dict->GetValueForKeyAsString("file_path", string))
3599 return llvm::None;
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00003600 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003601
3602 return result;
3603}
3604
3605llvm::Optional<std::vector<ModuleSpec>>
3606GDBRemoteCommunicationClient::GetModulesInfo(
3607 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
3608 if (!m_supports_jModulesInfo)
3609 return llvm::None;
3610
3611 JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
3612 for (const FileSpec &module_file_spec : module_file_specs) {
3613 JSONObject::SP module_sp = std::make_shared<JSONObject>();
3614 module_array_sp->AppendObject(module_sp);
3615 module_sp->SetObject(
Pavel Labath763f1c42017-01-05 13:18:46 +00003616 "file", std::make_shared<JSONString>(module_file_spec.GetPath(false)));
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003617 module_sp->SetObject("triple",
3618 std::make_shared<JSONString>(triple.getTriple()));
3619 }
3620 StreamString unescaped_payload;
3621 unescaped_payload.PutCString("jModulesInfo:");
3622 module_array_sp->Write(unescaped_payload);
3623 StreamGDBRemote payload;
Zachary Turnerc1564272016-11-16 21:15:24 +00003624 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003625 unescaped_payload.GetSize());
3626
Greg Clayton70a9f512017-04-14 17:10:04 +00003627 // Increase the timeout for jModulesInfo since this packet can take longer.
3628 ScopedTimeout timeout(*this, std::chrono::seconds(10));
3629
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003630 StringExtractorGDBRemote response;
3631 if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
3632 PacketResult::Success ||
3633 response.IsErrorResponse())
3634 return llvm::None;
3635
3636 if (response.IsUnsupportedResponse()) {
3637 m_supports_jModulesInfo = false;
3638 return llvm::None;
3639 }
3640
3641 StructuredData::ObjectSP response_object_sp =
3642 StructuredData::ParseJSON(response.GetStringRef());
3643 if (!response_object_sp)
3644 return llvm::None;
3645
3646 StructuredData::Array *response_array = response_object_sp->GetAsArray();
3647 if (!response_array)
3648 return llvm::None;
3649
3650 std::vector<ModuleSpec> result;
3651 for (size_t i = 0; i < response_array->GetSize(); ++i) {
3652 if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
3653 response_array->GetItemAtIndex(i)->GetAsDictionary()))
3654 result.push_back(*module_spec);
3655 }
3656
3657 return result;
3658}
3659
Colin Rileyc3c95b22015-04-16 15:51:33 +00003660// query the target remote for extended information using the qXfer packet
3661//
Adrian Prantl05097242018-04-30 16:49:04 +00003662// example: object='features', annex='target.xml', out=<xml output> return:
3663// 'true' on success
Colin Rileyc3c95b22015-04-16 15:51:33 +00003664// 'false' on failure (err set)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003665bool GDBRemoteCommunicationClient::ReadExtFeature(
3666 const lldb_private::ConstString object,
3667 const lldb_private::ConstString annex, std::string &out,
Zachary Turner97206d52017-05-12 04:51:55 +00003668 lldb_private::Status &err) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003669
Kate Stoneb9c1b512016-09-06 20:57:50 +00003670 std::stringstream output;
3671 StringExtractorGDBRemote chunk;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003672
Kate Stoneb9c1b512016-09-06 20:57:50 +00003673 uint64_t size = GetRemoteMaxPacketSize();
3674 if (size == 0)
3675 size = 0x1000;
3676 size = size - 1; // Leave space for the 'm' or 'l' character in the response
3677 int offset = 0;
3678 bool active = true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003679
Kate Stoneb9c1b512016-09-06 20:57:50 +00003680 // loop until all data has been read
3681 while (active) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003682
Kate Stoneb9c1b512016-09-06 20:57:50 +00003683 // send query extended feature packet
3684 std::stringstream packet;
3685 packet << "qXfer:" << object.AsCString("")
3686 << ":read:" << annex.AsCString("") << ":" << std::hex << offset
3687 << "," << std::hex << size;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003688
Kate Stoneb9c1b512016-09-06 20:57:50 +00003689 GDBRemoteCommunication::PacketResult res =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00003690 SendPacketAndWaitForResponse(packet.str(), chunk, false);
Colin Rileyc3c95b22015-04-16 15:51:33 +00003691
Kate Stoneb9c1b512016-09-06 20:57:50 +00003692 if (res != GDBRemoteCommunication::PacketResult::Success) {
3693 err.SetErrorString("Error sending $qXfer packet");
3694 return false;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003695 }
3696
Kate Stoneb9c1b512016-09-06 20:57:50 +00003697 const std::string &str = chunk.GetStringRef();
3698 if (str.length() == 0) {
3699 // should have some data in chunk
3700 err.SetErrorString("Empty response from $qXfer packet");
3701 return false;
3702 }
3703
3704 // check packet code
3705 switch (str[0]) {
3706 // last chunk
3707 case ('l'):
3708 active = false;
3709 LLVM_FALLTHROUGH;
3710
3711 // more chunks
3712 case ('m'):
3713 if (str.length() > 1)
3714 output << &str[1];
3715 offset += size;
3716 break;
3717
3718 // unknown chunk
3719 default:
3720 err.SetErrorString("Invalid continuation code from $qXfer packet");
3721 return false;
3722 }
3723 }
3724
3725 out = output.str();
3726 err.Success();
3727 return true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003728}
Greg Clayton0b90be12015-06-23 21:27:50 +00003729
3730// Notify the target that gdb is prepared to serve symbol lookup requests.
3731// packet: "qSymbol::"
3732// reply:
3733// OK The target does not need to look up any (more) symbols.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003734// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
3735// encoded).
3736// LLDB may provide the value by sending another qSymbol
3737// packet
Greg Clayton0b90be12015-06-23 21:27:50 +00003738// in the form of"qSymbol:<sym_value>:<sym_name>".
Jason Molenda50018d32016-01-13 04:08:10 +00003739//
3740// Three examples:
3741//
3742// lldb sends: qSymbol::
3743// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003744// Remote gdb stub does not need to know the addresses of any symbols, lldb
3745// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003746// need to ask again in this session.
3747//
3748// lldb sends: qSymbol::
3749// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3750// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
3751// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003752// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
3753// not know
3754// the address at this time. lldb needs to send qSymbol:: again when it has
3755// more
Jason Molenda50018d32016-01-13 04:08:10 +00003756// solibs loaded.
3757//
3758// lldb sends: qSymbol::
3759// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3760// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
3761// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003762// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
3763// that it
3764// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
3765// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003766// need any more symbols. lldb does not need to ask again in this session.
Greg Clayton0b90be12015-06-23 21:27:50 +00003767
Kate Stoneb9c1b512016-09-06 20:57:50 +00003768void GDBRemoteCommunicationClient::ServeSymbolLookups(
3769 lldb_private::Process *process) {
Adrian Prantl05097242018-04-30 16:49:04 +00003770 // Set to true once we've resolved a symbol to an address for the remote
3771 // stub. If we get an 'OK' response after this, the remote stub doesn't need
3772 // any more symbols and we can stop asking.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003773 bool symbol_response_provided = false;
Jason Molenda50018d32016-01-13 04:08:10 +00003774
Kate Stoneb9c1b512016-09-06 20:57:50 +00003775 // Is this the initial qSymbol:: packet?
3776 bool first_qsymbol_query = true;
Jason Molenda50018d32016-01-13 04:08:10 +00003777
Kate Stoneb9c1b512016-09-06 20:57:50 +00003778 if (m_supports_qSymbol && m_qSymbol_requests_done == false) {
3779 Lock lock(*this, false);
3780 if (lock) {
3781 StreamString packet;
3782 packet.PutCString("qSymbol::");
3783 StringExtractorGDBRemote response;
3784 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
3785 PacketResult::Success) {
3786 if (response.IsOKResponse()) {
3787 if (symbol_response_provided || first_qsymbol_query) {
3788 m_qSymbol_requests_done = true;
3789 }
3790
3791 // We are done serving symbols requests
3792 return;
3793 }
3794 first_qsymbol_query = false;
3795
3796 if (response.IsUnsupportedResponse()) {
Adrian Prantl05097242018-04-30 16:49:04 +00003797 // qSymbol is not supported by the current GDB server we are
3798 // connected to
Kate Stoneb9c1b512016-09-06 20:57:50 +00003799 m_supports_qSymbol = false;
3800 return;
3801 } else {
3802 llvm::StringRef response_str(response.GetStringRef());
3803 if (response_str.startswith("qSymbol:")) {
3804 response.SetFilePos(strlen("qSymbol:"));
3805 std::string symbol_name;
3806 if (response.GetHexByteString(symbol_name)) {
3807 if (symbol_name.empty())
3808 return;
3809
3810 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
3811 lldb_private::SymbolContextList sc_list;
3812 if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(
3813 ConstString(symbol_name), eSymbolTypeAny, sc_list)) {
3814 const size_t num_scs = sc_list.GetSize();
3815 for (size_t sc_idx = 0;
3816 sc_idx < num_scs &&
3817 symbol_load_addr == LLDB_INVALID_ADDRESS;
3818 ++sc_idx) {
3819 SymbolContext sc;
3820 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
3821 if (sc.symbol) {
3822 switch (sc.symbol->GetType()) {
3823 case eSymbolTypeInvalid:
3824 case eSymbolTypeAbsolute:
3825 case eSymbolTypeUndefined:
3826 case eSymbolTypeSourceFile:
3827 case eSymbolTypeHeaderFile:
3828 case eSymbolTypeObjectFile:
3829 case eSymbolTypeCommonBlock:
3830 case eSymbolTypeBlock:
3831 case eSymbolTypeLocal:
3832 case eSymbolTypeParam:
3833 case eSymbolTypeVariable:
3834 case eSymbolTypeVariableType:
3835 case eSymbolTypeLineEntry:
3836 case eSymbolTypeLineHeader:
3837 case eSymbolTypeScopeBegin:
3838 case eSymbolTypeScopeEnd:
3839 case eSymbolTypeAdditional:
3840 case eSymbolTypeCompiler:
3841 case eSymbolTypeInstrumentation:
3842 case eSymbolTypeTrampoline:
3843 break;
3844
3845 case eSymbolTypeCode:
3846 case eSymbolTypeResolver:
3847 case eSymbolTypeData:
3848 case eSymbolTypeRuntime:
3849 case eSymbolTypeException:
3850 case eSymbolTypeObjCClass:
3851 case eSymbolTypeObjCMetaClass:
3852 case eSymbolTypeObjCIVar:
3853 case eSymbolTypeReExported:
3854 symbol_load_addr =
3855 sc.symbol->GetLoadAddress(&process->GetTarget());
3856 break;
3857 }
Jason Molenda50018d32016-01-13 04:08:10 +00003858 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003859 }
Greg Clayton42b01482015-08-11 22:07:46 +00003860 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003861 }
3862 // This is the normal path where our symbol lookup was successful
Adrian Prantl05097242018-04-30 16:49:04 +00003863 // and we want to send a packet with the new symbol value and see
3864 // if another lookup needs to be done.
Greg Clayton0b90be12015-06-23 21:27:50 +00003865
Kate Stoneb9c1b512016-09-06 20:57:50 +00003866 // Change "packet" to contain the requested symbol value and name
3867 packet.Clear();
3868 packet.PutCString("qSymbol:");
3869 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
3870 packet.Printf("%" PRIx64, symbol_load_addr);
3871 symbol_response_provided = true;
3872 } else {
3873 symbol_response_provided = false;
3874 }
3875 packet.PutCString(":");
3876 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
3877 continue; // go back to the while loop and send "packet" and wait
3878 // for another response
Greg Clayton0b90be12015-06-23 21:27:50 +00003879 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003880 }
3881 }
3882 }
3883 // If we make it here, the symbol request packet response wasn't valid or
3884 // our symbol lookup failed so we must abort
3885 return;
Greg Clayton0b90be12015-06-23 21:27:50 +00003886
Kate Stoneb9c1b512016-09-06 20:57:50 +00003887 } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
3888 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
3889 log->Printf(
3890 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
3891 __FUNCTION__);
Greg Clayton0b90be12015-06-23 21:27:50 +00003892 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003893 }
Greg Clayton0b90be12015-06-23 21:27:50 +00003894}
3895
Kate Stoneb9c1b512016-09-06 20:57:50 +00003896StructuredData::Array *
3897GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
3898 if (!m_supported_async_json_packets_is_valid) {
Adrian Prantl05097242018-04-30 16:49:04 +00003899 // Query the server for the array of supported asynchronous JSON packets.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003900 m_supported_async_json_packets_is_valid = true;
Todd Fiala75930012016-08-19 04:21:48 +00003901
Kate Stoneb9c1b512016-09-06 20:57:50 +00003902 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Todd Fiala75930012016-08-19 04:21:48 +00003903
Kate Stoneb9c1b512016-09-06 20:57:50 +00003904 // Poll it now.
Todd Fiala75930012016-08-19 04:21:48 +00003905 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003906 const bool send_async = false;
3907 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
3908 send_async) == PacketResult::Success) {
3909 m_supported_async_json_packets_sp =
3910 StructuredData::ParseJSON(response.GetStringRef());
3911 if (m_supported_async_json_packets_sp &&
3912 !m_supported_async_json_packets_sp->GetAsArray()) {
Adrian Prantl05097242018-04-30 16:49:04 +00003913 // We were returned something other than a JSON array. This is
3914 // invalid. Clear it out.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003915 if (log)
3916 log->Printf("GDBRemoteCommunicationClient::%s(): "
3917 "QSupportedAsyncJSONPackets returned invalid "
3918 "result: %s",
3919 __FUNCTION__, response.GetStringRef().c_str());
3920 m_supported_async_json_packets_sp.reset();
3921 }
3922 } else {
3923 if (log)
3924 log->Printf("GDBRemoteCommunicationClient::%s(): "
3925 "QSupportedAsyncJSONPackets unsupported",
3926 __FUNCTION__);
Todd Fiala75930012016-08-19 04:21:48 +00003927 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003928
3929 if (log && m_supported_async_json_packets_sp) {
3930 StreamString stream;
3931 m_supported_async_json_packets_sp->Dump(stream);
3932 log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
3933 "JSON packets: %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00003934 __FUNCTION__, stream.GetData());
Todd Fiala75930012016-08-19 04:21:48 +00003935 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003936 }
3937
3938 return m_supported_async_json_packets_sp
3939 ? m_supported_async_json_packets_sp->GetAsArray()
3940 : nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00003941}
3942
Zachary Turner97206d52017-05-12 04:51:55 +00003943Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003944 llvm::ArrayRef<int32_t> signals) {
3945 // Format packet:
3946 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
3947 auto range = llvm::make_range(signals.begin(), signals.end());
3948 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
3949
3950 StringExtractorGDBRemote response;
3951 auto send_status = SendPacketAndWaitForResponse(packet, response, false);
3952
3953 if (send_status != GDBRemoteCommunication::PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00003954 return Status("Sending QPassSignals packet failed");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003955
3956 if (response.IsOKResponse()) {
Zachary Turner97206d52017-05-12 04:51:55 +00003957 return Status();
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003958 } else {
Zachary Turner97206d52017-05-12 04:51:55 +00003959 return Status("Unknown error happened during sending QPassSignals packet.");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003960 }
3961}
3962
Zachary Turner97206d52017-05-12 04:51:55 +00003963Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
Kate Stoneb9c1b512016-09-06 20:57:50 +00003964 const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
Zachary Turner97206d52017-05-12 04:51:55 +00003965 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003966
3967 if (type_name.GetLength() == 0) {
3968 error.SetErrorString("invalid type_name argument");
3969 return error;
3970 }
3971
Adrian Prantl05097242018-04-30 16:49:04 +00003972 // Build command: Configure{type_name}: serialized config data.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003973 StreamGDBRemote stream;
3974 stream.PutCString("QConfigure");
3975 stream.PutCString(type_name.AsCString());
3976 stream.PutChar(':');
3977 if (config_sp) {
3978 // Gather the plain-text version of the configuration data.
3979 StreamString unescaped_stream;
3980 config_sp->Dump(unescaped_stream);
3981 unescaped_stream.Flush();
3982
3983 // Add it to the stream in escaped fashion.
Zachary Turnerc1564272016-11-16 21:15:24 +00003984 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003985 unescaped_stream.GetSize());
3986 }
3987 stream.Flush();
3988
3989 // Send the packet.
3990 const bool send_async = false;
3991 StringExtractorGDBRemote response;
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00003992 auto result =
3993 SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003994 if (result == PacketResult::Success) {
3995 // We failed if the config result comes back other than OK.
3996 if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
3997 // Okay!
3998 error.Clear();
3999 } else {
4000 error.SetErrorStringWithFormat("configuring StructuredData feature "
4001 "%s failed with error %s",
4002 type_name.AsCString(),
4003 response.GetStringRef().c_str());
4004 }
4005 } else {
4006 // Can we get more data here on the failure?
4007 error.SetErrorStringWithFormat("configuring StructuredData feature %s "
4008 "failed when sending packet: "
4009 "PacketResult=%d",
Ilia K4f730dc2016-09-12 05:25:33 +00004010 type_name.AsCString(), (int)result);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004011 }
4012 return error;
4013}
4014
4015void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
4016 GDBRemoteClientBase::OnRunPacketSent(first);
4017 m_curr_tid = LLDB_INVALID_THREAD_ID;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00004018}