blob: 89059f74814570c727205c491025c15a73894a25 [file] [log] [blame]
Greg Clayton576d8832011-03-22 04:00:09 +00001//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Greg Clayton576d8832011-03-22 04:00:09 +00006//
7//===----------------------------------------------------------------------===//
8
Greg Clayton576d8832011-03-22 04:00:09 +00009#include "GDBRemoteCommunicationClient.h"
10
Greg Claytone034a042015-05-21 20:52:06 +000011#include <math.h>
Daniel Maleab89d0492013-08-28 16:06:16 +000012#include <sys/stat.h>
13
Greg Claytone034a042015-05-21 20:52:06 +000014#include <numeric>
Kate Stoneb9c1b512016-09-06 20:57:50 +000015#include <sstream>
Han Ming Ong4b6459f2013-01-18 23:11:53 +000016
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +000017#include "lldb/Core/ModuleSpec.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000018#include "lldb/Host/HostInfo.h"
Pavel Labath16064d32018-03-20 11:56:24 +000019#include "lldb/Host/XML.h"
Greg Clayton0b90be12015-06-23 21:27:50 +000020#include "lldb/Symbol/Symbol.h"
Pavel Labath4cb69922016-07-29 15:41:52 +000021#include "lldb/Target/MemoryRegionInfo.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000022#include "lldb/Target/Target.h"
Todd Fiala75930012016-08-19 04:21:48 +000023#include "lldb/Target/UnixSignals.h"
Pavel Labath145d95c2018-04-17 18:53:35 +000024#include "lldb/Utility/Args.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000025#include "lldb/Utility/DataBufferHeap.h"
Pavel Labath2f1fbae2016-09-08 10:07:04 +000026#include "lldb/Utility/JSON.h"
Todd Fiala75930012016-08-19 04:21:48 +000027#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000028#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000029#include "lldb/Utility/State.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000030#include "lldb/Utility/StreamString.h"
Greg Clayton576d8832011-03-22 04:00:09 +000031
Greg Clayton576d8832011-03-22 04:00:09 +000032#include "ProcessGDBRemote.h"
33#include "ProcessGDBRemoteLog.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000034#include "lldb/Host/Config.h"
Pavel Labath9af71b32018-03-20 16:14:00 +000035#include "lldb/Utility/StringExtractorGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000036
Zachary Turner54695a32016-08-29 19:58:14 +000037#include "llvm/ADT/StringSwitch.h"
38
Jason Molenda4a793c82018-12-18 23:02:50 +000039#if defined(__APPLE__)
40#define HAVE_LIBCOMPRESSION
Jason Molenda91ffe0a2015-06-18 21:46:06 +000041#include <compression.h>
42#endif
43
Greg Clayton576d8832011-03-22 04:00:09 +000044using namespace lldb;
45using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000046using namespace lldb_private::process_gdb_remote;
Pavel Labath1eff73c2016-11-24 10:54:49 +000047using namespace std::chrono;
Greg Clayton576d8832011-03-22 04:00:09 +000048
49//----------------------------------------------------------------------
50// GDBRemoteCommunicationClient constructor
51//----------------------------------------------------------------------
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000052GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000053 : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000054 m_supports_not_sending_acks(eLazyBoolCalculate),
55 m_supports_thread_suffix(eLazyBoolCalculate),
56 m_supports_threads_in_stop_reply(eLazyBoolCalculate),
57 m_supports_vCont_all(eLazyBoolCalculate),
58 m_supports_vCont_any(eLazyBoolCalculate),
59 m_supports_vCont_c(eLazyBoolCalculate),
60 m_supports_vCont_C(eLazyBoolCalculate),
61 m_supports_vCont_s(eLazyBoolCalculate),
62 m_supports_vCont_S(eLazyBoolCalculate),
63 m_qHostInfo_is_valid(eLazyBoolCalculate),
64 m_curr_pid_is_valid(eLazyBoolCalculate),
65 m_qProcessInfo_is_valid(eLazyBoolCalculate),
66 m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
67 m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
68 m_supports_memory_region_info(eLazyBoolCalculate),
69 m_supports_watchpoint_support_info(eLazyBoolCalculate),
70 m_supports_detach_stay_stopped(eLazyBoolCalculate),
71 m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
72 m_attach_or_wait_reply(eLazyBoolCalculate),
73 m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000075 m_avoid_g_packets(eLazyBoolCalculate),
76 m_supports_QSaveRegisterState(eLazyBoolCalculate),
77 m_supports_qXfer_auxv_read(eLazyBoolCalculate),
78 m_supports_qXfer_libraries_read(eLazyBoolCalculate),
79 m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
80 m_supports_qXfer_features_read(eLazyBoolCalculate),
Pavel Labath16064d32018-03-20 11:56:24 +000081 m_supports_qXfer_memory_map_read(eLazyBoolCalculate),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000082 m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
83 m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
84 m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000085 m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
Eugene Zemtsov7993cc52017-03-07 21:34:40 +000086 m_supports_QPassSignals(eLazyBoolCalculate),
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +000087 m_supports_error_string_reply(eLazyBoolCalculate),
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
89 m_supports_qUserName(true), m_supports_qGroupName(true),
90 m_supports_qThreadStopInfo(true), m_supports_z0(true),
91 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
92 m_supports_z4(true), m_supports_QEnvironment(true),
93 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
94 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
Pavel Labath2f1fbae2016-09-08 10:07:04 +000095 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
96 m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000097 m_curr_tid_run(LLDB_INVALID_THREAD_ID),
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
Pavel Labath2272c482018-06-18 15:02:23 +000099 m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
100 m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
101 m_max_packet_size(0), m_qSupported_response(),
102 m_supported_async_json_packets_is_valid(false),
Pavel Labath16064d32018-03-20 11:56:24 +0000103 m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
104 m_qXfer_memory_map_loaded(false) {}
Greg Clayton576d8832011-03-22 04:00:09 +0000105
106//----------------------------------------------------------------------
107// Destructor
108//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
110 if (IsConnected())
111 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000112}
113
Zachary Turner97206d52017-05-12 04:51:55 +0000114bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 ResetDiscoverableSettings(false);
Greg Claytonfb909312013-11-23 01:58:15 +0000116
Adrian Prantl05097242018-04-30 16:49:04 +0000117 // Start the read thread after we send the handshake ack since if we fail to
118 // send the handshake ack, there is no reason to continue...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 if (SendAck()) {
120 // Wait for any responses that might have been queued up in the remote
121 // GDB server and flush them all
122 StringExtractorGDBRemote response;
123 PacketResult packet_result = PacketResult::Success;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 while (packet_result == PacketResult::Success)
Pavel Labath1eff73c2016-11-24 10:54:49 +0000125 packet_result = ReadPacket(response, milliseconds(10), false);
Ed Maste48f986f2013-12-18 15:31:45 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 // The return value from QueryNoAckModeSupported() is true if the packet
Adrian Prantl05097242018-04-30 16:49:04 +0000128 // was sent and _any_ response (including UNIMPLEMENTED) was received), or
129 // false if no response was received. This quickly tells us if we have a
130 // live connection to a remote GDB server...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 if (QueryNoAckModeSupported()) {
132 return true;
133 } else {
134 if (error_ptr)
135 error_ptr->SetErrorString("failed to get reply to handshake packet");
Greg Claytonfb909312013-11-23 01:58:15 +0000136 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 } else {
138 if (error_ptr)
139 error_ptr->SetErrorString("failed to send the handshake ack");
140 }
141 return false;
Greg Clayton1cb64962011-03-24 04:28:38 +0000142}
143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144bool GDBRemoteCommunicationClient::GetEchoSupported() {
145 if (m_supports_qEcho == eLazyBoolCalculate) {
146 GetRemoteQSupported();
147 }
148 return m_supports_qEcho == eLazyBoolYes;
Greg Claytonb30c50c2015-05-29 00:01:55 +0000149}
150
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000151bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
152 if (m_supports_QPassSignals == eLazyBoolCalculate) {
153 GetRemoteQSupported();
154 }
155 return m_supports_QPassSignals == eLazyBoolYes;
156}
157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
159 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
160 GetRemoteQSupported();
161 }
162 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000163}
164
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
166 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
167 GetRemoteQSupported();
168 }
169 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000170}
171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
173 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
174 GetRemoteQSupported();
175 }
176 return m_supports_qXfer_libraries_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000177}
178
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
180 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
181 GetRemoteQSupported();
182 }
183 return m_supports_qXfer_auxv_read == eLazyBoolYes;
Steve Pucci03904ac2014-03-04 23:18:46 +0000184}
185
Kate Stoneb9c1b512016-09-06 20:57:50 +0000186bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
187 if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
188 GetRemoteQSupported();
189 }
190 return m_supports_qXfer_features_read == eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000191}
192
Pavel Labath16064d32018-03-20 11:56:24 +0000193bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
194 if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
195 GetRemoteQSupported();
196 }
197 return m_supports_qXfer_memory_map_read == eLazyBoolYes;
198}
199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
201 if (m_max_packet_size == 0) {
202 GetRemoteQSupported();
203 }
204 return m_max_packet_size;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000205}
206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
208 if (m_supports_not_sending_acks == eLazyBoolCalculate) {
209 m_send_acks = true;
210 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000211
Kate Stoneb9c1b512016-09-06 20:57:50 +0000212 // This is the first real packet that we'll send in a debug session and it
Adrian Prantl05097242018-04-30 16:49:04 +0000213 // may take a little longer than normal to receive a reply. Wait at least
214 // 6 seconds for a reply to this packet.
Jason Molenda36a216e2014-07-24 01:36:24 +0000215
Pavel Labath1eff73c2016-11-24 10:54:49 +0000216 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
Colin Rileyc3c95b22015-04-16 15:51:33 +0000217
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000218 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
220 PacketResult::Success) {
221 if (response.IsOKResponse()) {
222 m_send_acks = false;
223 m_supports_not_sending_acks = eLazyBoolYes;
224 }
225 return true;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000226 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000227 }
228 return false;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000229}
Greg Clayton576d8832011-03-22 04:00:09 +0000230
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
232 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
233 m_supports_threads_in_stop_reply = eLazyBoolNo;
234
235 StringExtractorGDBRemote response;
236 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
237 false) == PacketResult::Success) {
238 if (response.IsOKResponse())
239 m_supports_threads_in_stop_reply = eLazyBoolYes;
Pavel Labath5c95ee42016-08-30 13:56:11 +0000240 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241 }
Pavel Labath0faf3732016-08-25 08:34:57 +0000242}
Greg Clayton576d8832011-03-22 04:00:09 +0000243
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
245 if (m_attach_or_wait_reply == eLazyBoolCalculate) {
246 m_attach_or_wait_reply = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +0000247
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 StringExtractorGDBRemote response;
249 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
250 false) == PacketResult::Success) {
251 if (response.IsOKResponse())
252 m_attach_or_wait_reply = eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +0000253 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 }
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000255 return m_attach_or_wait_reply == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +0000256}
257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
259 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
260 m_prepare_for_reg_writing_reply = eLazyBoolNo;
261
262 StringExtractorGDBRemote response;
263 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
264 false) == PacketResult::Success) {
265 if (response.IsOKResponse())
266 m_prepare_for_reg_writing_reply = eLazyBoolYes;
267 }
268 }
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000269 return m_prepare_for_reg_writing_reply == eLazyBoolYes;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270}
271
272void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000273 if (!did_exec) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 // Hard reset everything, this is when we first connect to a GDB server
275 m_supports_not_sending_acks = eLazyBoolCalculate;
276 m_supports_thread_suffix = eLazyBoolCalculate;
277 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
278 m_supports_vCont_c = eLazyBoolCalculate;
279 m_supports_vCont_C = eLazyBoolCalculate;
280 m_supports_vCont_s = eLazyBoolCalculate;
281 m_supports_vCont_S = eLazyBoolCalculate;
282 m_supports_p = eLazyBoolCalculate;
283 m_supports_x = eLazyBoolCalculate;
284 m_supports_QSaveRegisterState = eLazyBoolCalculate;
285 m_qHostInfo_is_valid = eLazyBoolCalculate;
286 m_curr_pid_is_valid = eLazyBoolCalculate;
287 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
288 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
289 m_supports_memory_region_info = eLazyBoolCalculate;
290 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
291 m_attach_or_wait_reply = eLazyBoolCalculate;
292 m_avoid_g_packets = eLazyBoolCalculate;
293 m_supports_qXfer_auxv_read = eLazyBoolCalculate;
294 m_supports_qXfer_libraries_read = eLazyBoolCalculate;
295 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
296 m_supports_qXfer_features_read = eLazyBoolCalculate;
Pavel Labath16064d32018-03-20 11:56:24 +0000297 m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
299 m_supports_qProcessInfoPID = true;
300 m_supports_qfProcessInfo = true;
301 m_supports_qUserName = true;
302 m_supports_qGroupName = true;
303 m_supports_qThreadStopInfo = true;
304 m_supports_z0 = true;
305 m_supports_z1 = true;
306 m_supports_z2 = true;
307 m_supports_z3 = true;
308 m_supports_z4 = true;
309 m_supports_QEnvironment = true;
310 m_supports_QEnvironmentHexEncoded = true;
311 m_supports_qSymbol = true;
312 m_qSymbol_requests_done = false;
313 m_supports_qModuleInfo = true;
314 m_host_arch.Clear();
Pavel Labath2272c482018-06-18 15:02:23 +0000315 m_os_version = llvm::VersionTuple();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000316 m_os_build.clear();
317 m_os_kernel.clear();
318 m_hostname.clear();
319 m_gdb_server_name.clear();
320 m_gdb_server_version = UINT32_MAX;
Pavel Labath1eff73c2016-11-24 10:54:49 +0000321 m_default_packet_timeout = seconds(0);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322 m_max_packet_size = 0;
323 m_qSupported_response.clear();
324 m_supported_async_json_packets_is_valid = false;
325 m_supported_async_json_packets_sp.reset();
Pavel Labath2f1fbae2016-09-08 10:07:04 +0000326 m_supports_jModulesInfo = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 }
328
Adrian Prantl05097242018-04-30 16:49:04 +0000329 // These flags should be reset when we first connect to a GDB server and when
330 // our inferior process execs
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331 m_qProcessInfo_is_valid = eLazyBoolCalculate;
332 m_process_arch.Clear();
333}
334
335void GDBRemoteCommunicationClient::GetRemoteQSupported() {
336 // Clear out any capabilities we expect to see in the qSupported response
337 m_supports_qXfer_auxv_read = eLazyBoolNo;
338 m_supports_qXfer_libraries_read = eLazyBoolNo;
339 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
340 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
341 m_supports_qXfer_features_read = eLazyBoolNo;
Pavel Labath16064d32018-03-20 11:56:24 +0000342 m_supports_qXfer_memory_map_read = eLazyBoolNo;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
344 // not, we assume no limit
345
346 // build the qSupported packet
347 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
348 StreamString packet;
349 packet.PutCString("qSupported");
350 for (uint32_t i = 0; i < features.size(); ++i) {
351 packet.PutCString(i == 0 ? ":" : ";");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000352 packet.PutCString(features[i]);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 }
354
355 StringExtractorGDBRemote response;
Zachary Turnerc1564272016-11-16 21:15:24 +0000356 if (SendPacketAndWaitForResponse(packet.GetString(), response,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000357 /*send_async=*/false) ==
358 PacketResult::Success) {
359 const char *response_cstr = response.GetStringRef().c_str();
360
361 // Hang on to the qSupported packet, so that platforms can do custom
Adrian Prantl05097242018-04-30 16:49:04 +0000362 // configuration of the transport before attaching/launching the process.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363 m_qSupported_response = response_cstr;
364
365 if (::strstr(response_cstr, "qXfer:auxv:read+"))
366 m_supports_qXfer_auxv_read = eLazyBoolYes;
367 if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
368 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
369 if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
370 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
371 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
372 }
373 if (::strstr(response_cstr, "qXfer:libraries:read+"))
374 m_supports_qXfer_libraries_read = eLazyBoolYes;
375 if (::strstr(response_cstr, "qXfer:features:read+"))
376 m_supports_qXfer_features_read = eLazyBoolYes;
Pavel Labath16064d32018-03-20 11:56:24 +0000377 if (::strstr(response_cstr, "qXfer:memory-map:read+"))
378 m_supports_qXfer_memory_map_read = eLazyBoolYes;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379
380 // Look for a list of compressions in the features list e.g.
Adrian Prantl05097242018-04-30 16:49:04 +0000381 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
382 // deflate,lzma
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383 const char *features_list = ::strstr(response_cstr, "qXfer:features:");
384 if (features_list) {
385 const char *compressions =
386 ::strstr(features_list, "SupportedCompressions=");
387 if (compressions) {
388 std::vector<std::string> supported_compressions;
389 compressions += sizeof("SupportedCompressions=") - 1;
390 const char *end_of_compressions = strchr(compressions, ';');
391 if (end_of_compressions == NULL) {
392 end_of_compressions = strchr(compressions, '\0');
393 }
394 const char *current_compression = compressions;
395 while (current_compression < end_of_compressions) {
396 const char *next_compression_name = strchr(current_compression, ',');
397 const char *end_of_this_word = next_compression_name;
398 if (next_compression_name == NULL ||
399 end_of_compressions < next_compression_name) {
400 end_of_this_word = end_of_compressions;
401 }
402
403 if (end_of_this_word) {
404 if (end_of_this_word == current_compression) {
405 current_compression++;
406 } else {
407 std::string this_compression(
408 current_compression, end_of_this_word - current_compression);
409 supported_compressions.push_back(this_compression);
410 current_compression = end_of_this_word + 1;
411 }
412 } else {
413 supported_compressions.push_back(current_compression);
414 current_compression = end_of_compressions;
415 }
416 }
417
418 if (supported_compressions.size() > 0) {
419 MaybeEnableCompression(supported_compressions);
420 }
421 }
422 }
423
424 if (::strstr(response_cstr, "qEcho"))
425 m_supports_qEcho = eLazyBoolYes;
426 else
427 m_supports_qEcho = eLazyBoolNo;
428
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000429 if (::strstr(response_cstr, "QPassSignals+"))
430 m_supports_QPassSignals = eLazyBoolYes;
431 else
432 m_supports_QPassSignals = eLazyBoolNo;
433
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
435 if (packet_size_str) {
436 StringExtractorGDBRemote packet_response(packet_size_str +
437 strlen("PacketSize="));
438 m_max_packet_size =
439 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
440 if (m_max_packet_size == 0) {
441 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
442 Log *log(
443 ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
444 if (log)
445 log->Printf("Garbled PacketSize spec in qSupported response");
446 }
447 }
448 }
449}
450
451bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
452 if (m_supports_thread_suffix == eLazyBoolCalculate) {
453 StringExtractorGDBRemote response;
454 m_supports_thread_suffix = eLazyBoolNo;
455 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
456 false) == PacketResult::Success) {
457 if (response.IsOKResponse())
458 m_supports_thread_suffix = eLazyBoolYes;
459 }
460 }
461 return m_supports_thread_suffix;
462}
463bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
464 if (m_supports_vCont_c == eLazyBoolCalculate) {
465 StringExtractorGDBRemote response;
466 m_supports_vCont_any = eLazyBoolNo;
467 m_supports_vCont_all = eLazyBoolNo;
468 m_supports_vCont_c = eLazyBoolNo;
469 m_supports_vCont_C = eLazyBoolNo;
470 m_supports_vCont_s = eLazyBoolNo;
471 m_supports_vCont_S = eLazyBoolNo;
472 if (SendPacketAndWaitForResponse("vCont?", response, false) ==
473 PacketResult::Success) {
474 const char *response_cstr = response.GetStringRef().c_str();
475 if (::strstr(response_cstr, ";c"))
476 m_supports_vCont_c = eLazyBoolYes;
477
478 if (::strstr(response_cstr, ";C"))
479 m_supports_vCont_C = eLazyBoolYes;
480
481 if (::strstr(response_cstr, ";s"))
482 m_supports_vCont_s = eLazyBoolYes;
483
484 if (::strstr(response_cstr, ";S"))
485 m_supports_vCont_S = eLazyBoolYes;
486
487 if (m_supports_vCont_c == eLazyBoolYes &&
488 m_supports_vCont_C == eLazyBoolYes &&
489 m_supports_vCont_s == eLazyBoolYes &&
490 m_supports_vCont_S == eLazyBoolYes) {
491 m_supports_vCont_all = eLazyBoolYes;
492 }
493
494 if (m_supports_vCont_c == eLazyBoolYes ||
495 m_supports_vCont_C == eLazyBoolYes ||
496 m_supports_vCont_s == eLazyBoolYes ||
497 m_supports_vCont_S == eLazyBoolYes) {
498 m_supports_vCont_any = eLazyBoolYes;
499 }
500 }
501 }
502
503 switch (flavor) {
504 case 'a':
505 return m_supports_vCont_any;
506 case 'A':
507 return m_supports_vCont_all;
508 case 'c':
509 return m_supports_vCont_c;
510 case 'C':
511 return m_supports_vCont_C;
512 case 's':
513 return m_supports_vCont_s;
514 case 'S':
515 return m_supports_vCont_S;
516 default:
517 break;
518 }
519 return false;
520}
521
Pavel Labath4b6f9592016-08-18 08:30:03 +0000522GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
524 lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
525 bool send_async) {
526 Lock lock(*this, send_async);
527 if (!lock) {
528 if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
529 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
530 log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
531 "for %s packet.",
Zachary Turnerc1564272016-11-16 21:15:24 +0000532 __FUNCTION__, payload.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533 return PacketResult::ErrorNoSequenceLock;
534 }
Pavel Labath5c95ee42016-08-30 13:56:11 +0000535
Kate Stoneb9c1b512016-09-06 20:57:50 +0000536 if (GetThreadSuffixSupported())
537 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
538 else {
539 if (!SetCurrentThread(tid))
540 return PacketResult::ErrorSendFailed;
541 }
Pavel Labath4b6f9592016-08-18 08:30:03 +0000542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
Pavel Labath4b6f9592016-08-18 08:30:03 +0000544}
545
Adrian Prantl05097242018-04-30 16:49:04 +0000546// Check if the target supports 'p' packet. It sends out a 'p' packet and
547// checks the response. A normal packet will tell us that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000548//
549// Takes a valid thread ID because p needs to apply to a thread.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
551 if (m_supports_p == eLazyBoolCalculate) {
552 m_supports_p = eLazyBoolNo;
553 StreamString payload;
554 payload.PutCString("p0");
555 StringExtractorGDBRemote response;
556 if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
557 response, false) ==
558 PacketResult::Success &&
559 response.IsNormalResponse()) {
560 m_supports_p = eLazyBoolYes;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000561 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 }
563 return m_supports_p;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000564}
Greg Clayton576d8832011-03-22 04:00:09 +0000565
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
567 // Get information on all threads at one using the "jThreadsInfo" packet
568 StructuredData::ObjectSP object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000569
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 if (m_supports_jThreadsInfo) {
571 StringExtractorGDBRemote response;
572 response.SetResponseValidatorToJSON();
573 if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
574 PacketResult::Success) {
575 if (response.IsUnsupportedResponse()) {
576 m_supports_jThreadsInfo = false;
577 } else if (!response.Empty()) {
578 object_sp = StructuredData::ParseJSON(response.GetStringRef());
579 }
Greg Clayton358cf1e2015-06-25 21:46:34 +0000580 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581 }
582 return object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000583}
584
Kate Stoneb9c1b512016-09-06 20:57:50 +0000585bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
586 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
587 StringExtractorGDBRemote response;
588 m_supports_jThreadExtendedInfo = eLazyBoolNo;
589 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
590 PacketResult::Success) {
591 if (response.IsOKResponse()) {
592 m_supports_jThreadExtendedInfo = eLazyBoolYes;
593 }
Jason Molenda705b1802014-06-13 02:37:02 +0000594 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000595 }
596 return m_supports_jThreadExtendedInfo;
Jason Molenda705b1802014-06-13 02:37:02 +0000597}
598
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000599void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
600 if (m_supports_error_string_reply == eLazyBoolCalculate) {
601 StringExtractorGDBRemote response;
Adrian Prantl05097242018-04-30 16:49:04 +0000602 // We try to enable error strings in remote packets but if we fail, we just
603 // work in the older way.
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000604 m_supports_error_string_reply = eLazyBoolNo;
605 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
606 PacketResult::Success) {
607 if (response.IsOKResponse()) {
608 m_supports_error_string_reply = eLazyBoolYes;
609 }
610 }
611 }
612}
613
Kate Stoneb9c1b512016-09-06 20:57:50 +0000614bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
615 if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
616 StringExtractorGDBRemote response;
617 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
618 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
619 response,
620 false) == PacketResult::Success) {
621 if (response.IsOKResponse()) {
622 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
623 }
Jason Molenda20ee21b2015-07-10 23:15:22 +0000624 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000625 }
626 return m_supports_jLoadedDynamicLibrariesInfos;
Jason Molenda20ee21b2015-07-10 23:15:22 +0000627}
628
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
630 if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
631 StringExtractorGDBRemote response;
632 m_supports_jGetSharedCacheInfo = eLazyBoolNo;
633 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
634 PacketResult::Success) {
635 if (response.IsOKResponse()) {
636 m_supports_jGetSharedCacheInfo = eLazyBoolYes;
637 }
Jason Molenda37397352016-07-22 00:17:55 +0000638 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639 }
640 return m_supports_jGetSharedCacheInfo;
Jason Molenda37397352016-07-22 00:17:55 +0000641}
642
Kate Stoneb9c1b512016-09-06 20:57:50 +0000643bool GDBRemoteCommunicationClient::GetxPacketSupported() {
644 if (m_supports_x == eLazyBoolCalculate) {
645 StringExtractorGDBRemote response;
646 m_supports_x = eLazyBoolNo;
647 char packet[256];
648 snprintf(packet, sizeof(packet), "x0,0");
649 if (SendPacketAndWaitForResponse(packet, response, false) ==
650 PacketResult::Success) {
651 if (response.IsOKResponse())
652 m_supports_x = eLazyBoolYes;
Jason Molendabdc4f122014-05-06 02:59:39 +0000653 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654 }
655 return m_supports_x;
Jason Molendabdc4f122014-05-06 02:59:39 +0000656}
657
Greg Clayton3dedae12013-12-06 21:45:27 +0000658GDBRemoteCommunicationClient::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000659GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
660 const char *payload_prefix, std::string &response_string) {
661 Lock lock(*this, false);
662 if (!lock) {
663 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
664 GDBR_LOG_PACKETS));
665 if (log)
666 log->Printf("error: failed to get packet sequence mutex, not sending "
667 "packets with prefix '%s'",
668 payload_prefix);
669 return PacketResult::ErrorNoSequenceLock;
670 }
671
672 response_string = "";
673 std::string payload_prefix_str(payload_prefix);
674 unsigned int response_size = 0x1000;
675 if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
676 response_size = GetRemoteMaxPacketSize();
677 }
678
679 for (unsigned int offset = 0; true; offset += response_size) {
680 StringExtractorGDBRemote this_response;
681 // Construct payload
682 char sizeDescriptor[128];
683 snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
684 response_size);
685 PacketResult result = SendPacketAndWaitForResponseNoLock(
686 payload_prefix_str + sizeDescriptor, this_response);
687 if (result != PacketResult::Success)
688 return result;
689
690 const std::string &this_string = this_response.GetStringRef();
691
692 // Check for m or l as first character; l seems to mean this is the last
693 // chunk
694 char first_char = *this_string.c_str();
695 if (first_char != 'm' && first_char != 'l') {
696 return PacketResult::ErrorReplyInvalid;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000697 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000698 // Concatenate the result so far (skipping 'm' or 'l')
699 response_string.append(this_string, 1, std::string::npos);
700 if (first_char == 'l')
701 // We're done
702 return PacketResult::Success;
703 }
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000704}
705
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
707 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
708 return m_curr_pid;
Jaydeep Patil1142f832015-08-13 03:46:36 +0000709
Kate Stoneb9c1b512016-09-06 20:57:50 +0000710 // First try to retrieve the pid via the qProcessInfo request.
711 GetCurrentProcessInfo(allow_lazy);
712 if (m_curr_pid_is_valid == eLazyBoolYes) {
713 // We really got it.
714 return m_curr_pid;
715 } else {
716 // If we don't get a response for qProcessInfo, check if $qC gives us a
Adrian Prantl05097242018-04-30 16:49:04 +0000717 // result. $qC only returns a real process id on older debugserver and
718 // lldb-platform stubs. The gdb remote protocol documents $qC as returning
719 // the thread id, which newer debugserver and lldb-gdbserver stubs return
720 // correctly.
Greg Clayton576d8832011-03-22 04:00:09 +0000721 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000722 if (SendPacketAndWaitForResponse("qC", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 PacketResult::Success) {
724 if (response.GetChar() == 'Q') {
725 if (response.GetChar() == 'C') {
726 m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
727 if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
728 m_curr_pid_is_valid = eLazyBoolYes;
729 return m_curr_pid;
730 }
Greg Clayton576d8832011-03-22 04:00:09 +0000731 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732 }
Greg Clayton576d8832011-03-22 04:00:09 +0000733 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734
735 // If we don't get a response for $qC, check if $qfThreadID gives us a
736 // result.
737 if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
738 std::vector<lldb::tid_t> thread_ids;
739 bool sequence_mutex_unavailable;
740 size_t size;
741 size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000742 if (size && !sequence_mutex_unavailable) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743 m_curr_pid = thread_ids.front();
744 m_curr_pid_is_valid = eLazyBoolYes;
745 return m_curr_pid;
746 }
Greg Clayton576d8832011-03-22 04:00:09 +0000747 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000748 }
749
750 return LLDB_INVALID_PROCESS_ID;
Greg Clayton576d8832011-03-22 04:00:09 +0000751}
752
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
754 error_str.clear();
755 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000756 if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
757 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758 if (response.IsOKResponse())
759 return true;
760 if (response.GetChar() == 'E') {
761 // A string the describes what failed when launching...
762 error_str = response.GetStringRef().substr(1);
763 } else {
764 error_str.assign("unknown error occurred launching process");
Greg Claytonfbb76342013-11-20 21:07:01 +0000765 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000766 } else {
767 error_str.assign("timed out waiting for app to launch");
768 }
769 return false;
Greg Clayton576d8832011-03-22 04:00:09 +0000770}
771
Kate Stoneb9c1b512016-09-06 20:57:50 +0000772int GDBRemoteCommunicationClient::SendArgumentsPacket(
773 const ProcessLaunchInfo &launch_info) {
774 // Since we don't get the send argv0 separate from the executable path, we
Adrian Prantl05097242018-04-30 16:49:04 +0000775 // need to make sure to use the actual executable path found in the
776 // launch_info...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777 std::vector<const char *> argv;
778 FileSpec exe_file = launch_info.GetExecutableFile();
779 std::string exe_path;
780 const char *arg = NULL;
781 const Args &launch_args = launch_info.GetArguments();
782 if (exe_file)
783 exe_path = exe_file.GetPath(false);
784 else {
785 arg = launch_args.GetArgumentAtIndex(0);
786 if (arg)
787 exe_path = arg;
788 }
789 if (!exe_path.empty()) {
790 argv.push_back(exe_path.c_str());
791 for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL;
792 ++i) {
793 if (arg)
794 argv.push_back(arg);
Greg Clayton576d8832011-03-22 04:00:09 +0000795 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000796 }
797 if (!argv.empty()) {
Vince Harrone0be4252015-02-06 18:32:57 +0000798 StreamString packet;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000799 packet.PutChar('A');
800 for (size_t i = 0, n = argv.size(); i < n; ++i) {
801 arg = argv[i];
802 const int arg_len = strlen(arg);
803 if (i > 0)
804 packet.PutChar(',');
805 packet.Printf("%i,%i,", arg_len * 2, (int)i);
806 packet.PutBytesAsRawHex8(arg, arg_len);
807 }
808
Vince Harrone0be4252015-02-06 18:32:57 +0000809 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000810 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
811 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000812 if (response.IsOKResponse())
Vince Harrone0be4252015-02-06 18:32:57 +0000813 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000814 uint8_t error = response.GetError();
815 if (error)
Johnny Chen64637202012-05-23 21:09:52 +0000816 return error;
817 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000818 }
819 return -1;
820}
Johnny Chen64637202012-05-23 21:09:52 +0000821
Pavel Labath62930e52018-01-10 11:57:31 +0000822int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
823 for (const auto &KV : env) {
824 int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
825 if (r != 0)
826 return r;
827 }
828 return 0;
829}
830
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831int GDBRemoteCommunicationClient::SendEnvironmentPacket(
832 char const *name_equal_value) {
833 if (name_equal_value && name_equal_value[0]) {
834 StreamString packet;
835 bool send_hex_encoding = false;
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000836 for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
837 ++p) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 if (isprint(*p)) {
839 switch (*p) {
840 case '$':
841 case '#':
842 case '*':
843 case '}':
844 send_hex_encoding = true;
845 break;
846 default:
847 break;
Johnny Chen64637202012-05-23 21:09:52 +0000848 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000849 } else {
850 // We have non printable characters, lets hex encode this...
851 send_hex_encoding = true;
852 }
Johnny Chen64637202012-05-23 21:09:52 +0000853 }
854
Greg Claytonfbb76342013-11-20 21:07:01 +0000855 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 if (send_hex_encoding) {
857 if (m_supports_QEnvironmentHexEncoded) {
858 packet.PutCString("QEnvironmentHexEncoded:");
859 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000860 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
861 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000862 if (response.IsOKResponse())
863 return 0;
864 uint8_t error = response.GetError();
865 if (error)
866 return error;
867 if (response.IsUnsupportedResponse())
868 m_supports_QEnvironmentHexEncoded = false;
869 }
870 }
871
872 } else if (m_supports_QEnvironment) {
873 packet.Printf("QEnvironment:%s", name_equal_value);
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000874 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
875 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000876 if (response.IsOKResponse())
877 return 0;
878 uint8_t error = response.GetError();
879 if (error)
880 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000881 if (response.IsUnsupportedResponse())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 m_supports_QEnvironment = false;
883 }
Greg Claytonfbb76342013-11-20 21:07:01 +0000884 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000885 }
886 return -1;
Greg Claytonfbb76342013-11-20 21:07:01 +0000887}
888
Kate Stoneb9c1b512016-09-06 20:57:50 +0000889int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
890 if (arch && arch[0]) {
891 StreamString packet;
892 packet.Printf("QLaunchArch:%s", arch);
893 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000894 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
895 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000896 if (response.IsOKResponse())
897 return 0;
898 uint8_t error = response.GetError();
899 if (error)
900 return error;
901 }
902 }
903 return -1;
904}
Chaoren Lind3173f32015-05-29 19:52:29 +0000905
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
907 char const *data, bool *was_supported) {
908 if (data && *data != '\0') {
909 StreamString packet;
910 packet.Printf("QSetProcessEvent:%s", data);
911 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000912 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
913 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914 if (response.IsOKResponse()) {
915 if (was_supported)
916 *was_supported = true;
917 return 0;
918 } else if (response.IsUnsupportedResponse()) {
919 if (was_supported)
920 *was_supported = false;
921 return -1;
922 } else {
923 uint8_t error = response.GetError();
924 if (was_supported)
925 *was_supported = true;
926 if (error)
927 return error;
928 }
929 }
930 }
931 return -1;
932}
933
Pavel Labath2272c482018-06-18 15:02:23 +0000934llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
935 GetHostInfo();
936 return m_os_version;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000937}
938
939bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
940 if (GetHostInfo()) {
941 if (!m_os_build.empty()) {
942 s = m_os_build;
943 return true;
944 }
945 }
946 s.clear();
947 return false;
948}
949
950bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
951 if (GetHostInfo()) {
952 if (!m_os_kernel.empty()) {
953 s = m_os_kernel;
954 return true;
955 }
956 }
957 s.clear();
958 return false;
959}
960
961bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
962 if (GetHostInfo()) {
963 if (!m_hostname.empty()) {
964 s = m_hostname;
965 return true;
966 }
967 }
968 s.clear();
969 return false;
970}
971
972ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
973 if (GetHostInfo())
974 return m_host_arch;
975 return ArchSpec();
976}
977
978const lldb_private::ArchSpec &
979GDBRemoteCommunicationClient::GetProcessArchitecture() {
980 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
981 GetCurrentProcessInfo();
982 return m_process_arch;
983}
984
985bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
986 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
987 m_gdb_server_name.clear();
988 m_gdb_server_version = 0;
989 m_qGDBServerVersion_is_valid = eLazyBoolNo;
990
991 StringExtractorGDBRemote response;
992 if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
993 PacketResult::Success) {
994 if (response.IsNormalResponse()) {
995 llvm::StringRef name, value;
996 bool success = false;
997 while (response.GetNameColonValue(name, value)) {
998 if (name.equals("name")) {
999 success = true;
1000 m_gdb_server_name = value;
1001 } else if (name.equals("version")) {
1002 llvm::StringRef major, minor;
1003 std::tie(major, minor) = value.split('.');
1004 if (!major.getAsInteger(0, m_gdb_server_version))
1005 success = true;
1006 }
Greg Clayton576d8832011-03-22 04:00:09 +00001007 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 if (success)
1009 m_qGDBServerVersion_is_valid = eLazyBoolYes;
1010 }
Greg Clayton576d8832011-03-22 04:00:09 +00001011 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001012 }
1013 return m_qGDBServerVersion_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001014}
1015
Kate Stoneb9c1b512016-09-06 20:57:50 +00001016void GDBRemoteCommunicationClient::MaybeEnableCompression(
1017 std::vector<std::string> supported_compressions) {
1018 CompressionType avail_type = CompressionType::None;
1019 std::string avail_name;
1020
1021#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001022 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001023 for (auto compression : supported_compressions) {
1024 if (compression == "lzfse") {
1025 avail_type = CompressionType::LZFSE;
1026 avail_name = compression;
1027 break;
1028 }
1029 }
1030 }
1031#endif
1032
1033#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001034 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001035 for (auto compression : supported_compressions) {
1036 if (compression == "zlib-deflate") {
1037 avail_type = CompressionType::ZlibDeflate;
1038 avail_name = compression;
1039 break;
1040 }
1041 }
1042 }
1043#endif
1044
1045#if defined(HAVE_LIBZ)
1046 if (avail_type == CompressionType::None) {
1047 for (auto compression : supported_compressions) {
1048 if (compression == "zlib-deflate") {
1049 avail_type = CompressionType::ZlibDeflate;
1050 avail_name = compression;
1051 break;
1052 }
1053 }
1054 }
1055#endif
1056
1057#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001058 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001059 for (auto compression : supported_compressions) {
1060 if (compression == "lz4") {
1061 avail_type = CompressionType::LZ4;
1062 avail_name = compression;
1063 break;
1064 }
1065 }
1066 }
1067#endif
1068
1069#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001070 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001071 for (auto compression : supported_compressions) {
1072 if (compression == "lzma") {
1073 avail_type = CompressionType::LZMA;
1074 avail_name = compression;
1075 break;
1076 }
1077 }
1078 }
1079#endif
1080
1081 if (avail_type != CompressionType::None) {
Greg Clayton576d8832011-03-22 04:00:09 +00001082 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 std::string packet = "QEnableCompression:type:" + avail_name + ";";
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001084 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085 PacketResult::Success)
1086 return;
1087
1088 if (response.IsOKResponse()) {
1089 m_compression_type = avail_type;
Greg Clayton576d8832011-03-22 04:00:09 +00001090 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001091 }
Greg Clayton576d8832011-03-22 04:00:09 +00001092}
Greg Clayton32e0a752011-03-30 18:16:51 +00001093
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
1095 if (GetGDBServerVersion()) {
1096 if (!m_gdb_server_name.empty())
1097 return m_gdb_server_name.c_str();
1098 }
1099 return NULL;
1100}
1101
1102uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1103 if (GetGDBServerVersion())
1104 return m_gdb_server_version;
1105 return 0;
1106}
1107
1108bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
1109 StringExtractorGDBRemote response;
1110 if (SendPacketAndWaitForResponse("qC", response, false) !=
1111 PacketResult::Success)
1112 return false;
1113
1114 if (!response.IsNormalResponse())
1115 return false;
1116
1117 if (response.GetChar() == 'Q' && response.GetChar() == 'C')
1118 tid = response.GetHexMaxU32(true, -1);
1119
1120 return true;
1121}
1122
1123bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
1124 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
1125
1126 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
Pavel Labathe7ec0832018-08-31 05:34:03 +00001127 // host info computation can require DNS traffic and shelling out to external processes.
1128 // Increase the timeout to account for that.
1129 ScopedTimeout timeout(*this, seconds(10));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001130 m_qHostInfo_is_valid = eLazyBoolNo;
Jim Ingham106d0282014-06-25 02:32:56 +00001131 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132 if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
1133 PacketResult::Success) {
1134 if (response.IsNormalResponse()) {
Zachary Turner54695a32016-08-29 19:58:14 +00001135 llvm::StringRef name;
1136 llvm::StringRef value;
Jason Molenda89c37492014-01-27 22:23:20 +00001137 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1138 uint32_t sub = 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139 std::string arch_name;
1140 std::string os_name;
1141 std::string vendor_name;
1142 std::string triple;
1143 std::string distribution_id;
1144 uint32_t pointer_byte_size = 0;
1145 ByteOrder byte_order = eByteOrderInvalid;
1146 uint32_t num_keys_decoded = 0;
1147 while (response.GetNameColonValue(name, value)) {
1148 if (name.equals("cputype")) {
1149 // exception type in big endian hex
1150 if (!value.getAsInteger(0, cpu))
1151 ++num_keys_decoded;
1152 } else if (name.equals("cpusubtype")) {
1153 // exception count in big endian hex
1154 if (!value.getAsInteger(0, sub))
1155 ++num_keys_decoded;
1156 } else if (name.equals("arch")) {
1157 arch_name = value;
1158 ++num_keys_decoded;
1159 } else if (name.equals("triple")) {
1160 StringExtractor extractor(value);
1161 extractor.GetHexByteString(triple);
1162 ++num_keys_decoded;
1163 } else if (name.equals("distribution_id")) {
1164 StringExtractor extractor(value);
1165 extractor.GetHexByteString(distribution_id);
1166 ++num_keys_decoded;
1167 } else if (name.equals("os_build")) {
1168 StringExtractor extractor(value);
1169 extractor.GetHexByteString(m_os_build);
1170 ++num_keys_decoded;
1171 } else if (name.equals("hostname")) {
1172 StringExtractor extractor(value);
1173 extractor.GetHexByteString(m_hostname);
1174 ++num_keys_decoded;
1175 } else if (name.equals("os_kernel")) {
1176 StringExtractor extractor(value);
1177 extractor.GetHexByteString(m_os_kernel);
1178 ++num_keys_decoded;
1179 } else if (name.equals("ostype")) {
1180 os_name = value;
1181 ++num_keys_decoded;
1182 } else if (name.equals("vendor")) {
1183 vendor_name = value;
1184 ++num_keys_decoded;
1185 } else if (name.equals("endian")) {
1186 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1187 .Case("little", eByteOrderLittle)
1188 .Case("big", eByteOrderBig)
1189 .Case("pdp", eByteOrderPDP)
1190 .Default(eByteOrderInvalid);
1191 if (byte_order != eByteOrderInvalid)
1192 ++num_keys_decoded;
1193 } else if (name.equals("ptrsize")) {
1194 if (!value.getAsInteger(0, pointer_byte_size))
1195 ++num_keys_decoded;
1196 } else if (name.equals("os_version") ||
1197 name.equals(
1198 "version")) // Older debugserver binaries used the
1199 // "version" key instead of
1200 // "os_version"...
1201 {
Pavel Labath2272c482018-06-18 15:02:23 +00001202 if (!m_os_version.tryParse(value))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001203 ++num_keys_decoded;
1204 } else if (name.equals("watchpoint_exceptions_received")) {
1205 m_watchpoints_trigger_after_instruction =
1206 llvm::StringSwitch<LazyBool>(value)
1207 .Case("before", eLazyBoolNo)
1208 .Case("after", eLazyBoolYes)
1209 .Default(eLazyBoolCalculate);
1210 if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
1211 ++num_keys_decoded;
1212 } else if (name.equals("default_packet_timeout")) {
Pavel Labath3aa04912016-10-31 17:19:42 +00001213 uint32_t timeout_seconds;
1214 if (!value.getAsInteger(0, timeout_seconds)) {
Pavel Labath1eff73c2016-11-24 10:54:49 +00001215 m_default_packet_timeout = seconds(timeout_seconds);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216 SetPacketTimeout(m_default_packet_timeout);
1217 ++num_keys_decoded;
Greg Clayton32e0a752011-03-30 18:16:51 +00001218 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001219 }
Jason Molenda89c37492014-01-27 22:23:20 +00001220 }
1221
Kate Stoneb9c1b512016-09-06 20:57:50 +00001222 if (num_keys_decoded > 0)
1223 m_qHostInfo_is_valid = eLazyBoolYes;
1224
1225 if (triple.empty()) {
1226 if (arch_name.empty()) {
1227 if (cpu != LLDB_INVALID_CPUTYPE) {
1228 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1229 if (pointer_byte_size) {
1230 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1231 }
1232 if (byte_order != eByteOrderInvalid) {
1233 assert(byte_order == m_host_arch.GetByteOrder());
1234 }
1235
1236 if (!vendor_name.empty())
1237 m_host_arch.GetTriple().setVendorName(
1238 llvm::StringRef(vendor_name));
1239 if (!os_name.empty())
1240 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
Jason Molenda89c37492014-01-27 22:23:20 +00001241 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001242 } else {
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001243 std::string triple;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244 triple += arch_name;
1245 if (!vendor_name.empty() || !os_name.empty()) {
1246 triple += '-';
1247 if (vendor_name.empty())
1248 triple += "unknown";
1249 else
1250 triple += vendor_name;
1251 triple += '-';
1252 if (os_name.empty())
1253 triple += "unknown";
1254 else
1255 triple += os_name;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001256 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001257 m_host_arch.SetTriple(triple.c_str());
Todd Fialac540dd02014-08-26 18:21:02 +00001258
Kate Stoneb9c1b512016-09-06 20:57:50 +00001259 llvm::Triple &host_triple = m_host_arch.GetTriple();
1260 if (host_triple.getVendor() == llvm::Triple::Apple &&
1261 host_triple.getOS() == llvm::Triple::Darwin) {
1262 switch (m_host_arch.GetMachine()) {
1263 case llvm::Triple::aarch64:
1264 case llvm::Triple::arm:
1265 case llvm::Triple::thumb:
1266 host_triple.setOS(llvm::Triple::IOS);
Greg Claytonadc00cb2011-05-20 23:38:13 +00001267 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001268 default:
1269 host_triple.setOS(llvm::Triple::MacOSX);
1270 break;
1271 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001272 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001273 if (pointer_byte_size) {
1274 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1275 }
1276 if (byte_order != eByteOrderInvalid) {
1277 assert(byte_order == m_host_arch.GetByteOrder());
1278 }
1279 }
1280 } else {
1281 m_host_arch.SetTriple(triple.c_str());
1282 if (pointer_byte_size) {
1283 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1284 }
1285 if (byte_order != eByteOrderInvalid) {
1286 assert(byte_order == m_host_arch.GetByteOrder());
1287 }
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001288
Kate Stoneb9c1b512016-09-06 20:57:50 +00001289 if (log)
1290 log->Printf("GDBRemoteCommunicationClient::%s parsed host "
1291 "architecture as %s, triple as %s from triple text %s",
1292 __FUNCTION__, m_host_arch.GetArchitectureName()
1293 ? m_host_arch.GetArchitectureName()
1294 : "<null-arch-name>",
1295 m_host_arch.GetTriple().getTriple().c_str(),
1296 triple.c_str());
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001297 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001298 if (!distribution_id.empty())
1299 m_host_arch.SetDistributionId(distribution_id.c_str());
1300 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001301 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001302 }
1303 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Claytonadc00cb2011-05-20 23:38:13 +00001304}
Greg Clayton37a0a242012-04-11 00:24:49 +00001305
Kate Stoneb9c1b512016-09-06 20:57:50 +00001306int GDBRemoteCommunicationClient::SendAttach(
1307 lldb::pid_t pid, StringExtractorGDBRemote &response) {
1308 if (pid != LLDB_INVALID_PROCESS_ID) {
1309 char packet[64];
1310 const int packet_len =
1311 ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001312 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001313 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001314 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001315 PacketResult::Success) {
1316 if (response.IsErrorResponse())
1317 return response.GetError();
1318 return 0;
1319 }
1320 }
1321 return -1;
1322}
1323
1324int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
1325 size_t data_len) {
1326 StreamString packet;
1327 packet.PutCString("I");
1328 packet.PutBytesAsRawHex8(data, data_len);
1329 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001330 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1331 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001332 return 0;
1333 }
1334 return response.GetError();
1335}
1336
1337const lldb_private::ArchSpec &
1338GDBRemoteCommunicationClient::GetHostArchitecture() {
1339 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1340 GetHostInfo();
1341 return m_host_arch;
1342}
1343
Pavel Labath1eff73c2016-11-24 10:54:49 +00001344seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001345 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1346 GetHostInfo();
1347 return m_default_packet_timeout;
1348}
1349
1350addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
1351 uint32_t permissions) {
1352 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1353 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1354 char packet[64];
1355 const int packet_len = ::snprintf(
1356 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1357 permissions & lldb::ePermissionsReadable ? "r" : "",
1358 permissions & lldb::ePermissionsWritable ? "w" : "",
1359 permissions & lldb::ePermissionsExecutable ? "x" : "");
1360 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001361 UNUSED_IF_ASSERT_DISABLED(packet_len);
Pavel Labath83082a02016-08-18 14:33:55 +00001362 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001363 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001364 PacketResult::Success) {
1365 if (response.IsUnsupportedResponse())
1366 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1367 else if (!response.IsErrorResponse())
1368 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1369 } else {
1370 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1371 }
1372 }
1373 return LLDB_INVALID_ADDRESS;
1374}
1375
1376bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
1377 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1378 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1379 char packet[64];
1380 const int packet_len =
1381 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1382 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001383 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001384 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001385 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001386 PacketResult::Success) {
1387 if (response.IsUnsupportedResponse())
1388 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1389 else if (response.IsOKResponse())
1390 return true;
1391 } else {
1392 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1393 }
1394 }
1395 return false;
1396}
1397
Zachary Turner97206d52017-05-12 04:51:55 +00001398Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
1399 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001400
1401 if (keep_stopped) {
1402 if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
1403 char packet[64];
1404 const int packet_len =
1405 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1406 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001407 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001409 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001410 PacketResult::Success &&
1411 response.IsOKResponse()) {
1412 m_supports_detach_stay_stopped = eLazyBoolYes;
1413 } else {
1414 m_supports_detach_stay_stopped = eLazyBoolNo;
1415 }
1416 }
1417
1418 if (m_supports_detach_stay_stopped == eLazyBoolNo) {
1419 error.SetErrorString("Stays stopped not supported by this target.");
1420 return error;
1421 } else {
1422 StringExtractorGDBRemote response;
1423 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001424 SendPacketAndWaitForResponse("D1", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001425 if (packet_result != PacketResult::Success)
1426 error.SetErrorString("Sending extended disconnect packet failed.");
1427 }
1428 } else {
1429 StringExtractorGDBRemote response;
1430 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001431 SendPacketAndWaitForResponse("D", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001432 if (packet_result != PacketResult::Success)
1433 error.SetErrorString("Sending disconnect packet failed.");
1434 }
1435 return error;
1436}
1437
Zachary Turner97206d52017-05-12 04:51:55 +00001438Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001439 lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
Zachary Turner97206d52017-05-12 04:51:55 +00001440 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001441 region_info.Clear();
1442
1443 if (m_supports_memory_region_info != eLazyBoolNo) {
1444 m_supports_memory_region_info = eLazyBoolYes;
1445 char packet[64];
1446 const int packet_len = ::snprintf(
1447 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1448 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001449 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001450 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001451 if (SendPacketAndWaitForResponse(packet, response, false) ==
Pavel Labath16064d32018-03-20 11:56:24 +00001452 PacketResult::Success &&
1453 response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001454 llvm::StringRef name;
1455 llvm::StringRef value;
1456 addr_t addr_value = LLDB_INVALID_ADDRESS;
1457 bool success = true;
1458 bool saw_permissions = false;
1459 while (success && response.GetNameColonValue(name, value)) {
1460 if (name.equals("start")) {
1461 if (!value.getAsInteger(16, addr_value))
1462 region_info.GetRange().SetRangeBase(addr_value);
1463 } else if (name.equals("size")) {
1464 if (!value.getAsInteger(16, addr_value))
1465 region_info.GetRange().SetByteSize(addr_value);
1466 } else if (name.equals("permissions") &&
1467 region_info.GetRange().IsValid()) {
1468 saw_permissions = true;
1469 if (region_info.GetRange().Contains(addr)) {
1470 if (value.find('r') != llvm::StringRef::npos)
1471 region_info.SetReadable(MemoryRegionInfo::eYes);
1472 else
1473 region_info.SetReadable(MemoryRegionInfo::eNo);
1474
1475 if (value.find('w') != llvm::StringRef::npos)
1476 region_info.SetWritable(MemoryRegionInfo::eYes);
1477 else
1478 region_info.SetWritable(MemoryRegionInfo::eNo);
1479
1480 if (value.find('x') != llvm::StringRef::npos)
1481 region_info.SetExecutable(MemoryRegionInfo::eYes);
1482 else
1483 region_info.SetExecutable(MemoryRegionInfo::eNo);
1484
1485 region_info.SetMapped(MemoryRegionInfo::eYes);
1486 } else {
1487 // The reported region does not contain this address -- we're
1488 // looking at an unmapped page
1489 region_info.SetReadable(MemoryRegionInfo::eNo);
1490 region_info.SetWritable(MemoryRegionInfo::eNo);
1491 region_info.SetExecutable(MemoryRegionInfo::eNo);
1492 region_info.SetMapped(MemoryRegionInfo::eNo);
1493 }
1494 } else if (name.equals("name")) {
1495 StringExtractorGDBRemote name_extractor(value);
1496 std::string name;
1497 name_extractor.GetHexByteString(name);
1498 region_info.SetName(name.c_str());
1499 } else if (name.equals("error")) {
1500 StringExtractorGDBRemote error_extractor(value);
1501 std::string error_string;
1502 // Now convert the HEX bytes into a string value
1503 error_extractor.GetHexByteString(error_string);
1504 error.SetErrorString(error_string.c_str());
1505 }
1506 }
1507
Stephane Sezer48d14272017-03-31 18:00:48 +00001508 if (region_info.GetRange().IsValid()) {
1509 // We got a valid address range back but no permissions -- which means
1510 // this is an unmapped page
1511 if (!saw_permissions) {
1512 region_info.SetReadable(MemoryRegionInfo::eNo);
1513 region_info.SetWritable(MemoryRegionInfo::eNo);
1514 region_info.SetExecutable(MemoryRegionInfo::eNo);
1515 region_info.SetMapped(MemoryRegionInfo::eNo);
1516 }
1517 } else {
1518 // We got an invalid address range back
1519 error.SetErrorString("Server returned invalid range");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001520 }
1521 } else {
1522 m_supports_memory_region_info = eLazyBoolNo;
1523 }
1524 }
1525
1526 if (m_supports_memory_region_info == eLazyBoolNo) {
1527 error.SetErrorString("qMemoryRegionInfo is not supported");
1528 }
Pavel Labath16064d32018-03-20 11:56:24 +00001529
1530 // Try qXfer:memory-map:read to get region information not included in
1531 // qMemoryRegionInfo
1532 MemoryRegionInfo qXfer_region_info;
1533 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1534
1535 if (error.Fail()) {
Adrian Prantl05097242018-04-30 16:49:04 +00001536 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1537 // the qXfer result as a fallback
Pavel Labath16064d32018-03-20 11:56:24 +00001538 if (qXfer_error.Success()) {
1539 region_info = qXfer_region_info;
1540 error.Clear();
1541 } else {
1542 region_info.Clear();
1543 }
1544 } else if (qXfer_error.Success()) {
1545 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
Adrian Prantl05097242018-04-30 16:49:04 +00001546 // both regions are the same range, update the result to include the flash-
1547 // memory information that is specific to the qXfer result.
Pavel Labath16064d32018-03-20 11:56:24 +00001548 if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1549 region_info.SetFlash(qXfer_region_info.GetFlash());
1550 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1551 }
1552 }
1553 return error;
1554}
1555
1556Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1557 lldb::addr_t addr, MemoryRegionInfo &region) {
1558 Status error = LoadQXferMemoryMap();
1559 if (!error.Success())
1560 return error;
1561 for (const auto &map_region : m_qXfer_memory_map) {
1562 if (map_region.GetRange().Contains(addr)) {
1563 region = map_region;
1564 return error;
1565 }
1566 }
1567 error.SetErrorString("Region not found");
1568 return error;
1569}
1570
1571Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
1572
1573 Status error;
1574
1575 if (m_qXfer_memory_map_loaded)
1576 // Already loaded, return success
1577 return error;
1578
1579 if (!XMLDocument::XMLEnabled()) {
1580 error.SetErrorString("XML is not supported");
1581 return error;
1582 }
1583
1584 if (!GetQXferMemoryMapReadSupported()) {
1585 error.SetErrorString("Memory map is not supported");
1586 return error;
1587 }
1588
1589 std::string xml;
1590 lldb_private::Status lldberr;
1591 if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
1592 lldberr)) {
1593 error.SetErrorString("Failed to read memory map");
1594 return error;
1595 }
1596
1597 XMLDocument xml_document;
1598
1599 if (!xml_document.ParseMemory(xml.c_str(), xml.size())) {
1600 error.SetErrorString("Failed to parse memory map xml");
1601 return error;
1602 }
1603
1604 XMLNode map_node = xml_document.GetRootElement("memory-map");
1605 if (!map_node) {
1606 error.SetErrorString("Invalid root node in memory map xml");
1607 return error;
1608 }
1609
1610 m_qXfer_memory_map.clear();
1611
1612 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1613 if (!memory_node.IsElement())
1614 return true;
1615 if (memory_node.GetName() != "memory")
1616 return true;
1617 auto type = memory_node.GetAttributeValue("type", "");
1618 uint64_t start;
1619 uint64_t length;
1620 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1621 return true;
1622 if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1623 return true;
1624 MemoryRegionInfo region;
1625 region.GetRange().SetRangeBase(start);
1626 region.GetRange().SetByteSize(length);
1627 if (type == "rom") {
1628 region.SetReadable(MemoryRegionInfo::eYes);
1629 this->m_qXfer_memory_map.push_back(region);
1630 } else if (type == "ram") {
1631 region.SetReadable(MemoryRegionInfo::eYes);
1632 region.SetWritable(MemoryRegionInfo::eYes);
1633 this->m_qXfer_memory_map.push_back(region);
1634 } else if (type == "flash") {
1635 region.SetFlash(MemoryRegionInfo::eYes);
1636 memory_node.ForEachChildElement(
1637 [&region](const XMLNode &prop_node) -> bool {
1638 if (!prop_node.IsElement())
1639 return true;
1640 if (prop_node.GetName() != "property")
1641 return true;
1642 auto propname = prop_node.GetAttributeValue("name", "");
1643 if (propname == "blocksize") {
1644 uint64_t blocksize;
1645 if (prop_node.GetElementTextAsUnsigned(blocksize))
1646 region.SetBlocksize(blocksize);
1647 }
1648 return true;
1649 });
1650 this->m_qXfer_memory_map.push_back(region);
1651 }
1652 return true;
1653 });
1654
1655 m_qXfer_memory_map_loaded = true;
1656
Kate Stoneb9c1b512016-09-06 20:57:50 +00001657 return error;
1658}
1659
Zachary Turner97206d52017-05-12 04:51:55 +00001660Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
1661 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001662
1663 if (m_supports_watchpoint_support_info == eLazyBoolYes) {
1664 num = m_num_supported_hardware_watchpoints;
1665 return error;
1666 }
1667
1668 // Set num to 0 first.
1669 num = 0;
1670 if (m_supports_watchpoint_support_info != eLazyBoolNo) {
1671 char packet[64];
1672 const int packet_len =
1673 ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
1674 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001675 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001676 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001677 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001678 PacketResult::Success) {
1679 m_supports_watchpoint_support_info = eLazyBoolYes;
1680 llvm::StringRef name;
1681 llvm::StringRef value;
Jason Molendac0e793d2018-11-09 22:33:26 +00001682 bool found_num_field = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001683 while (response.GetNameColonValue(name, value)) {
1684 if (name.equals("num")) {
1685 value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1686 num = m_num_supported_hardware_watchpoints;
Jason Molendac0e793d2018-11-09 22:33:26 +00001687 found_num_field = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001688 }
1689 }
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001690 if (!found_num_field) {
Jason Molendac0e793d2018-11-09 22:33:26 +00001691 m_supports_watchpoint_support_info = eLazyBoolNo;
1692 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001693 } else {
1694 m_supports_watchpoint_support_info = eLazyBoolNo;
1695 }
1696 }
1697
1698 if (m_supports_watchpoint_support_info == eLazyBoolNo) {
1699 error.SetErrorString("qWatchpointSupportInfo is not supported");
1700 }
1701 return error;
1702}
1703
Zachary Turner97206d52017-05-12 04:51:55 +00001704lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001705 uint32_t &num, bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001706 Status error(GetWatchpointSupportInfo(num));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001707 if (error.Success())
1708 error = GetWatchpointsTriggerAfterInstruction(after, arch);
1709 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001710}
1711
Zachary Turner97206d52017-05-12 04:51:55 +00001712lldb_private::Status
Kate Stoneb9c1b512016-09-06 20:57:50 +00001713GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
1714 bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001715 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001716 llvm::Triple::ArchType atype = arch.GetMachine();
Daniel Maleae0f8f572013-08-26 23:57:52 +00001717
Adrian Prantl05097242018-04-30 16:49:04 +00001718 // we assume watchpoints will happen after running the relevant opcode and we
1719 // only want to override this behavior if we have explicitly received a
1720 // qHostInfo telling us otherwise
Kate Stoneb9c1b512016-09-06 20:57:50 +00001721 if (m_qHostInfo_is_valid != eLazyBoolYes) {
Pavel Labathc51ad482017-10-27 17:02:32 +00001722 // On targets like MIPS and ppc64le, watchpoint exceptions are always
Adrian Prantl05097242018-04-30 16:49:04 +00001723 // generated before the instruction is executed. The connected target may
1724 // not support qHostInfo or qWatchpointSupportInfo packets.
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001725 after =
1726 !(atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
1727 atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
1728 atype == llvm::Triple::ppc64le);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001729 } else {
Pavel Labathc51ad482017-10-27 17:02:32 +00001730 // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to
1731 // eLazyBoolNo if it is not calculated before.
1732 if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
1733 (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
1734 atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) ||
1735 atype == llvm::Triple::ppc64le) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001736 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
Pavel Labathc51ad482017-10-27 17:02:32 +00001737 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001738
1739 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1740 }
1741 return error;
1742}
1743
1744int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
1745 if (file_spec) {
1746 std::string path{file_spec.GetPath(false)};
1747 StreamString packet;
1748 packet.PutCString("QSetSTDIN:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001749 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001750
1751 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001752 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1753 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001754 if (response.IsOKResponse())
1755 return 0;
1756 uint8_t error = response.GetError();
1757 if (error)
1758 return error;
1759 }
1760 }
1761 return -1;
1762}
1763
1764int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
1765 if (file_spec) {
1766 std::string path{file_spec.GetPath(false)};
1767 StreamString packet;
1768 packet.PutCString("QSetSTDOUT:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001769 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001770
1771 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001772 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1773 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001774 if (response.IsOKResponse())
1775 return 0;
1776 uint8_t error = response.GetError();
1777 if (error)
1778 return error;
1779 }
1780 }
1781 return -1;
1782}
1783
1784int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
1785 if (file_spec) {
1786 std::string path{file_spec.GetPath(false)};
1787 StreamString packet;
1788 packet.PutCString("QSetSTDERR:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001789 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001790
1791 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001792 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1793 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001794 if (response.IsOKResponse())
1795 return 0;
1796 uint8_t error = response.GetError();
1797 if (error)
1798 return error;
1799 }
1800 }
1801 return -1;
1802}
1803
1804bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
1805 StringExtractorGDBRemote response;
1806 if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
1807 PacketResult::Success) {
1808 if (response.IsUnsupportedResponse())
1809 return false;
1810 if (response.IsErrorResponse())
1811 return false;
1812 std::string cwd;
1813 response.GetHexByteString(cwd);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00001814 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001815 return !cwd.empty();
1816 }
1817 return false;
1818}
1819
1820int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
1821 if (working_dir) {
1822 std::string path{working_dir.GetPath(false)};
1823 StreamString packet;
1824 packet.PutCString("QSetWorkingDir:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001825 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001826
1827 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001828 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1829 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001830 if (response.IsOKResponse())
1831 return 0;
1832 uint8_t error = response.GetError();
1833 if (error)
1834 return error;
1835 }
1836 }
1837 return -1;
1838}
1839
1840int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
1841 char packet[32];
1842 const int packet_len =
1843 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1844 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001845 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001846 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001847 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001848 PacketResult::Success) {
1849 if (response.IsOKResponse())
1850 return 0;
1851 uint8_t error = response.GetError();
1852 if (error)
1853 return error;
1854 }
1855 return -1;
1856}
1857
1858int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
1859 char packet[32];
1860 const int packet_len = ::snprintf(packet, sizeof(packet),
1861 "QSetDetachOnError:%i", enable ? 1 : 0);
1862 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001863 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001864 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001865 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001866 PacketResult::Success) {
1867 if (response.IsOKResponse())
1868 return 0;
1869 uint8_t error = response.GetError();
1870 if (error)
1871 return error;
1872 }
1873 return -1;
1874}
1875
1876bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
1877 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
1878 if (response.IsNormalResponse()) {
1879 llvm::StringRef name;
1880 llvm::StringRef value;
1881 StringExtractor extractor;
1882
1883 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1884 uint32_t sub = 0;
1885 std::string vendor;
1886 std::string os_type;
1887
1888 while (response.GetNameColonValue(name, value)) {
1889 if (name.equals("pid")) {
1890 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1891 value.getAsInteger(0, pid);
1892 process_info.SetProcessID(pid);
1893 } else if (name.equals("ppid")) {
1894 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1895 value.getAsInteger(0, pid);
1896 process_info.SetParentProcessID(pid);
1897 } else if (name.equals("uid")) {
1898 uint32_t uid = UINT32_MAX;
1899 value.getAsInteger(0, uid);
1900 process_info.SetUserID(uid);
1901 } else if (name.equals("euid")) {
1902 uint32_t uid = UINT32_MAX;
1903 value.getAsInteger(0, uid);
1904 process_info.SetEffectiveGroupID(uid);
1905 } else if (name.equals("gid")) {
1906 uint32_t gid = UINT32_MAX;
1907 value.getAsInteger(0, gid);
1908 process_info.SetGroupID(gid);
1909 } else if (name.equals("egid")) {
1910 uint32_t gid = UINT32_MAX;
1911 value.getAsInteger(0, gid);
1912 process_info.SetEffectiveGroupID(gid);
1913 } else if (name.equals("triple")) {
1914 StringExtractor extractor(value);
1915 std::string triple;
1916 extractor.GetHexByteString(triple);
1917 process_info.GetArchitecture().SetTriple(triple.c_str());
1918 } else if (name.equals("name")) {
1919 StringExtractor extractor(value);
Adrian Prantl05097242018-04-30 16:49:04 +00001920 // The process name from ASCII hex bytes since we can't control the
1921 // characters in a process name
Kate Stoneb9c1b512016-09-06 20:57:50 +00001922 std::string name;
1923 extractor.GetHexByteString(name);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00001924 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001925 } else if (name.equals("cputype")) {
1926 value.getAsInteger(0, cpu);
1927 } else if (name.equals("cpusubtype")) {
1928 value.getAsInteger(0, sub);
1929 } else if (name.equals("vendor")) {
1930 vendor = value;
1931 } else if (name.equals("ostype")) {
1932 os_type = value;
1933 }
1934 }
1935
1936 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
1937 if (vendor == "apple") {
1938 process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
1939 sub);
1940 process_info.GetArchitecture().GetTriple().setVendorName(
1941 llvm::StringRef(vendor));
1942 process_info.GetArchitecture().GetTriple().setOSName(
1943 llvm::StringRef(os_type));
1944 }
1945 }
1946
1947 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1948 return true;
1949 }
1950 return false;
1951}
1952
1953bool GDBRemoteCommunicationClient::GetProcessInfo(
1954 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
1955 process_info.Clear();
1956
1957 if (m_supports_qProcessInfoPID) {
1958 char packet[32];
1959 const int packet_len =
1960 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
1961 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001962 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001963 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001964 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001965 PacketResult::Success) {
1966 return DecodeProcessInfoResponse(response, process_info);
1967 } else {
1968 m_supports_qProcessInfoPID = false;
1969 return false;
1970 }
1971 }
1972 return false;
1973}
1974
1975bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
1976 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
1977 GDBR_LOG_PACKETS));
1978
1979 if (allow_lazy) {
1980 if (m_qProcessInfo_is_valid == eLazyBoolYes)
1981 return true;
1982 if (m_qProcessInfo_is_valid == eLazyBoolNo)
1983 return false;
1984 }
1985
1986 GetHostInfo();
1987
1988 StringExtractorGDBRemote response;
1989 if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
1990 PacketResult::Success) {
1991 if (response.IsNormalResponse()) {
1992 llvm::StringRef name;
1993 llvm::StringRef value;
1994 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1995 uint32_t sub = 0;
1996 std::string arch_name;
1997 std::string os_name;
1998 std::string vendor_name;
1999 std::string triple;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002000 std::string elf_abi;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002001 uint32_t pointer_byte_size = 0;
2002 StringExtractor extractor;
2003 ByteOrder byte_order = eByteOrderInvalid;
2004 uint32_t num_keys_decoded = 0;
2005 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
2006 while (response.GetNameColonValue(name, value)) {
2007 if (name.equals("cputype")) {
2008 if (!value.getAsInteger(16, cpu))
2009 ++num_keys_decoded;
2010 } else if (name.equals("cpusubtype")) {
2011 if (!value.getAsInteger(16, sub))
2012 ++num_keys_decoded;
2013 } else if (name.equals("triple")) {
2014 StringExtractor extractor(value);
2015 extractor.GetHexByteString(triple);
2016 ++num_keys_decoded;
2017 } else if (name.equals("ostype")) {
2018 os_name = value;
2019 ++num_keys_decoded;
2020 } else if (name.equals("vendor")) {
2021 vendor_name = value;
2022 ++num_keys_decoded;
2023 } else if (name.equals("endian")) {
2024 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2025 .Case("little", eByteOrderLittle)
2026 .Case("big", eByteOrderBig)
2027 .Case("pdp", eByteOrderPDP)
2028 .Default(eByteOrderInvalid);
2029 if (byte_order != eByteOrderInvalid)
2030 ++num_keys_decoded;
2031 } else if (name.equals("ptrsize")) {
2032 if (!value.getAsInteger(16, pointer_byte_size))
2033 ++num_keys_decoded;
2034 } else if (name.equals("pid")) {
2035 if (!value.getAsInteger(16, pid))
2036 ++num_keys_decoded;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002037 } else if (name.equals("elf_abi")) {
2038 elf_abi = value;
2039 ++num_keys_decoded;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002040 }
2041 }
2042 if (num_keys_decoded > 0)
2043 m_qProcessInfo_is_valid = eLazyBoolYes;
2044 if (pid != LLDB_INVALID_PROCESS_ID) {
2045 m_curr_pid_is_valid = eLazyBoolYes;
2046 m_curr_pid = pid;
2047 }
2048
2049 // Set the ArchSpec from the triple if we have it.
2050 if (!triple.empty()) {
2051 m_process_arch.SetTriple(triple.c_str());
Nitesh Jain8999edf2016-10-12 10:21:09 +00002052 m_process_arch.SetFlags(elf_abi);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002053 if (pointer_byte_size) {
2054 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2055 }
2056 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2057 !vendor_name.empty()) {
2058 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2059
2060 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
Pavel Labath4f19fce22017-02-17 13:39:50 +00002061 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
Jason Liua03ae732019-03-12 22:01:10 +00002062 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002063 switch (triple.getObjectFormat()) {
2064 case llvm::Triple::MachO:
2065 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2066 break;
2067 case llvm::Triple::ELF:
2068 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2069 break;
2070 case llvm::Triple::COFF:
2071 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2072 break;
Pavel Labath4f19fce22017-02-17 13:39:50 +00002073 case llvm::Triple::Wasm:
Jason Liua03ae732019-03-12 22:01:10 +00002074 case llvm::Triple::XCOFF:
Pavel Labath4f19fce22017-02-17 13:39:50 +00002075 if (log)
2076 log->Printf("error: not supported target architecture");
2077 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002078 case llvm::Triple::UnknownObjectFormat:
2079 if (log)
2080 log->Printf("error: failed to determine target architecture");
2081 return false;
2082 }
2083
2084 if (pointer_byte_size) {
2085 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2086 }
2087 if (byte_order != eByteOrderInvalid) {
2088 assert(byte_order == m_process_arch.GetByteOrder());
2089 }
2090 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2091 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2092 m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2093 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2094 }
2095 return true;
2096 }
2097 } else {
2098 m_qProcessInfo_is_valid = eLazyBoolNo;
2099 }
2100
2101 return false;
2102}
2103
2104uint32_t GDBRemoteCommunicationClient::FindProcesses(
2105 const ProcessInstanceInfoMatch &match_info,
2106 ProcessInstanceInfoList &process_infos) {
2107 process_infos.Clear();
2108
2109 if (m_supports_qfProcessInfo) {
2110 StreamString packet;
2111 packet.PutCString("qfProcessInfo");
2112 if (!match_info.MatchAllProcesses()) {
2113 packet.PutChar(':');
2114 const char *name = match_info.GetProcessInfo().GetName();
2115 bool has_name_match = false;
2116 if (name && name[0]) {
2117 has_name_match = true;
Pavel Labathc4a33952017-02-20 11:35:33 +00002118 NameMatch name_match_type = match_info.GetNameMatchType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002119 switch (name_match_type) {
Pavel Labathc4a33952017-02-20 11:35:33 +00002120 case NameMatch::Ignore:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002121 has_name_match = false;
2122 break;
2123
Pavel Labathc4a33952017-02-20 11:35:33 +00002124 case NameMatch::Equals:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002125 packet.PutCString("name_match:equals;");
2126 break;
2127
Pavel Labathc4a33952017-02-20 11:35:33 +00002128 case NameMatch::Contains:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002129 packet.PutCString("name_match:contains;");
2130 break;
2131
Pavel Labathc4a33952017-02-20 11:35:33 +00002132 case NameMatch::StartsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002133 packet.PutCString("name_match:starts_with;");
2134 break;
2135
Pavel Labathc4a33952017-02-20 11:35:33 +00002136 case NameMatch::EndsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002137 packet.PutCString("name_match:ends_with;");
2138 break;
2139
Pavel Labathc4a33952017-02-20 11:35:33 +00002140 case NameMatch::RegularExpression:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002141 packet.PutCString("name_match:regex;");
2142 break;
2143 }
2144 if (has_name_match) {
2145 packet.PutCString("name:");
2146 packet.PutBytesAsRawHex8(name, ::strlen(name));
2147 packet.PutChar(';');
2148 }
2149 }
2150
2151 if (match_info.GetProcessInfo().ProcessIDIsValid())
2152 packet.Printf("pid:%" PRIu64 ";",
2153 match_info.GetProcessInfo().GetProcessID());
2154 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2155 packet.Printf("parent_pid:%" PRIu64 ";",
2156 match_info.GetProcessInfo().GetParentProcessID());
2157 if (match_info.GetProcessInfo().UserIDIsValid())
2158 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2159 if (match_info.GetProcessInfo().GroupIDIsValid())
2160 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2161 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2162 packet.Printf("euid:%u;",
2163 match_info.GetProcessInfo().GetEffectiveUserID());
2164 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2165 packet.Printf("egid:%u;",
2166 match_info.GetProcessInfo().GetEffectiveGroupID());
2167 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2168 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
2169 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2170 const ArchSpec &match_arch =
2171 match_info.GetProcessInfo().GetArchitecture();
2172 const llvm::Triple &triple = match_arch.GetTriple();
2173 packet.PutCString("triple:");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00002174 packet.PutCString(triple.getTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002175 packet.PutChar(';');
2176 }
2177 }
2178 StringExtractorGDBRemote response;
Adrian Prantl05097242018-04-30 16:49:04 +00002179 // Increase timeout as the first qfProcessInfo packet takes a long time on
2180 // Android. The value of 1min was arrived at empirically.
Pavel Labath1eff73c2016-11-24 10:54:49 +00002181 ScopedTimeout timeout(*this, minutes(1));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002182 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2183 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002184 do {
2185 ProcessInstanceInfo process_info;
2186 if (!DecodeProcessInfoResponse(response, process_info))
2187 break;
2188 process_infos.Append(process_info);
2189 response.GetStringRef().clear();
2190 response.SetFilePos(0);
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002191 } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
2192 PacketResult::Success);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002193 } else {
2194 m_supports_qfProcessInfo = false;
2195 return 0;
2196 }
2197 }
2198 return process_infos.GetSize();
2199}
2200
2201bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
2202 std::string &name) {
2203 if (m_supports_qUserName) {
2204 char packet[32];
2205 const int packet_len =
2206 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2207 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002208 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002209 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002210 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002211 PacketResult::Success) {
2212 if (response.IsNormalResponse()) {
2213 // Make sure we parsed the right number of characters. The response is
Adrian Prantl05097242018-04-30 16:49:04 +00002214 // the hex encoded user name and should make up the entire packet. If
2215 // there are any non-hex ASCII bytes, the length won't match below..
Kate Stoneb9c1b512016-09-06 20:57:50 +00002216 if (response.GetHexByteString(name) * 2 ==
2217 response.GetStringRef().size())
2218 return true;
2219 }
2220 } else {
2221 m_supports_qUserName = false;
2222 return false;
2223 }
2224 }
2225 return false;
2226}
2227
2228bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
2229 std::string &name) {
2230 if (m_supports_qGroupName) {
2231 char packet[32];
2232 const int packet_len =
2233 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2234 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002235 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002236 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002237 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002238 PacketResult::Success) {
2239 if (response.IsNormalResponse()) {
2240 // Make sure we parsed the right number of characters. The response is
Adrian Prantl05097242018-04-30 16:49:04 +00002241 // the hex encoded group name and should make up the entire packet. If
2242 // there are any non-hex ASCII bytes, the length won't match below..
Kate Stoneb9c1b512016-09-06 20:57:50 +00002243 if (response.GetHexByteString(name) * 2 ==
2244 response.GetStringRef().size())
2245 return true;
2246 }
2247 } else {
2248 m_supports_qGroupName = false;
2249 return false;
2250 }
2251 }
2252 return false;
2253}
2254
2255bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
2256 // Form non-stop packet request
2257 char packet[32];
2258 const int packet_len =
2259 ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
2260 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002261 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002262
2263 StringExtractorGDBRemote response;
2264 // Send to target
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002265 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002266 PacketResult::Success)
2267 if (response.IsOKResponse())
2268 return true;
2269
2270 // Failed or not supported
2271 return false;
2272}
2273
2274static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2275 uint32_t recv_size) {
2276 packet.Clear();
2277 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2278 uint32_t bytes_left = send_size;
2279 while (bytes_left > 0) {
2280 if (bytes_left >= 26) {
2281 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2282 bytes_left -= 26;
2283 } else {
2284 packet.Printf("%*.*s;", bytes_left, bytes_left,
2285 "abcdefghijklmnopqrstuvwxyz");
2286 bytes_left = 0;
2287 }
2288 }
2289}
2290
Pavel Labath1eff73c2016-11-24 10:54:49 +00002291duration<float>
2292calculate_standard_deviation(const std::vector<duration<float>> &v) {
2293 using Dur = duration<float>;
Pavel Labath3aa04912016-10-31 17:19:42 +00002294 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2295 Dur mean = sum / v.size();
2296 float accum = 0;
2297 for (auto d : v) {
2298 float delta = (d - mean).count();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002299 accum += delta * delta;
Pavel Labath3aa04912016-10-31 17:19:42 +00002300 };
Kate Stoneb9c1b512016-09-06 20:57:50 +00002301
Pavel Labath3aa04912016-10-31 17:19:42 +00002302 return Dur(sqrtf(accum / (v.size() - 1)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002303}
2304
2305void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
2306 uint32_t max_send,
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002307 uint32_t max_recv,
2308 uint64_t recv_amount,
2309 bool json, Stream &strm) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002310 uint32_t i;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002311 if (SendSpeedTestPacket(0, 0)) {
2312 StreamString packet;
2313 if (json)
2314 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2315 "\"results\" : [",
2316 num_packets);
2317 else
2318 strm.Printf("Testing sending %u packets of various sizes:\n",
2319 num_packets);
2320 strm.Flush();
2321
2322 uint32_t result_idx = 0;
2323 uint32_t send_size;
Pavel Labath3aa04912016-10-31 17:19:42 +00002324 std::vector<duration<float>> packet_times;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002325
2326 for (send_size = 0; send_size <= max_send;
2327 send_size ? send_size *= 2 : send_size = 4) {
2328 for (uint32_t recv_size = 0; recv_size <= max_recv;
2329 recv_size ? recv_size *= 2 : recv_size = 4) {
2330 MakeSpeedTestPacket(packet, send_size, recv_size);
2331
2332 packet_times.clear();
2333 // Test how long it takes to send 'num_packets' packets
Pavel Labath3aa04912016-10-31 17:19:42 +00002334 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002335 for (i = 0; i < num_packets; ++i) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002336 const auto packet_start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002337 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002338 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Pavel Labath3aa04912016-10-31 17:19:42 +00002339 const auto packet_end_time = steady_clock::now();
2340 packet_times.push_back(packet_end_time - packet_start_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002341 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002342 const auto end_time = steady_clock::now();
2343 const auto total_time = end_time - start_time;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002344
2345 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002346 ((float)num_packets) / duration<float>(total_time).count();
2347 auto average_per_packet = total_time / num_packets;
2348 const duration<float> standard_deviation =
2349 calculate_standard_deviation(packet_times);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002350 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002351 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2352 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2353 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002354 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002355 total_time, standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002356 ++result_idx;
2357 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002358 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2359 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2360 "standard deviation of {5,10:ms+f6}\n",
2361 send_size, recv_size, duration<float>(total_time),
2362 packets_per_second, duration<float>(average_per_packet),
2363 standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002364 }
2365 strm.Flush();
2366 }
2367 }
2368
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002369 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002370 if (json)
2371 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2372 ": %" PRIu64 ",\n \"results\" : [",
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002373 recv_amount);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002374 else
2375 strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2376 "packet sizes:\n",
2377 k_recv_amount_mb);
2378 strm.Flush();
2379 send_size = 0;
2380 result_idx = 0;
2381 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2382 MakeSpeedTestPacket(packet, send_size, recv_size);
2383
2384 // If we have a receive size, test how long it takes to receive 4MB of
2385 // data
2386 if (recv_size > 0) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002387 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002388 uint32_t bytes_read = 0;
2389 uint32_t packet_count = 0;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002390 while (bytes_read < recv_amount) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002391 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002392 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393 bytes_read += recv_size;
2394 ++packet_count;
2395 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002396 const auto end_time = steady_clock::now();
2397 const auto total_time = end_time - start_time;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002398 float mb_second = ((float)recv_amount) /
Pavel Labath3aa04912016-10-31 17:19:42 +00002399 duration<float>(total_time).count() /
Kate Stoneb9c1b512016-09-06 20:57:50 +00002400 (1024.0 * 1024.0);
2401 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002402 ((float)packet_count) / duration<float>(total_time).count();
2403 const auto average_per_packet = total_time / packet_count;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002404
2405 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002406 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2407 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002408 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002409 total_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002410 ++result_idx;
2411 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002412 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2413 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2414 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002415 send_size, recv_size, packet_count, k_recv_amount_mb,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002416 duration<float>(total_time), mb_second,
2417 packets_per_second, duration<float>(average_per_packet));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002418 }
2419 strm.Flush();
2420 }
2421 }
2422 if (json)
2423 strm.Printf("\n ]\n }\n}\n");
2424 else
2425 strm.EOL();
2426 }
2427}
2428
2429bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
2430 uint32_t recv_size) {
2431 StreamString packet;
2432 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2433 uint32_t bytes_left = send_size;
2434 while (bytes_left > 0) {
2435 if (bytes_left >= 26) {
2436 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2437 bytes_left -= 26;
2438 } else {
2439 packet.Printf("%*.*s;", bytes_left, bytes_left,
2440 "abcdefghijklmnopqrstuvwxyz");
2441 bytes_left = 0;
2442 }
2443 }
2444
2445 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002446 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2447 PacketResult::Success;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002448}
2449
2450bool GDBRemoteCommunicationClient::LaunchGDBServer(
2451 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2452 std::string &socket_name) {
2453 pid = LLDB_INVALID_PROCESS_ID;
2454 port = 0;
2455 socket_name.clear();
2456
2457 StringExtractorGDBRemote response;
2458 StreamString stream;
2459 stream.PutCString("qLaunchGDBServer;");
2460 std::string hostname;
2461 if (remote_accept_hostname && remote_accept_hostname[0])
2462 hostname = remote_accept_hostname;
2463 else {
2464 if (HostInfo::GetHostname(hostname)) {
2465 // Make the GDB server we launch only accept connections from this host
2466 stream.Printf("host:%s;", hostname.c_str());
2467 } else {
Adrian Prantl05097242018-04-30 16:49:04 +00002468 // Make the GDB server we launch accept connections from any host since
2469 // we can't figure out the hostname
Kate Stoneb9c1b512016-09-06 20:57:50 +00002470 stream.Printf("host:*;");
2471 }
2472 }
2473 // give the process a few seconds to startup
Pavel Labath1eff73c2016-11-24 10:54:49 +00002474 ScopedTimeout timeout(*this, seconds(10));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002475
2476 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2477 PacketResult::Success) {
2478 llvm::StringRef name;
2479 llvm::StringRef value;
2480 while (response.GetNameColonValue(name, value)) {
2481 if (name.equals("port"))
2482 value.getAsInteger(0, port);
2483 else if (name.equals("pid"))
2484 value.getAsInteger(0, pid);
2485 else if (name.compare("socket_name") == 0) {
2486 StringExtractor extractor(value);
2487 extractor.GetHexByteString(socket_name);
2488 }
2489 }
2490 return true;
2491 }
2492 return false;
2493}
2494
2495size_t GDBRemoteCommunicationClient::QueryGDBServer(
2496 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2497 connection_urls.clear();
2498
2499 StringExtractorGDBRemote response;
2500 if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
2501 PacketResult::Success)
2502 return 0;
2503
2504 StructuredData::ObjectSP data =
2505 StructuredData::ParseJSON(response.GetStringRef());
2506 if (!data)
2507 return 0;
2508
2509 StructuredData::Array *array = data->GetAsArray();
2510 if (!array)
2511 return 0;
2512
2513 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2514 StructuredData::Dictionary *element = nullptr;
2515 if (!array->GetItemAtIndexAsDictionary(i, element))
2516 continue;
2517
2518 uint16_t port = 0;
2519 if (StructuredData::ObjectSP port_osp =
2520 element->GetValueForKey(llvm::StringRef("port")))
2521 port = port_osp->GetIntegerValue(0);
2522
2523 std::string socket_name;
2524 if (StructuredData::ObjectSP socket_name_osp =
2525 element->GetValueForKey(llvm::StringRef("socket_name")))
2526 socket_name = socket_name_osp->GetStringValue();
2527
2528 if (port != 0 || !socket_name.empty())
2529 connection_urls.emplace_back(port, socket_name);
2530 }
2531 return connection_urls.size();
2532}
2533
2534bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
2535 StreamString stream;
2536 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002537
2538 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002539 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002540 PacketResult::Success) {
2541 if (response.IsOKResponse())
2542 return true;
2543 }
2544 return false;
2545}
2546
2547bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
2548 if (m_curr_tid == tid)
2549 return true;
2550
2551 char packet[32];
2552 int packet_len;
2553 if (tid == UINT64_MAX)
2554 packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
2555 else
2556 packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
2557 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002558 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002559 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002560 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002561 PacketResult::Success) {
2562 if (response.IsOKResponse()) {
2563 m_curr_tid = tid;
2564 return true;
2565 }
2566
2567 /*
2568 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2569 * Hg packet.
2570 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2571 * which can
2572 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2573 */
2574 if (response.IsUnsupportedResponse() && IsConnected()) {
2575 m_curr_tid = 1;
2576 return true;
2577 }
2578 }
2579 return false;
2580}
2581
2582bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
2583 if (m_curr_tid_run == tid)
2584 return true;
2585
2586 char packet[32];
2587 int packet_len;
2588 if (tid == UINT64_MAX)
2589 packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
2590 else
2591 packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
2592
2593 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002594 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002595 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002596 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002597 PacketResult::Success) {
2598 if (response.IsOKResponse()) {
2599 m_curr_tid_run = tid;
2600 return true;
2601 }
2602
2603 /*
2604 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2605 * Hc packet.
2606 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2607 * which can
2608 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2609 */
2610 if (response.IsUnsupportedResponse() && IsConnected()) {
2611 m_curr_tid_run = 1;
2612 return true;
2613 }
2614 }
2615 return false;
2616}
2617
2618bool GDBRemoteCommunicationClient::GetStopReply(
2619 StringExtractorGDBRemote &response) {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002620 if (SendPacketAndWaitForResponse("?", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002621 PacketResult::Success)
2622 return response.IsNormalResponse();
2623 return false;
2624}
2625
2626bool GDBRemoteCommunicationClient::GetThreadStopInfo(
2627 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2628 if (m_supports_qThreadStopInfo) {
2629 char packet[256];
2630 int packet_len =
2631 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2632 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002633 UNUSED_IF_ASSERT_DISABLED(packet_len);
2634 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002635 PacketResult::Success) {
2636 if (response.IsUnsupportedResponse())
2637 m_supports_qThreadStopInfo = false;
2638 else if (response.IsNormalResponse())
2639 return true;
2640 else
2641 return false;
2642 } else {
2643 m_supports_qThreadStopInfo = false;
2644 }
2645 }
2646 return false;
2647}
2648
2649uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2650 GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
2651 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
2652 if (log)
2653 log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2654 __FUNCTION__, insert ? "add" : "remove", addr);
2655
2656 // Check if the stub is known not to support this breakpoint type
2657 if (!SupportsGDBStoppointPacket(type))
2658 return UINT8_MAX;
2659 // Construct the breakpoint packet
2660 char packet[64];
2661 const int packet_len =
2662 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
2663 insert ? 'Z' : 'z', type, addr, length);
2664 // Check we haven't overwritten the end of the packet buffer
2665 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002666 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002667 StringExtractorGDBRemote response;
2668 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2669 // or "" (unsupported)
2670 response.SetResponseValidatorToOKErrorNotSupported();
2671 // Try to send the breakpoint packet, and check that it was correctly sent
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002672 if (SendPacketAndWaitForResponse(packet, response, true) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002673 PacketResult::Success) {
2674 // Receive and OK packet when the breakpoint successfully placed
2675 if (response.IsOKResponse())
2676 return 0;
2677
Zachary Turner97206d52017-05-12 04:51:55 +00002678 // Status while setting breakpoint, send back specific error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002679 if (response.IsErrorResponse())
2680 return response.GetError();
2681
2682 // Empty packet informs us that breakpoint is not supported
2683 if (response.IsUnsupportedResponse()) {
2684 // Disable this breakpoint type since it is unsupported
2685 switch (type) {
2686 case eBreakpointSoftware:
2687 m_supports_z0 = false;
2688 break;
2689 case eBreakpointHardware:
2690 m_supports_z1 = false;
2691 break;
2692 case eWatchpointWrite:
2693 m_supports_z2 = false;
2694 break;
2695 case eWatchpointRead:
2696 m_supports_z3 = false;
2697 break;
2698 case eWatchpointReadWrite:
2699 m_supports_z4 = false;
2700 break;
2701 case eStoppointInvalid:
2702 return UINT8_MAX;
2703 }
2704 }
2705 }
2706 // Signal generic failure
2707 return UINT8_MAX;
2708}
2709
2710size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2711 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
2712 thread_ids.clear();
2713
2714 Lock lock(*this, false);
2715 if (lock) {
2716 sequence_mutex_unavailable = false;
2717 StringExtractorGDBRemote response;
2718
2719 PacketResult packet_result;
2720 for (packet_result =
2721 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
2722 packet_result == PacketResult::Success && response.IsNormalResponse();
2723 packet_result =
2724 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
2725 char ch = response.GetChar();
2726 if (ch == 'l')
2727 break;
2728 if (ch == 'm') {
2729 do {
2730 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
2731
2732 if (tid != LLDB_INVALID_THREAD_ID) {
2733 thread_ids.push_back(tid);
2734 }
2735 ch = response.GetChar(); // Skip the command separator
2736 } while (ch == ','); // Make sure we got a comma separator
2737 }
2738 }
2739
2740 /*
2741 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2742 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2743 * could
2744 * be as simple as 'S05'. There is no packet which can give us pid and/or
2745 * tid.
2746 * Assume pid=tid=1 in such cases.
2747 */
Tamas Berghammer1492cb82017-09-18 10:24:48 +00002748 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
2749 thread_ids.size() == 0 && IsConnected()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002750 thread_ids.push_back(1);
2751 }
2752 } else {
David Blaikiea322f362017-01-06 00:38:06 +00002753#if !defined(LLDB_CONFIGURATION_DEBUG)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002754 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2755 GDBR_LOG_PACKETS));
2756 if (log)
2757 log->Printf("error: failed to get packet sequence mutex, not sending "
2758 "packet 'qfThreadInfo'");
2759#endif
2760 sequence_mutex_unavailable = true;
2761 }
2762 return thread_ids.size();
2763}
2764
2765lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
2766 StringExtractorGDBRemote response;
2767 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
2768 PacketResult::Success ||
2769 !response.IsNormalResponse())
2770 return LLDB_INVALID_ADDRESS;
2771 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2772}
2773
Zachary Turner97206d52017-05-12 04:51:55 +00002774lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002775 const char *command, // Shouldn't be NULL
2776 const FileSpec &
2777 working_dir, // Pass empty FileSpec to use the current working directory
2778 int *status_ptr, // Pass NULL if you don't want the process exit status
2779 int *signo_ptr, // Pass NULL if you don't want the signal that caused the
2780 // process to exit
2781 std::string
2782 *command_output, // Pass NULL if you don't want the command output
Pavel Labath19dd1a02018-05-10 10:46:03 +00002783 const Timeout<std::micro> &timeout) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002784 lldb_private::StreamString stream;
2785 stream.PutCString("qPlatform_shell:");
2786 stream.PutBytesAsRawHex8(command, strlen(command));
2787 stream.PutChar(',');
Pavel Labath19dd1a02018-05-10 10:46:03 +00002788 uint32_t timeout_sec = UINT32_MAX;
2789 if (timeout) {
2790 // TODO: Use chrono version of std::ceil once c++17 is available.
2791 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2792 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002793 stream.PutHex32(timeout_sec);
2794 if (working_dir) {
2795 std::string path{working_dir.GetPath(false)};
2796 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00002797 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002798 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002799 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002800 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002801 PacketResult::Success) {
2802 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002803 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002804 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002805 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002806 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2807 if (exitcode == UINT32_MAX)
Zachary Turner97206d52017-05-12 04:51:55 +00002808 return Status("unable to run remote process");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002809 else if (status_ptr)
2810 *status_ptr = exitcode;
2811 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002812 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002813 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2814 if (signo_ptr)
2815 *signo_ptr = signo;
2816 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002817 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002818 std::string output;
2819 response.GetEscapedBinaryData(output);
2820 if (command_output)
2821 command_output->assign(output);
Zachary Turner97206d52017-05-12 04:51:55 +00002822 return Status();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002823 }
Zachary Turner97206d52017-05-12 04:51:55 +00002824 return Status("unable to send packet");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002825}
2826
Zachary Turner97206d52017-05-12 04:51:55 +00002827Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
2828 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002829 std::string path{file_spec.GetPath(false)};
2830 lldb_private::StreamString stream;
2831 stream.PutCString("qPlatform_mkdir:");
2832 stream.PutHex32(file_permissions);
2833 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00002834 stream.PutStringAsRawHex8(path);
Zachary Turnerc1564272016-11-16 21:15:24 +00002835 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002836 StringExtractorGDBRemote response;
2837
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002838 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002839 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002840 return Status("failed to send '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002841
2842 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002843 return Status("invalid response to '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002844
Zachary Turner97206d52017-05-12 04:51:55 +00002845 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002846}
2847
Zachary Turner97206d52017-05-12 04:51:55 +00002848Status
2849GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
2850 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002851 std::string path{file_spec.GetPath(false)};
2852 lldb_private::StreamString stream;
2853 stream.PutCString("qPlatform_chmod:");
2854 stream.PutHex32(file_permissions);
2855 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00002856 stream.PutStringAsRawHex8(path);
Zachary Turnerc1564272016-11-16 21:15:24 +00002857 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002858 StringExtractorGDBRemote response;
2859
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002860 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002861 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002862 return Status("failed to send '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002863
2864 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002865 return Status("invalid response to '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002866
Zachary Turner97206d52017-05-12 04:51:55 +00002867 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002868}
2869
2870static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
Zachary Turner97206d52017-05-12 04:51:55 +00002871 uint64_t fail_result, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002872 response.SetFilePos(0);
2873 if (response.GetChar() != 'F')
2874 return fail_result;
2875 int32_t result = response.GetS32(-2);
2876 if (result == -2)
2877 return fail_result;
2878 if (response.GetChar() == ',') {
2879 int result_errno = response.GetS32(-2);
2880 if (result_errno != -2)
2881 error.SetError(result_errno, eErrorTypePOSIX);
2882 else
2883 error.SetError(-1, eErrorTypeGeneric);
2884 } else
2885 error.Clear();
2886 return result;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002887}
2888lldb::user_id_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00002889GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
2890 uint32_t flags, mode_t mode,
Zachary Turner97206d52017-05-12 04:51:55 +00002891 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002892 std::string path(file_spec.GetPath(false));
2893 lldb_private::StreamString stream;
2894 stream.PutCString("vFile:open:");
2895 if (path.empty())
Daniel Maleae0f8f572013-08-26 23:57:52 +00002896 return UINT64_MAX;
Pavel Labath7f815a92019-02-12 14:28:55 +00002897 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002898 stream.PutChar(',');
2899 stream.PutHex32(flags);
2900 stream.PutChar(',');
2901 stream.PutHex32(mode);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002902 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002903 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002904 PacketResult::Success) {
2905 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
2906 }
2907 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002908}
2909
Zachary Turner97206d52017-05-12 04:51:55 +00002910bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
2911 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002912 lldb_private::StreamString stream;
2913 stream.Printf("vFile:close:%i", (int)fd);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002914 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002915 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002916 PacketResult::Success) {
2917 return ParseHostIOPacketResponse(response, -1, error) == 0;
2918 }
2919 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002920}
2921
2922// Extension of host I/O packets to get the file size.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002923lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
2924 const lldb_private::FileSpec &file_spec) {
2925 std::string path(file_spec.GetPath(false));
2926 lldb_private::StreamString stream;
2927 stream.PutCString("vFile:size:");
Pavel Labath7f815a92019-02-12 14:28:55 +00002928 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002929 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002930 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002931 PacketResult::Success) {
2932 if (response.GetChar() != 'F')
2933 return UINT64_MAX;
2934 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2935 return retcode;
2936 }
2937 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002938}
2939
Zachary Turner97206d52017-05-12 04:51:55 +00002940Status
2941GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
2942 uint32_t &file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002943 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00002944 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002945 lldb_private::StreamString stream;
2946 stream.PutCString("vFile:mode:");
Pavel Labath7f815a92019-02-12 14:28:55 +00002947 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002948 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002949 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002950 PacketResult::Success) {
2951 if (response.GetChar() != 'F') {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002952 error.SetErrorStringWithFormat("invalid response to '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00002953 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002954 } else {
2955 const uint32_t mode = response.GetS32(-1);
2956 if (static_cast<int32_t>(mode) == -1) {
2957 if (response.GetChar() == ',') {
2958 int response_errno = response.GetS32(-1);
2959 if (response_errno > 0)
2960 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2961 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00002962 error.SetErrorToGenericError();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002963 } else
2964 error.SetErrorToGenericError();
2965 } else {
2966 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
2967 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002968 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002969 } else {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002970 error.SetErrorStringWithFormat("failed to send '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00002971 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002972 }
2973 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002974}
2975
Kate Stoneb9c1b512016-09-06 20:57:50 +00002976uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
2977 uint64_t offset, void *dst,
2978 uint64_t dst_len,
Zachary Turner97206d52017-05-12 04:51:55 +00002979 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002980 lldb_private::StreamString stream;
2981 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
2982 offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002983 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002984 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002985 PacketResult::Success) {
2986 if (response.GetChar() != 'F')
2987 return 0;
2988 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
2989 if (retcode == UINT32_MAX)
2990 return retcode;
2991 const char next = (response.Peek() ? *response.Peek() : 0);
2992 if (next == ',')
2993 return 0;
2994 if (next == ';') {
2995 response.GetChar(); // skip the semicolon
2996 std::string buffer;
2997 if (response.GetEscapedBinaryData(buffer)) {
2998 const uint64_t data_to_write =
2999 std::min<uint64_t>(dst_len, buffer.size());
3000 if (data_to_write > 0)
3001 memcpy(dst, &buffer[0], data_to_write);
3002 return data_to_write;
3003 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003004 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003005 }
3006 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003007}
3008
Kate Stoneb9c1b512016-09-06 20:57:50 +00003009uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
3010 uint64_t offset,
3011 const void *src,
3012 uint64_t src_len,
Zachary Turner97206d52017-05-12 04:51:55 +00003013 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003014 lldb_private::StreamGDBRemote stream;
3015 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3016 stream.PutEscapedBytes(src, src_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003017 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003018 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003019 PacketResult::Success) {
3020 if (response.GetChar() != 'F') {
3021 error.SetErrorStringWithFormat("write file failed");
3022 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003023 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003024 uint64_t bytes_written = response.GetU64(UINT64_MAX);
3025 if (bytes_written == UINT64_MAX) {
3026 error.SetErrorToGenericError();
3027 if (response.GetChar() == ',') {
3028 int response_errno = response.GetS32(-1);
3029 if (response_errno > 0)
3030 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3031 }
3032 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003033 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003034 return bytes_written;
3035 } else {
3036 error.SetErrorString("failed to send vFile:pwrite packet");
3037 }
3038 return 0;
3039}
3040
Zachary Turner97206d52017-05-12 04:51:55 +00003041Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
3042 const FileSpec &dst) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003043 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00003044 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003045 lldb_private::StreamGDBRemote stream;
3046 stream.PutCString("vFile:symlink:");
3047 // the unix symlink() command reverses its parameters where the dst if first,
3048 // so we follow suit here
Pavel Labath7f815a92019-02-12 14:28:55 +00003049 stream.PutStringAsRawHex8(dst_path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003050 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00003051 stream.PutStringAsRawHex8(src_path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003052 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003053 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003054 PacketResult::Success) {
3055 if (response.GetChar() == 'F') {
3056 uint32_t result = response.GetU32(UINT32_MAX);
3057 if (result != 0) {
3058 error.SetErrorToGenericError();
3059 if (response.GetChar() == ',') {
3060 int response_errno = response.GetS32(-1);
3061 if (response_errno > 0)
3062 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3063 }
3064 }
3065 } else {
3066 // Should have returned with 'F<result>[,<errno>]'
3067 error.SetErrorStringWithFormat("symlink failed");
3068 }
3069 } else {
3070 error.SetErrorString("failed to send vFile:symlink packet");
3071 }
3072 return error;
3073}
3074
Zachary Turner97206d52017-05-12 04:51:55 +00003075Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003076 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00003077 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003078 lldb_private::StreamGDBRemote stream;
3079 stream.PutCString("vFile:unlink:");
3080 // the unix symlink() command reverses its parameters where the dst if first,
3081 // so we follow suit here
Pavel Labath7f815a92019-02-12 14:28:55 +00003082 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003083 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003084 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003085 PacketResult::Success) {
3086 if (response.GetChar() == 'F') {
3087 uint32_t result = response.GetU32(UINT32_MAX);
3088 if (result != 0) {
3089 error.SetErrorToGenericError();
3090 if (response.GetChar() == ',') {
3091 int response_errno = response.GetS32(-1);
3092 if (response_errno > 0)
3093 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3094 }
3095 }
3096 } else {
3097 // Should have returned with 'F<result>[,<errno>]'
3098 error.SetErrorStringWithFormat("unlink failed");
3099 }
3100 } else {
3101 error.SetErrorString("failed to send vFile:unlink packet");
3102 }
3103 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +00003104}
3105
Daniel Maleae0f8f572013-08-26 23:57:52 +00003106// Extension of host I/O packets to get whether a file exists.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003107bool GDBRemoteCommunicationClient::GetFileExists(
3108 const lldb_private::FileSpec &file_spec) {
3109 std::string path(file_spec.GetPath(false));
3110 lldb_private::StreamString stream;
3111 stream.PutCString("vFile:exists:");
Pavel Labath7f815a92019-02-12 14:28:55 +00003112 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003113 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003114 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003115 PacketResult::Success) {
3116 if (response.GetChar() != 'F')
3117 return false;
3118 if (response.GetChar() != ',')
3119 return false;
3120 bool retcode = (response.GetChar() != '0');
3121 return retcode;
3122 }
3123 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003124}
3125
Kate Stoneb9c1b512016-09-06 20:57:50 +00003126bool GDBRemoteCommunicationClient::CalculateMD5(
3127 const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
3128 std::string path(file_spec.GetPath(false));
3129 lldb_private::StreamString stream;
3130 stream.PutCString("vFile:MD5:");
Pavel Labath7f815a92019-02-12 14:28:55 +00003131 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003132 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003133 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003134 PacketResult::Success) {
3135 if (response.GetChar() != 'F')
3136 return false;
3137 if (response.GetChar() != ',')
3138 return false;
3139 if (response.Peek() && *response.Peek() == 'x')
3140 return false;
3141 low = response.GetHexMaxU64(false, UINT64_MAX);
3142 high = response.GetHexMaxU64(false, UINT64_MAX);
Pavel Labath4b6f9592016-08-18 08:30:03 +00003143 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003144 }
3145 return false;
Greg Claytonf74cf862013-11-13 23:28:31 +00003146}
3147
Kate Stoneb9c1b512016-09-06 20:57:50 +00003148bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
3149 // Some targets have issues with g/G packets and we need to avoid using them
3150 if (m_avoid_g_packets == eLazyBoolCalculate) {
3151 if (process) {
3152 m_avoid_g_packets = eLazyBoolNo;
3153 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3154 if (arch.IsValid() &&
3155 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3156 arch.GetTriple().getOS() == llvm::Triple::IOS &&
3157 arch.GetTriple().getArch() == llvm::Triple::aarch64) {
3158 m_avoid_g_packets = eLazyBoolYes;
3159 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3160 if (gdb_server_version != 0) {
3161 const char *gdb_server_name = GetGDBServerProgramName();
3162 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3163 if (gdb_server_version >= 310)
3164 m_avoid_g_packets = eLazyBoolNo;
3165 }
3166 }
3167 }
3168 }
3169 }
3170 return m_avoid_g_packets == eLazyBoolYes;
3171}
Saleem Abdulrasool2d6a9ec2016-07-28 17:32:20 +00003172
Kate Stoneb9c1b512016-09-06 20:57:50 +00003173DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
3174 uint32_t reg) {
3175 StreamString payload;
3176 payload.Printf("p%x", reg);
3177 StringExtractorGDBRemote response;
3178 if (SendThreadSpecificPacketAndWaitForResponse(
3179 tid, std::move(payload), response, false) != PacketResult::Success ||
3180 !response.IsNormalResponse())
3181 return nullptr;
Pavel Labath4b6f9592016-08-18 08:30:03 +00003182
Kate Stoneb9c1b512016-09-06 20:57:50 +00003183 DataBufferSP buffer_sp(
3184 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3185 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3186 return buffer_sp;
3187}
Pavel Labath4b6f9592016-08-18 08:30:03 +00003188
Kate Stoneb9c1b512016-09-06 20:57:50 +00003189DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
3190 StreamString payload;
3191 payload.PutChar('g');
3192 StringExtractorGDBRemote response;
3193 if (SendThreadSpecificPacketAndWaitForResponse(
3194 tid, std::move(payload), response, false) != PacketResult::Success ||
3195 !response.IsNormalResponse())
3196 return nullptr;
3197
3198 DataBufferSP buffer_sp(
3199 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3200 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3201 return buffer_sp;
3202}
3203
3204bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
3205 uint32_t reg_num,
3206 llvm::ArrayRef<uint8_t> data) {
3207 StreamString payload;
3208 payload.Printf("P%x=", reg_num);
3209 payload.PutBytesAsRawHex8(data.data(), data.size(),
3210 endian::InlHostByteOrder(),
3211 endian::InlHostByteOrder());
3212 StringExtractorGDBRemote response;
3213 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3214 response, false) ==
3215 PacketResult::Success &&
3216 response.IsOKResponse();
3217}
3218
3219bool GDBRemoteCommunicationClient::WriteAllRegisters(
3220 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3221 StreamString payload;
3222 payload.PutChar('G');
3223 payload.PutBytesAsRawHex8(data.data(), data.size(),
3224 endian::InlHostByteOrder(),
3225 endian::InlHostByteOrder());
3226 StringExtractorGDBRemote response;
3227 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3228 response, false) ==
3229 PacketResult::Success &&
3230 response.IsOKResponse();
3231}
3232
3233bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
3234 uint32_t &save_id) {
3235 save_id = 0; // Set to invalid save ID
3236 if (m_supports_QSaveRegisterState == eLazyBoolNo)
Greg Claytonf74cf862013-11-13 23:28:31 +00003237 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003238
3239 m_supports_QSaveRegisterState = eLazyBoolYes;
3240 StreamString payload;
3241 payload.PutCString("QSaveRegisterState");
3242 StringExtractorGDBRemote response;
3243 if (SendThreadSpecificPacketAndWaitForResponse(
3244 tid, std::move(payload), response, false) != PacketResult::Success)
3245 return false;
3246
3247 if (response.IsUnsupportedResponse())
3248 m_supports_QSaveRegisterState = eLazyBoolNo;
3249
3250 const uint32_t response_save_id = response.GetU32(0);
3251 if (response_save_id == 0)
3252 return false;
3253
3254 save_id = response_save_id;
3255 return true;
Greg Claytonf74cf862013-11-13 23:28:31 +00003256}
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003257
Kate Stoneb9c1b512016-09-06 20:57:50 +00003258bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
3259 uint32_t save_id) {
3260 // We use the "m_supports_QSaveRegisterState" variable here because the
Adrian Prantl05097242018-04-30 16:49:04 +00003261 // QSaveRegisterState and QRestoreRegisterState packets must both be
3262 // supported in order to be useful
Kate Stoneb9c1b512016-09-06 20:57:50 +00003263 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3264 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003265
Kate Stoneb9c1b512016-09-06 20:57:50 +00003266 StreamString payload;
3267 payload.Printf("QRestoreRegisterState:%u", save_id);
3268 StringExtractorGDBRemote response;
3269 if (SendThreadSpecificPacketAndWaitForResponse(
3270 tid, std::move(payload), response, false) != PacketResult::Success)
3271 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003272
Kate Stoneb9c1b512016-09-06 20:57:50 +00003273 if (response.IsOKResponse())
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003274 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003275
3276 if (response.IsUnsupportedResponse())
3277 m_supports_QSaveRegisterState = eLazyBoolNo;
3278 return false;
3279}
3280
3281bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
3282 if (!GetSyncThreadStateSupported())
3283 return false;
3284
3285 StreamString packet;
3286 StringExtractorGDBRemote response;
3287 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3288 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
3289 GDBRemoteCommunication::PacketResult::Success &&
3290 response.IsOKResponse();
3291}
3292
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003293lldb::user_id_t
3294GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
3295 Status &error) {
3296 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3297 lldb::user_id_t ret_uid = LLDB_INVALID_UID;
3298
3299 StreamGDBRemote escaped_packet;
3300 escaped_packet.PutCString("jTraceStart:");
3301
3302 StructuredData::Dictionary json_packet;
3303 json_packet.AddIntegerItem("type", options.getType());
3304 json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
3305 json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
3306
3307 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3308 json_packet.AddIntegerItem("threadid", options.getThreadID());
3309
3310 StructuredData::DictionarySP custom_params = options.getTraceParams();
3311 if (custom_params)
3312 json_packet.AddItem("params", custom_params);
3313
3314 StreamString json_string;
3315 json_packet.Dump(json_string, false);
3316 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3317
3318 StringExtractorGDBRemote response;
3319 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3320 true) ==
3321 GDBRemoteCommunication::PacketResult::Success) {
3322 if (!response.IsNormalResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003323 error = response.GetStatus();
3324 LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003325 } else {
3326 ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
3327 }
3328 } else {
3329 LLDB_LOG(log, "failed to send packet");
3330 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3331 escaped_packet.GetData());
3332 }
3333 return ret_uid;
3334}
3335
3336Status
3337GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
3338 lldb::tid_t thread_id) {
3339 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3340 StringExtractorGDBRemote response;
3341 Status error;
3342
3343 StructuredData::Dictionary json_packet;
3344 StreamGDBRemote escaped_packet;
3345 StreamString json_string;
3346 escaped_packet.PutCString("jTraceStop:");
3347
3348 json_packet.AddIntegerItem("traceid", uid);
3349
3350 if (thread_id != LLDB_INVALID_THREAD_ID)
3351 json_packet.AddIntegerItem("threadid", thread_id);
3352
3353 json_packet.Dump(json_string, false);
3354
3355 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3356
3357 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3358 true) ==
3359 GDBRemoteCommunication::PacketResult::Success) {
3360 if (!response.IsOKResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003361 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003362 LLDB_LOG(log, "stop tracing failed");
3363 }
3364 } else {
3365 LLDB_LOG(log, "failed to send packet");
3366 error.SetErrorStringWithFormat(
3367 "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
3368 response.GetError());
3369 }
3370 return error;
3371}
3372
3373Status GDBRemoteCommunicationClient::SendGetDataPacket(
3374 lldb::user_id_t uid, lldb::tid_t thread_id,
3375 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003376
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003377 StreamGDBRemote escaped_packet;
3378 escaped_packet.PutCString("jTraceBufferRead:");
3379 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3380}
3381
3382Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
3383 lldb::user_id_t uid, lldb::tid_t thread_id,
3384 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003385
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003386 StreamGDBRemote escaped_packet;
3387 escaped_packet.PutCString("jTraceMetaRead:");
3388 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3389}
3390
3391Status
3392GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
3393 TraceOptions &options) {
3394 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3395 StringExtractorGDBRemote response;
3396 Status error;
3397
3398 StreamString json_string;
3399 StreamGDBRemote escaped_packet;
3400 escaped_packet.PutCString("jTraceConfigRead:");
3401
3402 StructuredData::Dictionary json_packet;
3403 json_packet.AddIntegerItem("traceid", uid);
3404
3405 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3406 json_packet.AddIntegerItem("threadid", options.getThreadID());
3407
3408 json_packet.Dump(json_string, false);
3409 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3410
3411 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3412 true) ==
3413 GDBRemoteCommunication::PacketResult::Success) {
3414 if (response.IsNormalResponse()) {
3415 uint64_t type = std::numeric_limits<uint64_t>::max();
3416 uint64_t buffersize = std::numeric_limits<uint64_t>::max();
3417 uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
3418
3419 auto json_object = StructuredData::ParseJSON(response.Peek());
3420
3421 if (!json_object ||
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003422 json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003423 error.SetErrorString("Invalid Configuration obtained");
3424 return error;
3425 }
3426
3427 auto json_dict = json_object->GetAsDictionary();
3428
3429 json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
3430 metabuffersize);
3431 options.setMetaDataBufferSize(metabuffersize);
3432
3433 json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
3434 options.setTraceBufferSize(buffersize);
3435
3436 json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
3437 options.setType(static_cast<lldb::TraceType>(type));
3438
3439 StructuredData::ObjectSP custom_params_sp =
3440 json_dict->GetValueForKey("params");
3441 if (custom_params_sp) {
3442 if (custom_params_sp->GetType() !=
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003443 lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003444 error.SetErrorString("Invalid Configuration obtained");
3445 return error;
3446 } else
3447 options.setTraceParams(
3448 static_pointer_cast<StructuredData::Dictionary>(
3449 custom_params_sp));
3450 }
3451 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003452 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003453 }
3454 } else {
3455 LLDB_LOG(log, "failed to send packet");
3456 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3457 escaped_packet.GetData());
3458 }
3459 return error;
3460}
3461
3462Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
3463 StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
3464 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
3465 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3466 Status error;
3467
3468 StructuredData::Dictionary json_packet;
3469
3470 json_packet.AddIntegerItem("traceid", uid);
3471 json_packet.AddIntegerItem("offset", offset);
3472 json_packet.AddIntegerItem("buffersize", buffer.size());
3473
3474 if (thread_id != LLDB_INVALID_THREAD_ID)
3475 json_packet.AddIntegerItem("threadid", thread_id);
3476
3477 StreamString json_string;
3478 json_packet.Dump(json_string, false);
3479
3480 packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3481 StringExtractorGDBRemote response;
3482 if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
3483 GDBRemoteCommunication::PacketResult::Success) {
3484 if (response.IsNormalResponse()) {
3485 size_t filled_size = response.GetHexBytesAvail(buffer);
3486 buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
3487 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003488 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003489 buffer = buffer.slice(buffer.size());
3490 }
3491 } else {
3492 LLDB_LOG(log, "failed to send packet");
3493 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3494 packet.GetData());
3495 buffer = buffer.slice(buffer.size());
3496 }
3497 return error;
3498}
3499
Kate Stoneb9c1b512016-09-06 20:57:50 +00003500bool GDBRemoteCommunicationClient::GetModuleInfo(
3501 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3502 ModuleSpec &module_spec) {
3503 if (!m_supports_qModuleInfo)
3504 return false;
3505
3506 std::string module_path = module_file_spec.GetPath(false);
3507 if (module_path.empty())
3508 return false;
3509
3510 StreamString packet;
3511 packet.PutCString("qModuleInfo:");
Pavel Labath7f815a92019-02-12 14:28:55 +00003512 packet.PutStringAsRawHex8(module_path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003513 packet.PutCString(";");
3514 const auto &triple = arch_spec.GetTriple().getTriple();
Pavel Labath7f815a92019-02-12 14:28:55 +00003515 packet.PutStringAsRawHex8(triple);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003516
3517 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003518 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
3519 PacketResult::Success)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003520 return false;
3521
3522 if (response.IsErrorResponse())
3523 return false;
3524
3525 if (response.IsUnsupportedResponse()) {
3526 m_supports_qModuleInfo = false;
3527 return false;
3528 }
3529
3530 llvm::StringRef name;
3531 llvm::StringRef value;
3532
3533 module_spec.Clear();
3534 module_spec.GetFileSpec() = module_file_spec;
3535
3536 while (response.GetNameColonValue(name, value)) {
3537 if (name == "uuid" || name == "md5") {
3538 StringExtractor extractor(value);
3539 std::string uuid;
3540 extractor.GetHexByteString(uuid);
Pavel Labatha174bcb2018-06-21 15:24:39 +00003541 module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003542 } else if (name == "triple") {
3543 StringExtractor extractor(value);
3544 std::string triple;
3545 extractor.GetHexByteString(triple);
3546 module_spec.GetArchitecture().SetTriple(triple.c_str());
3547 } else if (name == "file_offset") {
3548 uint64_t ival = 0;
3549 if (!value.getAsInteger(16, ival))
3550 module_spec.SetObjectOffset(ival);
3551 } else if (name == "file_size") {
3552 uint64_t ival = 0;
3553 if (!value.getAsInteger(16, ival))
3554 module_spec.SetObjectSize(ival);
3555 } else if (name == "file_path") {
3556 StringExtractor extractor(value);
3557 std::string path;
3558 extractor.GetHexByteString(path);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00003559 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003560 }
3561 }
3562
3563 return true;
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003564}
Colin Rileyc3c95b22015-04-16 15:51:33 +00003565
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003566static llvm::Optional<ModuleSpec>
3567ParseModuleSpec(StructuredData::Dictionary *dict) {
3568 ModuleSpec result;
3569 if (!dict)
3570 return llvm::None;
3571
Zachary Turner28333212017-05-12 05:49:54 +00003572 llvm::StringRef string;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003573 uint64_t integer;
3574
3575 if (!dict->GetValueForKeyAsString("uuid", string))
3576 return llvm::None;
Pavel Labath8c92c892017-12-18 14:31:44 +00003577 if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
3578 string.size())
3579 return llvm::None;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003580
3581 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3582 return llvm::None;
3583 result.SetObjectOffset(integer);
3584
3585 if (!dict->GetValueForKeyAsInteger("file_size", integer))
3586 return llvm::None;
3587 result.SetObjectSize(integer);
3588
3589 if (!dict->GetValueForKeyAsString("triple", string))
3590 return llvm::None;
Zachary Turner28333212017-05-12 05:49:54 +00003591 result.GetArchitecture().SetTriple(string);
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003592
3593 if (!dict->GetValueForKeyAsString("file_path", string))
3594 return llvm::None;
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00003595 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003596
3597 return result;
3598}
3599
3600llvm::Optional<std::vector<ModuleSpec>>
3601GDBRemoteCommunicationClient::GetModulesInfo(
3602 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
3603 if (!m_supports_jModulesInfo)
3604 return llvm::None;
3605
3606 JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
3607 for (const FileSpec &module_file_spec : module_file_specs) {
3608 JSONObject::SP module_sp = std::make_shared<JSONObject>();
3609 module_array_sp->AppendObject(module_sp);
3610 module_sp->SetObject(
Pavel Labath763f1c42017-01-05 13:18:46 +00003611 "file", std::make_shared<JSONString>(module_file_spec.GetPath(false)));
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003612 module_sp->SetObject("triple",
3613 std::make_shared<JSONString>(triple.getTriple()));
3614 }
3615 StreamString unescaped_payload;
3616 unescaped_payload.PutCString("jModulesInfo:");
3617 module_array_sp->Write(unescaped_payload);
3618 StreamGDBRemote payload;
Zachary Turnerc1564272016-11-16 21:15:24 +00003619 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003620 unescaped_payload.GetSize());
3621
Greg Clayton70a9f512017-04-14 17:10:04 +00003622 // Increase the timeout for jModulesInfo since this packet can take longer.
3623 ScopedTimeout timeout(*this, std::chrono::seconds(10));
3624
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003625 StringExtractorGDBRemote response;
3626 if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
3627 PacketResult::Success ||
3628 response.IsErrorResponse())
3629 return llvm::None;
3630
3631 if (response.IsUnsupportedResponse()) {
3632 m_supports_jModulesInfo = false;
3633 return llvm::None;
3634 }
3635
3636 StructuredData::ObjectSP response_object_sp =
3637 StructuredData::ParseJSON(response.GetStringRef());
3638 if (!response_object_sp)
3639 return llvm::None;
3640
3641 StructuredData::Array *response_array = response_object_sp->GetAsArray();
3642 if (!response_array)
3643 return llvm::None;
3644
3645 std::vector<ModuleSpec> result;
3646 for (size_t i = 0; i < response_array->GetSize(); ++i) {
3647 if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
3648 response_array->GetItemAtIndex(i)->GetAsDictionary()))
3649 result.push_back(*module_spec);
3650 }
3651
3652 return result;
3653}
3654
Colin Rileyc3c95b22015-04-16 15:51:33 +00003655// query the target remote for extended information using the qXfer packet
3656//
Adrian Prantl05097242018-04-30 16:49:04 +00003657// example: object='features', annex='target.xml', out=<xml output> return:
3658// 'true' on success
Colin Rileyc3c95b22015-04-16 15:51:33 +00003659// 'false' on failure (err set)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003660bool GDBRemoteCommunicationClient::ReadExtFeature(
3661 const lldb_private::ConstString object,
3662 const lldb_private::ConstString annex, std::string &out,
Zachary Turner97206d52017-05-12 04:51:55 +00003663 lldb_private::Status &err) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003664
Kate Stoneb9c1b512016-09-06 20:57:50 +00003665 std::stringstream output;
3666 StringExtractorGDBRemote chunk;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003667
Kate Stoneb9c1b512016-09-06 20:57:50 +00003668 uint64_t size = GetRemoteMaxPacketSize();
3669 if (size == 0)
3670 size = 0x1000;
3671 size = size - 1; // Leave space for the 'm' or 'l' character in the response
3672 int offset = 0;
3673 bool active = true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003674
Kate Stoneb9c1b512016-09-06 20:57:50 +00003675 // loop until all data has been read
3676 while (active) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003677
Kate Stoneb9c1b512016-09-06 20:57:50 +00003678 // send query extended feature packet
3679 std::stringstream packet;
3680 packet << "qXfer:" << object.AsCString("")
3681 << ":read:" << annex.AsCString("") << ":" << std::hex << offset
3682 << "," << std::hex << size;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003683
Kate Stoneb9c1b512016-09-06 20:57:50 +00003684 GDBRemoteCommunication::PacketResult res =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00003685 SendPacketAndWaitForResponse(packet.str(), chunk, false);
Colin Rileyc3c95b22015-04-16 15:51:33 +00003686
Kate Stoneb9c1b512016-09-06 20:57:50 +00003687 if (res != GDBRemoteCommunication::PacketResult::Success) {
3688 err.SetErrorString("Error sending $qXfer packet");
3689 return false;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003690 }
3691
Kate Stoneb9c1b512016-09-06 20:57:50 +00003692 const std::string &str = chunk.GetStringRef();
3693 if (str.length() == 0) {
3694 // should have some data in chunk
3695 err.SetErrorString("Empty response from $qXfer packet");
3696 return false;
3697 }
3698
3699 // check packet code
3700 switch (str[0]) {
3701 // last chunk
3702 case ('l'):
3703 active = false;
3704 LLVM_FALLTHROUGH;
3705
3706 // more chunks
3707 case ('m'):
3708 if (str.length() > 1)
3709 output << &str[1];
3710 offset += size;
3711 break;
3712
3713 // unknown chunk
3714 default:
3715 err.SetErrorString("Invalid continuation code from $qXfer packet");
3716 return false;
3717 }
3718 }
3719
3720 out = output.str();
3721 err.Success();
3722 return true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003723}
Greg Clayton0b90be12015-06-23 21:27:50 +00003724
3725// Notify the target that gdb is prepared to serve symbol lookup requests.
3726// packet: "qSymbol::"
3727// reply:
3728// OK The target does not need to look up any (more) symbols.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003729// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
3730// encoded).
3731// LLDB may provide the value by sending another qSymbol
3732// packet
Greg Clayton0b90be12015-06-23 21:27:50 +00003733// in the form of"qSymbol:<sym_value>:<sym_name>".
Jason Molenda50018d32016-01-13 04:08:10 +00003734//
3735// Three examples:
3736//
3737// lldb sends: qSymbol::
3738// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003739// Remote gdb stub does not need to know the addresses of any symbols, lldb
3740// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003741// need to ask again in this session.
3742//
3743// lldb sends: qSymbol::
3744// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3745// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
3746// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003747// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
3748// not know
3749// the address at this time. lldb needs to send qSymbol:: again when it has
3750// more
Jason Molenda50018d32016-01-13 04:08:10 +00003751// solibs loaded.
3752//
3753// lldb sends: qSymbol::
3754// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3755// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
3756// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003757// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
3758// that it
3759// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
3760// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003761// need any more symbols. lldb does not need to ask again in this session.
Greg Clayton0b90be12015-06-23 21:27:50 +00003762
Kate Stoneb9c1b512016-09-06 20:57:50 +00003763void GDBRemoteCommunicationClient::ServeSymbolLookups(
3764 lldb_private::Process *process) {
Adrian Prantl05097242018-04-30 16:49:04 +00003765 // Set to true once we've resolved a symbol to an address for the remote
3766 // stub. If we get an 'OK' response after this, the remote stub doesn't need
3767 // any more symbols and we can stop asking.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003768 bool symbol_response_provided = false;
Jason Molenda50018d32016-01-13 04:08:10 +00003769
Kate Stoneb9c1b512016-09-06 20:57:50 +00003770 // Is this the initial qSymbol:: packet?
3771 bool first_qsymbol_query = true;
Jason Molenda50018d32016-01-13 04:08:10 +00003772
Jonas Devliegherea6682a42018-12-15 00:15:33 +00003773 if (m_supports_qSymbol && !m_qSymbol_requests_done) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003774 Lock lock(*this, false);
3775 if (lock) {
3776 StreamString packet;
3777 packet.PutCString("qSymbol::");
3778 StringExtractorGDBRemote response;
3779 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
3780 PacketResult::Success) {
3781 if (response.IsOKResponse()) {
3782 if (symbol_response_provided || first_qsymbol_query) {
3783 m_qSymbol_requests_done = true;
3784 }
3785
3786 // We are done serving symbols requests
3787 return;
3788 }
3789 first_qsymbol_query = false;
3790
3791 if (response.IsUnsupportedResponse()) {
Adrian Prantl05097242018-04-30 16:49:04 +00003792 // qSymbol is not supported by the current GDB server we are
3793 // connected to
Kate Stoneb9c1b512016-09-06 20:57:50 +00003794 m_supports_qSymbol = false;
3795 return;
3796 } else {
3797 llvm::StringRef response_str(response.GetStringRef());
3798 if (response_str.startswith("qSymbol:")) {
3799 response.SetFilePos(strlen("qSymbol:"));
3800 std::string symbol_name;
3801 if (response.GetHexByteString(symbol_name)) {
3802 if (symbol_name.empty())
3803 return;
3804
3805 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
3806 lldb_private::SymbolContextList sc_list;
3807 if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(
3808 ConstString(symbol_name), eSymbolTypeAny, sc_list)) {
3809 const size_t num_scs = sc_list.GetSize();
3810 for (size_t sc_idx = 0;
3811 sc_idx < num_scs &&
3812 symbol_load_addr == LLDB_INVALID_ADDRESS;
3813 ++sc_idx) {
3814 SymbolContext sc;
3815 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
3816 if (sc.symbol) {
3817 switch (sc.symbol->GetType()) {
3818 case eSymbolTypeInvalid:
3819 case eSymbolTypeAbsolute:
3820 case eSymbolTypeUndefined:
3821 case eSymbolTypeSourceFile:
3822 case eSymbolTypeHeaderFile:
3823 case eSymbolTypeObjectFile:
3824 case eSymbolTypeCommonBlock:
3825 case eSymbolTypeBlock:
3826 case eSymbolTypeLocal:
3827 case eSymbolTypeParam:
3828 case eSymbolTypeVariable:
3829 case eSymbolTypeVariableType:
3830 case eSymbolTypeLineEntry:
3831 case eSymbolTypeLineHeader:
3832 case eSymbolTypeScopeBegin:
3833 case eSymbolTypeScopeEnd:
3834 case eSymbolTypeAdditional:
3835 case eSymbolTypeCompiler:
3836 case eSymbolTypeInstrumentation:
3837 case eSymbolTypeTrampoline:
3838 break;
3839
3840 case eSymbolTypeCode:
3841 case eSymbolTypeResolver:
3842 case eSymbolTypeData:
3843 case eSymbolTypeRuntime:
3844 case eSymbolTypeException:
3845 case eSymbolTypeObjCClass:
3846 case eSymbolTypeObjCMetaClass:
3847 case eSymbolTypeObjCIVar:
3848 case eSymbolTypeReExported:
3849 symbol_load_addr =
3850 sc.symbol->GetLoadAddress(&process->GetTarget());
3851 break;
3852 }
Jason Molenda50018d32016-01-13 04:08:10 +00003853 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003854 }
Greg Clayton42b01482015-08-11 22:07:46 +00003855 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003856 }
3857 // This is the normal path where our symbol lookup was successful
Adrian Prantl05097242018-04-30 16:49:04 +00003858 // and we want to send a packet with the new symbol value and see
3859 // if another lookup needs to be done.
Greg Clayton0b90be12015-06-23 21:27:50 +00003860
Kate Stoneb9c1b512016-09-06 20:57:50 +00003861 // Change "packet" to contain the requested symbol value and name
3862 packet.Clear();
3863 packet.PutCString("qSymbol:");
3864 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
3865 packet.Printf("%" PRIx64, symbol_load_addr);
3866 symbol_response_provided = true;
3867 } else {
3868 symbol_response_provided = false;
3869 }
3870 packet.PutCString(":");
3871 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
3872 continue; // go back to the while loop and send "packet" and wait
3873 // for another response
Greg Clayton0b90be12015-06-23 21:27:50 +00003874 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003875 }
3876 }
3877 }
3878 // If we make it here, the symbol request packet response wasn't valid or
3879 // our symbol lookup failed so we must abort
3880 return;
Greg Clayton0b90be12015-06-23 21:27:50 +00003881
Kate Stoneb9c1b512016-09-06 20:57:50 +00003882 } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
3883 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
3884 log->Printf(
3885 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
3886 __FUNCTION__);
Greg Clayton0b90be12015-06-23 21:27:50 +00003887 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003888 }
Greg Clayton0b90be12015-06-23 21:27:50 +00003889}
3890
Kate Stoneb9c1b512016-09-06 20:57:50 +00003891StructuredData::Array *
3892GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
3893 if (!m_supported_async_json_packets_is_valid) {
Adrian Prantl05097242018-04-30 16:49:04 +00003894 // Query the server for the array of supported asynchronous JSON packets.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003895 m_supported_async_json_packets_is_valid = true;
Todd Fiala75930012016-08-19 04:21:48 +00003896
Kate Stoneb9c1b512016-09-06 20:57:50 +00003897 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Todd Fiala75930012016-08-19 04:21:48 +00003898
Kate Stoneb9c1b512016-09-06 20:57:50 +00003899 // Poll it now.
Todd Fiala75930012016-08-19 04:21:48 +00003900 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003901 const bool send_async = false;
3902 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
3903 send_async) == PacketResult::Success) {
3904 m_supported_async_json_packets_sp =
3905 StructuredData::ParseJSON(response.GetStringRef());
3906 if (m_supported_async_json_packets_sp &&
3907 !m_supported_async_json_packets_sp->GetAsArray()) {
Adrian Prantl05097242018-04-30 16:49:04 +00003908 // We were returned something other than a JSON array. This is
3909 // invalid. Clear it out.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003910 if (log)
3911 log->Printf("GDBRemoteCommunicationClient::%s(): "
3912 "QSupportedAsyncJSONPackets returned invalid "
3913 "result: %s",
3914 __FUNCTION__, response.GetStringRef().c_str());
3915 m_supported_async_json_packets_sp.reset();
3916 }
3917 } else {
3918 if (log)
3919 log->Printf("GDBRemoteCommunicationClient::%s(): "
3920 "QSupportedAsyncJSONPackets unsupported",
3921 __FUNCTION__);
Todd Fiala75930012016-08-19 04:21:48 +00003922 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003923
3924 if (log && m_supported_async_json_packets_sp) {
3925 StreamString stream;
3926 m_supported_async_json_packets_sp->Dump(stream);
3927 log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
3928 "JSON packets: %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00003929 __FUNCTION__, stream.GetData());
Todd Fiala75930012016-08-19 04:21:48 +00003930 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003931 }
3932
3933 return m_supported_async_json_packets_sp
3934 ? m_supported_async_json_packets_sp->GetAsArray()
3935 : nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00003936}
3937
Zachary Turner97206d52017-05-12 04:51:55 +00003938Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003939 llvm::ArrayRef<int32_t> signals) {
3940 // Format packet:
3941 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
3942 auto range = llvm::make_range(signals.begin(), signals.end());
3943 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
3944
3945 StringExtractorGDBRemote response;
3946 auto send_status = SendPacketAndWaitForResponse(packet, response, false);
3947
3948 if (send_status != GDBRemoteCommunication::PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00003949 return Status("Sending QPassSignals packet failed");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003950
3951 if (response.IsOKResponse()) {
Zachary Turner97206d52017-05-12 04:51:55 +00003952 return Status();
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003953 } else {
Zachary Turner97206d52017-05-12 04:51:55 +00003954 return Status("Unknown error happened during sending QPassSignals packet.");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003955 }
3956}
3957
Zachary Turner97206d52017-05-12 04:51:55 +00003958Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00003959 ConstString type_name, const StructuredData::ObjectSP &config_sp) {
Zachary Turner97206d52017-05-12 04:51:55 +00003960 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003961
3962 if (type_name.GetLength() == 0) {
3963 error.SetErrorString("invalid type_name argument");
3964 return error;
3965 }
3966
Adrian Prantl05097242018-04-30 16:49:04 +00003967 // Build command: Configure{type_name}: serialized config data.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003968 StreamGDBRemote stream;
3969 stream.PutCString("QConfigure");
3970 stream.PutCString(type_name.AsCString());
3971 stream.PutChar(':');
3972 if (config_sp) {
3973 // Gather the plain-text version of the configuration data.
3974 StreamString unescaped_stream;
3975 config_sp->Dump(unescaped_stream);
3976 unescaped_stream.Flush();
3977
3978 // Add it to the stream in escaped fashion.
Zachary Turnerc1564272016-11-16 21:15:24 +00003979 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003980 unescaped_stream.GetSize());
3981 }
3982 stream.Flush();
3983
3984 // Send the packet.
3985 const bool send_async = false;
3986 StringExtractorGDBRemote response;
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00003987 auto result =
3988 SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003989 if (result == PacketResult::Success) {
3990 // We failed if the config result comes back other than OK.
3991 if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
3992 // Okay!
3993 error.Clear();
3994 } else {
3995 error.SetErrorStringWithFormat("configuring StructuredData feature "
3996 "%s failed with error %s",
3997 type_name.AsCString(),
3998 response.GetStringRef().c_str());
3999 }
4000 } else {
4001 // Can we get more data here on the failure?
4002 error.SetErrorStringWithFormat("configuring StructuredData feature %s "
4003 "failed when sending packet: "
4004 "PacketResult=%d",
Ilia K4f730dc2016-09-12 05:25:33 +00004005 type_name.AsCString(), (int)result);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004006 }
4007 return error;
4008}
4009
4010void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
4011 GDBRemoteClientBase::OnRunPacketSent(first);
4012 m_curr_tid = LLDB_INVALID_THREAD_ID;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00004013}