blob: 83aca6a380d041e411a7d842f40f9cfb451aaf08 [file] [log] [blame]
Raphael Isemann80814282020-01-24 08:23:27 +01001//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//
Greg Clayton576d8832011-03-22 04:00:09 +00002//
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"
Todd Fiala75930012016-08-19 04:21:48 +000026#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000027#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000028#include "lldb/Utility/State.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000029#include "lldb/Utility/StreamString.h"
Greg Clayton576d8832011-03-22 04:00:09 +000030
Greg Clayton576d8832011-03-22 04:00:09 +000031#include "ProcessGDBRemote.h"
32#include "ProcessGDBRemoteLog.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000033#include "lldb/Host/Config.h"
Pavel Labath9af71b32018-03-20 16:14:00 +000034#include "lldb/Utility/StringExtractorGDBRemote.h"
Greg Clayton576d8832011-03-22 04:00:09 +000035
Zachary Turner54695a32016-08-29 19:58:14 +000036#include "llvm/ADT/StringSwitch.h"
Jonas Devlieghere2a5a9062019-10-02 18:02:26 +000037#include "llvm/Support/JSON.h"
Zachary Turner54695a32016-08-29 19:58:14 +000038
Haibo Huang7debc932019-08-08 21:42:33 +000039#if defined(HAVE_LIBCOMPRESSION)
Jason Molenda91ffe0a2015-06-18 21:46:06 +000040#include <compression.h>
41#endif
42
Greg Clayton576d8832011-03-22 04:00:09 +000043using namespace lldb;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000044using namespace lldb_private::process_gdb_remote;
Jonas Devlieghere2a5a9062019-10-02 18:02:26 +000045using namespace lldb_private;
Pavel Labath1eff73c2016-11-24 10:54:49 +000046using namespace std::chrono;
Greg Clayton576d8832011-03-22 04:00:09 +000047
Greg Clayton576d8832011-03-22 04:00:09 +000048// GDBRemoteCommunicationClient constructor
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000049GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000050 : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000051 m_supports_not_sending_acks(eLazyBoolCalculate),
52 m_supports_thread_suffix(eLazyBoolCalculate),
53 m_supports_threads_in_stop_reply(eLazyBoolCalculate),
54 m_supports_vCont_all(eLazyBoolCalculate),
55 m_supports_vCont_any(eLazyBoolCalculate),
56 m_supports_vCont_c(eLazyBoolCalculate),
57 m_supports_vCont_C(eLazyBoolCalculate),
58 m_supports_vCont_s(eLazyBoolCalculate),
59 m_supports_vCont_S(eLazyBoolCalculate),
60 m_qHostInfo_is_valid(eLazyBoolCalculate),
61 m_curr_pid_is_valid(eLazyBoolCalculate),
62 m_qProcessInfo_is_valid(eLazyBoolCalculate),
63 m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
64 m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
65 m_supports_memory_region_info(eLazyBoolCalculate),
66 m_supports_watchpoint_support_info(eLazyBoolCalculate),
67 m_supports_detach_stay_stopped(eLazyBoolCalculate),
68 m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
69 m_attach_or_wait_reply(eLazyBoolCalculate),
70 m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000072 m_avoid_g_packets(eLazyBoolCalculate),
73 m_supports_QSaveRegisterState(eLazyBoolCalculate),
74 m_supports_qXfer_auxv_read(eLazyBoolCalculate),
75 m_supports_qXfer_libraries_read(eLazyBoolCalculate),
76 m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
77 m_supports_qXfer_features_read(eLazyBoolCalculate),
Pavel Labath16064d32018-03-20 11:56:24 +000078 m_supports_qXfer_memory_map_read(eLazyBoolCalculate),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000079 m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
80 m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
81 m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000082 m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
Eugene Zemtsov7993cc52017-03-07 21:34:40 +000083 m_supports_QPassSignals(eLazyBoolCalculate),
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +000084 m_supports_error_string_reply(eLazyBoolCalculate),
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
86 m_supports_qUserName(true), m_supports_qGroupName(true),
87 m_supports_qThreadStopInfo(true), m_supports_z0(true),
88 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
89 m_supports_z4(true), m_supports_QEnvironment(true),
90 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
91 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
Pavel Labath2f1fbae2016-09-08 10:07:04 +000092 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
93 m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000094 m_curr_tid_run(LLDB_INVALID_THREAD_ID),
Kate Stoneb9c1b512016-09-06 20:57:50 +000095 m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
Pavel Labath2272c482018-06-18 15:02:23 +000096 m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
97 m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
98 m_max_packet_size(0), m_qSupported_response(),
99 m_supported_async_json_packets_is_valid(false),
Pavel Labath16064d32018-03-20 11:56:24 +0000100 m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
101 m_qXfer_memory_map_loaded(false) {}
Greg Clayton576d8832011-03-22 04:00:09 +0000102
Greg Clayton576d8832011-03-22 04:00:09 +0000103// Destructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
105 if (IsConnected())
106 Disconnect();
Greg Clayton576d8832011-03-22 04:00:09 +0000107}
108
Zachary Turner97206d52017-05-12 04:51:55 +0000109bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 ResetDiscoverableSettings(false);
Greg Claytonfb909312013-11-23 01:58:15 +0000111
Adrian Prantl05097242018-04-30 16:49:04 +0000112 // Start the read thread after we send the handshake ack since if we fail to
113 // send the handshake ack, there is no reason to continue...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 if (SendAck()) {
Jonas Devlieghere135cf982019-06-30 19:00:09 +0000115 // Wait for any responses that might have been queued up in the remote
116 // GDB server and flush them all
117 StringExtractorGDBRemote response;
118 PacketResult packet_result = PacketResult::Success;
119 while (packet_result == PacketResult::Success)
120 packet_result = ReadPacket(response, milliseconds(10), false);
121
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122 // The return value from QueryNoAckModeSupported() is true if the packet
Adrian Prantl05097242018-04-30 16:49:04 +0000123 // was sent and _any_ response (including UNIMPLEMENTED) was received), or
124 // false if no response was received. This quickly tells us if we have a
125 // live connection to a remote GDB server...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126 if (QueryNoAckModeSupported()) {
127 return true;
128 } else {
129 if (error_ptr)
130 error_ptr->SetErrorString("failed to get reply to handshake packet");
Greg Claytonfb909312013-11-23 01:58:15 +0000131 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 } else {
133 if (error_ptr)
134 error_ptr->SetErrorString("failed to send the handshake ack");
135 }
136 return false;
Greg Clayton1cb64962011-03-24 04:28:38 +0000137}
138
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139bool GDBRemoteCommunicationClient::GetEchoSupported() {
140 if (m_supports_qEcho == eLazyBoolCalculate) {
141 GetRemoteQSupported();
142 }
143 return m_supports_qEcho == eLazyBoolYes;
Greg Claytonb30c50c2015-05-29 00:01:55 +0000144}
145
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000146bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
147 if (m_supports_QPassSignals == eLazyBoolCalculate) {
148 GetRemoteQSupported();
149 }
150 return m_supports_QPassSignals == eLazyBoolYes;
151}
152
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
154 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
155 GetRemoteQSupported();
156 }
157 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000158}
159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
161 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
162 GetRemoteQSupported();
163 }
164 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000165}
166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
168 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
169 GetRemoteQSupported();
170 }
171 return m_supports_qXfer_libraries_read == eLazyBoolYes;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000172}
173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
175 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
176 GetRemoteQSupported();
177 }
178 return m_supports_qXfer_auxv_read == eLazyBoolYes;
Steve Pucci03904ac2014-03-04 23:18:46 +0000179}
180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
182 if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
183 GetRemoteQSupported();
184 }
185 return m_supports_qXfer_features_read == eLazyBoolYes;
Colin Rileyc3c95b22015-04-16 15:51:33 +0000186}
187
Pavel Labath16064d32018-03-20 11:56:24 +0000188bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
189 if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
190 GetRemoteQSupported();
191 }
192 return m_supports_qXfer_memory_map_read == eLazyBoolYes;
193}
194
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
196 if (m_max_packet_size == 0) {
197 GetRemoteQSupported();
198 }
199 return m_max_packet_size;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000200}
201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
203 if (m_supports_not_sending_acks == eLazyBoolCalculate) {
204 m_send_acks = true;
205 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton1cb64962011-03-24 04:28:38 +0000206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 // This is the first real packet that we'll send in a debug session and it
Adrian Prantl05097242018-04-30 16:49:04 +0000208 // may take a little longer than normal to receive a reply. Wait at least
209 // 6 seconds for a reply to this packet.
Jason Molenda36a216e2014-07-24 01:36:24 +0000210
Pavel Labath1eff73c2016-11-24 10:54:49 +0000211 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
Colin Rileyc3c95b22015-04-16 15:51:33 +0000212
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000213 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
215 PacketResult::Success) {
216 if (response.IsOKResponse()) {
217 m_send_acks = false;
218 m_supports_not_sending_acks = eLazyBoolYes;
219 }
220 return true;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000221 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222 }
223 return false;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000224}
Greg Clayton576d8832011-03-22 04:00:09 +0000225
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
227 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
228 m_supports_threads_in_stop_reply = eLazyBoolNo;
229
230 StringExtractorGDBRemote response;
231 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
232 false) == PacketResult::Success) {
233 if (response.IsOKResponse())
234 m_supports_threads_in_stop_reply = eLazyBoolYes;
Pavel Labath5c95ee42016-08-30 13:56:11 +0000235 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 }
Pavel Labath0faf3732016-08-25 08:34:57 +0000237}
Greg Clayton576d8832011-03-22 04:00:09 +0000238
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
240 if (m_attach_or_wait_reply == eLazyBoolCalculate) {
241 m_attach_or_wait_reply = eLazyBoolNo;
Greg Clayton576d8832011-03-22 04:00:09 +0000242
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243 StringExtractorGDBRemote response;
244 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
245 false) == PacketResult::Success) {
246 if (response.IsOKResponse())
247 m_attach_or_wait_reply = eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +0000248 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 }
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000250 return m_attach_or_wait_reply == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +0000251}
252
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
254 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
255 m_prepare_for_reg_writing_reply = eLazyBoolNo;
256
257 StringExtractorGDBRemote response;
258 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
259 false) == PacketResult::Success) {
260 if (response.IsOKResponse())
261 m_prepare_for_reg_writing_reply = eLazyBoolYes;
262 }
263 }
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000264 return m_prepare_for_reg_writing_reply == eLazyBoolYes;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265}
266
267void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000268 if (!did_exec) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000269 // Hard reset everything, this is when we first connect to a GDB server
270 m_supports_not_sending_acks = eLazyBoolCalculate;
271 m_supports_thread_suffix = eLazyBoolCalculate;
272 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
273 m_supports_vCont_c = eLazyBoolCalculate;
274 m_supports_vCont_C = eLazyBoolCalculate;
275 m_supports_vCont_s = eLazyBoolCalculate;
276 m_supports_vCont_S = eLazyBoolCalculate;
277 m_supports_p = eLazyBoolCalculate;
278 m_supports_x = eLazyBoolCalculate;
279 m_supports_QSaveRegisterState = eLazyBoolCalculate;
280 m_qHostInfo_is_valid = eLazyBoolCalculate;
281 m_curr_pid_is_valid = eLazyBoolCalculate;
282 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
283 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
284 m_supports_memory_region_info = eLazyBoolCalculate;
285 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
286 m_attach_or_wait_reply = eLazyBoolCalculate;
287 m_avoid_g_packets = eLazyBoolCalculate;
288 m_supports_qXfer_auxv_read = eLazyBoolCalculate;
289 m_supports_qXfer_libraries_read = eLazyBoolCalculate;
290 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
291 m_supports_qXfer_features_read = eLazyBoolCalculate;
Pavel Labath16064d32018-03-20 11:56:24 +0000292 m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
294 m_supports_qProcessInfoPID = true;
295 m_supports_qfProcessInfo = true;
296 m_supports_qUserName = true;
297 m_supports_qGroupName = true;
298 m_supports_qThreadStopInfo = true;
299 m_supports_z0 = true;
300 m_supports_z1 = true;
301 m_supports_z2 = true;
302 m_supports_z3 = true;
303 m_supports_z4 = true;
304 m_supports_QEnvironment = true;
305 m_supports_QEnvironmentHexEncoded = true;
306 m_supports_qSymbol = true;
307 m_qSymbol_requests_done = false;
308 m_supports_qModuleInfo = true;
309 m_host_arch.Clear();
Pavel Labath2272c482018-06-18 15:02:23 +0000310 m_os_version = llvm::VersionTuple();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000311 m_os_build.clear();
312 m_os_kernel.clear();
313 m_hostname.clear();
314 m_gdb_server_name.clear();
315 m_gdb_server_version = UINT32_MAX;
Pavel Labath1eff73c2016-11-24 10:54:49 +0000316 m_default_packet_timeout = seconds(0);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 m_max_packet_size = 0;
318 m_qSupported_response.clear();
319 m_supported_async_json_packets_is_valid = false;
320 m_supported_async_json_packets_sp.reset();
Pavel Labath2f1fbae2016-09-08 10:07:04 +0000321 m_supports_jModulesInfo = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322 }
323
Adrian Prantl05097242018-04-30 16:49:04 +0000324 // These flags should be reset when we first connect to a GDB server and when
325 // our inferior process execs
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 m_qProcessInfo_is_valid = eLazyBoolCalculate;
327 m_process_arch.Clear();
328}
329
330void GDBRemoteCommunicationClient::GetRemoteQSupported() {
331 // Clear out any capabilities we expect to see in the qSupported response
332 m_supports_qXfer_auxv_read = eLazyBoolNo;
333 m_supports_qXfer_libraries_read = eLazyBoolNo;
334 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
335 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
336 m_supports_qXfer_features_read = eLazyBoolNo;
Pavel Labath16064d32018-03-20 11:56:24 +0000337 m_supports_qXfer_memory_map_read = eLazyBoolNo;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
339 // not, we assume no limit
340
341 // build the qSupported packet
Tatyana Krasnukhafaf6b252019-10-17 15:16:21 +0000342 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 StreamString packet;
344 packet.PutCString("qSupported");
345 for (uint32_t i = 0; i < features.size(); ++i) {
346 packet.PutCString(i == 0 ? ":" : ";");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000347 packet.PutCString(features[i]);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348 }
349
350 StringExtractorGDBRemote response;
Zachary Turnerc1564272016-11-16 21:15:24 +0000351 if (SendPacketAndWaitForResponse(packet.GetString(), response,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352 /*send_async=*/false) ==
353 PacketResult::Success) {
Jonas Devlieghered35b42f2019-08-21 04:55:56 +0000354 const char *response_cstr = response.GetStringRef().data();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355
356 // Hang on to the qSupported packet, so that platforms can do custom
Adrian Prantl05097242018-04-30 16:49:04 +0000357 // configuration of the transport before attaching/launching the process.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 m_qSupported_response = response_cstr;
359
360 if (::strstr(response_cstr, "qXfer:auxv:read+"))
361 m_supports_qXfer_auxv_read = eLazyBoolYes;
362 if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
363 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
364 if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
365 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
366 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
367 }
368 if (::strstr(response_cstr, "qXfer:libraries:read+"))
369 m_supports_qXfer_libraries_read = eLazyBoolYes;
370 if (::strstr(response_cstr, "qXfer:features:read+"))
371 m_supports_qXfer_features_read = eLazyBoolYes;
Pavel Labath16064d32018-03-20 11:56:24 +0000372 if (::strstr(response_cstr, "qXfer:memory-map:read+"))
373 m_supports_qXfer_memory_map_read = eLazyBoolYes;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374
375 // Look for a list of compressions in the features list e.g.
Adrian Prantl05097242018-04-30 16:49:04 +0000376 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
377 // deflate,lzma
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378 const char *features_list = ::strstr(response_cstr, "qXfer:features:");
379 if (features_list) {
380 const char *compressions =
381 ::strstr(features_list, "SupportedCompressions=");
382 if (compressions) {
383 std::vector<std::string> supported_compressions;
384 compressions += sizeof("SupportedCompressions=") - 1;
385 const char *end_of_compressions = strchr(compressions, ';');
Konrad Kleine248a1302019-05-23 11:14:47 +0000386 if (end_of_compressions == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000387 end_of_compressions = strchr(compressions, '\0');
388 }
389 const char *current_compression = compressions;
390 while (current_compression < end_of_compressions) {
391 const char *next_compression_name = strchr(current_compression, ',');
392 const char *end_of_this_word = next_compression_name;
Konrad Kleine248a1302019-05-23 11:14:47 +0000393 if (next_compression_name == nullptr ||
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394 end_of_compressions < next_compression_name) {
395 end_of_this_word = end_of_compressions;
396 }
397
398 if (end_of_this_word) {
399 if (end_of_this_word == current_compression) {
400 current_compression++;
401 } else {
402 std::string this_compression(
403 current_compression, end_of_this_word - current_compression);
404 supported_compressions.push_back(this_compression);
405 current_compression = end_of_this_word + 1;
406 }
407 } else {
408 supported_compressions.push_back(current_compression);
409 current_compression = end_of_compressions;
410 }
411 }
412
413 if (supported_compressions.size() > 0) {
414 MaybeEnableCompression(supported_compressions);
415 }
416 }
417 }
418
419 if (::strstr(response_cstr, "qEcho"))
420 m_supports_qEcho = eLazyBoolYes;
421 else
422 m_supports_qEcho = eLazyBoolNo;
423
Eugene Zemtsov7993cc52017-03-07 21:34:40 +0000424 if (::strstr(response_cstr, "QPassSignals+"))
425 m_supports_QPassSignals = eLazyBoolYes;
426 else
427 m_supports_QPassSignals = eLazyBoolNo;
428
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429 const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
430 if (packet_size_str) {
431 StringExtractorGDBRemote packet_response(packet_size_str +
432 strlen("PacketSize="));
433 m_max_packet_size =
434 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
435 if (m_max_packet_size == 0) {
436 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
437 Log *log(
438 ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000439 LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000440 }
441 }
442 }
443}
444
445bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
446 if (m_supports_thread_suffix == eLazyBoolCalculate) {
447 StringExtractorGDBRemote response;
448 m_supports_thread_suffix = eLazyBoolNo;
449 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
450 false) == PacketResult::Success) {
451 if (response.IsOKResponse())
452 m_supports_thread_suffix = eLazyBoolYes;
453 }
454 }
455 return m_supports_thread_suffix;
456}
457bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
458 if (m_supports_vCont_c == eLazyBoolCalculate) {
459 StringExtractorGDBRemote response;
460 m_supports_vCont_any = eLazyBoolNo;
461 m_supports_vCont_all = eLazyBoolNo;
462 m_supports_vCont_c = eLazyBoolNo;
463 m_supports_vCont_C = eLazyBoolNo;
464 m_supports_vCont_s = eLazyBoolNo;
465 m_supports_vCont_S = eLazyBoolNo;
466 if (SendPacketAndWaitForResponse("vCont?", response, false) ==
467 PacketResult::Success) {
Jonas Devlieghered35b42f2019-08-21 04:55:56 +0000468 const char *response_cstr = response.GetStringRef().data();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000469 if (::strstr(response_cstr, ";c"))
470 m_supports_vCont_c = eLazyBoolYes;
471
472 if (::strstr(response_cstr, ";C"))
473 m_supports_vCont_C = eLazyBoolYes;
474
475 if (::strstr(response_cstr, ";s"))
476 m_supports_vCont_s = eLazyBoolYes;
477
478 if (::strstr(response_cstr, ";S"))
479 m_supports_vCont_S = eLazyBoolYes;
480
481 if (m_supports_vCont_c == eLazyBoolYes &&
482 m_supports_vCont_C == eLazyBoolYes &&
483 m_supports_vCont_s == eLazyBoolYes &&
484 m_supports_vCont_S == eLazyBoolYes) {
485 m_supports_vCont_all = eLazyBoolYes;
486 }
487
488 if (m_supports_vCont_c == eLazyBoolYes ||
489 m_supports_vCont_C == eLazyBoolYes ||
490 m_supports_vCont_s == eLazyBoolYes ||
491 m_supports_vCont_S == eLazyBoolYes) {
492 m_supports_vCont_any = eLazyBoolYes;
493 }
494 }
495 }
496
497 switch (flavor) {
498 case 'a':
499 return m_supports_vCont_any;
500 case 'A':
501 return m_supports_vCont_all;
502 case 'c':
503 return m_supports_vCont_c;
504 case 'C':
505 return m_supports_vCont_C;
506 case 's':
507 return m_supports_vCont_s;
508 case 'S':
509 return m_supports_vCont_S;
510 default:
511 break;
512 }
513 return false;
514}
515
Pavel Labath4b6f9592016-08-18 08:30:03 +0000516GDBRemoteCommunication::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
518 lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
519 bool send_async) {
520 Lock lock(*this, send_async);
521 if (!lock) {
522 if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
523 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000524 LLDB_LOGF(log,
525 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
526 "for %s packet.",
527 __FUNCTION__, payload.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528 return PacketResult::ErrorNoSequenceLock;
529 }
Pavel Labath5c95ee42016-08-30 13:56:11 +0000530
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531 if (GetThreadSuffixSupported())
532 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
533 else {
534 if (!SetCurrentThread(tid))
535 return PacketResult::ErrorSendFailed;
536 }
Pavel Labath4b6f9592016-08-18 08:30:03 +0000537
Kate Stoneb9c1b512016-09-06 20:57:50 +0000538 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
Pavel Labath4b6f9592016-08-18 08:30:03 +0000539}
540
Adrian Prantl05097242018-04-30 16:49:04 +0000541// Check if the target supports 'p' packet. It sends out a 'p' packet and
542// checks the response. A normal packet will tell us that support is available.
Sean Callananb1de1142013-09-04 23:24:15 +0000543//
544// Takes a valid thread ID because p needs to apply to a thread.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
Guilherme Andradeb1b70f62019-11-07 10:38:25 +0100546 if (m_supports_p == eLazyBoolCalculate)
547 m_supports_p = GetThreadPacketSupported(tid, "p0");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000548 return m_supports_p;
Hafiz Abid Qadeer9a78cdf2013-08-29 09:09:45 +0000549}
Greg Clayton576d8832011-03-22 04:00:09 +0000550
Guilherme Andradeb1b70f62019-11-07 10:38:25 +0100551LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(
552 lldb::tid_t tid, llvm::StringRef packetStr) {
553 StreamString payload;
554 payload.PutCString(packetStr);
555 StringExtractorGDBRemote response;
556 if (SendThreadSpecificPacketAndWaitForResponse(
557 tid, std::move(payload), response, false) == PacketResult::Success &&
558 response.IsNormalResponse()) {
559 return eLazyBoolYes;
560 }
561 return eLazyBoolNo;
562}
563
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
565 // Get information on all threads at one using the "jThreadsInfo" packet
566 StructuredData::ObjectSP object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000567
Kate Stoneb9c1b512016-09-06 20:57:50 +0000568 if (m_supports_jThreadsInfo) {
569 StringExtractorGDBRemote response;
570 response.SetResponseValidatorToJSON();
571 if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
572 PacketResult::Success) {
573 if (response.IsUnsupportedResponse()) {
574 m_supports_jThreadsInfo = false;
575 } else if (!response.Empty()) {
Benjamin Krameradcd0262020-01-28 20:23:46 +0100576 object_sp =
577 StructuredData::ParseJSON(std::string(response.GetStringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000578 }
Greg Clayton358cf1e2015-06-25 21:46:34 +0000579 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580 }
581 return object_sp;
Greg Clayton358cf1e2015-06-25 21:46:34 +0000582}
583
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
585 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
586 StringExtractorGDBRemote response;
587 m_supports_jThreadExtendedInfo = eLazyBoolNo;
588 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
589 PacketResult::Success) {
590 if (response.IsOKResponse()) {
591 m_supports_jThreadExtendedInfo = eLazyBoolYes;
592 }
Jason Molenda705b1802014-06-13 02:37:02 +0000593 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 }
595 return m_supports_jThreadExtendedInfo;
Jason Molenda705b1802014-06-13 02:37:02 +0000596}
597
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000598void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
599 if (m_supports_error_string_reply == eLazyBoolCalculate) {
600 StringExtractorGDBRemote response;
Adrian Prantl05097242018-04-30 16:49:04 +0000601 // We try to enable error strings in remote packets but if we fail, we just
602 // work in the older way.
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +0000603 m_supports_error_string_reply = eLazyBoolNo;
604 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
605 PacketResult::Success) {
606 if (response.IsOKResponse()) {
607 m_supports_error_string_reply = eLazyBoolYes;
608 }
609 }
610 }
611}
612
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
614 if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
615 StringExtractorGDBRemote response;
616 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
617 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
618 response,
619 false) == PacketResult::Success) {
620 if (response.IsOKResponse()) {
621 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
622 }
Jason Molenda20ee21b2015-07-10 23:15:22 +0000623 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624 }
625 return m_supports_jLoadedDynamicLibrariesInfos;
Jason Molenda20ee21b2015-07-10 23:15:22 +0000626}
627
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
629 if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
630 StringExtractorGDBRemote response;
631 m_supports_jGetSharedCacheInfo = eLazyBoolNo;
632 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
633 PacketResult::Success) {
634 if (response.IsOKResponse()) {
635 m_supports_jGetSharedCacheInfo = eLazyBoolYes;
636 }
Jason Molenda37397352016-07-22 00:17:55 +0000637 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000638 }
639 return m_supports_jGetSharedCacheInfo;
Jason Molenda37397352016-07-22 00:17:55 +0000640}
641
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642bool GDBRemoteCommunicationClient::GetxPacketSupported() {
643 if (m_supports_x == eLazyBoolCalculate) {
644 StringExtractorGDBRemote response;
645 m_supports_x = eLazyBoolNo;
646 char packet[256];
647 snprintf(packet, sizeof(packet), "x0,0");
648 if (SendPacketAndWaitForResponse(packet, response, false) ==
649 PacketResult::Success) {
650 if (response.IsOKResponse())
651 m_supports_x = eLazyBoolYes;
Jason Molendabdc4f122014-05-06 02:59:39 +0000652 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653 }
654 return m_supports_x;
Jason Molendabdc4f122014-05-06 02:59:39 +0000655}
656
Greg Clayton3dedae12013-12-06 21:45:27 +0000657GDBRemoteCommunicationClient::PacketResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
659 const char *payload_prefix, std::string &response_string) {
660 Lock lock(*this, false);
661 if (!lock) {
662 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
663 GDBR_LOG_PACKETS));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000664 LLDB_LOGF(log,
665 "error: failed to get packet sequence mutex, not sending "
666 "packets with prefix '%s'",
667 payload_prefix);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668 return PacketResult::ErrorNoSequenceLock;
669 }
670
671 response_string = "";
672 std::string payload_prefix_str(payload_prefix);
673 unsigned int response_size = 0x1000;
674 if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
675 response_size = GetRemoteMaxPacketSize();
676 }
677
678 for (unsigned int offset = 0; true; offset += response_size) {
679 StringExtractorGDBRemote this_response;
680 // Construct payload
681 char sizeDescriptor[128];
682 snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
683 response_size);
684 PacketResult result = SendPacketAndWaitForResponseNoLock(
685 payload_prefix_str + sizeDescriptor, this_response);
686 if (result != PacketResult::Success)
687 return result;
688
Benjamin Krameradcd0262020-01-28 20:23:46 +0100689 const std::string &this_string = std::string(this_response.GetStringRef());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690
691 // Check for m or l as first character; l seems to mean this is the last
692 // chunk
693 char first_char = *this_string.c_str();
694 if (first_char != 'm' && first_char != 'l') {
695 return PacketResult::ErrorReplyInvalid;
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000696 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697 // Concatenate the result so far (skipping 'm' or 'l')
698 response_string.append(this_string, 1, std::string::npos);
699 if (first_char == 'l')
700 // We're done
701 return PacketResult::Success;
702 }
Steve Pucci5ae54ae2014-01-25 05:46:51 +0000703}
704
Kate Stoneb9c1b512016-09-06 20:57:50 +0000705lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
706 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
707 return m_curr_pid;
Jaydeep Patil1142f832015-08-13 03:46:36 +0000708
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709 // First try to retrieve the pid via the qProcessInfo request.
710 GetCurrentProcessInfo(allow_lazy);
711 if (m_curr_pid_is_valid == eLazyBoolYes) {
712 // We really got it.
713 return m_curr_pid;
714 } else {
715 // If we don't get a response for qProcessInfo, check if $qC gives us a
Adrian Prantl05097242018-04-30 16:49:04 +0000716 // result. $qC only returns a real process id on older debugserver and
717 // lldb-platform stubs. The gdb remote protocol documents $qC as returning
718 // the thread id, which newer debugserver and lldb-gdbserver stubs return
719 // correctly.
Greg Clayton576d8832011-03-22 04:00:09 +0000720 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000721 if (SendPacketAndWaitForResponse("qC", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +0000722 PacketResult::Success) {
723 if (response.GetChar() == 'Q') {
724 if (response.GetChar() == 'C') {
725 m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
726 if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
727 m_curr_pid_is_valid = eLazyBoolYes;
728 return m_curr_pid;
729 }
Greg Clayton576d8832011-03-22 04:00:09 +0000730 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731 }
Greg Clayton576d8832011-03-22 04:00:09 +0000732 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733
734 // If we don't get a response for $qC, check if $qfThreadID gives us a
735 // result.
736 if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
737 std::vector<lldb::tid_t> thread_ids;
738 bool sequence_mutex_unavailable;
739 size_t size;
740 size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000741 if (size && !sequence_mutex_unavailable) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742 m_curr_pid = thread_ids.front();
743 m_curr_pid_is_valid = eLazyBoolYes;
744 return m_curr_pid;
745 }
Greg Clayton576d8832011-03-22 04:00:09 +0000746 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000747 }
748
749 return LLDB_INVALID_PROCESS_ID;
Greg Clayton576d8832011-03-22 04:00:09 +0000750}
751
Kate Stoneb9c1b512016-09-06 20:57:50 +0000752bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
753 error_str.clear();
754 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000755 if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
756 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000757 if (response.IsOKResponse())
758 return true;
759 if (response.GetChar() == 'E') {
760 // A string the describes what failed when launching...
Benjamin Krameradcd0262020-01-28 20:23:46 +0100761 error_str = std::string(response.GetStringRef().substr(1));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000762 } else {
763 error_str.assign("unknown error occurred launching process");
Greg Claytonfbb76342013-11-20 21:07:01 +0000764 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000765 } else {
766 error_str.assign("timed out waiting for app to launch");
767 }
768 return false;
Greg Clayton576d8832011-03-22 04:00:09 +0000769}
770
Kate Stoneb9c1b512016-09-06 20:57:50 +0000771int GDBRemoteCommunicationClient::SendArgumentsPacket(
772 const ProcessLaunchInfo &launch_info) {
773 // Since we don't get the send argv0 separate from the executable path, we
Adrian Prantl05097242018-04-30 16:49:04 +0000774 // need to make sure to use the actual executable path found in the
775 // launch_info...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776 std::vector<const char *> argv;
777 FileSpec exe_file = launch_info.GetExecutableFile();
778 std::string exe_path;
Konrad Kleine248a1302019-05-23 11:14:47 +0000779 const char *arg = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000780 const Args &launch_args = launch_info.GetArguments();
781 if (exe_file)
782 exe_path = exe_file.GetPath(false);
783 else {
784 arg = launch_args.GetArgumentAtIndex(0);
785 if (arg)
786 exe_path = arg;
787 }
788 if (!exe_path.empty()) {
789 argv.push_back(exe_path.c_str());
Konrad Kleine248a1302019-05-23 11:14:47 +0000790 for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000791 ++i) {
792 if (arg)
793 argv.push_back(arg);
Greg Clayton576d8832011-03-22 04:00:09 +0000794 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 }
796 if (!argv.empty()) {
Vince Harrone0be4252015-02-06 18:32:57 +0000797 StreamString packet;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000798 packet.PutChar('A');
799 for (size_t i = 0, n = argv.size(); i < n; ++i) {
800 arg = argv[i];
801 const int arg_len = strlen(arg);
802 if (i > 0)
803 packet.PutChar(',');
804 packet.Printf("%i,%i,", arg_len * 2, (int)i);
805 packet.PutBytesAsRawHex8(arg, arg_len);
806 }
807
Vince Harrone0be4252015-02-06 18:32:57 +0000808 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000809 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
810 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 if (response.IsOKResponse())
Vince Harrone0be4252015-02-06 18:32:57 +0000812 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 uint8_t error = response.GetError();
814 if (error)
Johnny Chen64637202012-05-23 21:09:52 +0000815 return error;
816 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000817 }
818 return -1;
819}
Johnny Chen64637202012-05-23 21:09:52 +0000820
Pavel Labath62930e52018-01-10 11:57:31 +0000821int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
822 for (const auto &KV : env) {
823 int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
824 if (r != 0)
825 return r;
826 }
827 return 0;
828}
829
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830int GDBRemoteCommunicationClient::SendEnvironmentPacket(
831 char const *name_equal_value) {
832 if (name_equal_value && name_equal_value[0]) {
833 StreamString packet;
834 bool send_hex_encoding = false;
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000835 for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
836 ++p) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000837 if (isprint(*p)) {
838 switch (*p) {
839 case '$':
840 case '#':
841 case '*':
842 case '}':
843 send_hex_encoding = true;
844 break;
845 default:
846 break;
Johnny Chen64637202012-05-23 21:09:52 +0000847 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000848 } else {
849 // We have non printable characters, lets hex encode this...
850 send_hex_encoding = true;
851 }
Johnny Chen64637202012-05-23 21:09:52 +0000852 }
853
Greg Claytonfbb76342013-11-20 21:07:01 +0000854 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000855 if (send_hex_encoding) {
856 if (m_supports_QEnvironmentHexEncoded) {
857 packet.PutCString("QEnvironmentHexEncoded:");
858 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000859 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
860 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861 if (response.IsOKResponse())
862 return 0;
863 uint8_t error = response.GetError();
864 if (error)
865 return error;
866 if (response.IsUnsupportedResponse())
867 m_supports_QEnvironmentHexEncoded = false;
868 }
869 }
870
871 } else if (m_supports_QEnvironment) {
872 packet.Printf("QEnvironment:%s", name_equal_value);
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000873 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
874 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000875 if (response.IsOKResponse())
876 return 0;
877 uint8_t error = response.GetError();
878 if (error)
879 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000880 if (response.IsUnsupportedResponse())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000881 m_supports_QEnvironment = false;
882 }
Greg Claytonfbb76342013-11-20 21:07:01 +0000883 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884 }
885 return -1;
Greg Claytonfbb76342013-11-20 21:07:01 +0000886}
887
Kate Stoneb9c1b512016-09-06 20:57:50 +0000888int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
889 if (arch && arch[0]) {
890 StreamString packet;
891 packet.Printf("QLaunchArch:%s", arch);
892 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000893 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
894 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000895 if (response.IsOKResponse())
896 return 0;
897 uint8_t error = response.GetError();
898 if (error)
899 return error;
900 }
901 }
902 return -1;
903}
Chaoren Lind3173f32015-05-29 19:52:29 +0000904
Kate Stoneb9c1b512016-09-06 20:57:50 +0000905int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
906 char const *data, bool *was_supported) {
907 if (data && *data != '\0') {
908 StreamString packet;
909 packet.Printf("QSetProcessEvent:%s", data);
910 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +0000911 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
912 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000913 if (response.IsOKResponse()) {
914 if (was_supported)
915 *was_supported = true;
916 return 0;
917 } else if (response.IsUnsupportedResponse()) {
918 if (was_supported)
919 *was_supported = false;
920 return -1;
921 } else {
922 uint8_t error = response.GetError();
923 if (was_supported)
924 *was_supported = true;
925 if (error)
926 return error;
927 }
928 }
929 }
930 return -1;
931}
932
Pavel Labath2272c482018-06-18 15:02:23 +0000933llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
934 GetHostInfo();
935 return m_os_version;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000936}
937
Adrian Prantl24610612019-09-04 17:23:15 +0000938llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
939 GetHostInfo();
940 return m_maccatalyst_version;
941}
942
Kate Stoneb9c1b512016-09-06 20:57:50 +0000943bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
944 if (GetHostInfo()) {
945 if (!m_os_build.empty()) {
946 s = m_os_build;
947 return true;
948 }
949 }
950 s.clear();
951 return false;
952}
953
954bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
955 if (GetHostInfo()) {
956 if (!m_os_kernel.empty()) {
957 s = m_os_kernel;
958 return true;
959 }
960 }
961 s.clear();
962 return false;
963}
964
965bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
966 if (GetHostInfo()) {
967 if (!m_hostname.empty()) {
968 s = m_hostname;
969 return true;
970 }
971 }
972 s.clear();
973 return false;
974}
975
976ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
977 if (GetHostInfo())
978 return m_host_arch;
979 return ArchSpec();
980}
981
982const lldb_private::ArchSpec &
983GDBRemoteCommunicationClient::GetProcessArchitecture() {
984 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
985 GetCurrentProcessInfo();
986 return m_process_arch;
987}
988
989bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
990 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
991 m_gdb_server_name.clear();
992 m_gdb_server_version = 0;
993 m_qGDBServerVersion_is_valid = eLazyBoolNo;
994
995 StringExtractorGDBRemote response;
996 if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
997 PacketResult::Success) {
998 if (response.IsNormalResponse()) {
999 llvm::StringRef name, value;
1000 bool success = false;
1001 while (response.GetNameColonValue(name, value)) {
1002 if (name.equals("name")) {
1003 success = true;
Benjamin Krameradcd0262020-01-28 20:23:46 +01001004 m_gdb_server_name = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 } else if (name.equals("version")) {
1006 llvm::StringRef major, minor;
1007 std::tie(major, minor) = value.split('.');
1008 if (!major.getAsInteger(0, m_gdb_server_version))
1009 success = true;
1010 }
Greg Clayton576d8832011-03-22 04:00:09 +00001011 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001012 if (success)
1013 m_qGDBServerVersion_is_valid = eLazyBoolYes;
1014 }
Greg Clayton576d8832011-03-22 04:00:09 +00001015 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001016 }
1017 return m_qGDBServerVersion_is_valid == eLazyBoolYes;
Greg Clayton576d8832011-03-22 04:00:09 +00001018}
1019
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020void GDBRemoteCommunicationClient::MaybeEnableCompression(
1021 std::vector<std::string> supported_compressions) {
1022 CompressionType avail_type = CompressionType::None;
1023 std::string avail_name;
1024
1025#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001026 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027 for (auto compression : supported_compressions) {
1028 if (compression == "lzfse") {
1029 avail_type = CompressionType::LZFSE;
1030 avail_name = compression;
1031 break;
1032 }
1033 }
1034 }
1035#endif
1036
1037#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001038 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039 for (auto compression : supported_compressions) {
1040 if (compression == "zlib-deflate") {
1041 avail_type = CompressionType::ZlibDeflate;
1042 avail_name = compression;
1043 break;
1044 }
1045 }
1046 }
1047#endif
1048
Saleem Abdulrasoolabb00752020-01-01 15:01:04 -08001049#if LLVM_ENABLE_ZLIB
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 if (avail_type == CompressionType::None) {
1051 for (auto compression : supported_compressions) {
1052 if (compression == "zlib-deflate") {
1053 avail_type = CompressionType::ZlibDeflate;
1054 avail_name = compression;
1055 break;
1056 }
1057 }
1058 }
1059#endif
1060
1061#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001062 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063 for (auto compression : supported_compressions) {
1064 if (compression == "lz4") {
1065 avail_type = CompressionType::LZ4;
1066 avail_name = compression;
1067 break;
1068 }
1069 }
1070 }
1071#endif
1072
1073#if defined(HAVE_LIBCOMPRESSION)
Vedant Kumar606908a2017-12-06 19:21:10 +00001074 if (avail_type == CompressionType::None) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 for (auto compression : supported_compressions) {
1076 if (compression == "lzma") {
1077 avail_type = CompressionType::LZMA;
1078 avail_name = compression;
1079 break;
1080 }
1081 }
1082 }
1083#endif
1084
1085 if (avail_type != CompressionType::None) {
Greg Clayton576d8832011-03-22 04:00:09 +00001086 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001087 std::string packet = "QEnableCompression:type:" + avail_name + ";";
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001088 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 PacketResult::Success)
1090 return;
1091
1092 if (response.IsOKResponse()) {
1093 m_compression_type = avail_type;
Greg Clayton576d8832011-03-22 04:00:09 +00001094 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001095 }
Greg Clayton576d8832011-03-22 04:00:09 +00001096}
Greg Clayton32e0a752011-03-30 18:16:51 +00001097
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
1099 if (GetGDBServerVersion()) {
1100 if (!m_gdb_server_name.empty())
1101 return m_gdb_server_name.c_str();
1102 }
Konrad Kleine248a1302019-05-23 11:14:47 +00001103 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104}
1105
1106uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1107 if (GetGDBServerVersion())
1108 return m_gdb_server_version;
1109 return 0;
1110}
1111
1112bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
1113 StringExtractorGDBRemote response;
1114 if (SendPacketAndWaitForResponse("qC", response, false) !=
1115 PacketResult::Success)
1116 return false;
1117
1118 if (!response.IsNormalResponse())
1119 return false;
1120
1121 if (response.GetChar() == 'Q' && response.GetChar() == 'C')
1122 tid = response.GetHexMaxU32(true, -1);
1123
1124 return true;
1125}
1126
1127bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
1128 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
1129
1130 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
Pavel Labathe7ec0832018-08-31 05:34:03 +00001131 // host info computation can require DNS traffic and shelling out to external processes.
1132 // Increase the timeout to account for that.
1133 ScopedTimeout timeout(*this, seconds(10));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134 m_qHostInfo_is_valid = eLazyBoolNo;
Jim Ingham106d0282014-06-25 02:32:56 +00001135 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
1137 PacketResult::Success) {
1138 if (response.IsNormalResponse()) {
Zachary Turner54695a32016-08-29 19:58:14 +00001139 llvm::StringRef name;
1140 llvm::StringRef value;
Jason Molenda89c37492014-01-27 22:23:20 +00001141 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1142 uint32_t sub = 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001143 std::string arch_name;
1144 std::string os_name;
Adrian Prantl24610612019-09-04 17:23:15 +00001145 std::string environment;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146 std::string vendor_name;
1147 std::string triple;
1148 std::string distribution_id;
1149 uint32_t pointer_byte_size = 0;
1150 ByteOrder byte_order = eByteOrderInvalid;
1151 uint32_t num_keys_decoded = 0;
1152 while (response.GetNameColonValue(name, value)) {
1153 if (name.equals("cputype")) {
1154 // exception type in big endian hex
1155 if (!value.getAsInteger(0, cpu))
1156 ++num_keys_decoded;
1157 } else if (name.equals("cpusubtype")) {
1158 // exception count in big endian hex
1159 if (!value.getAsInteger(0, sub))
1160 ++num_keys_decoded;
1161 } else if (name.equals("arch")) {
Benjamin Krameradcd0262020-01-28 20:23:46 +01001162 arch_name = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001163 ++num_keys_decoded;
1164 } else if (name.equals("triple")) {
1165 StringExtractor extractor(value);
1166 extractor.GetHexByteString(triple);
1167 ++num_keys_decoded;
1168 } else if (name.equals("distribution_id")) {
1169 StringExtractor extractor(value);
1170 extractor.GetHexByteString(distribution_id);
1171 ++num_keys_decoded;
1172 } else if (name.equals("os_build")) {
1173 StringExtractor extractor(value);
1174 extractor.GetHexByteString(m_os_build);
1175 ++num_keys_decoded;
1176 } else if (name.equals("hostname")) {
1177 StringExtractor extractor(value);
1178 extractor.GetHexByteString(m_hostname);
1179 ++num_keys_decoded;
1180 } else if (name.equals("os_kernel")) {
1181 StringExtractor extractor(value);
1182 extractor.GetHexByteString(m_os_kernel);
1183 ++num_keys_decoded;
1184 } else if (name.equals("ostype")) {
Adrian Prantl24610612019-09-04 17:23:15 +00001185 if (value.equals("maccatalyst")) {
1186 os_name = "ios";
1187 environment = "macabi";
1188 } else
Benjamin Krameradcd0262020-01-28 20:23:46 +01001189 os_name = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190 ++num_keys_decoded;
1191 } else if (name.equals("vendor")) {
Benjamin Krameradcd0262020-01-28 20:23:46 +01001192 vendor_name = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001193 ++num_keys_decoded;
1194 } else if (name.equals("endian")) {
1195 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1196 .Case("little", eByteOrderLittle)
1197 .Case("big", eByteOrderBig)
1198 .Case("pdp", eByteOrderPDP)
1199 .Default(eByteOrderInvalid);
1200 if (byte_order != eByteOrderInvalid)
1201 ++num_keys_decoded;
1202 } else if (name.equals("ptrsize")) {
1203 if (!value.getAsInteger(0, pointer_byte_size))
1204 ++num_keys_decoded;
1205 } else if (name.equals("os_version") ||
1206 name.equals(
1207 "version")) // Older debugserver binaries used the
1208 // "version" key instead of
1209 // "os_version"...
1210 {
Pavel Labath2272c482018-06-18 15:02:23 +00001211 if (!m_os_version.tryParse(value))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001212 ++num_keys_decoded;
Adrian Prantl24610612019-09-04 17:23:15 +00001213 } else if (name.equals("maccatalyst_version")) {
1214 if (!m_maccatalyst_version.tryParse(value))
1215 ++num_keys_decoded;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216 } else if (name.equals("watchpoint_exceptions_received")) {
1217 m_watchpoints_trigger_after_instruction =
1218 llvm::StringSwitch<LazyBool>(value)
1219 .Case("before", eLazyBoolNo)
1220 .Case("after", eLazyBoolYes)
1221 .Default(eLazyBoolCalculate);
1222 if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
1223 ++num_keys_decoded;
1224 } else if (name.equals("default_packet_timeout")) {
Pavel Labath3aa04912016-10-31 17:19:42 +00001225 uint32_t timeout_seconds;
1226 if (!value.getAsInteger(0, timeout_seconds)) {
Pavel Labath1eff73c2016-11-24 10:54:49 +00001227 m_default_packet_timeout = seconds(timeout_seconds);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001228 SetPacketTimeout(m_default_packet_timeout);
1229 ++num_keys_decoded;
Greg Clayton32e0a752011-03-30 18:16:51 +00001230 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001231 }
Jason Molenda89c37492014-01-27 22:23:20 +00001232 }
1233
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234 if (num_keys_decoded > 0)
1235 m_qHostInfo_is_valid = eLazyBoolYes;
1236
1237 if (triple.empty()) {
1238 if (arch_name.empty()) {
1239 if (cpu != LLDB_INVALID_CPUTYPE) {
1240 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1241 if (pointer_byte_size) {
1242 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1243 }
1244 if (byte_order != eByteOrderInvalid) {
1245 assert(byte_order == m_host_arch.GetByteOrder());
1246 }
1247
1248 if (!vendor_name.empty())
1249 m_host_arch.GetTriple().setVendorName(
1250 llvm::StringRef(vendor_name));
1251 if (!os_name.empty())
1252 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
Adrian Prantl24610612019-09-04 17:23:15 +00001253 if (!environment.empty())
1254 m_host_arch.GetTriple().setEnvironmentName(environment);
Jason Molenda89c37492014-01-27 22:23:20 +00001255 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001256 } else {
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001257 std::string triple;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001258 triple += arch_name;
1259 if (!vendor_name.empty() || !os_name.empty()) {
1260 triple += '-';
1261 if (vendor_name.empty())
1262 triple += "unknown";
1263 else
1264 triple += vendor_name;
1265 triple += '-';
1266 if (os_name.empty())
1267 triple += "unknown";
1268 else
1269 triple += os_name;
Jason Molendaf17b5ac2012-12-19 02:54:03 +00001270 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001271 m_host_arch.SetTriple(triple.c_str());
Todd Fialac540dd02014-08-26 18:21:02 +00001272
Kate Stoneb9c1b512016-09-06 20:57:50 +00001273 llvm::Triple &host_triple = m_host_arch.GetTriple();
1274 if (host_triple.getVendor() == llvm::Triple::Apple &&
1275 host_triple.getOS() == llvm::Triple::Darwin) {
1276 switch (m_host_arch.GetMachine()) {
1277 case llvm::Triple::aarch64:
Jason Molenda7dd7a362019-10-16 19:14:49 +00001278 case llvm::Triple::aarch64_32:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001279 case llvm::Triple::arm:
1280 case llvm::Triple::thumb:
1281 host_triple.setOS(llvm::Triple::IOS);
Greg Claytonadc00cb2011-05-20 23:38:13 +00001282 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001283 default:
1284 host_triple.setOS(llvm::Triple::MacOSX);
1285 break;
1286 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001287 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001288 if (pointer_byte_size) {
1289 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1290 }
1291 if (byte_order != eByteOrderInvalid) {
1292 assert(byte_order == m_host_arch.GetByteOrder());
1293 }
1294 }
1295 } else {
1296 m_host_arch.SetTriple(triple.c_str());
1297 if (pointer_byte_size) {
1298 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1299 }
1300 if (byte_order != eByteOrderInvalid) {
1301 assert(byte_order == m_host_arch.GetByteOrder());
1302 }
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001303
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001304 LLDB_LOGF(log,
1305 "GDBRemoteCommunicationClient::%s parsed host "
1306 "architecture as %s, triple as %s from triple text %s",
1307 __FUNCTION__,
1308 m_host_arch.GetArchitectureName()
1309 ? m_host_arch.GetArchitectureName()
1310 : "<null-arch-name>",
1311 m_host_arch.GetTriple().getTriple().c_str(),
1312 triple.c_str());
Jaydeep Patil630dd7f2015-09-18 05:32:54 +00001313 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001314 if (!distribution_id.empty())
1315 m_host_arch.SetDistributionId(distribution_id.c_str());
1316 }
Greg Claytonadc00cb2011-05-20 23:38:13 +00001317 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001318 }
1319 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Claytonadc00cb2011-05-20 23:38:13 +00001320}
Greg Clayton37a0a242012-04-11 00:24:49 +00001321
Kate Stoneb9c1b512016-09-06 20:57:50 +00001322int GDBRemoteCommunicationClient::SendAttach(
1323 lldb::pid_t pid, StringExtractorGDBRemote &response) {
1324 if (pid != LLDB_INVALID_PROCESS_ID) {
1325 char packet[64];
1326 const int packet_len =
1327 ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001328 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001329 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001330 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001331 PacketResult::Success) {
1332 if (response.IsErrorResponse())
1333 return response.GetError();
1334 return 0;
1335 }
1336 }
1337 return -1;
1338}
1339
1340int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
1341 size_t data_len) {
1342 StreamString packet;
1343 packet.PutCString("I");
1344 packet.PutBytesAsRawHex8(data, data_len);
1345 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001346 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1347 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001348 return 0;
1349 }
1350 return response.GetError();
1351}
1352
1353const lldb_private::ArchSpec &
1354GDBRemoteCommunicationClient::GetHostArchitecture() {
1355 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1356 GetHostInfo();
1357 return m_host_arch;
1358}
1359
Pavel Labath1eff73c2016-11-24 10:54:49 +00001360seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001361 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1362 GetHostInfo();
1363 return m_default_packet_timeout;
1364}
1365
1366addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
1367 uint32_t permissions) {
1368 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1369 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1370 char packet[64];
1371 const int packet_len = ::snprintf(
1372 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1373 permissions & lldb::ePermissionsReadable ? "r" : "",
1374 permissions & lldb::ePermissionsWritable ? "w" : "",
1375 permissions & lldb::ePermissionsExecutable ? "x" : "");
1376 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001377 UNUSED_IF_ASSERT_DISABLED(packet_len);
Pavel Labath83082a02016-08-18 14:33:55 +00001378 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001379 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001380 PacketResult::Success) {
1381 if (response.IsUnsupportedResponse())
1382 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1383 else if (!response.IsErrorResponse())
1384 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1385 } else {
1386 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1387 }
1388 }
1389 return LLDB_INVALID_ADDRESS;
1390}
1391
1392bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
1393 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1394 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1395 char packet[64];
1396 const int packet_len =
1397 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1398 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001399 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001400 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001401 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001402 PacketResult::Success) {
1403 if (response.IsUnsupportedResponse())
1404 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1405 else if (response.IsOKResponse())
1406 return true;
1407 } else {
1408 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1409 }
1410 }
1411 return false;
1412}
1413
Zachary Turner97206d52017-05-12 04:51:55 +00001414Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
1415 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001416
1417 if (keep_stopped) {
1418 if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
1419 char packet[64];
1420 const int packet_len =
1421 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1422 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001423 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001424 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001425 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001426 PacketResult::Success &&
1427 response.IsOKResponse()) {
1428 m_supports_detach_stay_stopped = eLazyBoolYes;
1429 } else {
1430 m_supports_detach_stay_stopped = eLazyBoolNo;
1431 }
1432 }
1433
1434 if (m_supports_detach_stay_stopped == eLazyBoolNo) {
1435 error.SetErrorString("Stays stopped not supported by this target.");
1436 return error;
1437 } else {
1438 StringExtractorGDBRemote response;
1439 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001440 SendPacketAndWaitForResponse("D1", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001441 if (packet_result != PacketResult::Success)
1442 error.SetErrorString("Sending extended disconnect packet failed.");
1443 }
1444 } else {
1445 StringExtractorGDBRemote response;
1446 PacketResult packet_result =
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001447 SendPacketAndWaitForResponse("D", response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001448 if (packet_result != PacketResult::Success)
1449 error.SetErrorString("Sending disconnect packet failed.");
1450 }
1451 return error;
1452}
1453
Zachary Turner97206d52017-05-12 04:51:55 +00001454Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001455 lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
Zachary Turner97206d52017-05-12 04:51:55 +00001456 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001457 region_info.Clear();
1458
1459 if (m_supports_memory_region_info != eLazyBoolNo) {
1460 m_supports_memory_region_info = eLazyBoolYes;
1461 char packet[64];
1462 const int packet_len = ::snprintf(
1463 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1464 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001465 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001466 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001467 if (SendPacketAndWaitForResponse(packet, response, false) ==
Pavel Labath16064d32018-03-20 11:56:24 +00001468 PacketResult::Success &&
1469 response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001470 llvm::StringRef name;
1471 llvm::StringRef value;
1472 addr_t addr_value = LLDB_INVALID_ADDRESS;
1473 bool success = true;
1474 bool saw_permissions = false;
1475 while (success && response.GetNameColonValue(name, value)) {
1476 if (name.equals("start")) {
1477 if (!value.getAsInteger(16, addr_value))
1478 region_info.GetRange().SetRangeBase(addr_value);
1479 } else if (name.equals("size")) {
1480 if (!value.getAsInteger(16, addr_value))
1481 region_info.GetRange().SetByteSize(addr_value);
1482 } else if (name.equals("permissions") &&
1483 region_info.GetRange().IsValid()) {
1484 saw_permissions = true;
1485 if (region_info.GetRange().Contains(addr)) {
1486 if (value.find('r') != llvm::StringRef::npos)
1487 region_info.SetReadable(MemoryRegionInfo::eYes);
1488 else
1489 region_info.SetReadable(MemoryRegionInfo::eNo);
1490
1491 if (value.find('w') != llvm::StringRef::npos)
1492 region_info.SetWritable(MemoryRegionInfo::eYes);
1493 else
1494 region_info.SetWritable(MemoryRegionInfo::eNo);
1495
1496 if (value.find('x') != llvm::StringRef::npos)
1497 region_info.SetExecutable(MemoryRegionInfo::eYes);
1498 else
1499 region_info.SetExecutable(MemoryRegionInfo::eNo);
1500
1501 region_info.SetMapped(MemoryRegionInfo::eYes);
1502 } else {
1503 // The reported region does not contain this address -- we're
1504 // looking at an unmapped page
1505 region_info.SetReadable(MemoryRegionInfo::eNo);
1506 region_info.SetWritable(MemoryRegionInfo::eNo);
1507 region_info.SetExecutable(MemoryRegionInfo::eNo);
1508 region_info.SetMapped(MemoryRegionInfo::eNo);
1509 }
1510 } else if (name.equals("name")) {
1511 StringExtractorGDBRemote name_extractor(value);
1512 std::string name;
1513 name_extractor.GetHexByteString(name);
1514 region_info.SetName(name.c_str());
1515 } else if (name.equals("error")) {
1516 StringExtractorGDBRemote error_extractor(value);
1517 std::string error_string;
1518 // Now convert the HEX bytes into a string value
1519 error_extractor.GetHexByteString(error_string);
1520 error.SetErrorString(error_string.c_str());
1521 }
1522 }
1523
Stephane Sezer48d14272017-03-31 18:00:48 +00001524 if (region_info.GetRange().IsValid()) {
1525 // We got a valid address range back but no permissions -- which means
1526 // this is an unmapped page
1527 if (!saw_permissions) {
1528 region_info.SetReadable(MemoryRegionInfo::eNo);
1529 region_info.SetWritable(MemoryRegionInfo::eNo);
1530 region_info.SetExecutable(MemoryRegionInfo::eNo);
1531 region_info.SetMapped(MemoryRegionInfo::eNo);
1532 }
1533 } else {
1534 // We got an invalid address range back
1535 error.SetErrorString("Server returned invalid range");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001536 }
1537 } else {
1538 m_supports_memory_region_info = eLazyBoolNo;
1539 }
1540 }
1541
1542 if (m_supports_memory_region_info == eLazyBoolNo) {
1543 error.SetErrorString("qMemoryRegionInfo is not supported");
1544 }
Pavel Labath16064d32018-03-20 11:56:24 +00001545
1546 // Try qXfer:memory-map:read to get region information not included in
1547 // qMemoryRegionInfo
1548 MemoryRegionInfo qXfer_region_info;
1549 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1550
1551 if (error.Fail()) {
Adrian Prantl05097242018-04-30 16:49:04 +00001552 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1553 // the qXfer result as a fallback
Pavel Labath16064d32018-03-20 11:56:24 +00001554 if (qXfer_error.Success()) {
1555 region_info = qXfer_region_info;
1556 error.Clear();
1557 } else {
1558 region_info.Clear();
1559 }
1560 } else if (qXfer_error.Success()) {
1561 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
Adrian Prantl05097242018-04-30 16:49:04 +00001562 // both regions are the same range, update the result to include the flash-
1563 // memory information that is specific to the qXfer result.
Pavel Labath16064d32018-03-20 11:56:24 +00001564 if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1565 region_info.SetFlash(qXfer_region_info.GetFlash());
1566 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1567 }
1568 }
1569 return error;
1570}
1571
1572Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1573 lldb::addr_t addr, MemoryRegionInfo &region) {
1574 Status error = LoadQXferMemoryMap();
1575 if (!error.Success())
1576 return error;
1577 for (const auto &map_region : m_qXfer_memory_map) {
1578 if (map_region.GetRange().Contains(addr)) {
1579 region = map_region;
1580 return error;
1581 }
1582 }
1583 error.SetErrorString("Region not found");
1584 return error;
1585}
1586
1587Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
1588
1589 Status error;
1590
1591 if (m_qXfer_memory_map_loaded)
1592 // Already loaded, return success
1593 return error;
1594
1595 if (!XMLDocument::XMLEnabled()) {
1596 error.SetErrorString("XML is not supported");
1597 return error;
1598 }
1599
1600 if (!GetQXferMemoryMapReadSupported()) {
1601 error.SetErrorString("Memory map is not supported");
1602 return error;
1603 }
1604
1605 std::string xml;
1606 lldb_private::Status lldberr;
1607 if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
1608 lldberr)) {
1609 error.SetErrorString("Failed to read memory map");
1610 return error;
1611 }
1612
1613 XMLDocument xml_document;
1614
1615 if (!xml_document.ParseMemory(xml.c_str(), xml.size())) {
1616 error.SetErrorString("Failed to parse memory map xml");
1617 return error;
1618 }
1619
1620 XMLNode map_node = xml_document.GetRootElement("memory-map");
1621 if (!map_node) {
1622 error.SetErrorString("Invalid root node in memory map xml");
1623 return error;
1624 }
1625
1626 m_qXfer_memory_map.clear();
1627
1628 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1629 if (!memory_node.IsElement())
1630 return true;
1631 if (memory_node.GetName() != "memory")
1632 return true;
1633 auto type = memory_node.GetAttributeValue("type", "");
1634 uint64_t start;
1635 uint64_t length;
1636 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1637 return true;
1638 if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1639 return true;
1640 MemoryRegionInfo region;
1641 region.GetRange().SetRangeBase(start);
1642 region.GetRange().SetByteSize(length);
1643 if (type == "rom") {
1644 region.SetReadable(MemoryRegionInfo::eYes);
1645 this->m_qXfer_memory_map.push_back(region);
1646 } else if (type == "ram") {
1647 region.SetReadable(MemoryRegionInfo::eYes);
1648 region.SetWritable(MemoryRegionInfo::eYes);
1649 this->m_qXfer_memory_map.push_back(region);
1650 } else if (type == "flash") {
1651 region.SetFlash(MemoryRegionInfo::eYes);
1652 memory_node.ForEachChildElement(
1653 [&region](const XMLNode &prop_node) -> bool {
1654 if (!prop_node.IsElement())
1655 return true;
1656 if (prop_node.GetName() != "property")
1657 return true;
1658 auto propname = prop_node.GetAttributeValue("name", "");
1659 if (propname == "blocksize") {
1660 uint64_t blocksize;
1661 if (prop_node.GetElementTextAsUnsigned(blocksize))
1662 region.SetBlocksize(blocksize);
1663 }
1664 return true;
1665 });
1666 this->m_qXfer_memory_map.push_back(region);
1667 }
1668 return true;
1669 });
1670
1671 m_qXfer_memory_map_loaded = true;
1672
Kate Stoneb9c1b512016-09-06 20:57:50 +00001673 return error;
1674}
1675
Zachary Turner97206d52017-05-12 04:51:55 +00001676Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
1677 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001678
1679 if (m_supports_watchpoint_support_info == eLazyBoolYes) {
1680 num = m_num_supported_hardware_watchpoints;
1681 return error;
1682 }
1683
1684 // Set num to 0 first.
1685 num = 0;
1686 if (m_supports_watchpoint_support_info != eLazyBoolNo) {
1687 char packet[64];
1688 const int packet_len =
1689 ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
1690 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001691 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001692 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001693 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001694 PacketResult::Success) {
1695 m_supports_watchpoint_support_info = eLazyBoolYes;
1696 llvm::StringRef name;
1697 llvm::StringRef value;
Jason Molendac0e793d2018-11-09 22:33:26 +00001698 bool found_num_field = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001699 while (response.GetNameColonValue(name, value)) {
1700 if (name.equals("num")) {
1701 value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1702 num = m_num_supported_hardware_watchpoints;
Jason Molendac0e793d2018-11-09 22:33:26 +00001703 found_num_field = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001704 }
1705 }
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001706 if (!found_num_field) {
Jason Molendac0e793d2018-11-09 22:33:26 +00001707 m_supports_watchpoint_support_info = eLazyBoolNo;
1708 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001709 } else {
1710 m_supports_watchpoint_support_info = eLazyBoolNo;
1711 }
1712 }
1713
1714 if (m_supports_watchpoint_support_info == eLazyBoolNo) {
1715 error.SetErrorString("qWatchpointSupportInfo is not supported");
1716 }
1717 return error;
1718}
1719
Zachary Turner97206d52017-05-12 04:51:55 +00001720lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001721 uint32_t &num, bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001722 Status error(GetWatchpointSupportInfo(num));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001723 if (error.Success())
1724 error = GetWatchpointsTriggerAfterInstruction(after, arch);
1725 return error;
Greg Clayton37a0a242012-04-11 00:24:49 +00001726}
1727
Zachary Turner97206d52017-05-12 04:51:55 +00001728lldb_private::Status
Kate Stoneb9c1b512016-09-06 20:57:50 +00001729GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
1730 bool &after, const ArchSpec &arch) {
Zachary Turner97206d52017-05-12 04:51:55 +00001731 Status error;
Fangrui Song2f677ab2019-05-16 09:07:33 +00001732 llvm::Triple triple = arch.GetTriple();
Daniel Maleae0f8f572013-08-26 23:57:52 +00001733
Adrian Prantl05097242018-04-30 16:49:04 +00001734 // we assume watchpoints will happen after running the relevant opcode and we
1735 // only want to override this behavior if we have explicitly received a
1736 // qHostInfo telling us otherwise
Kate Stoneb9c1b512016-09-06 20:57:50 +00001737 if (m_qHostInfo_is_valid != eLazyBoolYes) {
Fangrui Song2f677ab2019-05-16 09:07:33 +00001738 // On targets like MIPS and ppc64, watchpoint exceptions are always
Adrian Prantl05097242018-04-30 16:49:04 +00001739 // generated before the instruction is executed. The connected target may
1740 // not support qHostInfo or qWatchpointSupportInfo packets.
Fangrui Song2f677ab2019-05-16 09:07:33 +00001741 after = !(triple.isMIPS() || triple.isPPC64());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001742 } else {
Fangrui Song2f677ab2019-05-16 09:07:33 +00001743 // For MIPS and ppc64, set m_watchpoints_trigger_after_instruction to
Pavel Labathc51ad482017-10-27 17:02:32 +00001744 // eLazyBoolNo if it is not calculated before.
Fangrui Songddb93b62019-05-16 08:37:32 +00001745 if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
Fangrui Song2f677ab2019-05-16 09:07:33 +00001746 (triple.isMIPS() || triple.isPPC64()))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001747 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1748
1749 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1750 }
1751 return error;
1752}
1753
1754int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
1755 if (file_spec) {
1756 std::string path{file_spec.GetPath(false)};
1757 StreamString packet;
1758 packet.PutCString("QSetSTDIN:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001759 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001760
1761 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001762 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1763 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001764 if (response.IsOKResponse())
1765 return 0;
1766 uint8_t error = response.GetError();
1767 if (error)
1768 return error;
1769 }
1770 }
1771 return -1;
1772}
1773
1774int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
1775 if (file_spec) {
1776 std::string path{file_spec.GetPath(false)};
1777 StreamString packet;
1778 packet.PutCString("QSetSTDOUT:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001779 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001780
1781 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001782 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1783 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001784 if (response.IsOKResponse())
1785 return 0;
1786 uint8_t error = response.GetError();
1787 if (error)
1788 return error;
1789 }
1790 }
1791 return -1;
1792}
1793
1794int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
1795 if (file_spec) {
1796 std::string path{file_spec.GetPath(false)};
1797 StreamString packet;
1798 packet.PutCString("QSetSTDERR:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001799 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001800
1801 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001802 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1803 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001804 if (response.IsOKResponse())
1805 return 0;
1806 uint8_t error = response.GetError();
1807 if (error)
1808 return error;
1809 }
1810 }
1811 return -1;
1812}
1813
1814bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
1815 StringExtractorGDBRemote response;
1816 if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
1817 PacketResult::Success) {
1818 if (response.IsUnsupportedResponse())
1819 return false;
1820 if (response.IsErrorResponse())
1821 return false;
1822 std::string cwd;
1823 response.GetHexByteString(cwd);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00001824 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001825 return !cwd.empty();
1826 }
1827 return false;
1828}
1829
1830int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
1831 if (working_dir) {
1832 std::string path{working_dir.GetPath(false)};
1833 StreamString packet;
1834 packet.PutCString("QSetWorkingDir:");
Pavel Labath7f815a92019-02-12 14:28:55 +00001835 packet.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001836
1837 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001838 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1839 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001840 if (response.IsOKResponse())
1841 return 0;
1842 uint8_t error = response.GetError();
1843 if (error)
1844 return error;
1845 }
1846 }
1847 return -1;
1848}
1849
1850int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
1851 char packet[32];
1852 const int packet_len =
1853 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1854 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001855 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001856 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001857 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001858 PacketResult::Success) {
1859 if (response.IsOKResponse())
1860 return 0;
1861 uint8_t error = response.GetError();
1862 if (error)
1863 return error;
1864 }
1865 return -1;
1866}
1867
1868int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
1869 char packet[32];
1870 const int packet_len = ::snprintf(packet, sizeof(packet),
1871 "QSetDetachOnError:%i", enable ? 1 : 0);
1872 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001873 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001874 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001875 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001876 PacketResult::Success) {
1877 if (response.IsOKResponse())
1878 return 0;
1879 uint8_t error = response.GetError();
1880 if (error)
1881 return error;
1882 }
1883 return -1;
1884}
1885
1886bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
1887 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
1888 if (response.IsNormalResponse()) {
1889 llvm::StringRef name;
1890 llvm::StringRef value;
1891 StringExtractor extractor;
1892
1893 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1894 uint32_t sub = 0;
1895 std::string vendor;
1896 std::string os_type;
1897
1898 while (response.GetNameColonValue(name, value)) {
1899 if (name.equals("pid")) {
1900 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1901 value.getAsInteger(0, pid);
1902 process_info.SetProcessID(pid);
1903 } else if (name.equals("ppid")) {
1904 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1905 value.getAsInteger(0, pid);
1906 process_info.SetParentProcessID(pid);
1907 } else if (name.equals("uid")) {
1908 uint32_t uid = UINT32_MAX;
1909 value.getAsInteger(0, uid);
1910 process_info.SetUserID(uid);
1911 } else if (name.equals("euid")) {
1912 uint32_t uid = UINT32_MAX;
1913 value.getAsInteger(0, uid);
Walter Erquinigo8b6dcc12019-10-07 20:26:49 +00001914 process_info.SetEffectiveUserID(uid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001915 } else if (name.equals("gid")) {
1916 uint32_t gid = UINT32_MAX;
1917 value.getAsInteger(0, gid);
1918 process_info.SetGroupID(gid);
1919 } else if (name.equals("egid")) {
1920 uint32_t gid = UINT32_MAX;
1921 value.getAsInteger(0, gid);
1922 process_info.SetEffectiveGroupID(gid);
1923 } else if (name.equals("triple")) {
1924 StringExtractor extractor(value);
1925 std::string triple;
1926 extractor.GetHexByteString(triple);
1927 process_info.GetArchitecture().SetTriple(triple.c_str());
1928 } else if (name.equals("name")) {
1929 StringExtractor extractor(value);
Adrian Prantl05097242018-04-30 16:49:04 +00001930 // The process name from ASCII hex bytes since we can't control the
1931 // characters in a process name
Kate Stoneb9c1b512016-09-06 20:57:50 +00001932 std::string name;
1933 extractor.GetHexByteString(name);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00001934 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
Walter Erquinigo48a50ee2019-10-16 18:47:05 +00001935 } else if (name.equals("args")) {
1936 llvm::StringRef encoded_args(value), hex_arg;
1937
1938 bool is_arg0 = true;
1939 while (!encoded_args.empty()) {
1940 std::tie(hex_arg, encoded_args) = encoded_args.split('-');
1941 std::string arg;
1942 StringExtractor extractor(hex_arg);
1943 if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
1944 // In case of wrong encoding, we discard all the arguments
1945 process_info.GetArguments().Clear();
1946 process_info.SetArg0("");
1947 break;
1948 }
1949 if (is_arg0)
1950 process_info.SetArg0(arg);
1951 else
1952 process_info.GetArguments().AppendArgument(arg);
1953 is_arg0 = false;
1954 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001955 } else if (name.equals("cputype")) {
1956 value.getAsInteger(0, cpu);
1957 } else if (name.equals("cpusubtype")) {
1958 value.getAsInteger(0, sub);
1959 } else if (name.equals("vendor")) {
Benjamin Krameradcd0262020-01-28 20:23:46 +01001960 vendor = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001961 } else if (name.equals("ostype")) {
Benjamin Krameradcd0262020-01-28 20:23:46 +01001962 os_type = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001963 }
1964 }
1965
1966 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
1967 if (vendor == "apple") {
1968 process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
1969 sub);
1970 process_info.GetArchitecture().GetTriple().setVendorName(
1971 llvm::StringRef(vendor));
1972 process_info.GetArchitecture().GetTriple().setOSName(
1973 llvm::StringRef(os_type));
1974 }
1975 }
1976
1977 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1978 return true;
1979 }
1980 return false;
1981}
1982
1983bool GDBRemoteCommunicationClient::GetProcessInfo(
1984 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
1985 process_info.Clear();
1986
1987 if (m_supports_qProcessInfoPID) {
1988 char packet[32];
1989 const int packet_len =
1990 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
1991 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001992 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001993 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00001994 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00001995 PacketResult::Success) {
1996 return DecodeProcessInfoResponse(response, process_info);
1997 } else {
1998 m_supports_qProcessInfoPID = false;
1999 return false;
2000 }
2001 }
2002 return false;
2003}
2004
2005bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
2006 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2007 GDBR_LOG_PACKETS));
2008
2009 if (allow_lazy) {
2010 if (m_qProcessInfo_is_valid == eLazyBoolYes)
2011 return true;
2012 if (m_qProcessInfo_is_valid == eLazyBoolNo)
2013 return false;
2014 }
2015
2016 GetHostInfo();
2017
2018 StringExtractorGDBRemote response;
2019 if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
2020 PacketResult::Success) {
2021 if (response.IsNormalResponse()) {
2022 llvm::StringRef name;
2023 llvm::StringRef value;
2024 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2025 uint32_t sub = 0;
2026 std::string arch_name;
2027 std::string os_name;
Adrian Prantl24610612019-09-04 17:23:15 +00002028 std::string environment;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002029 std::string vendor_name;
2030 std::string triple;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002031 std::string elf_abi;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002032 uint32_t pointer_byte_size = 0;
2033 StringExtractor extractor;
2034 ByteOrder byte_order = eByteOrderInvalid;
2035 uint32_t num_keys_decoded = 0;
2036 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
2037 while (response.GetNameColonValue(name, value)) {
2038 if (name.equals("cputype")) {
2039 if (!value.getAsInteger(16, cpu))
2040 ++num_keys_decoded;
2041 } else if (name.equals("cpusubtype")) {
2042 if (!value.getAsInteger(16, sub))
2043 ++num_keys_decoded;
2044 } else if (name.equals("triple")) {
2045 StringExtractor extractor(value);
2046 extractor.GetHexByteString(triple);
2047 ++num_keys_decoded;
2048 } else if (name.equals("ostype")) {
Adrian Prantl24610612019-09-04 17:23:15 +00002049 if (value.equals("maccatalyst")) {
2050 os_name = "ios";
2051 environment = "macabi";
2052 } else
Benjamin Krameradcd0262020-01-28 20:23:46 +01002053 os_name = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002054 ++num_keys_decoded;
2055 } else if (name.equals("vendor")) {
Benjamin Krameradcd0262020-01-28 20:23:46 +01002056 vendor_name = std::string(value);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002057 ++num_keys_decoded;
2058 } else if (name.equals("endian")) {
2059 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2060 .Case("little", eByteOrderLittle)
2061 .Case("big", eByteOrderBig)
2062 .Case("pdp", eByteOrderPDP)
2063 .Default(eByteOrderInvalid);
2064 if (byte_order != eByteOrderInvalid)
2065 ++num_keys_decoded;
2066 } else if (name.equals("ptrsize")) {
2067 if (!value.getAsInteger(16, pointer_byte_size))
2068 ++num_keys_decoded;
2069 } else if (name.equals("pid")) {
2070 if (!value.getAsInteger(16, pid))
2071 ++num_keys_decoded;
Nitesh Jain8999edf2016-10-12 10:21:09 +00002072 } else if (name.equals("elf_abi")) {
Benjamin Krameradcd0262020-01-28 20:23:46 +01002073 elf_abi = std::string(value);
Nitesh Jain8999edf2016-10-12 10:21:09 +00002074 ++num_keys_decoded;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002075 }
2076 }
2077 if (num_keys_decoded > 0)
2078 m_qProcessInfo_is_valid = eLazyBoolYes;
2079 if (pid != LLDB_INVALID_PROCESS_ID) {
2080 m_curr_pid_is_valid = eLazyBoolYes;
2081 m_curr_pid = pid;
2082 }
2083
2084 // Set the ArchSpec from the triple if we have it.
2085 if (!triple.empty()) {
2086 m_process_arch.SetTriple(triple.c_str());
Nitesh Jain8999edf2016-10-12 10:21:09 +00002087 m_process_arch.SetFlags(elf_abi);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002088 if (pointer_byte_size) {
2089 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2090 }
2091 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2092 !vendor_name.empty()) {
2093 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
Adrian Prantl24610612019-09-04 17:23:15 +00002094 if (!environment.empty())
2095 triple.setEnvironmentName(environment);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002096
2097 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
Pavel Labath4f19fce22017-02-17 13:39:50 +00002098 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
Jason Liua03ae732019-03-12 22:01:10 +00002099 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002100 switch (triple.getObjectFormat()) {
2101 case llvm::Triple::MachO:
2102 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2103 break;
2104 case llvm::Triple::ELF:
2105 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2106 break;
2107 case llvm::Triple::COFF:
2108 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2109 break;
Pavel Labath4f19fce22017-02-17 13:39:50 +00002110 case llvm::Triple::Wasm:
Jason Liua03ae732019-03-12 22:01:10 +00002111 case llvm::Triple::XCOFF:
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002112 LLDB_LOGF(log, "error: not supported target architecture");
Pavel Labath4f19fce22017-02-17 13:39:50 +00002113 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002114 case llvm::Triple::UnknownObjectFormat:
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002115 LLDB_LOGF(log, "error: failed to determine target architecture");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002116 return false;
2117 }
2118
2119 if (pointer_byte_size) {
2120 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2121 }
2122 if (byte_order != eByteOrderInvalid) {
2123 assert(byte_order == m_process_arch.GetByteOrder());
2124 }
2125 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2126 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
Adrian Prantl24610612019-09-04 17:23:15 +00002127 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002128 m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2129 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
Adrian Prantl24610612019-09-04 17:23:15 +00002130 m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002131 }
2132 return true;
2133 }
2134 } else {
2135 m_qProcessInfo_is_valid = eLazyBoolNo;
2136 }
2137
2138 return false;
2139}
2140
2141uint32_t GDBRemoteCommunicationClient::FindProcesses(
2142 const ProcessInstanceInfoMatch &match_info,
2143 ProcessInstanceInfoList &process_infos) {
2144 process_infos.Clear();
2145
2146 if (m_supports_qfProcessInfo) {
2147 StreamString packet;
2148 packet.PutCString("qfProcessInfo");
2149 if (!match_info.MatchAllProcesses()) {
2150 packet.PutChar(':');
2151 const char *name = match_info.GetProcessInfo().GetName();
2152 bool has_name_match = false;
2153 if (name && name[0]) {
2154 has_name_match = true;
Pavel Labathc4a33952017-02-20 11:35:33 +00002155 NameMatch name_match_type = match_info.GetNameMatchType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002156 switch (name_match_type) {
Pavel Labathc4a33952017-02-20 11:35:33 +00002157 case NameMatch::Ignore:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002158 has_name_match = false;
2159 break;
2160
Pavel Labathc4a33952017-02-20 11:35:33 +00002161 case NameMatch::Equals:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002162 packet.PutCString("name_match:equals;");
2163 break;
2164
Pavel Labathc4a33952017-02-20 11:35:33 +00002165 case NameMatch::Contains:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002166 packet.PutCString("name_match:contains;");
2167 break;
2168
Pavel Labathc4a33952017-02-20 11:35:33 +00002169 case NameMatch::StartsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002170 packet.PutCString("name_match:starts_with;");
2171 break;
2172
Pavel Labathc4a33952017-02-20 11:35:33 +00002173 case NameMatch::EndsWith:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002174 packet.PutCString("name_match:ends_with;");
2175 break;
2176
Pavel Labathc4a33952017-02-20 11:35:33 +00002177 case NameMatch::RegularExpression:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002178 packet.PutCString("name_match:regex;");
2179 break;
2180 }
2181 if (has_name_match) {
2182 packet.PutCString("name:");
2183 packet.PutBytesAsRawHex8(name, ::strlen(name));
2184 packet.PutChar(';');
2185 }
2186 }
2187
2188 if (match_info.GetProcessInfo().ProcessIDIsValid())
2189 packet.Printf("pid:%" PRIu64 ";",
2190 match_info.GetProcessInfo().GetProcessID());
2191 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2192 packet.Printf("parent_pid:%" PRIu64 ";",
2193 match_info.GetProcessInfo().GetParentProcessID());
2194 if (match_info.GetProcessInfo().UserIDIsValid())
2195 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2196 if (match_info.GetProcessInfo().GroupIDIsValid())
2197 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2198 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2199 packet.Printf("euid:%u;",
2200 match_info.GetProcessInfo().GetEffectiveUserID());
2201 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2202 packet.Printf("egid:%u;",
2203 match_info.GetProcessInfo().GetEffectiveGroupID());
Walter Erquinigoaf1d27e2019-10-12 02:36:16 +00002204 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002205 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2206 const ArchSpec &match_arch =
2207 match_info.GetProcessInfo().GetArchitecture();
2208 const llvm::Triple &triple = match_arch.GetTriple();
2209 packet.PutCString("triple:");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00002210 packet.PutCString(triple.getTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002211 packet.PutChar(';');
2212 }
2213 }
2214 StringExtractorGDBRemote response;
Adrian Prantl05097242018-04-30 16:49:04 +00002215 // Increase timeout as the first qfProcessInfo packet takes a long time on
2216 // Android. The value of 1min was arrived at empirically.
Pavel Labath1eff73c2016-11-24 10:54:49 +00002217 ScopedTimeout timeout(*this, minutes(1));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002218 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2219 PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002220 do {
2221 ProcessInstanceInfo process_info;
2222 if (!DecodeProcessInfoResponse(response, process_info))
2223 break;
2224 process_infos.Append(process_info);
Jonas Devlieghered35b42f2019-08-21 04:55:56 +00002225 response = StringExtractorGDBRemote();
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002226 } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
2227 PacketResult::Success);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002228 } else {
2229 m_supports_qfProcessInfo = false;
2230 return 0;
2231 }
2232 }
2233 return process_infos.GetSize();
2234}
2235
2236bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
2237 std::string &name) {
2238 if (m_supports_qUserName) {
2239 char packet[32];
2240 const int packet_len =
2241 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2242 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002243 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002244 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002245 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002246 PacketResult::Success) {
2247 if (response.IsNormalResponse()) {
2248 // Make sure we parsed the right number of characters. The response is
Adrian Prantl05097242018-04-30 16:49:04 +00002249 // the hex encoded user name and should make up the entire packet. If
2250 // there are any non-hex ASCII bytes, the length won't match below..
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251 if (response.GetHexByteString(name) * 2 ==
2252 response.GetStringRef().size())
2253 return true;
2254 }
2255 } else {
2256 m_supports_qUserName = false;
2257 return false;
2258 }
2259 }
2260 return false;
2261}
2262
2263bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
2264 std::string &name) {
2265 if (m_supports_qGroupName) {
2266 char packet[32];
2267 const int packet_len =
2268 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2269 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002270 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002271 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002272 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002273 PacketResult::Success) {
2274 if (response.IsNormalResponse()) {
2275 // Make sure we parsed the right number of characters. The response is
Adrian Prantl05097242018-04-30 16:49:04 +00002276 // the hex encoded group name and should make up the entire packet. If
2277 // there are any non-hex ASCII bytes, the length won't match below..
Kate Stoneb9c1b512016-09-06 20:57:50 +00002278 if (response.GetHexByteString(name) * 2 ==
2279 response.GetStringRef().size())
2280 return true;
2281 }
2282 } else {
2283 m_supports_qGroupName = false;
2284 return false;
2285 }
2286 }
2287 return false;
2288}
2289
2290bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
2291 // Form non-stop packet request
2292 char packet[32];
2293 const int packet_len =
2294 ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
2295 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002296 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002297
2298 StringExtractorGDBRemote response;
2299 // Send to target
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002300 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002301 PacketResult::Success)
2302 if (response.IsOKResponse())
2303 return true;
2304
2305 // Failed or not supported
2306 return false;
2307}
2308
2309static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2310 uint32_t recv_size) {
2311 packet.Clear();
2312 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2313 uint32_t bytes_left = send_size;
2314 while (bytes_left > 0) {
2315 if (bytes_left >= 26) {
2316 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2317 bytes_left -= 26;
2318 } else {
2319 packet.Printf("%*.*s;", bytes_left, bytes_left,
2320 "abcdefghijklmnopqrstuvwxyz");
2321 bytes_left = 0;
2322 }
2323 }
2324}
2325
Pavel Labath1eff73c2016-11-24 10:54:49 +00002326duration<float>
2327calculate_standard_deviation(const std::vector<duration<float>> &v) {
2328 using Dur = duration<float>;
Pavel Labath3aa04912016-10-31 17:19:42 +00002329 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2330 Dur mean = sum / v.size();
2331 float accum = 0;
2332 for (auto d : v) {
2333 float delta = (d - mean).count();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002334 accum += delta * delta;
Pavel Labath3aa04912016-10-31 17:19:42 +00002335 };
Kate Stoneb9c1b512016-09-06 20:57:50 +00002336
Pavel Labath3aa04912016-10-31 17:19:42 +00002337 return Dur(sqrtf(accum / (v.size() - 1)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002338}
2339
2340void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
2341 uint32_t max_send,
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002342 uint32_t max_recv,
2343 uint64_t recv_amount,
2344 bool json, Stream &strm) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002345 uint32_t i;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002346 if (SendSpeedTestPacket(0, 0)) {
2347 StreamString packet;
2348 if (json)
2349 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2350 "\"results\" : [",
2351 num_packets);
2352 else
2353 strm.Printf("Testing sending %u packets of various sizes:\n",
2354 num_packets);
2355 strm.Flush();
2356
2357 uint32_t result_idx = 0;
2358 uint32_t send_size;
Pavel Labath3aa04912016-10-31 17:19:42 +00002359 std::vector<duration<float>> packet_times;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002360
2361 for (send_size = 0; send_size <= max_send;
2362 send_size ? send_size *= 2 : send_size = 4) {
2363 for (uint32_t recv_size = 0; recv_size <= max_recv;
2364 recv_size ? recv_size *= 2 : recv_size = 4) {
2365 MakeSpeedTestPacket(packet, send_size, recv_size);
2366
2367 packet_times.clear();
2368 // Test how long it takes to send 'num_packets' packets
Pavel Labath3aa04912016-10-31 17:19:42 +00002369 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002370 for (i = 0; i < num_packets; ++i) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002371 const auto packet_start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002372 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002373 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Pavel Labath3aa04912016-10-31 17:19:42 +00002374 const auto packet_end_time = steady_clock::now();
2375 packet_times.push_back(packet_end_time - packet_start_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002376 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002377 const auto end_time = steady_clock::now();
2378 const auto total_time = end_time - start_time;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002379
2380 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002381 ((float)num_packets) / duration<float>(total_time).count();
2382 auto average_per_packet = total_time / num_packets;
2383 const duration<float> standard_deviation =
2384 calculate_standard_deviation(packet_times);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002385 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002386 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2387 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2388 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002389 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002390 total_time, standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002391 ++result_idx;
2392 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002393 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2394 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2395 "standard deviation of {5,10:ms+f6}\n",
2396 send_size, recv_size, duration<float>(total_time),
2397 packets_per_second, duration<float>(average_per_packet),
2398 standard_deviation);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002399 }
2400 strm.Flush();
2401 }
2402 }
2403
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002404 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002405 if (json)
2406 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2407 ": %" PRIu64 ",\n \"results\" : [",
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002408 recv_amount);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002409 else
2410 strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2411 "packet sizes:\n",
2412 k_recv_amount_mb);
2413 strm.Flush();
2414 send_size = 0;
2415 result_idx = 0;
2416 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2417 MakeSpeedTestPacket(packet, send_size, recv_size);
2418
2419 // If we have a receive size, test how long it takes to receive 4MB of
2420 // data
2421 if (recv_size > 0) {
Pavel Labath3aa04912016-10-31 17:19:42 +00002422 const auto start_time = steady_clock::now();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002423 uint32_t bytes_read = 0;
2424 uint32_t packet_count = 0;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002425 while (bytes_read < recv_amount) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002426 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002427 SendPacketAndWaitForResponse(packet.GetString(), response, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002428 bytes_read += recv_size;
2429 ++packet_count;
2430 }
Pavel Labath3aa04912016-10-31 17:19:42 +00002431 const auto end_time = steady_clock::now();
2432 const auto total_time = end_time - start_time;
Pavel Labath2fd9a1e2016-11-04 11:49:06 +00002433 float mb_second = ((float)recv_amount) /
Pavel Labath3aa04912016-10-31 17:19:42 +00002434 duration<float>(total_time).count() /
Kate Stoneb9c1b512016-09-06 20:57:50 +00002435 (1024.0 * 1024.0);
2436 float packets_per_second =
Pavel Labath3aa04912016-10-31 17:19:42 +00002437 ((float)packet_count) / duration<float>(total_time).count();
2438 const auto average_per_packet = total_time / packet_count;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002439
2440 if (json) {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002441 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2442 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002443 result_idx > 0 ? "," : "", send_size, recv_size,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002444 total_time);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002445 ++result_idx;
2446 } else {
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002447 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2448 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2449 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +00002450 send_size, recv_size, packet_count, k_recv_amount_mb,
Pavel Labath2f7cfaf2017-02-10 11:49:40 +00002451 duration<float>(total_time), mb_second,
2452 packets_per_second, duration<float>(average_per_packet));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002453 }
2454 strm.Flush();
2455 }
2456 }
2457 if (json)
2458 strm.Printf("\n ]\n }\n}\n");
2459 else
2460 strm.EOL();
2461 }
2462}
2463
2464bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
2465 uint32_t recv_size) {
2466 StreamString packet;
2467 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2468 uint32_t bytes_left = send_size;
2469 while (bytes_left > 0) {
2470 if (bytes_left >= 26) {
2471 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2472 bytes_left -= 26;
2473 } else {
2474 packet.Printf("%*.*s;", bytes_left, bytes_left,
2475 "abcdefghijklmnopqrstuvwxyz");
2476 bytes_left = 0;
2477 }
2478 }
2479
2480 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002481 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2482 PacketResult::Success;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002483}
2484
2485bool GDBRemoteCommunicationClient::LaunchGDBServer(
2486 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2487 std::string &socket_name) {
2488 pid = LLDB_INVALID_PROCESS_ID;
2489 port = 0;
2490 socket_name.clear();
2491
2492 StringExtractorGDBRemote response;
2493 StreamString stream;
2494 stream.PutCString("qLaunchGDBServer;");
2495 std::string hostname;
2496 if (remote_accept_hostname && remote_accept_hostname[0])
2497 hostname = remote_accept_hostname;
2498 else {
2499 if (HostInfo::GetHostname(hostname)) {
2500 // Make the GDB server we launch only accept connections from this host
2501 stream.Printf("host:%s;", hostname.c_str());
2502 } else {
Adrian Prantl05097242018-04-30 16:49:04 +00002503 // Make the GDB server we launch accept connections from any host since
2504 // we can't figure out the hostname
Kate Stoneb9c1b512016-09-06 20:57:50 +00002505 stream.Printf("host:*;");
2506 }
2507 }
2508 // give the process a few seconds to startup
Pavel Labath1eff73c2016-11-24 10:54:49 +00002509 ScopedTimeout timeout(*this, seconds(10));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002510
2511 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2512 PacketResult::Success) {
2513 llvm::StringRef name;
2514 llvm::StringRef value;
2515 while (response.GetNameColonValue(name, value)) {
2516 if (name.equals("port"))
2517 value.getAsInteger(0, port);
2518 else if (name.equals("pid"))
2519 value.getAsInteger(0, pid);
2520 else if (name.compare("socket_name") == 0) {
2521 StringExtractor extractor(value);
2522 extractor.GetHexByteString(socket_name);
2523 }
2524 }
2525 return true;
2526 }
2527 return false;
2528}
2529
2530size_t GDBRemoteCommunicationClient::QueryGDBServer(
2531 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2532 connection_urls.clear();
2533
2534 StringExtractorGDBRemote response;
2535 if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
2536 PacketResult::Success)
2537 return 0;
2538
2539 StructuredData::ObjectSP data =
Benjamin Krameradcd0262020-01-28 20:23:46 +01002540 StructuredData::ParseJSON(std::string(response.GetStringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00002541 if (!data)
2542 return 0;
2543
2544 StructuredData::Array *array = data->GetAsArray();
2545 if (!array)
2546 return 0;
2547
2548 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2549 StructuredData::Dictionary *element = nullptr;
2550 if (!array->GetItemAtIndexAsDictionary(i, element))
2551 continue;
2552
2553 uint16_t port = 0;
2554 if (StructuredData::ObjectSP port_osp =
2555 element->GetValueForKey(llvm::StringRef("port")))
2556 port = port_osp->GetIntegerValue(0);
2557
2558 std::string socket_name;
2559 if (StructuredData::ObjectSP socket_name_osp =
2560 element->GetValueForKey(llvm::StringRef("socket_name")))
Benjamin Krameradcd0262020-01-28 20:23:46 +01002561 socket_name = std::string(socket_name_osp->GetStringValue());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002562
2563 if (port != 0 || !socket_name.empty())
2564 connection_urls.emplace_back(port, socket_name);
2565 }
2566 return connection_urls.size();
2567}
2568
2569bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
2570 StreamString stream;
2571 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002572
2573 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002574 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002575 PacketResult::Success) {
2576 if (response.IsOKResponse())
2577 return true;
2578 }
2579 return false;
2580}
2581
2582bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
2583 if (m_curr_tid == 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), "Hg-1");
2590 else
2591 packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
2592 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002593 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002594 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002595 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002596 PacketResult::Success) {
2597 if (response.IsOKResponse()) {
2598 m_curr_tid = tid;
2599 return true;
2600 }
2601
2602 /*
2603 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2604 * Hg packet.
2605 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2606 * which can
2607 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2608 */
2609 if (response.IsUnsupportedResponse() && IsConnected()) {
2610 m_curr_tid = 1;
2611 return true;
2612 }
2613 }
2614 return false;
2615}
2616
2617bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
2618 if (m_curr_tid_run == tid)
2619 return true;
2620
2621 char packet[32];
2622 int packet_len;
2623 if (tid == UINT64_MAX)
2624 packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
2625 else
2626 packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
2627
2628 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002629 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002630 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002631 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002632 PacketResult::Success) {
2633 if (response.IsOKResponse()) {
2634 m_curr_tid_run = tid;
2635 return true;
2636 }
2637
2638 /*
2639 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2640 * Hc packet.
2641 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2642 * which can
2643 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2644 */
2645 if (response.IsUnsupportedResponse() && IsConnected()) {
2646 m_curr_tid_run = 1;
2647 return true;
2648 }
2649 }
2650 return false;
2651}
2652
2653bool GDBRemoteCommunicationClient::GetStopReply(
2654 StringExtractorGDBRemote &response) {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002655 if (SendPacketAndWaitForResponse("?", response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002656 PacketResult::Success)
2657 return response.IsNormalResponse();
2658 return false;
2659}
2660
2661bool GDBRemoteCommunicationClient::GetThreadStopInfo(
2662 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2663 if (m_supports_qThreadStopInfo) {
2664 char packet[256];
2665 int packet_len =
2666 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2667 assert(packet_len < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002668 UNUSED_IF_ASSERT_DISABLED(packet_len);
2669 if (SendPacketAndWaitForResponse(packet, response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002670 PacketResult::Success) {
2671 if (response.IsUnsupportedResponse())
2672 m_supports_qThreadStopInfo = false;
2673 else if (response.IsNormalResponse())
2674 return true;
2675 else
2676 return false;
2677 } else {
2678 m_supports_qThreadStopInfo = false;
2679 }
2680 }
2681 return false;
2682}
2683
2684uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2685 GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
2686 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002687 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2688 __FUNCTION__, insert ? "add" : "remove", addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002689
2690 // Check if the stub is known not to support this breakpoint type
2691 if (!SupportsGDBStoppointPacket(type))
2692 return UINT8_MAX;
2693 // Construct the breakpoint packet
2694 char packet[64];
2695 const int packet_len =
2696 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
2697 insert ? 'Z' : 'z', type, addr, length);
2698 // Check we haven't overwritten the end of the packet buffer
2699 assert(packet_len + 1 < (int)sizeof(packet));
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002700 UNUSED_IF_ASSERT_DISABLED(packet_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002701 StringExtractorGDBRemote response;
2702 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2703 // or "" (unsupported)
2704 response.SetResponseValidatorToOKErrorNotSupported();
2705 // Try to send the breakpoint packet, and check that it was correctly sent
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002706 if (SendPacketAndWaitForResponse(packet, response, true) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002707 PacketResult::Success) {
2708 // Receive and OK packet when the breakpoint successfully placed
2709 if (response.IsOKResponse())
2710 return 0;
2711
Zachary Turner97206d52017-05-12 04:51:55 +00002712 // Status while setting breakpoint, send back specific error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002713 if (response.IsErrorResponse())
2714 return response.GetError();
2715
2716 // Empty packet informs us that breakpoint is not supported
2717 if (response.IsUnsupportedResponse()) {
2718 // Disable this breakpoint type since it is unsupported
2719 switch (type) {
2720 case eBreakpointSoftware:
2721 m_supports_z0 = false;
2722 break;
2723 case eBreakpointHardware:
2724 m_supports_z1 = false;
2725 break;
2726 case eWatchpointWrite:
2727 m_supports_z2 = false;
2728 break;
2729 case eWatchpointRead:
2730 m_supports_z3 = false;
2731 break;
2732 case eWatchpointReadWrite:
2733 m_supports_z4 = false;
2734 break;
2735 case eStoppointInvalid:
2736 return UINT8_MAX;
2737 }
2738 }
2739 }
2740 // Signal generic failure
2741 return UINT8_MAX;
2742}
2743
2744size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2745 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
2746 thread_ids.clear();
2747
2748 Lock lock(*this, false);
2749 if (lock) {
2750 sequence_mutex_unavailable = false;
2751 StringExtractorGDBRemote response;
2752
2753 PacketResult packet_result;
2754 for (packet_result =
2755 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
2756 packet_result == PacketResult::Success && response.IsNormalResponse();
2757 packet_result =
2758 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
2759 char ch = response.GetChar();
2760 if (ch == 'l')
2761 break;
2762 if (ch == 'm') {
2763 do {
2764 tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
2765
2766 if (tid != LLDB_INVALID_THREAD_ID) {
2767 thread_ids.push_back(tid);
2768 }
2769 ch = response.GetChar(); // Skip the command separator
2770 } while (ch == ','); // Make sure we got a comma separator
2771 }
2772 }
2773
2774 /*
2775 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2776 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2777 * could
2778 * be as simple as 'S05'. There is no packet which can give us pid and/or
2779 * tid.
2780 * Assume pid=tid=1 in such cases.
2781 */
Tamas Berghammer1492cb82017-09-18 10:24:48 +00002782 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
2783 thread_ids.size() == 0 && IsConnected()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002784 thread_ids.push_back(1);
2785 }
2786 } else {
David Blaikiea322f362017-01-06 00:38:06 +00002787#if !defined(LLDB_CONFIGURATION_DEBUG)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002788 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2789 GDBR_LOG_PACKETS));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002790 LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending "
2791 "packet 'qfThreadInfo'");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002792#endif
2793 sequence_mutex_unavailable = true;
2794 }
2795 return thread_ids.size();
2796}
2797
2798lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
2799 StringExtractorGDBRemote response;
2800 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
2801 PacketResult::Success ||
2802 !response.IsNormalResponse())
2803 return LLDB_INVALID_ADDRESS;
2804 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2805}
2806
Zachary Turner97206d52017-05-12 04:51:55 +00002807lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002808 const char *command, // Shouldn't be NULL
2809 const FileSpec &
2810 working_dir, // Pass empty FileSpec to use the current working directory
2811 int *status_ptr, // Pass NULL if you don't want the process exit status
2812 int *signo_ptr, // Pass NULL if you don't want the signal that caused the
2813 // process to exit
2814 std::string
2815 *command_output, // Pass NULL if you don't want the command output
Pavel Labath19dd1a02018-05-10 10:46:03 +00002816 const Timeout<std::micro> &timeout) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002817 lldb_private::StreamString stream;
2818 stream.PutCString("qPlatform_shell:");
2819 stream.PutBytesAsRawHex8(command, strlen(command));
2820 stream.PutChar(',');
Pavel Labath19dd1a02018-05-10 10:46:03 +00002821 uint32_t timeout_sec = UINT32_MAX;
2822 if (timeout) {
2823 // TODO: Use chrono version of std::ceil once c++17 is available.
2824 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2825 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002826 stream.PutHex32(timeout_sec);
2827 if (working_dir) {
2828 std::string path{working_dir.GetPath(false)};
2829 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00002830 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002831 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002832 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002833 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002834 PacketResult::Success) {
2835 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002836 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002837 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002838 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002839 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2840 if (exitcode == UINT32_MAX)
Zachary Turner97206d52017-05-12 04:51:55 +00002841 return Status("unable to run remote process");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002842 else if (status_ptr)
2843 *status_ptr = exitcode;
2844 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002845 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002846 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2847 if (signo_ptr)
2848 *signo_ptr = signo;
2849 if (response.GetChar() != ',')
Zachary Turner97206d52017-05-12 04:51:55 +00002850 return Status("malformed reply");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002851 std::string output;
2852 response.GetEscapedBinaryData(output);
2853 if (command_output)
2854 command_output->assign(output);
Zachary Turner97206d52017-05-12 04:51:55 +00002855 return Status();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002856 }
Zachary Turner97206d52017-05-12 04:51:55 +00002857 return Status("unable to send packet");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002858}
2859
Zachary Turner97206d52017-05-12 04:51:55 +00002860Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
2861 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002862 std::string path{file_spec.GetPath(false)};
2863 lldb_private::StreamString stream;
2864 stream.PutCString("qPlatform_mkdir:");
2865 stream.PutHex32(file_permissions);
2866 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00002867 stream.PutStringAsRawHex8(path);
Zachary Turnerc1564272016-11-16 21:15:24 +00002868 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002869 StringExtractorGDBRemote response;
2870
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002871 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002872 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002873 return Status("failed to send '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002874
2875 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002876 return Status("invalid response to '%s' packet", packet.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002877
Zachary Turner97206d52017-05-12 04:51:55 +00002878 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002879}
2880
Zachary Turner97206d52017-05-12 04:51:55 +00002881Status
2882GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
2883 uint32_t file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002884 std::string path{file_spec.GetPath(false)};
2885 lldb_private::StreamString stream;
2886 stream.PutCString("qPlatform_chmod:");
2887 stream.PutHex32(file_permissions);
2888 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00002889 stream.PutStringAsRawHex8(path);
Zachary Turnerc1564272016-11-16 21:15:24 +00002890 llvm::StringRef packet = stream.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002891 StringExtractorGDBRemote response;
2892
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002893 if (SendPacketAndWaitForResponse(packet, response, false) !=
Kate Stoneb9c1b512016-09-06 20:57:50 +00002894 PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00002895 return Status("failed to send '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002896
2897 if (response.GetChar() != 'F')
Zachary Turner97206d52017-05-12 04:51:55 +00002898 return Status("invalid response to '%s' packet", stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002899
Zachary Turner97206d52017-05-12 04:51:55 +00002900 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002901}
2902
2903static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
Zachary Turner97206d52017-05-12 04:51:55 +00002904 uint64_t fail_result, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002905 response.SetFilePos(0);
2906 if (response.GetChar() != 'F')
2907 return fail_result;
2908 int32_t result = response.GetS32(-2);
2909 if (result == -2)
2910 return fail_result;
2911 if (response.GetChar() == ',') {
2912 int result_errno = response.GetS32(-2);
2913 if (result_errno != -2)
2914 error.SetError(result_errno, eErrorTypePOSIX);
2915 else
2916 error.SetError(-1, eErrorTypeGeneric);
2917 } else
2918 error.Clear();
2919 return result;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002920}
2921lldb::user_id_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00002922GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
Lawrence D'Anna62c9fe42019-10-14 20:15:34 +00002923 File::OpenOptions flags, mode_t mode,
Zachary Turner97206d52017-05-12 04:51:55 +00002924 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002925 std::string path(file_spec.GetPath(false));
2926 lldb_private::StreamString stream;
2927 stream.PutCString("vFile:open:");
2928 if (path.empty())
Daniel Maleae0f8f572013-08-26 23:57:52 +00002929 return UINT64_MAX;
Pavel Labath7f815a92019-02-12 14:28:55 +00002930 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002931 stream.PutChar(',');
2932 stream.PutHex32(flags);
2933 stream.PutChar(',');
2934 stream.PutHex32(mode);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002935 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002936 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002937 PacketResult::Success) {
2938 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
2939 }
2940 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002941}
2942
Zachary Turner97206d52017-05-12 04:51:55 +00002943bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
2944 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002945 lldb_private::StreamString stream;
2946 stream.Printf("vFile:close:%i", (int)fd);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002947 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002948 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002949 PacketResult::Success) {
2950 return ParseHostIOPacketResponse(response, -1, error) == 0;
2951 }
2952 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002953}
2954
2955// Extension of host I/O packets to get the file size.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002956lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
2957 const lldb_private::FileSpec &file_spec) {
2958 std::string path(file_spec.GetPath(false));
2959 lldb_private::StreamString stream;
2960 stream.PutCString("vFile:size:");
Pavel Labath7f815a92019-02-12 14:28:55 +00002961 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002962 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002963 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002964 PacketResult::Success) {
2965 if (response.GetChar() != 'F')
2966 return UINT64_MAX;
2967 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2968 return retcode;
2969 }
2970 return UINT64_MAX;
Daniel Maleae0f8f572013-08-26 23:57:52 +00002971}
2972
Zachary Turner97206d52017-05-12 04:51:55 +00002973Status
2974GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
2975 uint32_t &file_permissions) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002976 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00002977 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002978 lldb_private::StreamString stream;
2979 stream.PutCString("vFile:mode:");
Pavel Labath7f815a92019-02-12 14:28:55 +00002980 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002981 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002982 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002983 PacketResult::Success) {
2984 if (response.GetChar() != 'F') {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00002985 error.SetErrorStringWithFormat("invalid response to '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00002986 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002987 } else {
2988 const uint32_t mode = response.GetS32(-1);
2989 if (static_cast<int32_t>(mode) == -1) {
2990 if (response.GetChar() == ',') {
2991 int response_errno = response.GetS32(-1);
2992 if (response_errno > 0)
2993 error.SetError(response_errno, lldb::eErrorTypePOSIX);
2994 else
Daniel Maleae0f8f572013-08-26 23:57:52 +00002995 error.SetErrorToGenericError();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002996 } else
2997 error.SetErrorToGenericError();
2998 } else {
2999 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
3000 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00003001 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003002 } else {
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003003 error.SetErrorStringWithFormat("failed to send '%s' packet",
Zachary Turnerc1564272016-11-16 21:15:24 +00003004 stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003005 }
3006 return error;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003007}
3008
Kate Stoneb9c1b512016-09-06 20:57:50 +00003009uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
3010 uint64_t offset, void *dst,
3011 uint64_t dst_len,
Zachary Turner97206d52017-05-12 04:51:55 +00003012 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003013 lldb_private::StreamString stream;
3014 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
3015 offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003016 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003017 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003018 PacketResult::Success) {
3019 if (response.GetChar() != 'F')
3020 return 0;
3021 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
3022 if (retcode == UINT32_MAX)
3023 return retcode;
3024 const char next = (response.Peek() ? *response.Peek() : 0);
3025 if (next == ',')
3026 return 0;
3027 if (next == ';') {
3028 response.GetChar(); // skip the semicolon
3029 std::string buffer;
3030 if (response.GetEscapedBinaryData(buffer)) {
3031 const uint64_t data_to_write =
3032 std::min<uint64_t>(dst_len, buffer.size());
3033 if (data_to_write > 0)
3034 memcpy(dst, &buffer[0], data_to_write);
3035 return data_to_write;
3036 }
Greg Claytonfbb76342013-11-20 21:07:01 +00003037 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003038 }
3039 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003040}
3041
Kate Stoneb9c1b512016-09-06 20:57:50 +00003042uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
3043 uint64_t offset,
3044 const void *src,
3045 uint64_t src_len,
Zachary Turner97206d52017-05-12 04:51:55 +00003046 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003047 lldb_private::StreamGDBRemote stream;
3048 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3049 stream.PutEscapedBytes(src, src_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003050 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003051 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003052 PacketResult::Success) {
3053 if (response.GetChar() != 'F') {
3054 error.SetErrorStringWithFormat("write file failed");
3055 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003056 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003057 uint64_t bytes_written = response.GetU64(UINT64_MAX);
3058 if (bytes_written == UINT64_MAX) {
3059 error.SetErrorToGenericError();
3060 if (response.GetChar() == ',') {
3061 int response_errno = response.GetS32(-1);
3062 if (response_errno > 0)
3063 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3064 }
3065 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +00003066 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003067 return bytes_written;
3068 } else {
3069 error.SetErrorString("failed to send vFile:pwrite packet");
3070 }
3071 return 0;
3072}
3073
Zachary Turner97206d52017-05-12 04:51:55 +00003074Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
3075 const FileSpec &dst) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003076 std::string src_path{src.GetPath(false)}, dst_path{dst.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:symlink:");
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(dst_path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003083 stream.PutChar(',');
Pavel Labath7f815a92019-02-12 14:28:55 +00003084 stream.PutStringAsRawHex8(src_path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003085 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003086 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003087 PacketResult::Success) {
3088 if (response.GetChar() == 'F') {
3089 uint32_t result = response.GetU32(UINT32_MAX);
3090 if (result != 0) {
3091 error.SetErrorToGenericError();
3092 if (response.GetChar() == ',') {
3093 int response_errno = response.GetS32(-1);
3094 if (response_errno > 0)
3095 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3096 }
3097 }
3098 } else {
3099 // Should have returned with 'F<result>[,<errno>]'
3100 error.SetErrorStringWithFormat("symlink failed");
3101 }
3102 } else {
3103 error.SetErrorString("failed to send vFile:symlink packet");
3104 }
3105 return error;
3106}
3107
Zachary Turner97206d52017-05-12 04:51:55 +00003108Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003109 std::string path{file_spec.GetPath(false)};
Zachary Turner97206d52017-05-12 04:51:55 +00003110 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003111 lldb_private::StreamGDBRemote stream;
3112 stream.PutCString("vFile:unlink:");
3113 // the unix symlink() command reverses its parameters where the dst if first,
3114 // so we follow suit here
Pavel Labath7f815a92019-02-12 14:28:55 +00003115 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003116 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003117 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003118 PacketResult::Success) {
3119 if (response.GetChar() == 'F') {
3120 uint32_t result = response.GetU32(UINT32_MAX);
3121 if (result != 0) {
3122 error.SetErrorToGenericError();
3123 if (response.GetChar() == ',') {
3124 int response_errno = response.GetS32(-1);
3125 if (response_errno > 0)
3126 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3127 }
3128 }
3129 } else {
3130 // Should have returned with 'F<result>[,<errno>]'
3131 error.SetErrorStringWithFormat("unlink failed");
3132 }
3133 } else {
3134 error.SetErrorString("failed to send vFile:unlink packet");
3135 }
3136 return error;
Greg Claytonfbb76342013-11-20 21:07:01 +00003137}
3138
Daniel Maleae0f8f572013-08-26 23:57:52 +00003139// Extension of host I/O packets to get whether a file exists.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003140bool GDBRemoteCommunicationClient::GetFileExists(
3141 const lldb_private::FileSpec &file_spec) {
3142 std::string path(file_spec.GetPath(false));
3143 lldb_private::StreamString stream;
3144 stream.PutCString("vFile:exists:");
Pavel Labath7f815a92019-02-12 14:28:55 +00003145 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003146 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003147 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003148 PacketResult::Success) {
3149 if (response.GetChar() != 'F')
3150 return false;
3151 if (response.GetChar() != ',')
3152 return false;
3153 bool retcode = (response.GetChar() != '0');
3154 return retcode;
3155 }
3156 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +00003157}
3158
Kate Stoneb9c1b512016-09-06 20:57:50 +00003159bool GDBRemoteCommunicationClient::CalculateMD5(
3160 const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
3161 std::string path(file_spec.GetPath(false));
3162 lldb_private::StreamString stream;
3163 stream.PutCString("vFile:MD5:");
Pavel Labath7f815a92019-02-12 14:28:55 +00003164 stream.PutStringAsRawHex8(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003165 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003166 if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00003167 PacketResult::Success) {
3168 if (response.GetChar() != 'F')
3169 return false;
3170 if (response.GetChar() != ',')
3171 return false;
3172 if (response.Peek() && *response.Peek() == 'x')
3173 return false;
3174 low = response.GetHexMaxU64(false, UINT64_MAX);
3175 high = response.GetHexMaxU64(false, UINT64_MAX);
Pavel Labath4b6f9592016-08-18 08:30:03 +00003176 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003177 }
3178 return false;
Greg Claytonf74cf862013-11-13 23:28:31 +00003179}
3180
Kate Stoneb9c1b512016-09-06 20:57:50 +00003181bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
3182 // Some targets have issues with g/G packets and we need to avoid using them
3183 if (m_avoid_g_packets == eLazyBoolCalculate) {
3184 if (process) {
3185 m_avoid_g_packets = eLazyBoolNo;
3186 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3187 if (arch.IsValid() &&
3188 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3189 arch.GetTriple().getOS() == llvm::Triple::IOS &&
Jason Molenda7dd7a362019-10-16 19:14:49 +00003190 (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
3191 arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003192 m_avoid_g_packets = eLazyBoolYes;
3193 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3194 if (gdb_server_version != 0) {
3195 const char *gdb_server_name = GetGDBServerProgramName();
3196 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3197 if (gdb_server_version >= 310)
3198 m_avoid_g_packets = eLazyBoolNo;
3199 }
3200 }
3201 }
3202 }
3203 }
3204 return m_avoid_g_packets == eLazyBoolYes;
3205}
Saleem Abdulrasool2d6a9ec2016-07-28 17:32:20 +00003206
Kate Stoneb9c1b512016-09-06 20:57:50 +00003207DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
3208 uint32_t reg) {
3209 StreamString payload;
3210 payload.Printf("p%x", reg);
3211 StringExtractorGDBRemote response;
3212 if (SendThreadSpecificPacketAndWaitForResponse(
3213 tid, std::move(payload), response, false) != PacketResult::Success ||
3214 !response.IsNormalResponse())
3215 return nullptr;
Pavel Labath4b6f9592016-08-18 08:30:03 +00003216
Kate Stoneb9c1b512016-09-06 20:57:50 +00003217 DataBufferSP buffer_sp(
3218 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3219 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3220 return buffer_sp;
3221}
Pavel Labath4b6f9592016-08-18 08:30:03 +00003222
Kate Stoneb9c1b512016-09-06 20:57:50 +00003223DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
3224 StreamString payload;
3225 payload.PutChar('g');
3226 StringExtractorGDBRemote response;
3227 if (SendThreadSpecificPacketAndWaitForResponse(
3228 tid, std::move(payload), response, false) != PacketResult::Success ||
3229 !response.IsNormalResponse())
3230 return nullptr;
3231
3232 DataBufferSP buffer_sp(
3233 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3234 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3235 return buffer_sp;
3236}
3237
3238bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
3239 uint32_t reg_num,
3240 llvm::ArrayRef<uint8_t> data) {
3241 StreamString payload;
3242 payload.Printf("P%x=", reg_num);
3243 payload.PutBytesAsRawHex8(data.data(), data.size(),
3244 endian::InlHostByteOrder(),
3245 endian::InlHostByteOrder());
3246 StringExtractorGDBRemote response;
3247 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3248 response, false) ==
3249 PacketResult::Success &&
3250 response.IsOKResponse();
3251}
3252
3253bool GDBRemoteCommunicationClient::WriteAllRegisters(
3254 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3255 StreamString payload;
3256 payload.PutChar('G');
3257 payload.PutBytesAsRawHex8(data.data(), data.size(),
3258 endian::InlHostByteOrder(),
3259 endian::InlHostByteOrder());
3260 StringExtractorGDBRemote response;
3261 return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3262 response, false) ==
3263 PacketResult::Success &&
3264 response.IsOKResponse();
3265}
3266
3267bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
3268 uint32_t &save_id) {
3269 save_id = 0; // Set to invalid save ID
3270 if (m_supports_QSaveRegisterState == eLazyBoolNo)
Greg Claytonf74cf862013-11-13 23:28:31 +00003271 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003272
3273 m_supports_QSaveRegisterState = eLazyBoolYes;
3274 StreamString payload;
3275 payload.PutCString("QSaveRegisterState");
3276 StringExtractorGDBRemote response;
3277 if (SendThreadSpecificPacketAndWaitForResponse(
3278 tid, std::move(payload), response, false) != PacketResult::Success)
3279 return false;
3280
3281 if (response.IsUnsupportedResponse())
3282 m_supports_QSaveRegisterState = eLazyBoolNo;
3283
3284 const uint32_t response_save_id = response.GetU32(0);
3285 if (response_save_id == 0)
3286 return false;
3287
3288 save_id = response_save_id;
3289 return true;
Greg Claytonf74cf862013-11-13 23:28:31 +00003290}
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003291
Kate Stoneb9c1b512016-09-06 20:57:50 +00003292bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
3293 uint32_t save_id) {
3294 // We use the "m_supports_QSaveRegisterState" variable here because the
Adrian Prantl05097242018-04-30 16:49:04 +00003295 // QSaveRegisterState and QRestoreRegisterState packets must both be
3296 // supported in order to be useful
Kate Stoneb9c1b512016-09-06 20:57:50 +00003297 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3298 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003299
Kate Stoneb9c1b512016-09-06 20:57:50 +00003300 StreamString payload;
3301 payload.Printf("QRestoreRegisterState:%u", save_id);
3302 StringExtractorGDBRemote response;
3303 if (SendThreadSpecificPacketAndWaitForResponse(
3304 tid, std::move(payload), response, false) != PacketResult::Success)
3305 return false;
Pavel Labath27402d22016-08-18 12:32:41 +00003306
Kate Stoneb9c1b512016-09-06 20:57:50 +00003307 if (response.IsOKResponse())
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00003308 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003309
3310 if (response.IsUnsupportedResponse())
3311 m_supports_QSaveRegisterState = eLazyBoolNo;
3312 return false;
3313}
3314
3315bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
3316 if (!GetSyncThreadStateSupported())
3317 return false;
3318
3319 StreamString packet;
3320 StringExtractorGDBRemote response;
3321 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3322 return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
3323 GDBRemoteCommunication::PacketResult::Success &&
3324 response.IsOKResponse();
3325}
3326
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003327lldb::user_id_t
3328GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
3329 Status &error) {
3330 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3331 lldb::user_id_t ret_uid = LLDB_INVALID_UID;
3332
3333 StreamGDBRemote escaped_packet;
3334 escaped_packet.PutCString("jTraceStart:");
3335
3336 StructuredData::Dictionary json_packet;
3337 json_packet.AddIntegerItem("type", options.getType());
3338 json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
3339 json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
3340
3341 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3342 json_packet.AddIntegerItem("threadid", options.getThreadID());
3343
3344 StructuredData::DictionarySP custom_params = options.getTraceParams();
3345 if (custom_params)
3346 json_packet.AddItem("params", custom_params);
3347
3348 StreamString json_string;
3349 json_packet.Dump(json_string, false);
3350 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3351
3352 StringExtractorGDBRemote response;
3353 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3354 true) ==
3355 GDBRemoteCommunication::PacketResult::Success) {
3356 if (!response.IsNormalResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003357 error = response.GetStatus();
3358 LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003359 } else {
3360 ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
3361 }
3362 } else {
3363 LLDB_LOG(log, "failed to send packet");
3364 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3365 escaped_packet.GetData());
3366 }
3367 return ret_uid;
3368}
3369
3370Status
3371GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
3372 lldb::tid_t thread_id) {
3373 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3374 StringExtractorGDBRemote response;
3375 Status error;
3376
3377 StructuredData::Dictionary json_packet;
3378 StreamGDBRemote escaped_packet;
3379 StreamString json_string;
3380 escaped_packet.PutCString("jTraceStop:");
3381
3382 json_packet.AddIntegerItem("traceid", uid);
3383
3384 if (thread_id != LLDB_INVALID_THREAD_ID)
3385 json_packet.AddIntegerItem("threadid", thread_id);
3386
3387 json_packet.Dump(json_string, false);
3388
3389 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3390
3391 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3392 true) ==
3393 GDBRemoteCommunication::PacketResult::Success) {
3394 if (!response.IsOKResponse()) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003395 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003396 LLDB_LOG(log, "stop tracing failed");
3397 }
3398 } else {
3399 LLDB_LOG(log, "failed to send packet");
3400 error.SetErrorStringWithFormat(
3401 "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
3402 response.GetError());
3403 }
3404 return error;
3405}
3406
3407Status GDBRemoteCommunicationClient::SendGetDataPacket(
3408 lldb::user_id_t uid, lldb::tid_t thread_id,
3409 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003410
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003411 StreamGDBRemote escaped_packet;
3412 escaped_packet.PutCString("jTraceBufferRead:");
3413 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3414}
3415
3416Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
3417 lldb::user_id_t uid, lldb::tid_t thread_id,
3418 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003419
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003420 StreamGDBRemote escaped_packet;
3421 escaped_packet.PutCString("jTraceMetaRead:");
3422 return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3423}
3424
3425Status
3426GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
3427 TraceOptions &options) {
3428 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3429 StringExtractorGDBRemote response;
3430 Status error;
3431
3432 StreamString json_string;
3433 StreamGDBRemote escaped_packet;
3434 escaped_packet.PutCString("jTraceConfigRead:");
3435
3436 StructuredData::Dictionary json_packet;
3437 json_packet.AddIntegerItem("traceid", uid);
3438
3439 if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3440 json_packet.AddIntegerItem("threadid", options.getThreadID());
3441
3442 json_packet.Dump(json_string, false);
3443 escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3444
3445 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3446 true) ==
3447 GDBRemoteCommunication::PacketResult::Success) {
3448 if (response.IsNormalResponse()) {
3449 uint64_t type = std::numeric_limits<uint64_t>::max();
3450 uint64_t buffersize = std::numeric_limits<uint64_t>::max();
3451 uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
3452
3453 auto json_object = StructuredData::ParseJSON(response.Peek());
3454
3455 if (!json_object ||
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003456 json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003457 error.SetErrorString("Invalid Configuration obtained");
3458 return error;
3459 }
3460
3461 auto json_dict = json_object->GetAsDictionary();
3462
3463 json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
3464 metabuffersize);
3465 options.setMetaDataBufferSize(metabuffersize);
3466
3467 json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
3468 options.setTraceBufferSize(buffersize);
3469
3470 json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
3471 options.setType(static_cast<lldb::TraceType>(type));
3472
3473 StructuredData::ObjectSP custom_params_sp =
3474 json_dict->GetValueForKey("params");
3475 if (custom_params_sp) {
3476 if (custom_params_sp->GetType() !=
Stephan Bergmanncf4321a2017-05-29 08:51:58 +00003477 lldb::eStructuredDataTypeDictionary) {
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003478 error.SetErrorString("Invalid Configuration obtained");
3479 return error;
3480 } else
3481 options.setTraceParams(
Pavel Labath31cf5812020-02-06 10:53:34 -08003482 std::static_pointer_cast<StructuredData::Dictionary>(
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003483 custom_params_sp));
3484 }
3485 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003486 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003487 }
3488 } else {
3489 LLDB_LOG(log, "failed to send packet");
3490 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3491 escaped_packet.GetData());
3492 }
3493 return error;
3494}
3495
3496Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
3497 StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
3498 llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
3499 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3500 Status error;
3501
3502 StructuredData::Dictionary json_packet;
3503
3504 json_packet.AddIntegerItem("traceid", uid);
3505 json_packet.AddIntegerItem("offset", offset);
3506 json_packet.AddIntegerItem("buffersize", buffer.size());
3507
3508 if (thread_id != LLDB_INVALID_THREAD_ID)
3509 json_packet.AddIntegerItem("threadid", thread_id);
3510
3511 StreamString json_string;
3512 json_packet.Dump(json_string, false);
3513
3514 packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3515 StringExtractorGDBRemote response;
3516 if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
3517 GDBRemoteCommunication::PacketResult::Success) {
3518 if (response.IsNormalResponse()) {
3519 size_t filled_size = response.GetHexBytesAvail(buffer);
3520 buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
3521 } else {
Ravitheja Addepallydab1d5f2017-07-12 11:15:34 +00003522 error = response.GetStatus();
Ravitheja Addepallye714c4f2017-05-26 11:46:27 +00003523 buffer = buffer.slice(buffer.size());
3524 }
3525 } else {
3526 LLDB_LOG(log, "failed to send packet");
3527 error.SetErrorStringWithFormat("failed to send packet: '%s'",
3528 packet.GetData());
3529 buffer = buffer.slice(buffer.size());
3530 }
3531 return error;
3532}
3533
Kate Stoneb9c1b512016-09-06 20:57:50 +00003534bool GDBRemoteCommunicationClient::GetModuleInfo(
3535 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3536 ModuleSpec &module_spec) {
3537 if (!m_supports_qModuleInfo)
3538 return false;
3539
3540 std::string module_path = module_file_spec.GetPath(false);
3541 if (module_path.empty())
3542 return false;
3543
3544 StreamString packet;
3545 packet.PutCString("qModuleInfo:");
Pavel Labath7f815a92019-02-12 14:28:55 +00003546 packet.PutStringAsRawHex8(module_path);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003547 packet.PutCString(";");
3548 const auto &triple = arch_spec.GetTriple().getTriple();
Pavel Labath7f815a92019-02-12 14:28:55 +00003549 packet.PutStringAsRawHex8(triple);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003550
3551 StringExtractorGDBRemote response;
Pavel Labath0f8f0d32016-09-23 09:11:49 +00003552 if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
3553 PacketResult::Success)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003554 return false;
3555
3556 if (response.IsErrorResponse())
3557 return false;
3558
3559 if (response.IsUnsupportedResponse()) {
3560 m_supports_qModuleInfo = false;
3561 return false;
3562 }
3563
3564 llvm::StringRef name;
3565 llvm::StringRef value;
3566
3567 module_spec.Clear();
3568 module_spec.GetFileSpec() = module_file_spec;
3569
3570 while (response.GetNameColonValue(name, value)) {
3571 if (name == "uuid" || name == "md5") {
3572 StringExtractor extractor(value);
3573 std::string uuid;
3574 extractor.GetHexByteString(uuid);
Pavel Labatha174bcb2018-06-21 15:24:39 +00003575 module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003576 } else if (name == "triple") {
3577 StringExtractor extractor(value);
3578 std::string triple;
3579 extractor.GetHexByteString(triple);
3580 module_spec.GetArchitecture().SetTriple(triple.c_str());
3581 } else if (name == "file_offset") {
3582 uint64_t ival = 0;
3583 if (!value.getAsInteger(16, ival))
3584 module_spec.SetObjectOffset(ival);
3585 } else if (name == "file_size") {
3586 uint64_t ival = 0;
3587 if (!value.getAsInteger(16, ival))
3588 module_spec.SetObjectSize(ival);
3589 } else if (name == "file_path") {
3590 StringExtractor extractor(value);
3591 std::string path;
3592 extractor.GetHexByteString(path);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00003593 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003594 }
3595 }
3596
3597 return true;
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00003598}
Colin Rileyc3c95b22015-04-16 15:51:33 +00003599
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003600static llvm::Optional<ModuleSpec>
3601ParseModuleSpec(StructuredData::Dictionary *dict) {
3602 ModuleSpec result;
3603 if (!dict)
3604 return llvm::None;
3605
Zachary Turner28333212017-05-12 05:49:54 +00003606 llvm::StringRef string;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003607 uint64_t integer;
3608
3609 if (!dict->GetValueForKeyAsString("uuid", string))
3610 return llvm::None;
Pavel Labath8c92c892017-12-18 14:31:44 +00003611 if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
3612 string.size())
3613 return llvm::None;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003614
3615 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3616 return llvm::None;
3617 result.SetObjectOffset(integer);
3618
3619 if (!dict->GetValueForKeyAsInteger("file_size", integer))
3620 return llvm::None;
3621 result.SetObjectSize(integer);
3622
3623 if (!dict->GetValueForKeyAsString("triple", string))
3624 return llvm::None;
Zachary Turner28333212017-05-12 05:49:54 +00003625 result.GetArchitecture().SetTriple(string);
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003626
3627 if (!dict->GetValueForKeyAsString("file_path", string))
3628 return llvm::None;
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +00003629 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003630
3631 return result;
3632}
3633
3634llvm::Optional<std::vector<ModuleSpec>>
3635GDBRemoteCommunicationClient::GetModulesInfo(
3636 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
Jonas Devlieghere2a5a9062019-10-02 18:02:26 +00003637 namespace json = llvm::json;
3638
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003639 if (!m_supports_jModulesInfo)
3640 return llvm::None;
3641
Jonas Devlieghere2a5a9062019-10-02 18:02:26 +00003642 json::Array module_array;
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003643 for (const FileSpec &module_file_spec : module_file_specs) {
Jonas Devlieghere2a5a9062019-10-02 18:02:26 +00003644 module_array.push_back(
3645 json::Object{{"file", module_file_spec.GetPath(false)},
3646 {"triple", triple.getTriple()}});
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003647 }
3648 StreamString unescaped_payload;
3649 unescaped_payload.PutCString("jModulesInfo:");
Jonas Devlieghere2a5a9062019-10-02 18:02:26 +00003650 unescaped_payload.AsRawOstream() << std::move(module_array);
3651
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003652 StreamGDBRemote payload;
Zachary Turnerc1564272016-11-16 21:15:24 +00003653 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003654 unescaped_payload.GetSize());
3655
Greg Clayton70a9f512017-04-14 17:10:04 +00003656 // Increase the timeout for jModulesInfo since this packet can take longer.
3657 ScopedTimeout timeout(*this, std::chrono::seconds(10));
3658
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003659 StringExtractorGDBRemote response;
3660 if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
3661 PacketResult::Success ||
3662 response.IsErrorResponse())
3663 return llvm::None;
3664
3665 if (response.IsUnsupportedResponse()) {
3666 m_supports_jModulesInfo = false;
3667 return llvm::None;
3668 }
3669
3670 StructuredData::ObjectSP response_object_sp =
Benjamin Krameradcd0262020-01-28 20:23:46 +01003671 StructuredData::ParseJSON(std::string(response.GetStringRef()));
Pavel Labath2f1fbae2016-09-08 10:07:04 +00003672 if (!response_object_sp)
3673 return llvm::None;
3674
3675 StructuredData::Array *response_array = response_object_sp->GetAsArray();
3676 if (!response_array)
3677 return llvm::None;
3678
3679 std::vector<ModuleSpec> result;
3680 for (size_t i = 0; i < response_array->GetSize(); ++i) {
3681 if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
3682 response_array->GetItemAtIndex(i)->GetAsDictionary()))
3683 result.push_back(*module_spec);
3684 }
3685
3686 return result;
3687}
3688
Colin Rileyc3c95b22015-04-16 15:51:33 +00003689// query the target remote for extended information using the qXfer packet
3690//
Adrian Prantl05097242018-04-30 16:49:04 +00003691// example: object='features', annex='target.xml', out=<xml output> return:
3692// 'true' on success
Colin Rileyc3c95b22015-04-16 15:51:33 +00003693// 'false' on failure (err set)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003694bool GDBRemoteCommunicationClient::ReadExtFeature(
3695 const lldb_private::ConstString object,
3696 const lldb_private::ConstString annex, std::string &out,
Zachary Turner97206d52017-05-12 04:51:55 +00003697 lldb_private::Status &err) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003698
Kate Stoneb9c1b512016-09-06 20:57:50 +00003699 std::stringstream output;
3700 StringExtractorGDBRemote chunk;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003701
Kate Stoneb9c1b512016-09-06 20:57:50 +00003702 uint64_t size = GetRemoteMaxPacketSize();
3703 if (size == 0)
3704 size = 0x1000;
3705 size = size - 1; // Leave space for the 'm' or 'l' character in the response
3706 int offset = 0;
3707 bool active = true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003708
Kate Stoneb9c1b512016-09-06 20:57:50 +00003709 // loop until all data has been read
3710 while (active) {
Colin Rileyc3c95b22015-04-16 15:51:33 +00003711
Kate Stoneb9c1b512016-09-06 20:57:50 +00003712 // send query extended feature packet
3713 std::stringstream packet;
3714 packet << "qXfer:" << object.AsCString("")
3715 << ":read:" << annex.AsCString("") << ":" << std::hex << offset
3716 << "," << std::hex << size;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003717
Kate Stoneb9c1b512016-09-06 20:57:50 +00003718 GDBRemoteCommunication::PacketResult res =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00003719 SendPacketAndWaitForResponse(packet.str(), chunk, false);
Colin Rileyc3c95b22015-04-16 15:51:33 +00003720
Kate Stoneb9c1b512016-09-06 20:57:50 +00003721 if (res != GDBRemoteCommunication::PacketResult::Success) {
3722 err.SetErrorString("Error sending $qXfer packet");
3723 return false;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003724 }
3725
Benjamin Krameradcd0262020-01-28 20:23:46 +01003726 const std::string &str = std::string(chunk.GetStringRef());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003727 if (str.length() == 0) {
3728 // should have some data in chunk
3729 err.SetErrorString("Empty response from $qXfer packet");
3730 return false;
3731 }
3732
3733 // check packet code
3734 switch (str[0]) {
3735 // last chunk
3736 case ('l'):
3737 active = false;
3738 LLVM_FALLTHROUGH;
3739
3740 // more chunks
3741 case ('m'):
3742 if (str.length() > 1)
3743 output << &str[1];
Jason Molenda02113912020-01-09 16:05:38 -08003744 offset += str.length() - 1;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003745 break;
3746
3747 // unknown chunk
3748 default:
3749 err.SetErrorString("Invalid continuation code from $qXfer packet");
3750 return false;
3751 }
3752 }
3753
3754 out = output.str();
3755 err.Success();
3756 return true;
Colin Rileyc3c95b22015-04-16 15:51:33 +00003757}
Greg Clayton0b90be12015-06-23 21:27:50 +00003758
3759// Notify the target that gdb is prepared to serve symbol lookup requests.
3760// packet: "qSymbol::"
3761// reply:
3762// OK The target does not need to look up any (more) symbols.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003763// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
3764// encoded).
3765// LLDB may provide the value by sending another qSymbol
3766// packet
Greg Clayton0b90be12015-06-23 21:27:50 +00003767// in the form of"qSymbol:<sym_value>:<sym_name>".
Jason Molenda50018d32016-01-13 04:08:10 +00003768//
3769// Three examples:
3770//
3771// lldb sends: qSymbol::
3772// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003773// Remote gdb stub does not need to know the addresses of any symbols, lldb
3774// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003775// need to ask again in this session.
3776//
3777// lldb sends: qSymbol::
3778// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3779// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
3780// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003781// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
3782// not know
3783// the address at this time. lldb needs to send qSymbol:: again when it has
3784// more
Jason Molenda50018d32016-01-13 04:08:10 +00003785// solibs loaded.
3786//
3787// lldb sends: qSymbol::
3788// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3789// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
3790// lldb receives: OK
Kate Stoneb9c1b512016-09-06 20:57:50 +00003791// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
3792// that it
3793// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
3794// does not
Jason Molenda50018d32016-01-13 04:08:10 +00003795// need any more symbols. lldb does not need to ask again in this session.
Greg Clayton0b90be12015-06-23 21:27:50 +00003796
Kate Stoneb9c1b512016-09-06 20:57:50 +00003797void GDBRemoteCommunicationClient::ServeSymbolLookups(
3798 lldb_private::Process *process) {
Adrian Prantl05097242018-04-30 16:49:04 +00003799 // Set to true once we've resolved a symbol to an address for the remote
3800 // stub. If we get an 'OK' response after this, the remote stub doesn't need
3801 // any more symbols and we can stop asking.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003802 bool symbol_response_provided = false;
Jason Molenda50018d32016-01-13 04:08:10 +00003803
Kate Stoneb9c1b512016-09-06 20:57:50 +00003804 // Is this the initial qSymbol:: packet?
3805 bool first_qsymbol_query = true;
Jason Molenda50018d32016-01-13 04:08:10 +00003806
Jonas Devliegherea6682a42018-12-15 00:15:33 +00003807 if (m_supports_qSymbol && !m_qSymbol_requests_done) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003808 Lock lock(*this, false);
3809 if (lock) {
3810 StreamString packet;
3811 packet.PutCString("qSymbol::");
3812 StringExtractorGDBRemote response;
3813 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
3814 PacketResult::Success) {
3815 if (response.IsOKResponse()) {
3816 if (symbol_response_provided || first_qsymbol_query) {
3817 m_qSymbol_requests_done = true;
3818 }
3819
3820 // We are done serving symbols requests
3821 return;
3822 }
3823 first_qsymbol_query = false;
3824
3825 if (response.IsUnsupportedResponse()) {
Adrian Prantl05097242018-04-30 16:49:04 +00003826 // qSymbol is not supported by the current GDB server we are
3827 // connected to
Kate Stoneb9c1b512016-09-06 20:57:50 +00003828 m_supports_qSymbol = false;
3829 return;
3830 } else {
3831 llvm::StringRef response_str(response.GetStringRef());
3832 if (response_str.startswith("qSymbol:")) {
3833 response.SetFilePos(strlen("qSymbol:"));
3834 std::string symbol_name;
3835 if (response.GetHexByteString(symbol_name)) {
3836 if (symbol_name.empty())
3837 return;
3838
3839 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
3840 lldb_private::SymbolContextList sc_list;
Adrian Prantl1ad655e2019-10-17 19:56:40 +00003841 process->GetTarget().GetImages().FindSymbolsWithNameAndType(
3842 ConstString(symbol_name), eSymbolTypeAny, sc_list);
3843 if (!sc_list.IsEmpty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003844 const size_t num_scs = sc_list.GetSize();
3845 for (size_t sc_idx = 0;
3846 sc_idx < num_scs &&
3847 symbol_load_addr == LLDB_INVALID_ADDRESS;
3848 ++sc_idx) {
3849 SymbolContext sc;
3850 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
3851 if (sc.symbol) {
3852 switch (sc.symbol->GetType()) {
3853 case eSymbolTypeInvalid:
3854 case eSymbolTypeAbsolute:
3855 case eSymbolTypeUndefined:
3856 case eSymbolTypeSourceFile:
3857 case eSymbolTypeHeaderFile:
3858 case eSymbolTypeObjectFile:
3859 case eSymbolTypeCommonBlock:
3860 case eSymbolTypeBlock:
3861 case eSymbolTypeLocal:
3862 case eSymbolTypeParam:
3863 case eSymbolTypeVariable:
3864 case eSymbolTypeVariableType:
3865 case eSymbolTypeLineEntry:
3866 case eSymbolTypeLineHeader:
3867 case eSymbolTypeScopeBegin:
3868 case eSymbolTypeScopeEnd:
3869 case eSymbolTypeAdditional:
3870 case eSymbolTypeCompiler:
3871 case eSymbolTypeInstrumentation:
3872 case eSymbolTypeTrampoline:
3873 break;
3874
3875 case eSymbolTypeCode:
3876 case eSymbolTypeResolver:
3877 case eSymbolTypeData:
3878 case eSymbolTypeRuntime:
3879 case eSymbolTypeException:
3880 case eSymbolTypeObjCClass:
3881 case eSymbolTypeObjCMetaClass:
3882 case eSymbolTypeObjCIVar:
3883 case eSymbolTypeReExported:
3884 symbol_load_addr =
3885 sc.symbol->GetLoadAddress(&process->GetTarget());
3886 break;
3887 }
Jason Molenda50018d32016-01-13 04:08:10 +00003888 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003889 }
Greg Clayton42b01482015-08-11 22:07:46 +00003890 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003891 }
3892 // This is the normal path where our symbol lookup was successful
Adrian Prantl05097242018-04-30 16:49:04 +00003893 // and we want to send a packet with the new symbol value and see
3894 // if another lookup needs to be done.
Greg Clayton0b90be12015-06-23 21:27:50 +00003895
Kate Stoneb9c1b512016-09-06 20:57:50 +00003896 // Change "packet" to contain the requested symbol value and name
3897 packet.Clear();
3898 packet.PutCString("qSymbol:");
3899 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
3900 packet.Printf("%" PRIx64, symbol_load_addr);
3901 symbol_response_provided = true;
3902 } else {
3903 symbol_response_provided = false;
3904 }
3905 packet.PutCString(":");
3906 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
3907 continue; // go back to the while loop and send "packet" and wait
3908 // for another response
Greg Clayton0b90be12015-06-23 21:27:50 +00003909 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003910 }
3911 }
3912 }
3913 // If we make it here, the symbol request packet response wasn't valid or
3914 // our symbol lookup failed so we must abort
3915 return;
Greg Clayton0b90be12015-06-23 21:27:50 +00003916
Kate Stoneb9c1b512016-09-06 20:57:50 +00003917 } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
3918 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00003919 LLDB_LOGF(log,
3920 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
3921 __FUNCTION__);
Greg Clayton0b90be12015-06-23 21:27:50 +00003922 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003923 }
Greg Clayton0b90be12015-06-23 21:27:50 +00003924}
3925
Kate Stoneb9c1b512016-09-06 20:57:50 +00003926StructuredData::Array *
3927GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
3928 if (!m_supported_async_json_packets_is_valid) {
Adrian Prantl05097242018-04-30 16:49:04 +00003929 // Query the server for the array of supported asynchronous JSON packets.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003930 m_supported_async_json_packets_is_valid = true;
Todd Fiala75930012016-08-19 04:21:48 +00003931
Kate Stoneb9c1b512016-09-06 20:57:50 +00003932 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Todd Fiala75930012016-08-19 04:21:48 +00003933
Kate Stoneb9c1b512016-09-06 20:57:50 +00003934 // Poll it now.
Todd Fiala75930012016-08-19 04:21:48 +00003935 StringExtractorGDBRemote response;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003936 const bool send_async = false;
3937 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
3938 send_async) == PacketResult::Success) {
3939 m_supported_async_json_packets_sp =
Benjamin Krameradcd0262020-01-28 20:23:46 +01003940 StructuredData::ParseJSON(std::string(response.GetStringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00003941 if (m_supported_async_json_packets_sp &&
3942 !m_supported_async_json_packets_sp->GetAsArray()) {
Adrian Prantl05097242018-04-30 16:49:04 +00003943 // We were returned something other than a JSON array. This is
3944 // invalid. Clear it out.
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00003945 LLDB_LOGF(log,
3946 "GDBRemoteCommunicationClient::%s(): "
3947 "QSupportedAsyncJSONPackets returned invalid "
3948 "result: %s",
Jonas Devlieghered35b42f2019-08-21 04:55:56 +00003949 __FUNCTION__, response.GetStringRef().data());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003950 m_supported_async_json_packets_sp.reset();
3951 }
3952 } else {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00003953 LLDB_LOGF(log,
3954 "GDBRemoteCommunicationClient::%s(): "
3955 "QSupportedAsyncJSONPackets unsupported",
3956 __FUNCTION__);
Todd Fiala75930012016-08-19 04:21:48 +00003957 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003958
3959 if (log && m_supported_async_json_packets_sp) {
3960 StreamString stream;
3961 m_supported_async_json_packets_sp->Dump(stream);
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00003962 LLDB_LOGF(log,
3963 "GDBRemoteCommunicationClient::%s(): supported async "
3964 "JSON packets: %s",
3965 __FUNCTION__, stream.GetData());
Todd Fiala75930012016-08-19 04:21:48 +00003966 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003967 }
3968
3969 return m_supported_async_json_packets_sp
3970 ? m_supported_async_json_packets_sp->GetAsArray()
3971 : nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00003972}
3973
Zachary Turner97206d52017-05-12 04:51:55 +00003974Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003975 llvm::ArrayRef<int32_t> signals) {
3976 // Format packet:
3977 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
3978 auto range = llvm::make_range(signals.begin(), signals.end());
3979 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
3980
3981 StringExtractorGDBRemote response;
3982 auto send_status = SendPacketAndWaitForResponse(packet, response, false);
3983
3984 if (send_status != GDBRemoteCommunication::PacketResult::Success)
Zachary Turner97206d52017-05-12 04:51:55 +00003985 return Status("Sending QPassSignals packet failed");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003986
3987 if (response.IsOKResponse()) {
Zachary Turner97206d52017-05-12 04:51:55 +00003988 return Status();
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003989 } else {
Zachary Turner97206d52017-05-12 04:51:55 +00003990 return Status("Unknown error happened during sending QPassSignals packet.");
Eugene Zemtsov7993cc52017-03-07 21:34:40 +00003991 }
3992}
3993
Zachary Turner97206d52017-05-12 04:51:55 +00003994Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00003995 ConstString type_name, const StructuredData::ObjectSP &config_sp) {
Zachary Turner97206d52017-05-12 04:51:55 +00003996 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003997
3998 if (type_name.GetLength() == 0) {
3999 error.SetErrorString("invalid type_name argument");
4000 return error;
4001 }
4002
Adrian Prantl05097242018-04-30 16:49:04 +00004003 // Build command: Configure{type_name}: serialized config data.
Kate Stoneb9c1b512016-09-06 20:57:50 +00004004 StreamGDBRemote stream;
4005 stream.PutCString("QConfigure");
4006 stream.PutCString(type_name.AsCString());
4007 stream.PutChar(':');
4008 if (config_sp) {
4009 // Gather the plain-text version of the configuration data.
4010 StreamString unescaped_stream;
4011 config_sp->Dump(unescaped_stream);
4012 unescaped_stream.Flush();
4013
4014 // Add it to the stream in escaped fashion.
Zachary Turnerc1564272016-11-16 21:15:24 +00004015 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00004016 unescaped_stream.GetSize());
4017 }
4018 stream.Flush();
4019
4020 // Send the packet.
4021 const bool send_async = false;
4022 StringExtractorGDBRemote response;
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00004023 auto result =
4024 SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004025 if (result == PacketResult::Success) {
4026 // We failed if the config result comes back other than OK.
Jonas Devlieghered35b42f2019-08-21 04:55:56 +00004027 if (strcmp(response.GetStringRef().data(), "OK") == 0) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004028 // Okay!
4029 error.Clear();
4030 } else {
4031 error.SetErrorStringWithFormat("configuring StructuredData feature "
4032 "%s failed with error %s",
4033 type_name.AsCString(),
Jonas Devlieghered35b42f2019-08-21 04:55:56 +00004034 response.GetStringRef().data());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004035 }
4036 } else {
4037 // Can we get more data here on the failure?
4038 error.SetErrorStringWithFormat("configuring StructuredData feature %s "
4039 "failed when sending packet: "
4040 "PacketResult=%d",
Ilia K4f730dc2016-09-12 05:25:33 +00004041 type_name.AsCString(), (int)result);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004042 }
4043 return error;
4044}
4045
4046void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
4047 GDBRemoteClientBase::OnRunPacketSent(first);
4048 m_curr_tid = LLDB_INVALID_THREAD_ID;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00004049}