xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick //===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
2*061da546Spatrick //
3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*061da546Spatrick //
7*061da546Spatrick //===----------------------------------------------------------------------===//
8*061da546Spatrick 
9*061da546Spatrick #include "GDBRemoteCommunicationClient.h"
10*061da546Spatrick 
11*061da546Spatrick #include <math.h>
12*061da546Spatrick #include <sys/stat.h>
13*061da546Spatrick 
14*061da546Spatrick #include <numeric>
15*061da546Spatrick #include <sstream>
16*061da546Spatrick 
17*061da546Spatrick #include "lldb/Core/ModuleSpec.h"
18*061da546Spatrick #include "lldb/Host/HostInfo.h"
19*061da546Spatrick #include "lldb/Host/XML.h"
20*061da546Spatrick #include "lldb/Symbol/Symbol.h"
21*061da546Spatrick #include "lldb/Target/MemoryRegionInfo.h"
22*061da546Spatrick #include "lldb/Target/Target.h"
23*061da546Spatrick #include "lldb/Target/UnixSignals.h"
24*061da546Spatrick #include "lldb/Utility/Args.h"
25*061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
26*061da546Spatrick #include "lldb/Utility/LLDBAssert.h"
27*061da546Spatrick #include "lldb/Utility/Log.h"
28*061da546Spatrick #include "lldb/Utility/State.h"
29*061da546Spatrick #include "lldb/Utility/StreamString.h"
30*061da546Spatrick 
31*061da546Spatrick #include "ProcessGDBRemote.h"
32*061da546Spatrick #include "ProcessGDBRemoteLog.h"
33*061da546Spatrick #include "lldb/Host/Config.h"
34*061da546Spatrick #include "lldb/Utility/StringExtractorGDBRemote.h"
35*061da546Spatrick 
36*061da546Spatrick #include "llvm/ADT/StringSwitch.h"
37*061da546Spatrick #include "llvm/Support/JSON.h"
38*061da546Spatrick 
39*061da546Spatrick #if defined(HAVE_LIBCOMPRESSION)
40*061da546Spatrick #include <compression.h>
41*061da546Spatrick #endif
42*061da546Spatrick 
43*061da546Spatrick using namespace lldb;
44*061da546Spatrick using namespace lldb_private::process_gdb_remote;
45*061da546Spatrick using namespace lldb_private;
46*061da546Spatrick using namespace std::chrono;
47*061da546Spatrick 
48*061da546Spatrick // GDBRemoteCommunicationClient constructor
49*061da546Spatrick GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
50*061da546Spatrick     : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
51*061da546Spatrick       m_supports_not_sending_acks(eLazyBoolCalculate),
52*061da546Spatrick       m_supports_thread_suffix(eLazyBoolCalculate),
53*061da546Spatrick       m_supports_threads_in_stop_reply(eLazyBoolCalculate),
54*061da546Spatrick       m_supports_vCont_all(eLazyBoolCalculate),
55*061da546Spatrick       m_supports_vCont_any(eLazyBoolCalculate),
56*061da546Spatrick       m_supports_vCont_c(eLazyBoolCalculate),
57*061da546Spatrick       m_supports_vCont_C(eLazyBoolCalculate),
58*061da546Spatrick       m_supports_vCont_s(eLazyBoolCalculate),
59*061da546Spatrick       m_supports_vCont_S(eLazyBoolCalculate),
60*061da546Spatrick       m_qHostInfo_is_valid(eLazyBoolCalculate),
61*061da546Spatrick       m_curr_pid_is_valid(eLazyBoolCalculate),
62*061da546Spatrick       m_qProcessInfo_is_valid(eLazyBoolCalculate),
63*061da546Spatrick       m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
64*061da546Spatrick       m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
65*061da546Spatrick       m_supports_memory_region_info(eLazyBoolCalculate),
66*061da546Spatrick       m_supports_watchpoint_support_info(eLazyBoolCalculate),
67*061da546Spatrick       m_supports_detach_stay_stopped(eLazyBoolCalculate),
68*061da546Spatrick       m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
69*061da546Spatrick       m_attach_or_wait_reply(eLazyBoolCalculate),
70*061da546Spatrick       m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
71*061da546Spatrick       m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
72*061da546Spatrick       m_avoid_g_packets(eLazyBoolCalculate),
73*061da546Spatrick       m_supports_QSaveRegisterState(eLazyBoolCalculate),
74*061da546Spatrick       m_supports_qXfer_auxv_read(eLazyBoolCalculate),
75*061da546Spatrick       m_supports_qXfer_libraries_read(eLazyBoolCalculate),
76*061da546Spatrick       m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
77*061da546Spatrick       m_supports_qXfer_features_read(eLazyBoolCalculate),
78*061da546Spatrick       m_supports_qXfer_memory_map_read(eLazyBoolCalculate),
79*061da546Spatrick       m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
80*061da546Spatrick       m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
81*061da546Spatrick       m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
82*061da546Spatrick       m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
83*061da546Spatrick       m_supports_QPassSignals(eLazyBoolCalculate),
84*061da546Spatrick       m_supports_error_string_reply(eLazyBoolCalculate),
85*061da546Spatrick       m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
86*061da546Spatrick       m_supports_qUserName(true), m_supports_qGroupName(true),
87*061da546Spatrick       m_supports_qThreadStopInfo(true), m_supports_z0(true),
88*061da546Spatrick       m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
89*061da546Spatrick       m_supports_z4(true), m_supports_QEnvironment(true),
90*061da546Spatrick       m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
91*061da546Spatrick       m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
92*061da546Spatrick       m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
93*061da546Spatrick       m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
94*061da546Spatrick       m_curr_tid_run(LLDB_INVALID_THREAD_ID),
95*061da546Spatrick       m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
96*061da546Spatrick       m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
97*061da546Spatrick       m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
98*061da546Spatrick       m_max_packet_size(0), m_qSupported_response(),
99*061da546Spatrick       m_supported_async_json_packets_is_valid(false),
100*061da546Spatrick       m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
101*061da546Spatrick       m_qXfer_memory_map_loaded(false) {}
102*061da546Spatrick 
103*061da546Spatrick // Destructor
104*061da546Spatrick GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
105*061da546Spatrick   if (IsConnected())
106*061da546Spatrick     Disconnect();
107*061da546Spatrick }
108*061da546Spatrick 
109*061da546Spatrick bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
110*061da546Spatrick   ResetDiscoverableSettings(false);
111*061da546Spatrick 
112*061da546Spatrick   // Start the read thread after we send the handshake ack since if we fail to
113*061da546Spatrick   // send the handshake ack, there is no reason to continue...
114*061da546Spatrick   if (SendAck()) {
115*061da546Spatrick     // Wait for any responses that might have been queued up in the remote
116*061da546Spatrick     // GDB server and flush them all
117*061da546Spatrick     StringExtractorGDBRemote response;
118*061da546Spatrick     PacketResult packet_result = PacketResult::Success;
119*061da546Spatrick     while (packet_result == PacketResult::Success)
120*061da546Spatrick       packet_result = ReadPacket(response, milliseconds(10), false);
121*061da546Spatrick 
122*061da546Spatrick     // The return value from QueryNoAckModeSupported() is true if the packet
123*061da546Spatrick     // was sent and _any_ response (including UNIMPLEMENTED) was received), or
124*061da546Spatrick     // false if no response was received. This quickly tells us if we have a
125*061da546Spatrick     // live connection to a remote GDB server...
126*061da546Spatrick     if (QueryNoAckModeSupported()) {
127*061da546Spatrick       return true;
128*061da546Spatrick     } else {
129*061da546Spatrick       if (error_ptr)
130*061da546Spatrick         error_ptr->SetErrorString("failed to get reply to handshake packet");
131*061da546Spatrick     }
132*061da546Spatrick   } else {
133*061da546Spatrick     if (error_ptr)
134*061da546Spatrick       error_ptr->SetErrorString("failed to send the handshake ack");
135*061da546Spatrick   }
136*061da546Spatrick   return false;
137*061da546Spatrick }
138*061da546Spatrick 
139*061da546Spatrick bool GDBRemoteCommunicationClient::GetEchoSupported() {
140*061da546Spatrick   if (m_supports_qEcho == eLazyBoolCalculate) {
141*061da546Spatrick     GetRemoteQSupported();
142*061da546Spatrick   }
143*061da546Spatrick   return m_supports_qEcho == eLazyBoolYes;
144*061da546Spatrick }
145*061da546Spatrick 
146*061da546Spatrick bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
147*061da546Spatrick   if (m_supports_QPassSignals == eLazyBoolCalculate) {
148*061da546Spatrick     GetRemoteQSupported();
149*061da546Spatrick   }
150*061da546Spatrick   return m_supports_QPassSignals == eLazyBoolYes;
151*061da546Spatrick }
152*061da546Spatrick 
153*061da546Spatrick bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
154*061da546Spatrick   if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
155*061da546Spatrick     GetRemoteQSupported();
156*061da546Spatrick   }
157*061da546Spatrick   return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
158*061da546Spatrick }
159*061da546Spatrick 
160*061da546Spatrick bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
161*061da546Spatrick   if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
162*061da546Spatrick     GetRemoteQSupported();
163*061da546Spatrick   }
164*061da546Spatrick   return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
165*061da546Spatrick }
166*061da546Spatrick 
167*061da546Spatrick bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
168*061da546Spatrick   if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
169*061da546Spatrick     GetRemoteQSupported();
170*061da546Spatrick   }
171*061da546Spatrick   return m_supports_qXfer_libraries_read == eLazyBoolYes;
172*061da546Spatrick }
173*061da546Spatrick 
174*061da546Spatrick bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
175*061da546Spatrick   if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
176*061da546Spatrick     GetRemoteQSupported();
177*061da546Spatrick   }
178*061da546Spatrick   return m_supports_qXfer_auxv_read == eLazyBoolYes;
179*061da546Spatrick }
180*061da546Spatrick 
181*061da546Spatrick bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
182*061da546Spatrick   if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
183*061da546Spatrick     GetRemoteQSupported();
184*061da546Spatrick   }
185*061da546Spatrick   return m_supports_qXfer_features_read == eLazyBoolYes;
186*061da546Spatrick }
187*061da546Spatrick 
188*061da546Spatrick bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
189*061da546Spatrick   if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
190*061da546Spatrick     GetRemoteQSupported();
191*061da546Spatrick   }
192*061da546Spatrick   return m_supports_qXfer_memory_map_read == eLazyBoolYes;
193*061da546Spatrick }
194*061da546Spatrick 
195*061da546Spatrick uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
196*061da546Spatrick   if (m_max_packet_size == 0) {
197*061da546Spatrick     GetRemoteQSupported();
198*061da546Spatrick   }
199*061da546Spatrick   return m_max_packet_size;
200*061da546Spatrick }
201*061da546Spatrick 
202*061da546Spatrick bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
203*061da546Spatrick   if (m_supports_not_sending_acks == eLazyBoolCalculate) {
204*061da546Spatrick     m_send_acks = true;
205*061da546Spatrick     m_supports_not_sending_acks = eLazyBoolNo;
206*061da546Spatrick 
207*061da546Spatrick     // This is the first real packet that we'll send in a debug session and it
208*061da546Spatrick     // may take a little longer than normal to receive a reply.  Wait at least
209*061da546Spatrick     // 6 seconds for a reply to this packet.
210*061da546Spatrick 
211*061da546Spatrick     ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
212*061da546Spatrick 
213*061da546Spatrick     StringExtractorGDBRemote response;
214*061da546Spatrick     if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
215*061da546Spatrick         PacketResult::Success) {
216*061da546Spatrick       if (response.IsOKResponse()) {
217*061da546Spatrick         m_send_acks = false;
218*061da546Spatrick         m_supports_not_sending_acks = eLazyBoolYes;
219*061da546Spatrick       }
220*061da546Spatrick       return true;
221*061da546Spatrick     }
222*061da546Spatrick   }
223*061da546Spatrick   return false;
224*061da546Spatrick }
225*061da546Spatrick 
226*061da546Spatrick void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
227*061da546Spatrick   if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
228*061da546Spatrick     m_supports_threads_in_stop_reply = eLazyBoolNo;
229*061da546Spatrick 
230*061da546Spatrick     StringExtractorGDBRemote response;
231*061da546Spatrick     if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
232*061da546Spatrick                                      false) == PacketResult::Success) {
233*061da546Spatrick       if (response.IsOKResponse())
234*061da546Spatrick         m_supports_threads_in_stop_reply = eLazyBoolYes;
235*061da546Spatrick     }
236*061da546Spatrick   }
237*061da546Spatrick }
238*061da546Spatrick 
239*061da546Spatrick bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
240*061da546Spatrick   if (m_attach_or_wait_reply == eLazyBoolCalculate) {
241*061da546Spatrick     m_attach_or_wait_reply = eLazyBoolNo;
242*061da546Spatrick 
243*061da546Spatrick     StringExtractorGDBRemote response;
244*061da546Spatrick     if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
245*061da546Spatrick                                      false) == PacketResult::Success) {
246*061da546Spatrick       if (response.IsOKResponse())
247*061da546Spatrick         m_attach_or_wait_reply = eLazyBoolYes;
248*061da546Spatrick     }
249*061da546Spatrick   }
250*061da546Spatrick   return m_attach_or_wait_reply == eLazyBoolYes;
251*061da546Spatrick }
252*061da546Spatrick 
253*061da546Spatrick bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
254*061da546Spatrick   if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
255*061da546Spatrick     m_prepare_for_reg_writing_reply = eLazyBoolNo;
256*061da546Spatrick 
257*061da546Spatrick     StringExtractorGDBRemote response;
258*061da546Spatrick     if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
259*061da546Spatrick                                      false) == PacketResult::Success) {
260*061da546Spatrick       if (response.IsOKResponse())
261*061da546Spatrick         m_prepare_for_reg_writing_reply = eLazyBoolYes;
262*061da546Spatrick     }
263*061da546Spatrick   }
264*061da546Spatrick   return m_prepare_for_reg_writing_reply == eLazyBoolYes;
265*061da546Spatrick }
266*061da546Spatrick 
267*061da546Spatrick void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
268*061da546Spatrick   if (!did_exec) {
269*061da546Spatrick     // Hard reset everything, this is when we first connect to a GDB server
270*061da546Spatrick     m_supports_not_sending_acks = eLazyBoolCalculate;
271*061da546Spatrick     m_supports_thread_suffix = eLazyBoolCalculate;
272*061da546Spatrick     m_supports_threads_in_stop_reply = eLazyBoolCalculate;
273*061da546Spatrick     m_supports_vCont_c = eLazyBoolCalculate;
274*061da546Spatrick     m_supports_vCont_C = eLazyBoolCalculate;
275*061da546Spatrick     m_supports_vCont_s = eLazyBoolCalculate;
276*061da546Spatrick     m_supports_vCont_S = eLazyBoolCalculate;
277*061da546Spatrick     m_supports_p = eLazyBoolCalculate;
278*061da546Spatrick     m_supports_x = eLazyBoolCalculate;
279*061da546Spatrick     m_supports_QSaveRegisterState = eLazyBoolCalculate;
280*061da546Spatrick     m_qHostInfo_is_valid = eLazyBoolCalculate;
281*061da546Spatrick     m_curr_pid_is_valid = eLazyBoolCalculate;
282*061da546Spatrick     m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
283*061da546Spatrick     m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
284*061da546Spatrick     m_supports_memory_region_info = eLazyBoolCalculate;
285*061da546Spatrick     m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
286*061da546Spatrick     m_attach_or_wait_reply = eLazyBoolCalculate;
287*061da546Spatrick     m_avoid_g_packets = eLazyBoolCalculate;
288*061da546Spatrick     m_supports_qXfer_auxv_read = eLazyBoolCalculate;
289*061da546Spatrick     m_supports_qXfer_libraries_read = eLazyBoolCalculate;
290*061da546Spatrick     m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
291*061da546Spatrick     m_supports_qXfer_features_read = eLazyBoolCalculate;
292*061da546Spatrick     m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
293*061da546Spatrick     m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
294*061da546Spatrick     m_supports_qProcessInfoPID = true;
295*061da546Spatrick     m_supports_qfProcessInfo = true;
296*061da546Spatrick     m_supports_qUserName = true;
297*061da546Spatrick     m_supports_qGroupName = true;
298*061da546Spatrick     m_supports_qThreadStopInfo = true;
299*061da546Spatrick     m_supports_z0 = true;
300*061da546Spatrick     m_supports_z1 = true;
301*061da546Spatrick     m_supports_z2 = true;
302*061da546Spatrick     m_supports_z3 = true;
303*061da546Spatrick     m_supports_z4 = true;
304*061da546Spatrick     m_supports_QEnvironment = true;
305*061da546Spatrick     m_supports_QEnvironmentHexEncoded = true;
306*061da546Spatrick     m_supports_qSymbol = true;
307*061da546Spatrick     m_qSymbol_requests_done = false;
308*061da546Spatrick     m_supports_qModuleInfo = true;
309*061da546Spatrick     m_host_arch.Clear();
310*061da546Spatrick     m_os_version = llvm::VersionTuple();
311*061da546Spatrick     m_os_build.clear();
312*061da546Spatrick     m_os_kernel.clear();
313*061da546Spatrick     m_hostname.clear();
314*061da546Spatrick     m_gdb_server_name.clear();
315*061da546Spatrick     m_gdb_server_version = UINT32_MAX;
316*061da546Spatrick     m_default_packet_timeout = seconds(0);
317*061da546Spatrick     m_max_packet_size = 0;
318*061da546Spatrick     m_qSupported_response.clear();
319*061da546Spatrick     m_supported_async_json_packets_is_valid = false;
320*061da546Spatrick     m_supported_async_json_packets_sp.reset();
321*061da546Spatrick     m_supports_jModulesInfo = true;
322*061da546Spatrick   }
323*061da546Spatrick 
324*061da546Spatrick   // These flags should be reset when we first connect to a GDB server and when
325*061da546Spatrick   // our inferior process execs
326*061da546Spatrick   m_qProcessInfo_is_valid = eLazyBoolCalculate;
327*061da546Spatrick   m_process_arch.Clear();
328*061da546Spatrick }
329*061da546Spatrick 
330*061da546Spatrick void GDBRemoteCommunicationClient::GetRemoteQSupported() {
331*061da546Spatrick   // Clear out any capabilities we expect to see in the qSupported response
332*061da546Spatrick   m_supports_qXfer_auxv_read = eLazyBoolNo;
333*061da546Spatrick   m_supports_qXfer_libraries_read = eLazyBoolNo;
334*061da546Spatrick   m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
335*061da546Spatrick   m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
336*061da546Spatrick   m_supports_qXfer_features_read = eLazyBoolNo;
337*061da546Spatrick   m_supports_qXfer_memory_map_read = eLazyBoolNo;
338*061da546Spatrick   m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
339*061da546Spatrick                                   // not, we assume no limit
340*061da546Spatrick 
341*061da546Spatrick   // build the qSupported packet
342*061da546Spatrick   std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
343*061da546Spatrick   StreamString packet;
344*061da546Spatrick   packet.PutCString("qSupported");
345*061da546Spatrick   for (uint32_t i = 0; i < features.size(); ++i) {
346*061da546Spatrick     packet.PutCString(i == 0 ? ":" : ";");
347*061da546Spatrick     packet.PutCString(features[i]);
348*061da546Spatrick   }
349*061da546Spatrick 
350*061da546Spatrick   StringExtractorGDBRemote response;
351*061da546Spatrick   if (SendPacketAndWaitForResponse(packet.GetString(), response,
352*061da546Spatrick                                    /*send_async=*/false) ==
353*061da546Spatrick       PacketResult::Success) {
354*061da546Spatrick     const char *response_cstr = response.GetStringRef().data();
355*061da546Spatrick 
356*061da546Spatrick     // Hang on to the qSupported packet, so that platforms can do custom
357*061da546Spatrick     // configuration of the transport before attaching/launching the process.
358*061da546Spatrick     m_qSupported_response = response_cstr;
359*061da546Spatrick 
360*061da546Spatrick     if (::strstr(response_cstr, "qXfer:auxv:read+"))
361*061da546Spatrick       m_supports_qXfer_auxv_read = eLazyBoolYes;
362*061da546Spatrick     if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
363*061da546Spatrick       m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
364*061da546Spatrick     if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
365*061da546Spatrick       m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
366*061da546Spatrick       m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
367*061da546Spatrick     }
368*061da546Spatrick     if (::strstr(response_cstr, "qXfer:libraries:read+"))
369*061da546Spatrick       m_supports_qXfer_libraries_read = eLazyBoolYes;
370*061da546Spatrick     if (::strstr(response_cstr, "qXfer:features:read+"))
371*061da546Spatrick       m_supports_qXfer_features_read = eLazyBoolYes;
372*061da546Spatrick     if (::strstr(response_cstr, "qXfer:memory-map:read+"))
373*061da546Spatrick       m_supports_qXfer_memory_map_read = eLazyBoolYes;
374*061da546Spatrick 
375*061da546Spatrick     // Look for a list of compressions in the features list e.g.
376*061da546Spatrick     // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
377*061da546Spatrick     // deflate,lzma
378*061da546Spatrick     const char *features_list = ::strstr(response_cstr, "qXfer:features:");
379*061da546Spatrick     if (features_list) {
380*061da546Spatrick       const char *compressions =
381*061da546Spatrick           ::strstr(features_list, "SupportedCompressions=");
382*061da546Spatrick       if (compressions) {
383*061da546Spatrick         std::vector<std::string> supported_compressions;
384*061da546Spatrick         compressions += sizeof("SupportedCompressions=") - 1;
385*061da546Spatrick         const char *end_of_compressions = strchr(compressions, ';');
386*061da546Spatrick         if (end_of_compressions == nullptr) {
387*061da546Spatrick           end_of_compressions = strchr(compressions, '\0');
388*061da546Spatrick         }
389*061da546Spatrick         const char *current_compression = compressions;
390*061da546Spatrick         while (current_compression < end_of_compressions) {
391*061da546Spatrick           const char *next_compression_name = strchr(current_compression, ',');
392*061da546Spatrick           const char *end_of_this_word = next_compression_name;
393*061da546Spatrick           if (next_compression_name == nullptr ||
394*061da546Spatrick               end_of_compressions < next_compression_name) {
395*061da546Spatrick             end_of_this_word = end_of_compressions;
396*061da546Spatrick           }
397*061da546Spatrick 
398*061da546Spatrick           if (end_of_this_word) {
399*061da546Spatrick             if (end_of_this_word == current_compression) {
400*061da546Spatrick               current_compression++;
401*061da546Spatrick             } else {
402*061da546Spatrick               std::string this_compression(
403*061da546Spatrick                   current_compression, end_of_this_word - current_compression);
404*061da546Spatrick               supported_compressions.push_back(this_compression);
405*061da546Spatrick               current_compression = end_of_this_word + 1;
406*061da546Spatrick             }
407*061da546Spatrick           } else {
408*061da546Spatrick             supported_compressions.push_back(current_compression);
409*061da546Spatrick             current_compression = end_of_compressions;
410*061da546Spatrick           }
411*061da546Spatrick         }
412*061da546Spatrick 
413*061da546Spatrick         if (supported_compressions.size() > 0) {
414*061da546Spatrick           MaybeEnableCompression(supported_compressions);
415*061da546Spatrick         }
416*061da546Spatrick       }
417*061da546Spatrick     }
418*061da546Spatrick 
419*061da546Spatrick     if (::strstr(response_cstr, "qEcho"))
420*061da546Spatrick       m_supports_qEcho = eLazyBoolYes;
421*061da546Spatrick     else
422*061da546Spatrick       m_supports_qEcho = eLazyBoolNo;
423*061da546Spatrick 
424*061da546Spatrick     if (::strstr(response_cstr, "QPassSignals+"))
425*061da546Spatrick       m_supports_QPassSignals = eLazyBoolYes;
426*061da546Spatrick     else
427*061da546Spatrick       m_supports_QPassSignals = eLazyBoolNo;
428*061da546Spatrick 
429*061da546Spatrick     const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
430*061da546Spatrick     if (packet_size_str) {
431*061da546Spatrick       StringExtractorGDBRemote packet_response(packet_size_str +
432*061da546Spatrick                                                strlen("PacketSize="));
433*061da546Spatrick       m_max_packet_size =
434*061da546Spatrick           packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
435*061da546Spatrick       if (m_max_packet_size == 0) {
436*061da546Spatrick         m_max_packet_size = UINT64_MAX; // Must have been a garbled response
437*061da546Spatrick         Log *log(
438*061da546Spatrick             ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
439*061da546Spatrick         LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
440*061da546Spatrick       }
441*061da546Spatrick     }
442*061da546Spatrick   }
443*061da546Spatrick }
444*061da546Spatrick 
445*061da546Spatrick bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
446*061da546Spatrick   if (m_supports_thread_suffix == eLazyBoolCalculate) {
447*061da546Spatrick     StringExtractorGDBRemote response;
448*061da546Spatrick     m_supports_thread_suffix = eLazyBoolNo;
449*061da546Spatrick     if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
450*061da546Spatrick                                      false) == PacketResult::Success) {
451*061da546Spatrick       if (response.IsOKResponse())
452*061da546Spatrick         m_supports_thread_suffix = eLazyBoolYes;
453*061da546Spatrick     }
454*061da546Spatrick   }
455*061da546Spatrick   return m_supports_thread_suffix;
456*061da546Spatrick }
457*061da546Spatrick bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
458*061da546Spatrick   if (m_supports_vCont_c == eLazyBoolCalculate) {
459*061da546Spatrick     StringExtractorGDBRemote response;
460*061da546Spatrick     m_supports_vCont_any = eLazyBoolNo;
461*061da546Spatrick     m_supports_vCont_all = eLazyBoolNo;
462*061da546Spatrick     m_supports_vCont_c = eLazyBoolNo;
463*061da546Spatrick     m_supports_vCont_C = eLazyBoolNo;
464*061da546Spatrick     m_supports_vCont_s = eLazyBoolNo;
465*061da546Spatrick     m_supports_vCont_S = eLazyBoolNo;
466*061da546Spatrick     if (SendPacketAndWaitForResponse("vCont?", response, false) ==
467*061da546Spatrick         PacketResult::Success) {
468*061da546Spatrick       const char *response_cstr = response.GetStringRef().data();
469*061da546Spatrick       if (::strstr(response_cstr, ";c"))
470*061da546Spatrick         m_supports_vCont_c = eLazyBoolYes;
471*061da546Spatrick 
472*061da546Spatrick       if (::strstr(response_cstr, ";C"))
473*061da546Spatrick         m_supports_vCont_C = eLazyBoolYes;
474*061da546Spatrick 
475*061da546Spatrick       if (::strstr(response_cstr, ";s"))
476*061da546Spatrick         m_supports_vCont_s = eLazyBoolYes;
477*061da546Spatrick 
478*061da546Spatrick       if (::strstr(response_cstr, ";S"))
479*061da546Spatrick         m_supports_vCont_S = eLazyBoolYes;
480*061da546Spatrick 
481*061da546Spatrick       if (m_supports_vCont_c == eLazyBoolYes &&
482*061da546Spatrick           m_supports_vCont_C == eLazyBoolYes &&
483*061da546Spatrick           m_supports_vCont_s == eLazyBoolYes &&
484*061da546Spatrick           m_supports_vCont_S == eLazyBoolYes) {
485*061da546Spatrick         m_supports_vCont_all = eLazyBoolYes;
486*061da546Spatrick       }
487*061da546Spatrick 
488*061da546Spatrick       if (m_supports_vCont_c == eLazyBoolYes ||
489*061da546Spatrick           m_supports_vCont_C == eLazyBoolYes ||
490*061da546Spatrick           m_supports_vCont_s == eLazyBoolYes ||
491*061da546Spatrick           m_supports_vCont_S == eLazyBoolYes) {
492*061da546Spatrick         m_supports_vCont_any = eLazyBoolYes;
493*061da546Spatrick       }
494*061da546Spatrick     }
495*061da546Spatrick   }
496*061da546Spatrick 
497*061da546Spatrick   switch (flavor) {
498*061da546Spatrick   case 'a':
499*061da546Spatrick     return m_supports_vCont_any;
500*061da546Spatrick   case 'A':
501*061da546Spatrick     return m_supports_vCont_all;
502*061da546Spatrick   case 'c':
503*061da546Spatrick     return m_supports_vCont_c;
504*061da546Spatrick   case 'C':
505*061da546Spatrick     return m_supports_vCont_C;
506*061da546Spatrick   case 's':
507*061da546Spatrick     return m_supports_vCont_s;
508*061da546Spatrick   case 'S':
509*061da546Spatrick     return m_supports_vCont_S;
510*061da546Spatrick   default:
511*061da546Spatrick     break;
512*061da546Spatrick   }
513*061da546Spatrick   return false;
514*061da546Spatrick }
515*061da546Spatrick 
516*061da546Spatrick GDBRemoteCommunication::PacketResult
517*061da546Spatrick GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
518*061da546Spatrick     lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
519*061da546Spatrick     bool send_async) {
520*061da546Spatrick   Lock lock(*this, send_async);
521*061da546Spatrick   if (!lock) {
522*061da546Spatrick     if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
523*061da546Spatrick             GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
524*061da546Spatrick       LLDB_LOGF(log,
525*061da546Spatrick                 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
526*061da546Spatrick                 "for %s packet.",
527*061da546Spatrick                 __FUNCTION__, payload.GetData());
528*061da546Spatrick     return PacketResult::ErrorNoSequenceLock;
529*061da546Spatrick   }
530*061da546Spatrick 
531*061da546Spatrick   if (GetThreadSuffixSupported())
532*061da546Spatrick     payload.Printf(";thread:%4.4" PRIx64 ";", tid);
533*061da546Spatrick   else {
534*061da546Spatrick     if (!SetCurrentThread(tid))
535*061da546Spatrick       return PacketResult::ErrorSendFailed;
536*061da546Spatrick   }
537*061da546Spatrick 
538*061da546Spatrick   return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
539*061da546Spatrick }
540*061da546Spatrick 
541*061da546Spatrick // Check if the target supports 'p' packet. It sends out a 'p' packet and
542*061da546Spatrick // checks the response. A normal packet will tell us that support is available.
543*061da546Spatrick //
544*061da546Spatrick // Takes a valid thread ID because p needs to apply to a thread.
545*061da546Spatrick bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
546*061da546Spatrick   if (m_supports_p == eLazyBoolCalculate)
547*061da546Spatrick     m_supports_p = GetThreadPacketSupported(tid, "p0");
548*061da546Spatrick   return m_supports_p;
549*061da546Spatrick }
550*061da546Spatrick 
551*061da546Spatrick LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(
552*061da546Spatrick     lldb::tid_t tid, llvm::StringRef packetStr) {
553*061da546Spatrick   StreamString payload;
554*061da546Spatrick   payload.PutCString(packetStr);
555*061da546Spatrick   StringExtractorGDBRemote response;
556*061da546Spatrick   if (SendThreadSpecificPacketAndWaitForResponse(
557*061da546Spatrick           tid, std::move(payload), response, false) == PacketResult::Success &&
558*061da546Spatrick       response.IsNormalResponse()) {
559*061da546Spatrick     return eLazyBoolYes;
560*061da546Spatrick   }
561*061da546Spatrick   return eLazyBoolNo;
562*061da546Spatrick }
563*061da546Spatrick 
564*061da546Spatrick StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
565*061da546Spatrick   // Get information on all threads at one using the "jThreadsInfo" packet
566*061da546Spatrick   StructuredData::ObjectSP object_sp;
567*061da546Spatrick 
568*061da546Spatrick   if (m_supports_jThreadsInfo) {
569*061da546Spatrick     StringExtractorGDBRemote response;
570*061da546Spatrick     response.SetResponseValidatorToJSON();
571*061da546Spatrick     if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
572*061da546Spatrick         PacketResult::Success) {
573*061da546Spatrick       if (response.IsUnsupportedResponse()) {
574*061da546Spatrick         m_supports_jThreadsInfo = false;
575*061da546Spatrick       } else if (!response.Empty()) {
576*061da546Spatrick         object_sp = StructuredData::ParseJSON(response.GetStringRef());
577*061da546Spatrick       }
578*061da546Spatrick     }
579*061da546Spatrick   }
580*061da546Spatrick   return object_sp;
581*061da546Spatrick }
582*061da546Spatrick 
583*061da546Spatrick bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
584*061da546Spatrick   if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
585*061da546Spatrick     StringExtractorGDBRemote response;
586*061da546Spatrick     m_supports_jThreadExtendedInfo = eLazyBoolNo;
587*061da546Spatrick     if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
588*061da546Spatrick         PacketResult::Success) {
589*061da546Spatrick       if (response.IsOKResponse()) {
590*061da546Spatrick         m_supports_jThreadExtendedInfo = eLazyBoolYes;
591*061da546Spatrick       }
592*061da546Spatrick     }
593*061da546Spatrick   }
594*061da546Spatrick   return m_supports_jThreadExtendedInfo;
595*061da546Spatrick }
596*061da546Spatrick 
597*061da546Spatrick void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
598*061da546Spatrick   if (m_supports_error_string_reply == eLazyBoolCalculate) {
599*061da546Spatrick     StringExtractorGDBRemote response;
600*061da546Spatrick     // We try to enable error strings in remote packets but if we fail, we just
601*061da546Spatrick     // work in the older way.
602*061da546Spatrick     m_supports_error_string_reply = eLazyBoolNo;
603*061da546Spatrick     if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
604*061da546Spatrick         PacketResult::Success) {
605*061da546Spatrick       if (response.IsOKResponse()) {
606*061da546Spatrick         m_supports_error_string_reply = eLazyBoolYes;
607*061da546Spatrick       }
608*061da546Spatrick     }
609*061da546Spatrick   }
610*061da546Spatrick }
611*061da546Spatrick 
612*061da546Spatrick bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
613*061da546Spatrick   if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
614*061da546Spatrick     StringExtractorGDBRemote response;
615*061da546Spatrick     m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
616*061da546Spatrick     if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
617*061da546Spatrick                                      response,
618*061da546Spatrick                                      false) == PacketResult::Success) {
619*061da546Spatrick       if (response.IsOKResponse()) {
620*061da546Spatrick         m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
621*061da546Spatrick       }
622*061da546Spatrick     }
623*061da546Spatrick   }
624*061da546Spatrick   return m_supports_jLoadedDynamicLibrariesInfos;
625*061da546Spatrick }
626*061da546Spatrick 
627*061da546Spatrick bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
628*061da546Spatrick   if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
629*061da546Spatrick     StringExtractorGDBRemote response;
630*061da546Spatrick     m_supports_jGetSharedCacheInfo = eLazyBoolNo;
631*061da546Spatrick     if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
632*061da546Spatrick         PacketResult::Success) {
633*061da546Spatrick       if (response.IsOKResponse()) {
634*061da546Spatrick         m_supports_jGetSharedCacheInfo = eLazyBoolYes;
635*061da546Spatrick       }
636*061da546Spatrick     }
637*061da546Spatrick   }
638*061da546Spatrick   return m_supports_jGetSharedCacheInfo;
639*061da546Spatrick }
640*061da546Spatrick 
641*061da546Spatrick bool GDBRemoteCommunicationClient::GetxPacketSupported() {
642*061da546Spatrick   if (m_supports_x == eLazyBoolCalculate) {
643*061da546Spatrick     StringExtractorGDBRemote response;
644*061da546Spatrick     m_supports_x = eLazyBoolNo;
645*061da546Spatrick     char packet[256];
646*061da546Spatrick     snprintf(packet, sizeof(packet), "x0,0");
647*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
648*061da546Spatrick         PacketResult::Success) {
649*061da546Spatrick       if (response.IsOKResponse())
650*061da546Spatrick         m_supports_x = eLazyBoolYes;
651*061da546Spatrick     }
652*061da546Spatrick   }
653*061da546Spatrick   return m_supports_x;
654*061da546Spatrick }
655*061da546Spatrick 
656*061da546Spatrick GDBRemoteCommunicationClient::PacketResult
657*061da546Spatrick GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
658*061da546Spatrick     const char *payload_prefix, std::string &response_string) {
659*061da546Spatrick   Lock lock(*this, false);
660*061da546Spatrick   if (!lock) {
661*061da546Spatrick     Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
662*061da546Spatrick                                                            GDBR_LOG_PACKETS));
663*061da546Spatrick     LLDB_LOGF(log,
664*061da546Spatrick               "error: failed to get packet sequence mutex, not sending "
665*061da546Spatrick               "packets with prefix '%s'",
666*061da546Spatrick               payload_prefix);
667*061da546Spatrick     return PacketResult::ErrorNoSequenceLock;
668*061da546Spatrick   }
669*061da546Spatrick 
670*061da546Spatrick   response_string = "";
671*061da546Spatrick   std::string payload_prefix_str(payload_prefix);
672*061da546Spatrick   unsigned int response_size = 0x1000;
673*061da546Spatrick   if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
674*061da546Spatrick     response_size = GetRemoteMaxPacketSize();
675*061da546Spatrick   }
676*061da546Spatrick 
677*061da546Spatrick   for (unsigned int offset = 0; true; offset += response_size) {
678*061da546Spatrick     StringExtractorGDBRemote this_response;
679*061da546Spatrick     // Construct payload
680*061da546Spatrick     char sizeDescriptor[128];
681*061da546Spatrick     snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
682*061da546Spatrick              response_size);
683*061da546Spatrick     PacketResult result = SendPacketAndWaitForResponseNoLock(
684*061da546Spatrick         payload_prefix_str + sizeDescriptor, this_response);
685*061da546Spatrick     if (result != PacketResult::Success)
686*061da546Spatrick       return result;
687*061da546Spatrick 
688*061da546Spatrick     const std::string &this_string = this_response.GetStringRef();
689*061da546Spatrick 
690*061da546Spatrick     // Check for m or l as first character; l seems to mean this is the last
691*061da546Spatrick     // chunk
692*061da546Spatrick     char first_char = *this_string.c_str();
693*061da546Spatrick     if (first_char != 'm' && first_char != 'l') {
694*061da546Spatrick       return PacketResult::ErrorReplyInvalid;
695*061da546Spatrick     }
696*061da546Spatrick     // Concatenate the result so far (skipping 'm' or 'l')
697*061da546Spatrick     response_string.append(this_string, 1, std::string::npos);
698*061da546Spatrick     if (first_char == 'l')
699*061da546Spatrick       // We're done
700*061da546Spatrick       return PacketResult::Success;
701*061da546Spatrick   }
702*061da546Spatrick }
703*061da546Spatrick 
704*061da546Spatrick lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
705*061da546Spatrick   if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
706*061da546Spatrick     return m_curr_pid;
707*061da546Spatrick 
708*061da546Spatrick   // First try to retrieve the pid via the qProcessInfo request.
709*061da546Spatrick   GetCurrentProcessInfo(allow_lazy);
710*061da546Spatrick   if (m_curr_pid_is_valid == eLazyBoolYes) {
711*061da546Spatrick     // We really got it.
712*061da546Spatrick     return m_curr_pid;
713*061da546Spatrick   } else {
714*061da546Spatrick     // If we don't get a response for qProcessInfo, check if $qC gives us a
715*061da546Spatrick     // result. $qC only returns a real process id on older debugserver and
716*061da546Spatrick     // lldb-platform stubs. The gdb remote protocol documents $qC as returning
717*061da546Spatrick     // the thread id, which newer debugserver and lldb-gdbserver stubs return
718*061da546Spatrick     // correctly.
719*061da546Spatrick     StringExtractorGDBRemote response;
720*061da546Spatrick     if (SendPacketAndWaitForResponse("qC", response, false) ==
721*061da546Spatrick         PacketResult::Success) {
722*061da546Spatrick       if (response.GetChar() == 'Q') {
723*061da546Spatrick         if (response.GetChar() == 'C') {
724*061da546Spatrick           m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
725*061da546Spatrick           if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
726*061da546Spatrick             m_curr_pid_is_valid = eLazyBoolYes;
727*061da546Spatrick             return m_curr_pid;
728*061da546Spatrick           }
729*061da546Spatrick         }
730*061da546Spatrick       }
731*061da546Spatrick     }
732*061da546Spatrick 
733*061da546Spatrick     // If we don't get a response for $qC, check if $qfThreadID gives us a
734*061da546Spatrick     // result.
735*061da546Spatrick     if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
736*061da546Spatrick       std::vector<lldb::tid_t> thread_ids;
737*061da546Spatrick       bool sequence_mutex_unavailable;
738*061da546Spatrick       size_t size;
739*061da546Spatrick       size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
740*061da546Spatrick       if (size && !sequence_mutex_unavailable) {
741*061da546Spatrick         m_curr_pid = thread_ids.front();
742*061da546Spatrick         m_curr_pid_is_valid = eLazyBoolYes;
743*061da546Spatrick         return m_curr_pid;
744*061da546Spatrick       }
745*061da546Spatrick     }
746*061da546Spatrick   }
747*061da546Spatrick 
748*061da546Spatrick   return LLDB_INVALID_PROCESS_ID;
749*061da546Spatrick }
750*061da546Spatrick 
751*061da546Spatrick bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
752*061da546Spatrick   error_str.clear();
753*061da546Spatrick   StringExtractorGDBRemote response;
754*061da546Spatrick   if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
755*061da546Spatrick       PacketResult::Success) {
756*061da546Spatrick     if (response.IsOKResponse())
757*061da546Spatrick       return true;
758*061da546Spatrick     if (response.GetChar() == 'E') {
759*061da546Spatrick       // A string the describes what failed when launching...
760*061da546Spatrick       error_str = response.GetStringRef().substr(1);
761*061da546Spatrick     } else {
762*061da546Spatrick       error_str.assign("unknown error occurred launching process");
763*061da546Spatrick     }
764*061da546Spatrick   } else {
765*061da546Spatrick     error_str.assign("timed out waiting for app to launch");
766*061da546Spatrick   }
767*061da546Spatrick   return false;
768*061da546Spatrick }
769*061da546Spatrick 
770*061da546Spatrick int GDBRemoteCommunicationClient::SendArgumentsPacket(
771*061da546Spatrick     const ProcessLaunchInfo &launch_info) {
772*061da546Spatrick   // Since we don't get the send argv0 separate from the executable path, we
773*061da546Spatrick   // need to make sure to use the actual executable path found in the
774*061da546Spatrick   // launch_info...
775*061da546Spatrick   std::vector<const char *> argv;
776*061da546Spatrick   FileSpec exe_file = launch_info.GetExecutableFile();
777*061da546Spatrick   std::string exe_path;
778*061da546Spatrick   const char *arg = nullptr;
779*061da546Spatrick   const Args &launch_args = launch_info.GetArguments();
780*061da546Spatrick   if (exe_file)
781*061da546Spatrick     exe_path = exe_file.GetPath(false);
782*061da546Spatrick   else {
783*061da546Spatrick     arg = launch_args.GetArgumentAtIndex(0);
784*061da546Spatrick     if (arg)
785*061da546Spatrick       exe_path = arg;
786*061da546Spatrick   }
787*061da546Spatrick   if (!exe_path.empty()) {
788*061da546Spatrick     argv.push_back(exe_path.c_str());
789*061da546Spatrick     for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != nullptr;
790*061da546Spatrick          ++i) {
791*061da546Spatrick       if (arg)
792*061da546Spatrick         argv.push_back(arg);
793*061da546Spatrick     }
794*061da546Spatrick   }
795*061da546Spatrick   if (!argv.empty()) {
796*061da546Spatrick     StreamString packet;
797*061da546Spatrick     packet.PutChar('A');
798*061da546Spatrick     for (size_t i = 0, n = argv.size(); i < n; ++i) {
799*061da546Spatrick       arg = argv[i];
800*061da546Spatrick       const int arg_len = strlen(arg);
801*061da546Spatrick       if (i > 0)
802*061da546Spatrick         packet.PutChar(',');
803*061da546Spatrick       packet.Printf("%i,%i,", arg_len * 2, (int)i);
804*061da546Spatrick       packet.PutBytesAsRawHex8(arg, arg_len);
805*061da546Spatrick     }
806*061da546Spatrick 
807*061da546Spatrick     StringExtractorGDBRemote response;
808*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
809*061da546Spatrick         PacketResult::Success) {
810*061da546Spatrick       if (response.IsOKResponse())
811*061da546Spatrick         return 0;
812*061da546Spatrick       uint8_t error = response.GetError();
813*061da546Spatrick       if (error)
814*061da546Spatrick         return error;
815*061da546Spatrick     }
816*061da546Spatrick   }
817*061da546Spatrick   return -1;
818*061da546Spatrick }
819*061da546Spatrick 
820*061da546Spatrick int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
821*061da546Spatrick   for (const auto &KV : env) {
822*061da546Spatrick     int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
823*061da546Spatrick     if (r != 0)
824*061da546Spatrick       return r;
825*061da546Spatrick   }
826*061da546Spatrick   return 0;
827*061da546Spatrick }
828*061da546Spatrick 
829*061da546Spatrick int GDBRemoteCommunicationClient::SendEnvironmentPacket(
830*061da546Spatrick     char const *name_equal_value) {
831*061da546Spatrick   if (name_equal_value && name_equal_value[0]) {
832*061da546Spatrick     StreamString packet;
833*061da546Spatrick     bool send_hex_encoding = false;
834*061da546Spatrick     for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
835*061da546Spatrick          ++p) {
836*061da546Spatrick       if (isprint(*p)) {
837*061da546Spatrick         switch (*p) {
838*061da546Spatrick         case '$':
839*061da546Spatrick         case '#':
840*061da546Spatrick         case '*':
841*061da546Spatrick         case '}':
842*061da546Spatrick           send_hex_encoding = true;
843*061da546Spatrick           break;
844*061da546Spatrick         default:
845*061da546Spatrick           break;
846*061da546Spatrick         }
847*061da546Spatrick       } else {
848*061da546Spatrick         // We have non printable characters, lets hex encode this...
849*061da546Spatrick         send_hex_encoding = true;
850*061da546Spatrick       }
851*061da546Spatrick     }
852*061da546Spatrick 
853*061da546Spatrick     StringExtractorGDBRemote response;
854*061da546Spatrick     if (send_hex_encoding) {
855*061da546Spatrick       if (m_supports_QEnvironmentHexEncoded) {
856*061da546Spatrick         packet.PutCString("QEnvironmentHexEncoded:");
857*061da546Spatrick         packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
858*061da546Spatrick         if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
859*061da546Spatrick             PacketResult::Success) {
860*061da546Spatrick           if (response.IsOKResponse())
861*061da546Spatrick             return 0;
862*061da546Spatrick           uint8_t error = response.GetError();
863*061da546Spatrick           if (error)
864*061da546Spatrick             return error;
865*061da546Spatrick           if (response.IsUnsupportedResponse())
866*061da546Spatrick             m_supports_QEnvironmentHexEncoded = false;
867*061da546Spatrick         }
868*061da546Spatrick       }
869*061da546Spatrick 
870*061da546Spatrick     } else if (m_supports_QEnvironment) {
871*061da546Spatrick       packet.Printf("QEnvironment:%s", name_equal_value);
872*061da546Spatrick       if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
873*061da546Spatrick           PacketResult::Success) {
874*061da546Spatrick         if (response.IsOKResponse())
875*061da546Spatrick           return 0;
876*061da546Spatrick         uint8_t error = response.GetError();
877*061da546Spatrick         if (error)
878*061da546Spatrick           return error;
879*061da546Spatrick         if (response.IsUnsupportedResponse())
880*061da546Spatrick           m_supports_QEnvironment = false;
881*061da546Spatrick       }
882*061da546Spatrick     }
883*061da546Spatrick   }
884*061da546Spatrick   return -1;
885*061da546Spatrick }
886*061da546Spatrick 
887*061da546Spatrick int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
888*061da546Spatrick   if (arch && arch[0]) {
889*061da546Spatrick     StreamString packet;
890*061da546Spatrick     packet.Printf("QLaunchArch:%s", arch);
891*061da546Spatrick     StringExtractorGDBRemote response;
892*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
893*061da546Spatrick         PacketResult::Success) {
894*061da546Spatrick       if (response.IsOKResponse())
895*061da546Spatrick         return 0;
896*061da546Spatrick       uint8_t error = response.GetError();
897*061da546Spatrick       if (error)
898*061da546Spatrick         return error;
899*061da546Spatrick     }
900*061da546Spatrick   }
901*061da546Spatrick   return -1;
902*061da546Spatrick }
903*061da546Spatrick 
904*061da546Spatrick int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
905*061da546Spatrick     char const *data, bool *was_supported) {
906*061da546Spatrick   if (data && *data != '\0') {
907*061da546Spatrick     StreamString packet;
908*061da546Spatrick     packet.Printf("QSetProcessEvent:%s", data);
909*061da546Spatrick     StringExtractorGDBRemote response;
910*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
911*061da546Spatrick         PacketResult::Success) {
912*061da546Spatrick       if (response.IsOKResponse()) {
913*061da546Spatrick         if (was_supported)
914*061da546Spatrick           *was_supported = true;
915*061da546Spatrick         return 0;
916*061da546Spatrick       } else if (response.IsUnsupportedResponse()) {
917*061da546Spatrick         if (was_supported)
918*061da546Spatrick           *was_supported = false;
919*061da546Spatrick         return -1;
920*061da546Spatrick       } else {
921*061da546Spatrick         uint8_t error = response.GetError();
922*061da546Spatrick         if (was_supported)
923*061da546Spatrick           *was_supported = true;
924*061da546Spatrick         if (error)
925*061da546Spatrick           return error;
926*061da546Spatrick       }
927*061da546Spatrick     }
928*061da546Spatrick   }
929*061da546Spatrick   return -1;
930*061da546Spatrick }
931*061da546Spatrick 
932*061da546Spatrick llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
933*061da546Spatrick   GetHostInfo();
934*061da546Spatrick   return m_os_version;
935*061da546Spatrick }
936*061da546Spatrick 
937*061da546Spatrick llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
938*061da546Spatrick   GetHostInfo();
939*061da546Spatrick   return m_maccatalyst_version;
940*061da546Spatrick }
941*061da546Spatrick 
942*061da546Spatrick bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
943*061da546Spatrick   if (GetHostInfo()) {
944*061da546Spatrick     if (!m_os_build.empty()) {
945*061da546Spatrick       s = m_os_build;
946*061da546Spatrick       return true;
947*061da546Spatrick     }
948*061da546Spatrick   }
949*061da546Spatrick   s.clear();
950*061da546Spatrick   return false;
951*061da546Spatrick }
952*061da546Spatrick 
953*061da546Spatrick bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
954*061da546Spatrick   if (GetHostInfo()) {
955*061da546Spatrick     if (!m_os_kernel.empty()) {
956*061da546Spatrick       s = m_os_kernel;
957*061da546Spatrick       return true;
958*061da546Spatrick     }
959*061da546Spatrick   }
960*061da546Spatrick   s.clear();
961*061da546Spatrick   return false;
962*061da546Spatrick }
963*061da546Spatrick 
964*061da546Spatrick bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
965*061da546Spatrick   if (GetHostInfo()) {
966*061da546Spatrick     if (!m_hostname.empty()) {
967*061da546Spatrick       s = m_hostname;
968*061da546Spatrick       return true;
969*061da546Spatrick     }
970*061da546Spatrick   }
971*061da546Spatrick   s.clear();
972*061da546Spatrick   return false;
973*061da546Spatrick }
974*061da546Spatrick 
975*061da546Spatrick ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
976*061da546Spatrick   if (GetHostInfo())
977*061da546Spatrick     return m_host_arch;
978*061da546Spatrick   return ArchSpec();
979*061da546Spatrick }
980*061da546Spatrick 
981*061da546Spatrick const lldb_private::ArchSpec &
982*061da546Spatrick GDBRemoteCommunicationClient::GetProcessArchitecture() {
983*061da546Spatrick   if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
984*061da546Spatrick     GetCurrentProcessInfo();
985*061da546Spatrick   return m_process_arch;
986*061da546Spatrick }
987*061da546Spatrick 
988*061da546Spatrick bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
989*061da546Spatrick   if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
990*061da546Spatrick     m_gdb_server_name.clear();
991*061da546Spatrick     m_gdb_server_version = 0;
992*061da546Spatrick     m_qGDBServerVersion_is_valid = eLazyBoolNo;
993*061da546Spatrick 
994*061da546Spatrick     StringExtractorGDBRemote response;
995*061da546Spatrick     if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
996*061da546Spatrick         PacketResult::Success) {
997*061da546Spatrick       if (response.IsNormalResponse()) {
998*061da546Spatrick         llvm::StringRef name, value;
999*061da546Spatrick         bool success = false;
1000*061da546Spatrick         while (response.GetNameColonValue(name, value)) {
1001*061da546Spatrick           if (name.equals("name")) {
1002*061da546Spatrick             success = true;
1003*061da546Spatrick             m_gdb_server_name = value;
1004*061da546Spatrick           } else if (name.equals("version")) {
1005*061da546Spatrick             llvm::StringRef major, minor;
1006*061da546Spatrick             std::tie(major, minor) = value.split('.');
1007*061da546Spatrick             if (!major.getAsInteger(0, m_gdb_server_version))
1008*061da546Spatrick               success = true;
1009*061da546Spatrick           }
1010*061da546Spatrick         }
1011*061da546Spatrick         if (success)
1012*061da546Spatrick           m_qGDBServerVersion_is_valid = eLazyBoolYes;
1013*061da546Spatrick       }
1014*061da546Spatrick     }
1015*061da546Spatrick   }
1016*061da546Spatrick   return m_qGDBServerVersion_is_valid == eLazyBoolYes;
1017*061da546Spatrick }
1018*061da546Spatrick 
1019*061da546Spatrick void GDBRemoteCommunicationClient::MaybeEnableCompression(
1020*061da546Spatrick     std::vector<std::string> supported_compressions) {
1021*061da546Spatrick   CompressionType avail_type = CompressionType::None;
1022*061da546Spatrick   std::string avail_name;
1023*061da546Spatrick 
1024*061da546Spatrick #if defined(HAVE_LIBCOMPRESSION)
1025*061da546Spatrick   if (avail_type == CompressionType::None) {
1026*061da546Spatrick     for (auto compression : supported_compressions) {
1027*061da546Spatrick       if (compression == "lzfse") {
1028*061da546Spatrick         avail_type = CompressionType::LZFSE;
1029*061da546Spatrick         avail_name = compression;
1030*061da546Spatrick         break;
1031*061da546Spatrick       }
1032*061da546Spatrick     }
1033*061da546Spatrick   }
1034*061da546Spatrick #endif
1035*061da546Spatrick 
1036*061da546Spatrick #if defined(HAVE_LIBCOMPRESSION)
1037*061da546Spatrick   if (avail_type == CompressionType::None) {
1038*061da546Spatrick     for (auto compression : supported_compressions) {
1039*061da546Spatrick       if (compression == "zlib-deflate") {
1040*061da546Spatrick         avail_type = CompressionType::ZlibDeflate;
1041*061da546Spatrick         avail_name = compression;
1042*061da546Spatrick         break;
1043*061da546Spatrick       }
1044*061da546Spatrick     }
1045*061da546Spatrick   }
1046*061da546Spatrick #endif
1047*061da546Spatrick 
1048*061da546Spatrick #if defined(HAVE_LIBZ)
1049*061da546Spatrick   if (avail_type == CompressionType::None) {
1050*061da546Spatrick     for (auto compression : supported_compressions) {
1051*061da546Spatrick       if (compression == "zlib-deflate") {
1052*061da546Spatrick         avail_type = CompressionType::ZlibDeflate;
1053*061da546Spatrick         avail_name = compression;
1054*061da546Spatrick         break;
1055*061da546Spatrick       }
1056*061da546Spatrick     }
1057*061da546Spatrick   }
1058*061da546Spatrick #endif
1059*061da546Spatrick 
1060*061da546Spatrick #if defined(HAVE_LIBCOMPRESSION)
1061*061da546Spatrick   if (avail_type == CompressionType::None) {
1062*061da546Spatrick     for (auto compression : supported_compressions) {
1063*061da546Spatrick       if (compression == "lz4") {
1064*061da546Spatrick         avail_type = CompressionType::LZ4;
1065*061da546Spatrick         avail_name = compression;
1066*061da546Spatrick         break;
1067*061da546Spatrick       }
1068*061da546Spatrick     }
1069*061da546Spatrick   }
1070*061da546Spatrick #endif
1071*061da546Spatrick 
1072*061da546Spatrick #if defined(HAVE_LIBCOMPRESSION)
1073*061da546Spatrick   if (avail_type == CompressionType::None) {
1074*061da546Spatrick     for (auto compression : supported_compressions) {
1075*061da546Spatrick       if (compression == "lzma") {
1076*061da546Spatrick         avail_type = CompressionType::LZMA;
1077*061da546Spatrick         avail_name = compression;
1078*061da546Spatrick         break;
1079*061da546Spatrick       }
1080*061da546Spatrick     }
1081*061da546Spatrick   }
1082*061da546Spatrick #endif
1083*061da546Spatrick 
1084*061da546Spatrick   if (avail_type != CompressionType::None) {
1085*061da546Spatrick     StringExtractorGDBRemote response;
1086*061da546Spatrick     std::string packet = "QEnableCompression:type:" + avail_name + ";";
1087*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) !=
1088*061da546Spatrick         PacketResult::Success)
1089*061da546Spatrick       return;
1090*061da546Spatrick 
1091*061da546Spatrick     if (response.IsOKResponse()) {
1092*061da546Spatrick       m_compression_type = avail_type;
1093*061da546Spatrick     }
1094*061da546Spatrick   }
1095*061da546Spatrick }
1096*061da546Spatrick 
1097*061da546Spatrick const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
1098*061da546Spatrick   if (GetGDBServerVersion()) {
1099*061da546Spatrick     if (!m_gdb_server_name.empty())
1100*061da546Spatrick       return m_gdb_server_name.c_str();
1101*061da546Spatrick   }
1102*061da546Spatrick   return nullptr;
1103*061da546Spatrick }
1104*061da546Spatrick 
1105*061da546Spatrick uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1106*061da546Spatrick   if (GetGDBServerVersion())
1107*061da546Spatrick     return m_gdb_server_version;
1108*061da546Spatrick   return 0;
1109*061da546Spatrick }
1110*061da546Spatrick 
1111*061da546Spatrick bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
1112*061da546Spatrick   StringExtractorGDBRemote response;
1113*061da546Spatrick   if (SendPacketAndWaitForResponse("qC", response, false) !=
1114*061da546Spatrick       PacketResult::Success)
1115*061da546Spatrick     return false;
1116*061da546Spatrick 
1117*061da546Spatrick   if (!response.IsNormalResponse())
1118*061da546Spatrick     return false;
1119*061da546Spatrick 
1120*061da546Spatrick   if (response.GetChar() == 'Q' && response.GetChar() == 'C')
1121*061da546Spatrick     tid = response.GetHexMaxU32(true, -1);
1122*061da546Spatrick 
1123*061da546Spatrick   return true;
1124*061da546Spatrick }
1125*061da546Spatrick 
1126*061da546Spatrick bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
1127*061da546Spatrick   Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
1128*061da546Spatrick 
1129*061da546Spatrick   if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
1130*061da546Spatrick     // host info computation can require DNS traffic and shelling out to external processes.
1131*061da546Spatrick     // Increase the timeout to account for that.
1132*061da546Spatrick     ScopedTimeout timeout(*this, seconds(10));
1133*061da546Spatrick     m_qHostInfo_is_valid = eLazyBoolNo;
1134*061da546Spatrick     StringExtractorGDBRemote response;
1135*061da546Spatrick     if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
1136*061da546Spatrick         PacketResult::Success) {
1137*061da546Spatrick       if (response.IsNormalResponse()) {
1138*061da546Spatrick         llvm::StringRef name;
1139*061da546Spatrick         llvm::StringRef value;
1140*061da546Spatrick         uint32_t cpu = LLDB_INVALID_CPUTYPE;
1141*061da546Spatrick         uint32_t sub = 0;
1142*061da546Spatrick         std::string arch_name;
1143*061da546Spatrick         std::string os_name;
1144*061da546Spatrick         std::string environment;
1145*061da546Spatrick         std::string vendor_name;
1146*061da546Spatrick         std::string triple;
1147*061da546Spatrick         std::string distribution_id;
1148*061da546Spatrick         uint32_t pointer_byte_size = 0;
1149*061da546Spatrick         ByteOrder byte_order = eByteOrderInvalid;
1150*061da546Spatrick         uint32_t num_keys_decoded = 0;
1151*061da546Spatrick         while (response.GetNameColonValue(name, value)) {
1152*061da546Spatrick           if (name.equals("cputype")) {
1153*061da546Spatrick             // exception type in big endian hex
1154*061da546Spatrick             if (!value.getAsInteger(0, cpu))
1155*061da546Spatrick               ++num_keys_decoded;
1156*061da546Spatrick           } else if (name.equals("cpusubtype")) {
1157*061da546Spatrick             // exception count in big endian hex
1158*061da546Spatrick             if (!value.getAsInteger(0, sub))
1159*061da546Spatrick               ++num_keys_decoded;
1160*061da546Spatrick           } else if (name.equals("arch")) {
1161*061da546Spatrick             arch_name = value;
1162*061da546Spatrick             ++num_keys_decoded;
1163*061da546Spatrick           } else if (name.equals("triple")) {
1164*061da546Spatrick             StringExtractor extractor(value);
1165*061da546Spatrick             extractor.GetHexByteString(triple);
1166*061da546Spatrick             ++num_keys_decoded;
1167*061da546Spatrick           } else if (name.equals("distribution_id")) {
1168*061da546Spatrick             StringExtractor extractor(value);
1169*061da546Spatrick             extractor.GetHexByteString(distribution_id);
1170*061da546Spatrick             ++num_keys_decoded;
1171*061da546Spatrick           } else if (name.equals("os_build")) {
1172*061da546Spatrick             StringExtractor extractor(value);
1173*061da546Spatrick             extractor.GetHexByteString(m_os_build);
1174*061da546Spatrick             ++num_keys_decoded;
1175*061da546Spatrick           } else if (name.equals("hostname")) {
1176*061da546Spatrick             StringExtractor extractor(value);
1177*061da546Spatrick             extractor.GetHexByteString(m_hostname);
1178*061da546Spatrick             ++num_keys_decoded;
1179*061da546Spatrick           } else if (name.equals("os_kernel")) {
1180*061da546Spatrick             StringExtractor extractor(value);
1181*061da546Spatrick             extractor.GetHexByteString(m_os_kernel);
1182*061da546Spatrick             ++num_keys_decoded;
1183*061da546Spatrick           } else if (name.equals("ostype")) {
1184*061da546Spatrick             if (value.equals("maccatalyst")) {
1185*061da546Spatrick               os_name = "ios";
1186*061da546Spatrick               environment = "macabi";
1187*061da546Spatrick             } else
1188*061da546Spatrick               os_name = value;
1189*061da546Spatrick             ++num_keys_decoded;
1190*061da546Spatrick           } else if (name.equals("vendor")) {
1191*061da546Spatrick             vendor_name = value;
1192*061da546Spatrick             ++num_keys_decoded;
1193*061da546Spatrick           } else if (name.equals("endian")) {
1194*061da546Spatrick             byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1195*061da546Spatrick                              .Case("little", eByteOrderLittle)
1196*061da546Spatrick                              .Case("big", eByteOrderBig)
1197*061da546Spatrick                              .Case("pdp", eByteOrderPDP)
1198*061da546Spatrick                              .Default(eByteOrderInvalid);
1199*061da546Spatrick             if (byte_order != eByteOrderInvalid)
1200*061da546Spatrick               ++num_keys_decoded;
1201*061da546Spatrick           } else if (name.equals("ptrsize")) {
1202*061da546Spatrick             if (!value.getAsInteger(0, pointer_byte_size))
1203*061da546Spatrick               ++num_keys_decoded;
1204*061da546Spatrick           } else if (name.equals("os_version") ||
1205*061da546Spatrick                      name.equals(
1206*061da546Spatrick                          "version")) // Older debugserver binaries used the
1207*061da546Spatrick                                      // "version" key instead of
1208*061da546Spatrick                                      // "os_version"...
1209*061da546Spatrick           {
1210*061da546Spatrick             if (!m_os_version.tryParse(value))
1211*061da546Spatrick               ++num_keys_decoded;
1212*061da546Spatrick           } else if (name.equals("maccatalyst_version")) {
1213*061da546Spatrick             if (!m_maccatalyst_version.tryParse(value))
1214*061da546Spatrick               ++num_keys_decoded;
1215*061da546Spatrick           } else if (name.equals("watchpoint_exceptions_received")) {
1216*061da546Spatrick             m_watchpoints_trigger_after_instruction =
1217*061da546Spatrick                 llvm::StringSwitch<LazyBool>(value)
1218*061da546Spatrick                     .Case("before", eLazyBoolNo)
1219*061da546Spatrick                     .Case("after", eLazyBoolYes)
1220*061da546Spatrick                     .Default(eLazyBoolCalculate);
1221*061da546Spatrick             if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
1222*061da546Spatrick               ++num_keys_decoded;
1223*061da546Spatrick           } else if (name.equals("default_packet_timeout")) {
1224*061da546Spatrick             uint32_t timeout_seconds;
1225*061da546Spatrick             if (!value.getAsInteger(0, timeout_seconds)) {
1226*061da546Spatrick               m_default_packet_timeout = seconds(timeout_seconds);
1227*061da546Spatrick               SetPacketTimeout(m_default_packet_timeout);
1228*061da546Spatrick               ++num_keys_decoded;
1229*061da546Spatrick             }
1230*061da546Spatrick           }
1231*061da546Spatrick         }
1232*061da546Spatrick 
1233*061da546Spatrick         if (num_keys_decoded > 0)
1234*061da546Spatrick           m_qHostInfo_is_valid = eLazyBoolYes;
1235*061da546Spatrick 
1236*061da546Spatrick         if (triple.empty()) {
1237*061da546Spatrick           if (arch_name.empty()) {
1238*061da546Spatrick             if (cpu != LLDB_INVALID_CPUTYPE) {
1239*061da546Spatrick               m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1240*061da546Spatrick               if (pointer_byte_size) {
1241*061da546Spatrick                 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1242*061da546Spatrick               }
1243*061da546Spatrick               if (byte_order != eByteOrderInvalid) {
1244*061da546Spatrick                 assert(byte_order == m_host_arch.GetByteOrder());
1245*061da546Spatrick               }
1246*061da546Spatrick 
1247*061da546Spatrick               if (!vendor_name.empty())
1248*061da546Spatrick                 m_host_arch.GetTriple().setVendorName(
1249*061da546Spatrick                     llvm::StringRef(vendor_name));
1250*061da546Spatrick               if (!os_name.empty())
1251*061da546Spatrick                 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1252*061da546Spatrick               if (!environment.empty())
1253*061da546Spatrick                 m_host_arch.GetTriple().setEnvironmentName(environment);
1254*061da546Spatrick             }
1255*061da546Spatrick           } else {
1256*061da546Spatrick             std::string triple;
1257*061da546Spatrick             triple += arch_name;
1258*061da546Spatrick             if (!vendor_name.empty() || !os_name.empty()) {
1259*061da546Spatrick               triple += '-';
1260*061da546Spatrick               if (vendor_name.empty())
1261*061da546Spatrick                 triple += "unknown";
1262*061da546Spatrick               else
1263*061da546Spatrick                 triple += vendor_name;
1264*061da546Spatrick               triple += '-';
1265*061da546Spatrick               if (os_name.empty())
1266*061da546Spatrick                 triple += "unknown";
1267*061da546Spatrick               else
1268*061da546Spatrick                 triple += os_name;
1269*061da546Spatrick             }
1270*061da546Spatrick             m_host_arch.SetTriple(triple.c_str());
1271*061da546Spatrick 
1272*061da546Spatrick             llvm::Triple &host_triple = m_host_arch.GetTriple();
1273*061da546Spatrick             if (host_triple.getVendor() == llvm::Triple::Apple &&
1274*061da546Spatrick                 host_triple.getOS() == llvm::Triple::Darwin) {
1275*061da546Spatrick               switch (m_host_arch.GetMachine()) {
1276*061da546Spatrick               case llvm::Triple::aarch64:
1277*061da546Spatrick               case llvm::Triple::aarch64_32:
1278*061da546Spatrick               case llvm::Triple::arm:
1279*061da546Spatrick               case llvm::Triple::thumb:
1280*061da546Spatrick                 host_triple.setOS(llvm::Triple::IOS);
1281*061da546Spatrick                 break;
1282*061da546Spatrick               default:
1283*061da546Spatrick                 host_triple.setOS(llvm::Triple::MacOSX);
1284*061da546Spatrick                 break;
1285*061da546Spatrick               }
1286*061da546Spatrick             }
1287*061da546Spatrick             if (pointer_byte_size) {
1288*061da546Spatrick               assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1289*061da546Spatrick             }
1290*061da546Spatrick             if (byte_order != eByteOrderInvalid) {
1291*061da546Spatrick               assert(byte_order == m_host_arch.GetByteOrder());
1292*061da546Spatrick             }
1293*061da546Spatrick           }
1294*061da546Spatrick         } else {
1295*061da546Spatrick           m_host_arch.SetTriple(triple.c_str());
1296*061da546Spatrick           if (pointer_byte_size) {
1297*061da546Spatrick             assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1298*061da546Spatrick           }
1299*061da546Spatrick           if (byte_order != eByteOrderInvalid) {
1300*061da546Spatrick             assert(byte_order == m_host_arch.GetByteOrder());
1301*061da546Spatrick           }
1302*061da546Spatrick 
1303*061da546Spatrick           LLDB_LOGF(log,
1304*061da546Spatrick                     "GDBRemoteCommunicationClient::%s parsed host "
1305*061da546Spatrick                     "architecture as %s, triple as %s from triple text %s",
1306*061da546Spatrick                     __FUNCTION__,
1307*061da546Spatrick                     m_host_arch.GetArchitectureName()
1308*061da546Spatrick                         ? m_host_arch.GetArchitectureName()
1309*061da546Spatrick                         : "<null-arch-name>",
1310*061da546Spatrick                     m_host_arch.GetTriple().getTriple().c_str(),
1311*061da546Spatrick                     triple.c_str());
1312*061da546Spatrick         }
1313*061da546Spatrick         if (!distribution_id.empty())
1314*061da546Spatrick           m_host_arch.SetDistributionId(distribution_id.c_str());
1315*061da546Spatrick       }
1316*061da546Spatrick     }
1317*061da546Spatrick   }
1318*061da546Spatrick   return m_qHostInfo_is_valid == eLazyBoolYes;
1319*061da546Spatrick }
1320*061da546Spatrick 
1321*061da546Spatrick int GDBRemoteCommunicationClient::SendAttach(
1322*061da546Spatrick     lldb::pid_t pid, StringExtractorGDBRemote &response) {
1323*061da546Spatrick   if (pid != LLDB_INVALID_PROCESS_ID) {
1324*061da546Spatrick     char packet[64];
1325*061da546Spatrick     const int packet_len =
1326*061da546Spatrick         ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
1327*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
1328*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
1329*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
1330*061da546Spatrick         PacketResult::Success) {
1331*061da546Spatrick       if (response.IsErrorResponse())
1332*061da546Spatrick         return response.GetError();
1333*061da546Spatrick       return 0;
1334*061da546Spatrick     }
1335*061da546Spatrick   }
1336*061da546Spatrick   return -1;
1337*061da546Spatrick }
1338*061da546Spatrick 
1339*061da546Spatrick int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
1340*061da546Spatrick                                                         size_t data_len) {
1341*061da546Spatrick   StreamString packet;
1342*061da546Spatrick   packet.PutCString("I");
1343*061da546Spatrick   packet.PutBytesAsRawHex8(data, data_len);
1344*061da546Spatrick   StringExtractorGDBRemote response;
1345*061da546Spatrick   if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1346*061da546Spatrick       PacketResult::Success) {
1347*061da546Spatrick     return 0;
1348*061da546Spatrick   }
1349*061da546Spatrick   return response.GetError();
1350*061da546Spatrick }
1351*061da546Spatrick 
1352*061da546Spatrick const lldb_private::ArchSpec &
1353*061da546Spatrick GDBRemoteCommunicationClient::GetHostArchitecture() {
1354*061da546Spatrick   if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1355*061da546Spatrick     GetHostInfo();
1356*061da546Spatrick   return m_host_arch;
1357*061da546Spatrick }
1358*061da546Spatrick 
1359*061da546Spatrick seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
1360*061da546Spatrick   if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1361*061da546Spatrick     GetHostInfo();
1362*061da546Spatrick   return m_default_packet_timeout;
1363*061da546Spatrick }
1364*061da546Spatrick 
1365*061da546Spatrick addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
1366*061da546Spatrick                                                     uint32_t permissions) {
1367*061da546Spatrick   if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1368*061da546Spatrick     m_supports_alloc_dealloc_memory = eLazyBoolYes;
1369*061da546Spatrick     char packet[64];
1370*061da546Spatrick     const int packet_len = ::snprintf(
1371*061da546Spatrick         packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1372*061da546Spatrick         permissions & lldb::ePermissionsReadable ? "r" : "",
1373*061da546Spatrick         permissions & lldb::ePermissionsWritable ? "w" : "",
1374*061da546Spatrick         permissions & lldb::ePermissionsExecutable ? "x" : "");
1375*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
1376*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
1377*061da546Spatrick     StringExtractorGDBRemote response;
1378*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
1379*061da546Spatrick         PacketResult::Success) {
1380*061da546Spatrick       if (response.IsUnsupportedResponse())
1381*061da546Spatrick         m_supports_alloc_dealloc_memory = eLazyBoolNo;
1382*061da546Spatrick       else if (!response.IsErrorResponse())
1383*061da546Spatrick         return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1384*061da546Spatrick     } else {
1385*061da546Spatrick       m_supports_alloc_dealloc_memory = eLazyBoolNo;
1386*061da546Spatrick     }
1387*061da546Spatrick   }
1388*061da546Spatrick   return LLDB_INVALID_ADDRESS;
1389*061da546Spatrick }
1390*061da546Spatrick 
1391*061da546Spatrick bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
1392*061da546Spatrick   if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1393*061da546Spatrick     m_supports_alloc_dealloc_memory = eLazyBoolYes;
1394*061da546Spatrick     char packet[64];
1395*061da546Spatrick     const int packet_len =
1396*061da546Spatrick         ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1397*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
1398*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
1399*061da546Spatrick     StringExtractorGDBRemote response;
1400*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
1401*061da546Spatrick         PacketResult::Success) {
1402*061da546Spatrick       if (response.IsUnsupportedResponse())
1403*061da546Spatrick         m_supports_alloc_dealloc_memory = eLazyBoolNo;
1404*061da546Spatrick       else if (response.IsOKResponse())
1405*061da546Spatrick         return true;
1406*061da546Spatrick     } else {
1407*061da546Spatrick       m_supports_alloc_dealloc_memory = eLazyBoolNo;
1408*061da546Spatrick     }
1409*061da546Spatrick   }
1410*061da546Spatrick   return false;
1411*061da546Spatrick }
1412*061da546Spatrick 
1413*061da546Spatrick Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
1414*061da546Spatrick   Status error;
1415*061da546Spatrick 
1416*061da546Spatrick   if (keep_stopped) {
1417*061da546Spatrick     if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
1418*061da546Spatrick       char packet[64];
1419*061da546Spatrick       const int packet_len =
1420*061da546Spatrick           ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1421*061da546Spatrick       assert(packet_len < (int)sizeof(packet));
1422*061da546Spatrick       UNUSED_IF_ASSERT_DISABLED(packet_len);
1423*061da546Spatrick       StringExtractorGDBRemote response;
1424*061da546Spatrick       if (SendPacketAndWaitForResponse(packet, response, false) ==
1425*061da546Spatrick               PacketResult::Success &&
1426*061da546Spatrick           response.IsOKResponse()) {
1427*061da546Spatrick         m_supports_detach_stay_stopped = eLazyBoolYes;
1428*061da546Spatrick       } else {
1429*061da546Spatrick         m_supports_detach_stay_stopped = eLazyBoolNo;
1430*061da546Spatrick       }
1431*061da546Spatrick     }
1432*061da546Spatrick 
1433*061da546Spatrick     if (m_supports_detach_stay_stopped == eLazyBoolNo) {
1434*061da546Spatrick       error.SetErrorString("Stays stopped not supported by this target.");
1435*061da546Spatrick       return error;
1436*061da546Spatrick     } else {
1437*061da546Spatrick       StringExtractorGDBRemote response;
1438*061da546Spatrick       PacketResult packet_result =
1439*061da546Spatrick           SendPacketAndWaitForResponse("D1", response, false);
1440*061da546Spatrick       if (packet_result != PacketResult::Success)
1441*061da546Spatrick         error.SetErrorString("Sending extended disconnect packet failed.");
1442*061da546Spatrick     }
1443*061da546Spatrick   } else {
1444*061da546Spatrick     StringExtractorGDBRemote response;
1445*061da546Spatrick     PacketResult packet_result =
1446*061da546Spatrick         SendPacketAndWaitForResponse("D", response, false);
1447*061da546Spatrick     if (packet_result != PacketResult::Success)
1448*061da546Spatrick       error.SetErrorString("Sending disconnect packet failed.");
1449*061da546Spatrick   }
1450*061da546Spatrick   return error;
1451*061da546Spatrick }
1452*061da546Spatrick 
1453*061da546Spatrick Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
1454*061da546Spatrick     lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
1455*061da546Spatrick   Status error;
1456*061da546Spatrick   region_info.Clear();
1457*061da546Spatrick 
1458*061da546Spatrick   if (m_supports_memory_region_info != eLazyBoolNo) {
1459*061da546Spatrick     m_supports_memory_region_info = eLazyBoolYes;
1460*061da546Spatrick     char packet[64];
1461*061da546Spatrick     const int packet_len = ::snprintf(
1462*061da546Spatrick         packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1463*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
1464*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
1465*061da546Spatrick     StringExtractorGDBRemote response;
1466*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
1467*061da546Spatrick             PacketResult::Success &&
1468*061da546Spatrick         response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
1469*061da546Spatrick       llvm::StringRef name;
1470*061da546Spatrick       llvm::StringRef value;
1471*061da546Spatrick       addr_t addr_value = LLDB_INVALID_ADDRESS;
1472*061da546Spatrick       bool success = true;
1473*061da546Spatrick       bool saw_permissions = false;
1474*061da546Spatrick       while (success && response.GetNameColonValue(name, value)) {
1475*061da546Spatrick         if (name.equals("start")) {
1476*061da546Spatrick           if (!value.getAsInteger(16, addr_value))
1477*061da546Spatrick             region_info.GetRange().SetRangeBase(addr_value);
1478*061da546Spatrick         } else if (name.equals("size")) {
1479*061da546Spatrick           if (!value.getAsInteger(16, addr_value))
1480*061da546Spatrick             region_info.GetRange().SetByteSize(addr_value);
1481*061da546Spatrick         } else if (name.equals("permissions") &&
1482*061da546Spatrick                    region_info.GetRange().IsValid()) {
1483*061da546Spatrick           saw_permissions = true;
1484*061da546Spatrick           if (region_info.GetRange().Contains(addr)) {
1485*061da546Spatrick             if (value.find('r') != llvm::StringRef::npos)
1486*061da546Spatrick               region_info.SetReadable(MemoryRegionInfo::eYes);
1487*061da546Spatrick             else
1488*061da546Spatrick               region_info.SetReadable(MemoryRegionInfo::eNo);
1489*061da546Spatrick 
1490*061da546Spatrick             if (value.find('w') != llvm::StringRef::npos)
1491*061da546Spatrick               region_info.SetWritable(MemoryRegionInfo::eYes);
1492*061da546Spatrick             else
1493*061da546Spatrick               region_info.SetWritable(MemoryRegionInfo::eNo);
1494*061da546Spatrick 
1495*061da546Spatrick             if (value.find('x') != llvm::StringRef::npos)
1496*061da546Spatrick               region_info.SetExecutable(MemoryRegionInfo::eYes);
1497*061da546Spatrick             else
1498*061da546Spatrick               region_info.SetExecutable(MemoryRegionInfo::eNo);
1499*061da546Spatrick 
1500*061da546Spatrick             region_info.SetMapped(MemoryRegionInfo::eYes);
1501*061da546Spatrick           } else {
1502*061da546Spatrick             // The reported region does not contain this address -- we're
1503*061da546Spatrick             // looking at an unmapped page
1504*061da546Spatrick             region_info.SetReadable(MemoryRegionInfo::eNo);
1505*061da546Spatrick             region_info.SetWritable(MemoryRegionInfo::eNo);
1506*061da546Spatrick             region_info.SetExecutable(MemoryRegionInfo::eNo);
1507*061da546Spatrick             region_info.SetMapped(MemoryRegionInfo::eNo);
1508*061da546Spatrick           }
1509*061da546Spatrick         } else if (name.equals("name")) {
1510*061da546Spatrick           StringExtractorGDBRemote name_extractor(value);
1511*061da546Spatrick           std::string name;
1512*061da546Spatrick           name_extractor.GetHexByteString(name);
1513*061da546Spatrick           region_info.SetName(name.c_str());
1514*061da546Spatrick         } else if (name.equals("error")) {
1515*061da546Spatrick           StringExtractorGDBRemote error_extractor(value);
1516*061da546Spatrick           std::string error_string;
1517*061da546Spatrick           // Now convert the HEX bytes into a string value
1518*061da546Spatrick           error_extractor.GetHexByteString(error_string);
1519*061da546Spatrick           error.SetErrorString(error_string.c_str());
1520*061da546Spatrick         }
1521*061da546Spatrick       }
1522*061da546Spatrick 
1523*061da546Spatrick       if (region_info.GetRange().IsValid()) {
1524*061da546Spatrick         // We got a valid address range back but no permissions -- which means
1525*061da546Spatrick         // this is an unmapped page
1526*061da546Spatrick         if (!saw_permissions) {
1527*061da546Spatrick           region_info.SetReadable(MemoryRegionInfo::eNo);
1528*061da546Spatrick           region_info.SetWritable(MemoryRegionInfo::eNo);
1529*061da546Spatrick           region_info.SetExecutable(MemoryRegionInfo::eNo);
1530*061da546Spatrick           region_info.SetMapped(MemoryRegionInfo::eNo);
1531*061da546Spatrick         }
1532*061da546Spatrick       } else {
1533*061da546Spatrick         // We got an invalid address range back
1534*061da546Spatrick         error.SetErrorString("Server returned invalid range");
1535*061da546Spatrick       }
1536*061da546Spatrick     } else {
1537*061da546Spatrick       m_supports_memory_region_info = eLazyBoolNo;
1538*061da546Spatrick     }
1539*061da546Spatrick   }
1540*061da546Spatrick 
1541*061da546Spatrick   if (m_supports_memory_region_info == eLazyBoolNo) {
1542*061da546Spatrick     error.SetErrorString("qMemoryRegionInfo is not supported");
1543*061da546Spatrick   }
1544*061da546Spatrick 
1545*061da546Spatrick   // Try qXfer:memory-map:read to get region information not included in
1546*061da546Spatrick   // qMemoryRegionInfo
1547*061da546Spatrick   MemoryRegionInfo qXfer_region_info;
1548*061da546Spatrick   Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1549*061da546Spatrick 
1550*061da546Spatrick   if (error.Fail()) {
1551*061da546Spatrick     // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1552*061da546Spatrick     // the qXfer result as a fallback
1553*061da546Spatrick     if (qXfer_error.Success()) {
1554*061da546Spatrick       region_info = qXfer_region_info;
1555*061da546Spatrick       error.Clear();
1556*061da546Spatrick     } else {
1557*061da546Spatrick       region_info.Clear();
1558*061da546Spatrick     }
1559*061da546Spatrick   } else if (qXfer_error.Success()) {
1560*061da546Spatrick     // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
1561*061da546Spatrick     // both regions are the same range, update the result to include the flash-
1562*061da546Spatrick     // memory information that is specific to the qXfer result.
1563*061da546Spatrick     if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1564*061da546Spatrick       region_info.SetFlash(qXfer_region_info.GetFlash());
1565*061da546Spatrick       region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1566*061da546Spatrick     }
1567*061da546Spatrick   }
1568*061da546Spatrick   return error;
1569*061da546Spatrick }
1570*061da546Spatrick 
1571*061da546Spatrick Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1572*061da546Spatrick     lldb::addr_t addr, MemoryRegionInfo &region) {
1573*061da546Spatrick   Status error = LoadQXferMemoryMap();
1574*061da546Spatrick   if (!error.Success())
1575*061da546Spatrick     return error;
1576*061da546Spatrick   for (const auto &map_region : m_qXfer_memory_map) {
1577*061da546Spatrick     if (map_region.GetRange().Contains(addr)) {
1578*061da546Spatrick       region = map_region;
1579*061da546Spatrick       return error;
1580*061da546Spatrick     }
1581*061da546Spatrick   }
1582*061da546Spatrick   error.SetErrorString("Region not found");
1583*061da546Spatrick   return error;
1584*061da546Spatrick }
1585*061da546Spatrick 
1586*061da546Spatrick Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
1587*061da546Spatrick 
1588*061da546Spatrick   Status error;
1589*061da546Spatrick 
1590*061da546Spatrick   if (m_qXfer_memory_map_loaded)
1591*061da546Spatrick     // Already loaded, return success
1592*061da546Spatrick     return error;
1593*061da546Spatrick 
1594*061da546Spatrick   if (!XMLDocument::XMLEnabled()) {
1595*061da546Spatrick     error.SetErrorString("XML is not supported");
1596*061da546Spatrick     return error;
1597*061da546Spatrick   }
1598*061da546Spatrick 
1599*061da546Spatrick   if (!GetQXferMemoryMapReadSupported()) {
1600*061da546Spatrick     error.SetErrorString("Memory map is not supported");
1601*061da546Spatrick     return error;
1602*061da546Spatrick   }
1603*061da546Spatrick 
1604*061da546Spatrick   std::string xml;
1605*061da546Spatrick   lldb_private::Status lldberr;
1606*061da546Spatrick   if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
1607*061da546Spatrick                       lldberr)) {
1608*061da546Spatrick     error.SetErrorString("Failed to read memory map");
1609*061da546Spatrick     return error;
1610*061da546Spatrick   }
1611*061da546Spatrick 
1612*061da546Spatrick   XMLDocument xml_document;
1613*061da546Spatrick 
1614*061da546Spatrick   if (!xml_document.ParseMemory(xml.c_str(), xml.size())) {
1615*061da546Spatrick     error.SetErrorString("Failed to parse memory map xml");
1616*061da546Spatrick     return error;
1617*061da546Spatrick   }
1618*061da546Spatrick 
1619*061da546Spatrick   XMLNode map_node = xml_document.GetRootElement("memory-map");
1620*061da546Spatrick   if (!map_node) {
1621*061da546Spatrick     error.SetErrorString("Invalid root node in memory map xml");
1622*061da546Spatrick     return error;
1623*061da546Spatrick   }
1624*061da546Spatrick 
1625*061da546Spatrick   m_qXfer_memory_map.clear();
1626*061da546Spatrick 
1627*061da546Spatrick   map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1628*061da546Spatrick     if (!memory_node.IsElement())
1629*061da546Spatrick       return true;
1630*061da546Spatrick     if (memory_node.GetName() != "memory")
1631*061da546Spatrick       return true;
1632*061da546Spatrick     auto type = memory_node.GetAttributeValue("type", "");
1633*061da546Spatrick     uint64_t start;
1634*061da546Spatrick     uint64_t length;
1635*061da546Spatrick     if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1636*061da546Spatrick       return true;
1637*061da546Spatrick     if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1638*061da546Spatrick       return true;
1639*061da546Spatrick     MemoryRegionInfo region;
1640*061da546Spatrick     region.GetRange().SetRangeBase(start);
1641*061da546Spatrick     region.GetRange().SetByteSize(length);
1642*061da546Spatrick     if (type == "rom") {
1643*061da546Spatrick       region.SetReadable(MemoryRegionInfo::eYes);
1644*061da546Spatrick       this->m_qXfer_memory_map.push_back(region);
1645*061da546Spatrick     } else if (type == "ram") {
1646*061da546Spatrick       region.SetReadable(MemoryRegionInfo::eYes);
1647*061da546Spatrick       region.SetWritable(MemoryRegionInfo::eYes);
1648*061da546Spatrick       this->m_qXfer_memory_map.push_back(region);
1649*061da546Spatrick     } else if (type == "flash") {
1650*061da546Spatrick       region.SetFlash(MemoryRegionInfo::eYes);
1651*061da546Spatrick       memory_node.ForEachChildElement(
1652*061da546Spatrick           [&region](const XMLNode &prop_node) -> bool {
1653*061da546Spatrick             if (!prop_node.IsElement())
1654*061da546Spatrick               return true;
1655*061da546Spatrick             if (prop_node.GetName() != "property")
1656*061da546Spatrick               return true;
1657*061da546Spatrick             auto propname = prop_node.GetAttributeValue("name", "");
1658*061da546Spatrick             if (propname == "blocksize") {
1659*061da546Spatrick               uint64_t blocksize;
1660*061da546Spatrick               if (prop_node.GetElementTextAsUnsigned(blocksize))
1661*061da546Spatrick                 region.SetBlocksize(blocksize);
1662*061da546Spatrick             }
1663*061da546Spatrick             return true;
1664*061da546Spatrick           });
1665*061da546Spatrick       this->m_qXfer_memory_map.push_back(region);
1666*061da546Spatrick     }
1667*061da546Spatrick     return true;
1668*061da546Spatrick   });
1669*061da546Spatrick 
1670*061da546Spatrick   m_qXfer_memory_map_loaded = true;
1671*061da546Spatrick 
1672*061da546Spatrick   return error;
1673*061da546Spatrick }
1674*061da546Spatrick 
1675*061da546Spatrick Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
1676*061da546Spatrick   Status error;
1677*061da546Spatrick 
1678*061da546Spatrick   if (m_supports_watchpoint_support_info == eLazyBoolYes) {
1679*061da546Spatrick     num = m_num_supported_hardware_watchpoints;
1680*061da546Spatrick     return error;
1681*061da546Spatrick   }
1682*061da546Spatrick 
1683*061da546Spatrick   // Set num to 0 first.
1684*061da546Spatrick   num = 0;
1685*061da546Spatrick   if (m_supports_watchpoint_support_info != eLazyBoolNo) {
1686*061da546Spatrick     char packet[64];
1687*061da546Spatrick     const int packet_len =
1688*061da546Spatrick         ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
1689*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
1690*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
1691*061da546Spatrick     StringExtractorGDBRemote response;
1692*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
1693*061da546Spatrick         PacketResult::Success) {
1694*061da546Spatrick       m_supports_watchpoint_support_info = eLazyBoolYes;
1695*061da546Spatrick       llvm::StringRef name;
1696*061da546Spatrick       llvm::StringRef value;
1697*061da546Spatrick       bool found_num_field = false;
1698*061da546Spatrick       while (response.GetNameColonValue(name, value)) {
1699*061da546Spatrick         if (name.equals("num")) {
1700*061da546Spatrick           value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1701*061da546Spatrick           num = m_num_supported_hardware_watchpoints;
1702*061da546Spatrick           found_num_field = true;
1703*061da546Spatrick         }
1704*061da546Spatrick       }
1705*061da546Spatrick       if (!found_num_field) {
1706*061da546Spatrick         m_supports_watchpoint_support_info = eLazyBoolNo;
1707*061da546Spatrick       }
1708*061da546Spatrick     } else {
1709*061da546Spatrick       m_supports_watchpoint_support_info = eLazyBoolNo;
1710*061da546Spatrick     }
1711*061da546Spatrick   }
1712*061da546Spatrick 
1713*061da546Spatrick   if (m_supports_watchpoint_support_info == eLazyBoolNo) {
1714*061da546Spatrick     error.SetErrorString("qWatchpointSupportInfo is not supported");
1715*061da546Spatrick   }
1716*061da546Spatrick   return error;
1717*061da546Spatrick }
1718*061da546Spatrick 
1719*061da546Spatrick lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
1720*061da546Spatrick     uint32_t &num, bool &after, const ArchSpec &arch) {
1721*061da546Spatrick   Status error(GetWatchpointSupportInfo(num));
1722*061da546Spatrick   if (error.Success())
1723*061da546Spatrick     error = GetWatchpointsTriggerAfterInstruction(after, arch);
1724*061da546Spatrick   return error;
1725*061da546Spatrick }
1726*061da546Spatrick 
1727*061da546Spatrick lldb_private::Status
1728*061da546Spatrick GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
1729*061da546Spatrick     bool &after, const ArchSpec &arch) {
1730*061da546Spatrick   Status error;
1731*061da546Spatrick   llvm::Triple triple = arch.GetTriple();
1732*061da546Spatrick 
1733*061da546Spatrick   // we assume watchpoints will happen after running the relevant opcode and we
1734*061da546Spatrick   // only want to override this behavior if we have explicitly received a
1735*061da546Spatrick   // qHostInfo telling us otherwise
1736*061da546Spatrick   if (m_qHostInfo_is_valid != eLazyBoolYes) {
1737*061da546Spatrick     // On targets like MIPS and ppc64, watchpoint exceptions are always
1738*061da546Spatrick     // generated before the instruction is executed. The connected target may
1739*061da546Spatrick     // not support qHostInfo or qWatchpointSupportInfo packets.
1740*061da546Spatrick     after = !(triple.isMIPS() || triple.isPPC64());
1741*061da546Spatrick   } else {
1742*061da546Spatrick     // For MIPS and ppc64, set m_watchpoints_trigger_after_instruction to
1743*061da546Spatrick     // eLazyBoolNo if it is not calculated before.
1744*061da546Spatrick     if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
1745*061da546Spatrick         (triple.isMIPS() || triple.isPPC64()))
1746*061da546Spatrick       m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1747*061da546Spatrick 
1748*061da546Spatrick     after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1749*061da546Spatrick   }
1750*061da546Spatrick   return error;
1751*061da546Spatrick }
1752*061da546Spatrick 
1753*061da546Spatrick int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
1754*061da546Spatrick   if (file_spec) {
1755*061da546Spatrick     std::string path{file_spec.GetPath(false)};
1756*061da546Spatrick     StreamString packet;
1757*061da546Spatrick     packet.PutCString("QSetSTDIN:");
1758*061da546Spatrick     packet.PutStringAsRawHex8(path);
1759*061da546Spatrick 
1760*061da546Spatrick     StringExtractorGDBRemote response;
1761*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1762*061da546Spatrick         PacketResult::Success) {
1763*061da546Spatrick       if (response.IsOKResponse())
1764*061da546Spatrick         return 0;
1765*061da546Spatrick       uint8_t error = response.GetError();
1766*061da546Spatrick       if (error)
1767*061da546Spatrick         return error;
1768*061da546Spatrick     }
1769*061da546Spatrick   }
1770*061da546Spatrick   return -1;
1771*061da546Spatrick }
1772*061da546Spatrick 
1773*061da546Spatrick int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
1774*061da546Spatrick   if (file_spec) {
1775*061da546Spatrick     std::string path{file_spec.GetPath(false)};
1776*061da546Spatrick     StreamString packet;
1777*061da546Spatrick     packet.PutCString("QSetSTDOUT:");
1778*061da546Spatrick     packet.PutStringAsRawHex8(path);
1779*061da546Spatrick 
1780*061da546Spatrick     StringExtractorGDBRemote response;
1781*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1782*061da546Spatrick         PacketResult::Success) {
1783*061da546Spatrick       if (response.IsOKResponse())
1784*061da546Spatrick         return 0;
1785*061da546Spatrick       uint8_t error = response.GetError();
1786*061da546Spatrick       if (error)
1787*061da546Spatrick         return error;
1788*061da546Spatrick     }
1789*061da546Spatrick   }
1790*061da546Spatrick   return -1;
1791*061da546Spatrick }
1792*061da546Spatrick 
1793*061da546Spatrick int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
1794*061da546Spatrick   if (file_spec) {
1795*061da546Spatrick     std::string path{file_spec.GetPath(false)};
1796*061da546Spatrick     StreamString packet;
1797*061da546Spatrick     packet.PutCString("QSetSTDERR:");
1798*061da546Spatrick     packet.PutStringAsRawHex8(path);
1799*061da546Spatrick 
1800*061da546Spatrick     StringExtractorGDBRemote response;
1801*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1802*061da546Spatrick         PacketResult::Success) {
1803*061da546Spatrick       if (response.IsOKResponse())
1804*061da546Spatrick         return 0;
1805*061da546Spatrick       uint8_t error = response.GetError();
1806*061da546Spatrick       if (error)
1807*061da546Spatrick         return error;
1808*061da546Spatrick     }
1809*061da546Spatrick   }
1810*061da546Spatrick   return -1;
1811*061da546Spatrick }
1812*061da546Spatrick 
1813*061da546Spatrick bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
1814*061da546Spatrick   StringExtractorGDBRemote response;
1815*061da546Spatrick   if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
1816*061da546Spatrick       PacketResult::Success) {
1817*061da546Spatrick     if (response.IsUnsupportedResponse())
1818*061da546Spatrick       return false;
1819*061da546Spatrick     if (response.IsErrorResponse())
1820*061da546Spatrick       return false;
1821*061da546Spatrick     std::string cwd;
1822*061da546Spatrick     response.GetHexByteString(cwd);
1823*061da546Spatrick     working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
1824*061da546Spatrick     return !cwd.empty();
1825*061da546Spatrick   }
1826*061da546Spatrick   return false;
1827*061da546Spatrick }
1828*061da546Spatrick 
1829*061da546Spatrick int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
1830*061da546Spatrick   if (working_dir) {
1831*061da546Spatrick     std::string path{working_dir.GetPath(false)};
1832*061da546Spatrick     StreamString packet;
1833*061da546Spatrick     packet.PutCString("QSetWorkingDir:");
1834*061da546Spatrick     packet.PutStringAsRawHex8(path);
1835*061da546Spatrick 
1836*061da546Spatrick     StringExtractorGDBRemote response;
1837*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
1838*061da546Spatrick         PacketResult::Success) {
1839*061da546Spatrick       if (response.IsOKResponse())
1840*061da546Spatrick         return 0;
1841*061da546Spatrick       uint8_t error = response.GetError();
1842*061da546Spatrick       if (error)
1843*061da546Spatrick         return error;
1844*061da546Spatrick     }
1845*061da546Spatrick   }
1846*061da546Spatrick   return -1;
1847*061da546Spatrick }
1848*061da546Spatrick 
1849*061da546Spatrick int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
1850*061da546Spatrick   char packet[32];
1851*061da546Spatrick   const int packet_len =
1852*061da546Spatrick       ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1853*061da546Spatrick   assert(packet_len < (int)sizeof(packet));
1854*061da546Spatrick   UNUSED_IF_ASSERT_DISABLED(packet_len);
1855*061da546Spatrick   StringExtractorGDBRemote response;
1856*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, false) ==
1857*061da546Spatrick       PacketResult::Success) {
1858*061da546Spatrick     if (response.IsOKResponse())
1859*061da546Spatrick       return 0;
1860*061da546Spatrick     uint8_t error = response.GetError();
1861*061da546Spatrick     if (error)
1862*061da546Spatrick       return error;
1863*061da546Spatrick   }
1864*061da546Spatrick   return -1;
1865*061da546Spatrick }
1866*061da546Spatrick 
1867*061da546Spatrick int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
1868*061da546Spatrick   char packet[32];
1869*061da546Spatrick   const int packet_len = ::snprintf(packet, sizeof(packet),
1870*061da546Spatrick                                     "QSetDetachOnError:%i", enable ? 1 : 0);
1871*061da546Spatrick   assert(packet_len < (int)sizeof(packet));
1872*061da546Spatrick   UNUSED_IF_ASSERT_DISABLED(packet_len);
1873*061da546Spatrick   StringExtractorGDBRemote response;
1874*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, false) ==
1875*061da546Spatrick       PacketResult::Success) {
1876*061da546Spatrick     if (response.IsOKResponse())
1877*061da546Spatrick       return 0;
1878*061da546Spatrick     uint8_t error = response.GetError();
1879*061da546Spatrick     if (error)
1880*061da546Spatrick       return error;
1881*061da546Spatrick   }
1882*061da546Spatrick   return -1;
1883*061da546Spatrick }
1884*061da546Spatrick 
1885*061da546Spatrick bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
1886*061da546Spatrick     StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
1887*061da546Spatrick   if (response.IsNormalResponse()) {
1888*061da546Spatrick     llvm::StringRef name;
1889*061da546Spatrick     llvm::StringRef value;
1890*061da546Spatrick     StringExtractor extractor;
1891*061da546Spatrick 
1892*061da546Spatrick     uint32_t cpu = LLDB_INVALID_CPUTYPE;
1893*061da546Spatrick     uint32_t sub = 0;
1894*061da546Spatrick     std::string vendor;
1895*061da546Spatrick     std::string os_type;
1896*061da546Spatrick 
1897*061da546Spatrick     while (response.GetNameColonValue(name, value)) {
1898*061da546Spatrick       if (name.equals("pid")) {
1899*061da546Spatrick         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1900*061da546Spatrick         value.getAsInteger(0, pid);
1901*061da546Spatrick         process_info.SetProcessID(pid);
1902*061da546Spatrick       } else if (name.equals("ppid")) {
1903*061da546Spatrick         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1904*061da546Spatrick         value.getAsInteger(0, pid);
1905*061da546Spatrick         process_info.SetParentProcessID(pid);
1906*061da546Spatrick       } else if (name.equals("uid")) {
1907*061da546Spatrick         uint32_t uid = UINT32_MAX;
1908*061da546Spatrick         value.getAsInteger(0, uid);
1909*061da546Spatrick         process_info.SetUserID(uid);
1910*061da546Spatrick       } else if (name.equals("euid")) {
1911*061da546Spatrick         uint32_t uid = UINT32_MAX;
1912*061da546Spatrick         value.getAsInteger(0, uid);
1913*061da546Spatrick         process_info.SetEffectiveUserID(uid);
1914*061da546Spatrick       } else if (name.equals("gid")) {
1915*061da546Spatrick         uint32_t gid = UINT32_MAX;
1916*061da546Spatrick         value.getAsInteger(0, gid);
1917*061da546Spatrick         process_info.SetGroupID(gid);
1918*061da546Spatrick       } else if (name.equals("egid")) {
1919*061da546Spatrick         uint32_t gid = UINT32_MAX;
1920*061da546Spatrick         value.getAsInteger(0, gid);
1921*061da546Spatrick         process_info.SetEffectiveGroupID(gid);
1922*061da546Spatrick       } else if (name.equals("triple")) {
1923*061da546Spatrick         StringExtractor extractor(value);
1924*061da546Spatrick         std::string triple;
1925*061da546Spatrick         extractor.GetHexByteString(triple);
1926*061da546Spatrick         process_info.GetArchitecture().SetTriple(triple.c_str());
1927*061da546Spatrick       } else if (name.equals("name")) {
1928*061da546Spatrick         StringExtractor extractor(value);
1929*061da546Spatrick         // The process name from ASCII hex bytes since we can't control the
1930*061da546Spatrick         // characters in a process name
1931*061da546Spatrick         std::string name;
1932*061da546Spatrick         extractor.GetHexByteString(name);
1933*061da546Spatrick         process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
1934*061da546Spatrick       } else if (name.equals("args")) {
1935*061da546Spatrick         llvm::StringRef encoded_args(value), hex_arg;
1936*061da546Spatrick 
1937*061da546Spatrick         bool is_arg0 = true;
1938*061da546Spatrick         while (!encoded_args.empty()) {
1939*061da546Spatrick           std::tie(hex_arg, encoded_args) = encoded_args.split('-');
1940*061da546Spatrick           std::string arg;
1941*061da546Spatrick           StringExtractor extractor(hex_arg);
1942*061da546Spatrick           if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
1943*061da546Spatrick             // In case of wrong encoding, we discard all the arguments
1944*061da546Spatrick             process_info.GetArguments().Clear();
1945*061da546Spatrick             process_info.SetArg0("");
1946*061da546Spatrick             break;
1947*061da546Spatrick           }
1948*061da546Spatrick           if (is_arg0)
1949*061da546Spatrick             process_info.SetArg0(arg);
1950*061da546Spatrick           else
1951*061da546Spatrick             process_info.GetArguments().AppendArgument(arg);
1952*061da546Spatrick           is_arg0 = false;
1953*061da546Spatrick         }
1954*061da546Spatrick       } else if (name.equals("cputype")) {
1955*061da546Spatrick         value.getAsInteger(0, cpu);
1956*061da546Spatrick       } else if (name.equals("cpusubtype")) {
1957*061da546Spatrick         value.getAsInteger(0, sub);
1958*061da546Spatrick       } else if (name.equals("vendor")) {
1959*061da546Spatrick         vendor = value;
1960*061da546Spatrick       } else if (name.equals("ostype")) {
1961*061da546Spatrick         os_type = value;
1962*061da546Spatrick       }
1963*061da546Spatrick     }
1964*061da546Spatrick 
1965*061da546Spatrick     if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
1966*061da546Spatrick       if (vendor == "apple") {
1967*061da546Spatrick         process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
1968*061da546Spatrick                                                        sub);
1969*061da546Spatrick         process_info.GetArchitecture().GetTriple().setVendorName(
1970*061da546Spatrick             llvm::StringRef(vendor));
1971*061da546Spatrick         process_info.GetArchitecture().GetTriple().setOSName(
1972*061da546Spatrick             llvm::StringRef(os_type));
1973*061da546Spatrick       }
1974*061da546Spatrick     }
1975*061da546Spatrick 
1976*061da546Spatrick     if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1977*061da546Spatrick       return true;
1978*061da546Spatrick   }
1979*061da546Spatrick   return false;
1980*061da546Spatrick }
1981*061da546Spatrick 
1982*061da546Spatrick bool GDBRemoteCommunicationClient::GetProcessInfo(
1983*061da546Spatrick     lldb::pid_t pid, ProcessInstanceInfo &process_info) {
1984*061da546Spatrick   process_info.Clear();
1985*061da546Spatrick 
1986*061da546Spatrick   if (m_supports_qProcessInfoPID) {
1987*061da546Spatrick     char packet[32];
1988*061da546Spatrick     const int packet_len =
1989*061da546Spatrick         ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
1990*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
1991*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
1992*061da546Spatrick     StringExtractorGDBRemote response;
1993*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
1994*061da546Spatrick         PacketResult::Success) {
1995*061da546Spatrick       return DecodeProcessInfoResponse(response, process_info);
1996*061da546Spatrick     } else {
1997*061da546Spatrick       m_supports_qProcessInfoPID = false;
1998*061da546Spatrick       return false;
1999*061da546Spatrick     }
2000*061da546Spatrick   }
2001*061da546Spatrick   return false;
2002*061da546Spatrick }
2003*061da546Spatrick 
2004*061da546Spatrick bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
2005*061da546Spatrick   Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2006*061da546Spatrick                                                          GDBR_LOG_PACKETS));
2007*061da546Spatrick 
2008*061da546Spatrick   if (allow_lazy) {
2009*061da546Spatrick     if (m_qProcessInfo_is_valid == eLazyBoolYes)
2010*061da546Spatrick       return true;
2011*061da546Spatrick     if (m_qProcessInfo_is_valid == eLazyBoolNo)
2012*061da546Spatrick       return false;
2013*061da546Spatrick   }
2014*061da546Spatrick 
2015*061da546Spatrick   GetHostInfo();
2016*061da546Spatrick 
2017*061da546Spatrick   StringExtractorGDBRemote response;
2018*061da546Spatrick   if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
2019*061da546Spatrick       PacketResult::Success) {
2020*061da546Spatrick     if (response.IsNormalResponse()) {
2021*061da546Spatrick       llvm::StringRef name;
2022*061da546Spatrick       llvm::StringRef value;
2023*061da546Spatrick       uint32_t cpu = LLDB_INVALID_CPUTYPE;
2024*061da546Spatrick       uint32_t sub = 0;
2025*061da546Spatrick       std::string arch_name;
2026*061da546Spatrick       std::string os_name;
2027*061da546Spatrick       std::string environment;
2028*061da546Spatrick       std::string vendor_name;
2029*061da546Spatrick       std::string triple;
2030*061da546Spatrick       std::string elf_abi;
2031*061da546Spatrick       uint32_t pointer_byte_size = 0;
2032*061da546Spatrick       StringExtractor extractor;
2033*061da546Spatrick       ByteOrder byte_order = eByteOrderInvalid;
2034*061da546Spatrick       uint32_t num_keys_decoded = 0;
2035*061da546Spatrick       lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
2036*061da546Spatrick       while (response.GetNameColonValue(name, value)) {
2037*061da546Spatrick         if (name.equals("cputype")) {
2038*061da546Spatrick           if (!value.getAsInteger(16, cpu))
2039*061da546Spatrick             ++num_keys_decoded;
2040*061da546Spatrick         } else if (name.equals("cpusubtype")) {
2041*061da546Spatrick           if (!value.getAsInteger(16, sub))
2042*061da546Spatrick             ++num_keys_decoded;
2043*061da546Spatrick         } else if (name.equals("triple")) {
2044*061da546Spatrick           StringExtractor extractor(value);
2045*061da546Spatrick           extractor.GetHexByteString(triple);
2046*061da546Spatrick           ++num_keys_decoded;
2047*061da546Spatrick         } else if (name.equals("ostype")) {
2048*061da546Spatrick           if (value.equals("maccatalyst")) {
2049*061da546Spatrick             os_name = "ios";
2050*061da546Spatrick             environment = "macabi";
2051*061da546Spatrick           } else
2052*061da546Spatrick             os_name = value;
2053*061da546Spatrick           ++num_keys_decoded;
2054*061da546Spatrick         } else if (name.equals("vendor")) {
2055*061da546Spatrick           vendor_name = value;
2056*061da546Spatrick           ++num_keys_decoded;
2057*061da546Spatrick         } else if (name.equals("endian")) {
2058*061da546Spatrick           byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2059*061da546Spatrick                            .Case("little", eByteOrderLittle)
2060*061da546Spatrick                            .Case("big", eByteOrderBig)
2061*061da546Spatrick                            .Case("pdp", eByteOrderPDP)
2062*061da546Spatrick                            .Default(eByteOrderInvalid);
2063*061da546Spatrick           if (byte_order != eByteOrderInvalid)
2064*061da546Spatrick             ++num_keys_decoded;
2065*061da546Spatrick         } else if (name.equals("ptrsize")) {
2066*061da546Spatrick           if (!value.getAsInteger(16, pointer_byte_size))
2067*061da546Spatrick             ++num_keys_decoded;
2068*061da546Spatrick         } else if (name.equals("pid")) {
2069*061da546Spatrick           if (!value.getAsInteger(16, pid))
2070*061da546Spatrick             ++num_keys_decoded;
2071*061da546Spatrick         } else if (name.equals("elf_abi")) {
2072*061da546Spatrick           elf_abi = value;
2073*061da546Spatrick           ++num_keys_decoded;
2074*061da546Spatrick         }
2075*061da546Spatrick       }
2076*061da546Spatrick       if (num_keys_decoded > 0)
2077*061da546Spatrick         m_qProcessInfo_is_valid = eLazyBoolYes;
2078*061da546Spatrick       if (pid != LLDB_INVALID_PROCESS_ID) {
2079*061da546Spatrick         m_curr_pid_is_valid = eLazyBoolYes;
2080*061da546Spatrick         m_curr_pid = pid;
2081*061da546Spatrick       }
2082*061da546Spatrick 
2083*061da546Spatrick       // Set the ArchSpec from the triple if we have it.
2084*061da546Spatrick       if (!triple.empty()) {
2085*061da546Spatrick         m_process_arch.SetTriple(triple.c_str());
2086*061da546Spatrick         m_process_arch.SetFlags(elf_abi);
2087*061da546Spatrick         if (pointer_byte_size) {
2088*061da546Spatrick           assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2089*061da546Spatrick         }
2090*061da546Spatrick       } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2091*061da546Spatrick                  !vendor_name.empty()) {
2092*061da546Spatrick         llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2093*061da546Spatrick         if (!environment.empty())
2094*061da546Spatrick             triple.setEnvironmentName(environment);
2095*061da546Spatrick 
2096*061da546Spatrick         assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2097*061da546Spatrick         assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2098*061da546Spatrick         assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2099*061da546Spatrick         switch (triple.getObjectFormat()) {
2100*061da546Spatrick         case llvm::Triple::MachO:
2101*061da546Spatrick           m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2102*061da546Spatrick           break;
2103*061da546Spatrick         case llvm::Triple::ELF:
2104*061da546Spatrick           m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2105*061da546Spatrick           break;
2106*061da546Spatrick         case llvm::Triple::COFF:
2107*061da546Spatrick           m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2108*061da546Spatrick           break;
2109*061da546Spatrick         case llvm::Triple::Wasm:
2110*061da546Spatrick         case llvm::Triple::XCOFF:
2111*061da546Spatrick           LLDB_LOGF(log, "error: not supported target architecture");
2112*061da546Spatrick           return false;
2113*061da546Spatrick         case llvm::Triple::UnknownObjectFormat:
2114*061da546Spatrick           LLDB_LOGF(log, "error: failed to determine target architecture");
2115*061da546Spatrick           return false;
2116*061da546Spatrick         }
2117*061da546Spatrick 
2118*061da546Spatrick         if (pointer_byte_size) {
2119*061da546Spatrick           assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2120*061da546Spatrick         }
2121*061da546Spatrick         if (byte_order != eByteOrderInvalid) {
2122*061da546Spatrick           assert(byte_order == m_process_arch.GetByteOrder());
2123*061da546Spatrick         }
2124*061da546Spatrick         m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2125*061da546Spatrick         m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2126*061da546Spatrick         m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2127*061da546Spatrick         m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2128*061da546Spatrick         m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2129*061da546Spatrick         m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2130*061da546Spatrick       }
2131*061da546Spatrick       return true;
2132*061da546Spatrick     }
2133*061da546Spatrick   } else {
2134*061da546Spatrick     m_qProcessInfo_is_valid = eLazyBoolNo;
2135*061da546Spatrick   }
2136*061da546Spatrick 
2137*061da546Spatrick   return false;
2138*061da546Spatrick }
2139*061da546Spatrick 
2140*061da546Spatrick uint32_t GDBRemoteCommunicationClient::FindProcesses(
2141*061da546Spatrick     const ProcessInstanceInfoMatch &match_info,
2142*061da546Spatrick     ProcessInstanceInfoList &process_infos) {
2143*061da546Spatrick   process_infos.Clear();
2144*061da546Spatrick 
2145*061da546Spatrick   if (m_supports_qfProcessInfo) {
2146*061da546Spatrick     StreamString packet;
2147*061da546Spatrick     packet.PutCString("qfProcessInfo");
2148*061da546Spatrick     if (!match_info.MatchAllProcesses()) {
2149*061da546Spatrick       packet.PutChar(':');
2150*061da546Spatrick       const char *name = match_info.GetProcessInfo().GetName();
2151*061da546Spatrick       bool has_name_match = false;
2152*061da546Spatrick       if (name && name[0]) {
2153*061da546Spatrick         has_name_match = true;
2154*061da546Spatrick         NameMatch name_match_type = match_info.GetNameMatchType();
2155*061da546Spatrick         switch (name_match_type) {
2156*061da546Spatrick         case NameMatch::Ignore:
2157*061da546Spatrick           has_name_match = false;
2158*061da546Spatrick           break;
2159*061da546Spatrick 
2160*061da546Spatrick         case NameMatch::Equals:
2161*061da546Spatrick           packet.PutCString("name_match:equals;");
2162*061da546Spatrick           break;
2163*061da546Spatrick 
2164*061da546Spatrick         case NameMatch::Contains:
2165*061da546Spatrick           packet.PutCString("name_match:contains;");
2166*061da546Spatrick           break;
2167*061da546Spatrick 
2168*061da546Spatrick         case NameMatch::StartsWith:
2169*061da546Spatrick           packet.PutCString("name_match:starts_with;");
2170*061da546Spatrick           break;
2171*061da546Spatrick 
2172*061da546Spatrick         case NameMatch::EndsWith:
2173*061da546Spatrick           packet.PutCString("name_match:ends_with;");
2174*061da546Spatrick           break;
2175*061da546Spatrick 
2176*061da546Spatrick         case NameMatch::RegularExpression:
2177*061da546Spatrick           packet.PutCString("name_match:regex;");
2178*061da546Spatrick           break;
2179*061da546Spatrick         }
2180*061da546Spatrick         if (has_name_match) {
2181*061da546Spatrick           packet.PutCString("name:");
2182*061da546Spatrick           packet.PutBytesAsRawHex8(name, ::strlen(name));
2183*061da546Spatrick           packet.PutChar(';');
2184*061da546Spatrick         }
2185*061da546Spatrick       }
2186*061da546Spatrick 
2187*061da546Spatrick       if (match_info.GetProcessInfo().ProcessIDIsValid())
2188*061da546Spatrick         packet.Printf("pid:%" PRIu64 ";",
2189*061da546Spatrick                       match_info.GetProcessInfo().GetProcessID());
2190*061da546Spatrick       if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2191*061da546Spatrick         packet.Printf("parent_pid:%" PRIu64 ";",
2192*061da546Spatrick                       match_info.GetProcessInfo().GetParentProcessID());
2193*061da546Spatrick       if (match_info.GetProcessInfo().UserIDIsValid())
2194*061da546Spatrick         packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2195*061da546Spatrick       if (match_info.GetProcessInfo().GroupIDIsValid())
2196*061da546Spatrick         packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2197*061da546Spatrick       if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2198*061da546Spatrick         packet.Printf("euid:%u;",
2199*061da546Spatrick                       match_info.GetProcessInfo().GetEffectiveUserID());
2200*061da546Spatrick       if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2201*061da546Spatrick         packet.Printf("egid:%u;",
2202*061da546Spatrick                       match_info.GetProcessInfo().GetEffectiveGroupID());
2203*061da546Spatrick       packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
2204*061da546Spatrick       if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2205*061da546Spatrick         const ArchSpec &match_arch =
2206*061da546Spatrick             match_info.GetProcessInfo().GetArchitecture();
2207*061da546Spatrick         const llvm::Triple &triple = match_arch.GetTriple();
2208*061da546Spatrick         packet.PutCString("triple:");
2209*061da546Spatrick         packet.PutCString(triple.getTriple());
2210*061da546Spatrick         packet.PutChar(';');
2211*061da546Spatrick       }
2212*061da546Spatrick     }
2213*061da546Spatrick     StringExtractorGDBRemote response;
2214*061da546Spatrick     // Increase timeout as the first qfProcessInfo packet takes a long time on
2215*061da546Spatrick     // Android. The value of 1min was arrived at empirically.
2216*061da546Spatrick     ScopedTimeout timeout(*this, minutes(1));
2217*061da546Spatrick     if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2218*061da546Spatrick         PacketResult::Success) {
2219*061da546Spatrick       do {
2220*061da546Spatrick         ProcessInstanceInfo process_info;
2221*061da546Spatrick         if (!DecodeProcessInfoResponse(response, process_info))
2222*061da546Spatrick           break;
2223*061da546Spatrick         process_infos.Append(process_info);
2224*061da546Spatrick         response = StringExtractorGDBRemote();
2225*061da546Spatrick       } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
2226*061da546Spatrick                PacketResult::Success);
2227*061da546Spatrick     } else {
2228*061da546Spatrick       m_supports_qfProcessInfo = false;
2229*061da546Spatrick       return 0;
2230*061da546Spatrick     }
2231*061da546Spatrick   }
2232*061da546Spatrick   return process_infos.GetSize();
2233*061da546Spatrick }
2234*061da546Spatrick 
2235*061da546Spatrick bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
2236*061da546Spatrick                                                std::string &name) {
2237*061da546Spatrick   if (m_supports_qUserName) {
2238*061da546Spatrick     char packet[32];
2239*061da546Spatrick     const int packet_len =
2240*061da546Spatrick         ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2241*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
2242*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
2243*061da546Spatrick     StringExtractorGDBRemote response;
2244*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
2245*061da546Spatrick         PacketResult::Success) {
2246*061da546Spatrick       if (response.IsNormalResponse()) {
2247*061da546Spatrick         // Make sure we parsed the right number of characters. The response is
2248*061da546Spatrick         // the hex encoded user name and should make up the entire packet. If
2249*061da546Spatrick         // there are any non-hex ASCII bytes, the length won't match below..
2250*061da546Spatrick         if (response.GetHexByteString(name) * 2 ==
2251*061da546Spatrick             response.GetStringRef().size())
2252*061da546Spatrick           return true;
2253*061da546Spatrick       }
2254*061da546Spatrick     } else {
2255*061da546Spatrick       m_supports_qUserName = false;
2256*061da546Spatrick       return false;
2257*061da546Spatrick     }
2258*061da546Spatrick   }
2259*061da546Spatrick   return false;
2260*061da546Spatrick }
2261*061da546Spatrick 
2262*061da546Spatrick bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
2263*061da546Spatrick                                                 std::string &name) {
2264*061da546Spatrick   if (m_supports_qGroupName) {
2265*061da546Spatrick     char packet[32];
2266*061da546Spatrick     const int packet_len =
2267*061da546Spatrick         ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2268*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
2269*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
2270*061da546Spatrick     StringExtractorGDBRemote response;
2271*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
2272*061da546Spatrick         PacketResult::Success) {
2273*061da546Spatrick       if (response.IsNormalResponse()) {
2274*061da546Spatrick         // Make sure we parsed the right number of characters. The response is
2275*061da546Spatrick         // the hex encoded group name and should make up the entire packet. If
2276*061da546Spatrick         // there are any non-hex ASCII bytes, the length won't match below..
2277*061da546Spatrick         if (response.GetHexByteString(name) * 2 ==
2278*061da546Spatrick             response.GetStringRef().size())
2279*061da546Spatrick           return true;
2280*061da546Spatrick       }
2281*061da546Spatrick     } else {
2282*061da546Spatrick       m_supports_qGroupName = false;
2283*061da546Spatrick       return false;
2284*061da546Spatrick     }
2285*061da546Spatrick   }
2286*061da546Spatrick   return false;
2287*061da546Spatrick }
2288*061da546Spatrick 
2289*061da546Spatrick bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
2290*061da546Spatrick   // Form non-stop packet request
2291*061da546Spatrick   char packet[32];
2292*061da546Spatrick   const int packet_len =
2293*061da546Spatrick       ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
2294*061da546Spatrick   assert(packet_len < (int)sizeof(packet));
2295*061da546Spatrick   UNUSED_IF_ASSERT_DISABLED(packet_len);
2296*061da546Spatrick 
2297*061da546Spatrick   StringExtractorGDBRemote response;
2298*061da546Spatrick   // Send to target
2299*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, false) ==
2300*061da546Spatrick       PacketResult::Success)
2301*061da546Spatrick     if (response.IsOKResponse())
2302*061da546Spatrick       return true;
2303*061da546Spatrick 
2304*061da546Spatrick   // Failed or not supported
2305*061da546Spatrick   return false;
2306*061da546Spatrick }
2307*061da546Spatrick 
2308*061da546Spatrick static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2309*061da546Spatrick                                 uint32_t recv_size) {
2310*061da546Spatrick   packet.Clear();
2311*061da546Spatrick   packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2312*061da546Spatrick   uint32_t bytes_left = send_size;
2313*061da546Spatrick   while (bytes_left > 0) {
2314*061da546Spatrick     if (bytes_left >= 26) {
2315*061da546Spatrick       packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2316*061da546Spatrick       bytes_left -= 26;
2317*061da546Spatrick     } else {
2318*061da546Spatrick       packet.Printf("%*.*s;", bytes_left, bytes_left,
2319*061da546Spatrick                     "abcdefghijklmnopqrstuvwxyz");
2320*061da546Spatrick       bytes_left = 0;
2321*061da546Spatrick     }
2322*061da546Spatrick   }
2323*061da546Spatrick }
2324*061da546Spatrick 
2325*061da546Spatrick duration<float>
2326*061da546Spatrick calculate_standard_deviation(const std::vector<duration<float>> &v) {
2327*061da546Spatrick   using Dur = duration<float>;
2328*061da546Spatrick   Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2329*061da546Spatrick   Dur mean = sum / v.size();
2330*061da546Spatrick   float accum = 0;
2331*061da546Spatrick   for (auto d : v) {
2332*061da546Spatrick     float delta = (d - mean).count();
2333*061da546Spatrick     accum += delta * delta;
2334*061da546Spatrick   };
2335*061da546Spatrick 
2336*061da546Spatrick   return Dur(sqrtf(accum / (v.size() - 1)));
2337*061da546Spatrick }
2338*061da546Spatrick 
2339*061da546Spatrick void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
2340*061da546Spatrick                                                    uint32_t max_send,
2341*061da546Spatrick                                                    uint32_t max_recv,
2342*061da546Spatrick                                                    uint64_t recv_amount,
2343*061da546Spatrick                                                    bool json, Stream &strm) {
2344*061da546Spatrick   uint32_t i;
2345*061da546Spatrick   if (SendSpeedTestPacket(0, 0)) {
2346*061da546Spatrick     StreamString packet;
2347*061da546Spatrick     if (json)
2348*061da546Spatrick       strm.Printf("{ \"packet_speeds\" : {\n    \"num_packets\" : %u,\n    "
2349*061da546Spatrick                   "\"results\" : [",
2350*061da546Spatrick                   num_packets);
2351*061da546Spatrick     else
2352*061da546Spatrick       strm.Printf("Testing sending %u packets of various sizes:\n",
2353*061da546Spatrick                   num_packets);
2354*061da546Spatrick     strm.Flush();
2355*061da546Spatrick 
2356*061da546Spatrick     uint32_t result_idx = 0;
2357*061da546Spatrick     uint32_t send_size;
2358*061da546Spatrick     std::vector<duration<float>> packet_times;
2359*061da546Spatrick 
2360*061da546Spatrick     for (send_size = 0; send_size <= max_send;
2361*061da546Spatrick          send_size ? send_size *= 2 : send_size = 4) {
2362*061da546Spatrick       for (uint32_t recv_size = 0; recv_size <= max_recv;
2363*061da546Spatrick            recv_size ? recv_size *= 2 : recv_size = 4) {
2364*061da546Spatrick         MakeSpeedTestPacket(packet, send_size, recv_size);
2365*061da546Spatrick 
2366*061da546Spatrick         packet_times.clear();
2367*061da546Spatrick         // Test how long it takes to send 'num_packets' packets
2368*061da546Spatrick         const auto start_time = steady_clock::now();
2369*061da546Spatrick         for (i = 0; i < num_packets; ++i) {
2370*061da546Spatrick           const auto packet_start_time = steady_clock::now();
2371*061da546Spatrick           StringExtractorGDBRemote response;
2372*061da546Spatrick           SendPacketAndWaitForResponse(packet.GetString(), response, false);
2373*061da546Spatrick           const auto packet_end_time = steady_clock::now();
2374*061da546Spatrick           packet_times.push_back(packet_end_time - packet_start_time);
2375*061da546Spatrick         }
2376*061da546Spatrick         const auto end_time = steady_clock::now();
2377*061da546Spatrick         const auto total_time = end_time - start_time;
2378*061da546Spatrick 
2379*061da546Spatrick         float packets_per_second =
2380*061da546Spatrick             ((float)num_packets) / duration<float>(total_time).count();
2381*061da546Spatrick         auto average_per_packet = total_time / num_packets;
2382*061da546Spatrick         const duration<float> standard_deviation =
2383*061da546Spatrick             calculate_standard_deviation(packet_times);
2384*061da546Spatrick         if (json) {
2385*061da546Spatrick           strm.Format("{0}\n     {{\"send_size\" : {1,6}, \"recv_size\" : "
2386*061da546Spatrick                       "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2387*061da546Spatrick                       "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2388*061da546Spatrick                       result_idx > 0 ? "," : "", send_size, recv_size,
2389*061da546Spatrick                       total_time, standard_deviation);
2390*061da546Spatrick           ++result_idx;
2391*061da546Spatrick         } else {
2392*061da546Spatrick           strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2393*061da546Spatrick                       "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2394*061da546Spatrick                       "standard deviation of {5,10:ms+f6}\n",
2395*061da546Spatrick                       send_size, recv_size, duration<float>(total_time),
2396*061da546Spatrick                       packets_per_second, duration<float>(average_per_packet),
2397*061da546Spatrick                       standard_deviation);
2398*061da546Spatrick         }
2399*061da546Spatrick         strm.Flush();
2400*061da546Spatrick       }
2401*061da546Spatrick     }
2402*061da546Spatrick 
2403*061da546Spatrick     const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2404*061da546Spatrick     if (json)
2405*061da546Spatrick       strm.Printf("\n    ]\n  },\n  \"download_speed\" : {\n    \"byte_size\" "
2406*061da546Spatrick                   ": %" PRIu64 ",\n    \"results\" : [",
2407*061da546Spatrick                   recv_amount);
2408*061da546Spatrick     else
2409*061da546Spatrick       strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2410*061da546Spatrick                   "packet sizes:\n",
2411*061da546Spatrick                   k_recv_amount_mb);
2412*061da546Spatrick     strm.Flush();
2413*061da546Spatrick     send_size = 0;
2414*061da546Spatrick     result_idx = 0;
2415*061da546Spatrick     for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2416*061da546Spatrick       MakeSpeedTestPacket(packet, send_size, recv_size);
2417*061da546Spatrick 
2418*061da546Spatrick       // If we have a receive size, test how long it takes to receive 4MB of
2419*061da546Spatrick       // data
2420*061da546Spatrick       if (recv_size > 0) {
2421*061da546Spatrick         const auto start_time = steady_clock::now();
2422*061da546Spatrick         uint32_t bytes_read = 0;
2423*061da546Spatrick         uint32_t packet_count = 0;
2424*061da546Spatrick         while (bytes_read < recv_amount) {
2425*061da546Spatrick           StringExtractorGDBRemote response;
2426*061da546Spatrick           SendPacketAndWaitForResponse(packet.GetString(), response, false);
2427*061da546Spatrick           bytes_read += recv_size;
2428*061da546Spatrick           ++packet_count;
2429*061da546Spatrick         }
2430*061da546Spatrick         const auto end_time = steady_clock::now();
2431*061da546Spatrick         const auto total_time = end_time - start_time;
2432*061da546Spatrick         float mb_second = ((float)recv_amount) /
2433*061da546Spatrick                           duration<float>(total_time).count() /
2434*061da546Spatrick                           (1024.0 * 1024.0);
2435*061da546Spatrick         float packets_per_second =
2436*061da546Spatrick             ((float)packet_count) / duration<float>(total_time).count();
2437*061da546Spatrick         const auto average_per_packet = total_time / packet_count;
2438*061da546Spatrick 
2439*061da546Spatrick         if (json) {
2440*061da546Spatrick           strm.Format("{0}\n     {{\"send_size\" : {1,6}, \"recv_size\" : "
2441*061da546Spatrick                       "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2442*061da546Spatrick                       result_idx > 0 ? "," : "", send_size, recv_size,
2443*061da546Spatrick                       total_time);
2444*061da546Spatrick           ++result_idx;
2445*061da546Spatrick         } else {
2446*061da546Spatrick           strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2447*061da546Spatrick                       "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2448*061da546Spatrick                       "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2449*061da546Spatrick                       send_size, recv_size, packet_count, k_recv_amount_mb,
2450*061da546Spatrick                       duration<float>(total_time), mb_second,
2451*061da546Spatrick                       packets_per_second, duration<float>(average_per_packet));
2452*061da546Spatrick         }
2453*061da546Spatrick         strm.Flush();
2454*061da546Spatrick       }
2455*061da546Spatrick     }
2456*061da546Spatrick     if (json)
2457*061da546Spatrick       strm.Printf("\n    ]\n  }\n}\n");
2458*061da546Spatrick     else
2459*061da546Spatrick       strm.EOL();
2460*061da546Spatrick   }
2461*061da546Spatrick }
2462*061da546Spatrick 
2463*061da546Spatrick bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
2464*061da546Spatrick                                                        uint32_t recv_size) {
2465*061da546Spatrick   StreamString packet;
2466*061da546Spatrick   packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2467*061da546Spatrick   uint32_t bytes_left = send_size;
2468*061da546Spatrick   while (bytes_left > 0) {
2469*061da546Spatrick     if (bytes_left >= 26) {
2470*061da546Spatrick       packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2471*061da546Spatrick       bytes_left -= 26;
2472*061da546Spatrick     } else {
2473*061da546Spatrick       packet.Printf("%*.*s;", bytes_left, bytes_left,
2474*061da546Spatrick                     "abcdefghijklmnopqrstuvwxyz");
2475*061da546Spatrick       bytes_left = 0;
2476*061da546Spatrick     }
2477*061da546Spatrick   }
2478*061da546Spatrick 
2479*061da546Spatrick   StringExtractorGDBRemote response;
2480*061da546Spatrick   return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
2481*061da546Spatrick          PacketResult::Success;
2482*061da546Spatrick }
2483*061da546Spatrick 
2484*061da546Spatrick bool GDBRemoteCommunicationClient::LaunchGDBServer(
2485*061da546Spatrick     const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2486*061da546Spatrick     std::string &socket_name) {
2487*061da546Spatrick   pid = LLDB_INVALID_PROCESS_ID;
2488*061da546Spatrick   port = 0;
2489*061da546Spatrick   socket_name.clear();
2490*061da546Spatrick 
2491*061da546Spatrick   StringExtractorGDBRemote response;
2492*061da546Spatrick   StreamString stream;
2493*061da546Spatrick   stream.PutCString("qLaunchGDBServer;");
2494*061da546Spatrick   std::string hostname;
2495*061da546Spatrick   if (remote_accept_hostname && remote_accept_hostname[0])
2496*061da546Spatrick     hostname = remote_accept_hostname;
2497*061da546Spatrick   else {
2498*061da546Spatrick     if (HostInfo::GetHostname(hostname)) {
2499*061da546Spatrick       // Make the GDB server we launch only accept connections from this host
2500*061da546Spatrick       stream.Printf("host:%s;", hostname.c_str());
2501*061da546Spatrick     } else {
2502*061da546Spatrick       // Make the GDB server we launch accept connections from any host since
2503*061da546Spatrick       // we can't figure out the hostname
2504*061da546Spatrick       stream.Printf("host:*;");
2505*061da546Spatrick     }
2506*061da546Spatrick   }
2507*061da546Spatrick   // give the process a few seconds to startup
2508*061da546Spatrick   ScopedTimeout timeout(*this, seconds(10));
2509*061da546Spatrick 
2510*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2511*061da546Spatrick       PacketResult::Success) {
2512*061da546Spatrick     llvm::StringRef name;
2513*061da546Spatrick     llvm::StringRef value;
2514*061da546Spatrick     while (response.GetNameColonValue(name, value)) {
2515*061da546Spatrick       if (name.equals("port"))
2516*061da546Spatrick         value.getAsInteger(0, port);
2517*061da546Spatrick       else if (name.equals("pid"))
2518*061da546Spatrick         value.getAsInteger(0, pid);
2519*061da546Spatrick       else if (name.compare("socket_name") == 0) {
2520*061da546Spatrick         StringExtractor extractor(value);
2521*061da546Spatrick         extractor.GetHexByteString(socket_name);
2522*061da546Spatrick       }
2523*061da546Spatrick     }
2524*061da546Spatrick     return true;
2525*061da546Spatrick   }
2526*061da546Spatrick   return false;
2527*061da546Spatrick }
2528*061da546Spatrick 
2529*061da546Spatrick size_t GDBRemoteCommunicationClient::QueryGDBServer(
2530*061da546Spatrick     std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2531*061da546Spatrick   connection_urls.clear();
2532*061da546Spatrick 
2533*061da546Spatrick   StringExtractorGDBRemote response;
2534*061da546Spatrick   if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
2535*061da546Spatrick       PacketResult::Success)
2536*061da546Spatrick     return 0;
2537*061da546Spatrick 
2538*061da546Spatrick   StructuredData::ObjectSP data =
2539*061da546Spatrick       StructuredData::ParseJSON(response.GetStringRef());
2540*061da546Spatrick   if (!data)
2541*061da546Spatrick     return 0;
2542*061da546Spatrick 
2543*061da546Spatrick   StructuredData::Array *array = data->GetAsArray();
2544*061da546Spatrick   if (!array)
2545*061da546Spatrick     return 0;
2546*061da546Spatrick 
2547*061da546Spatrick   for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2548*061da546Spatrick     StructuredData::Dictionary *element = nullptr;
2549*061da546Spatrick     if (!array->GetItemAtIndexAsDictionary(i, element))
2550*061da546Spatrick       continue;
2551*061da546Spatrick 
2552*061da546Spatrick     uint16_t port = 0;
2553*061da546Spatrick     if (StructuredData::ObjectSP port_osp =
2554*061da546Spatrick             element->GetValueForKey(llvm::StringRef("port")))
2555*061da546Spatrick       port = port_osp->GetIntegerValue(0);
2556*061da546Spatrick 
2557*061da546Spatrick     std::string socket_name;
2558*061da546Spatrick     if (StructuredData::ObjectSP socket_name_osp =
2559*061da546Spatrick             element->GetValueForKey(llvm::StringRef("socket_name")))
2560*061da546Spatrick       socket_name = socket_name_osp->GetStringValue();
2561*061da546Spatrick 
2562*061da546Spatrick     if (port != 0 || !socket_name.empty())
2563*061da546Spatrick       connection_urls.emplace_back(port, socket_name);
2564*061da546Spatrick   }
2565*061da546Spatrick   return connection_urls.size();
2566*061da546Spatrick }
2567*061da546Spatrick 
2568*061da546Spatrick bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
2569*061da546Spatrick   StreamString stream;
2570*061da546Spatrick   stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
2571*061da546Spatrick 
2572*061da546Spatrick   StringExtractorGDBRemote response;
2573*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2574*061da546Spatrick       PacketResult::Success) {
2575*061da546Spatrick     if (response.IsOKResponse())
2576*061da546Spatrick       return true;
2577*061da546Spatrick   }
2578*061da546Spatrick   return false;
2579*061da546Spatrick }
2580*061da546Spatrick 
2581*061da546Spatrick bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
2582*061da546Spatrick   if (m_curr_tid == tid)
2583*061da546Spatrick     return true;
2584*061da546Spatrick 
2585*061da546Spatrick   char packet[32];
2586*061da546Spatrick   int packet_len;
2587*061da546Spatrick   if (tid == UINT64_MAX)
2588*061da546Spatrick     packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
2589*061da546Spatrick   else
2590*061da546Spatrick     packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
2591*061da546Spatrick   assert(packet_len + 1 < (int)sizeof(packet));
2592*061da546Spatrick   UNUSED_IF_ASSERT_DISABLED(packet_len);
2593*061da546Spatrick   StringExtractorGDBRemote response;
2594*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, false) ==
2595*061da546Spatrick       PacketResult::Success) {
2596*061da546Spatrick     if (response.IsOKResponse()) {
2597*061da546Spatrick       m_curr_tid = tid;
2598*061da546Spatrick       return true;
2599*061da546Spatrick     }
2600*061da546Spatrick 
2601*061da546Spatrick     /*
2602*061da546Spatrick      * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2603*061da546Spatrick      * Hg packet.
2604*061da546Spatrick      * The reply from '?' packet could be as simple as 'S05'. There is no packet
2605*061da546Spatrick      * which can
2606*061da546Spatrick      * give us pid and/or tid. Assume pid=tid=1 in such cases.
2607*061da546Spatrick     */
2608*061da546Spatrick     if (response.IsUnsupportedResponse() && IsConnected()) {
2609*061da546Spatrick       m_curr_tid = 1;
2610*061da546Spatrick       return true;
2611*061da546Spatrick     }
2612*061da546Spatrick   }
2613*061da546Spatrick   return false;
2614*061da546Spatrick }
2615*061da546Spatrick 
2616*061da546Spatrick bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
2617*061da546Spatrick   if (m_curr_tid_run == tid)
2618*061da546Spatrick     return true;
2619*061da546Spatrick 
2620*061da546Spatrick   char packet[32];
2621*061da546Spatrick   int packet_len;
2622*061da546Spatrick   if (tid == UINT64_MAX)
2623*061da546Spatrick     packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
2624*061da546Spatrick   else
2625*061da546Spatrick     packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
2626*061da546Spatrick 
2627*061da546Spatrick   assert(packet_len + 1 < (int)sizeof(packet));
2628*061da546Spatrick   UNUSED_IF_ASSERT_DISABLED(packet_len);
2629*061da546Spatrick   StringExtractorGDBRemote response;
2630*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, false) ==
2631*061da546Spatrick       PacketResult::Success) {
2632*061da546Spatrick     if (response.IsOKResponse()) {
2633*061da546Spatrick       m_curr_tid_run = tid;
2634*061da546Spatrick       return true;
2635*061da546Spatrick     }
2636*061da546Spatrick 
2637*061da546Spatrick     /*
2638*061da546Spatrick      * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2639*061da546Spatrick      * Hc packet.
2640*061da546Spatrick      * The reply from '?' packet could be as simple as 'S05'. There is no packet
2641*061da546Spatrick      * which can
2642*061da546Spatrick      * give us pid and/or tid. Assume pid=tid=1 in such cases.
2643*061da546Spatrick     */
2644*061da546Spatrick     if (response.IsUnsupportedResponse() && IsConnected()) {
2645*061da546Spatrick       m_curr_tid_run = 1;
2646*061da546Spatrick       return true;
2647*061da546Spatrick     }
2648*061da546Spatrick   }
2649*061da546Spatrick   return false;
2650*061da546Spatrick }
2651*061da546Spatrick 
2652*061da546Spatrick bool GDBRemoteCommunicationClient::GetStopReply(
2653*061da546Spatrick     StringExtractorGDBRemote &response) {
2654*061da546Spatrick   if (SendPacketAndWaitForResponse("?", response, false) ==
2655*061da546Spatrick       PacketResult::Success)
2656*061da546Spatrick     return response.IsNormalResponse();
2657*061da546Spatrick   return false;
2658*061da546Spatrick }
2659*061da546Spatrick 
2660*061da546Spatrick bool GDBRemoteCommunicationClient::GetThreadStopInfo(
2661*061da546Spatrick     lldb::tid_t tid, StringExtractorGDBRemote &response) {
2662*061da546Spatrick   if (m_supports_qThreadStopInfo) {
2663*061da546Spatrick     char packet[256];
2664*061da546Spatrick     int packet_len =
2665*061da546Spatrick         ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2666*061da546Spatrick     assert(packet_len < (int)sizeof(packet));
2667*061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(packet_len);
2668*061da546Spatrick     if (SendPacketAndWaitForResponse(packet, response, false) ==
2669*061da546Spatrick         PacketResult::Success) {
2670*061da546Spatrick       if (response.IsUnsupportedResponse())
2671*061da546Spatrick         m_supports_qThreadStopInfo = false;
2672*061da546Spatrick       else if (response.IsNormalResponse())
2673*061da546Spatrick         return true;
2674*061da546Spatrick       else
2675*061da546Spatrick         return false;
2676*061da546Spatrick     } else {
2677*061da546Spatrick       m_supports_qThreadStopInfo = false;
2678*061da546Spatrick     }
2679*061da546Spatrick   }
2680*061da546Spatrick   return false;
2681*061da546Spatrick }
2682*061da546Spatrick 
2683*061da546Spatrick uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2684*061da546Spatrick     GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
2685*061da546Spatrick   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
2686*061da546Spatrick   LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2687*061da546Spatrick             __FUNCTION__, insert ? "add" : "remove", addr);
2688*061da546Spatrick 
2689*061da546Spatrick   // Check if the stub is known not to support this breakpoint type
2690*061da546Spatrick   if (!SupportsGDBStoppointPacket(type))
2691*061da546Spatrick     return UINT8_MAX;
2692*061da546Spatrick   // Construct the breakpoint packet
2693*061da546Spatrick   char packet[64];
2694*061da546Spatrick   const int packet_len =
2695*061da546Spatrick       ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
2696*061da546Spatrick                  insert ? 'Z' : 'z', type, addr, length);
2697*061da546Spatrick   // Check we haven't overwritten the end of the packet buffer
2698*061da546Spatrick   assert(packet_len + 1 < (int)sizeof(packet));
2699*061da546Spatrick   UNUSED_IF_ASSERT_DISABLED(packet_len);
2700*061da546Spatrick   StringExtractorGDBRemote response;
2701*061da546Spatrick   // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2702*061da546Spatrick   // or "" (unsupported)
2703*061da546Spatrick   response.SetResponseValidatorToOKErrorNotSupported();
2704*061da546Spatrick   // Try to send the breakpoint packet, and check that it was correctly sent
2705*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, true) ==
2706*061da546Spatrick       PacketResult::Success) {
2707*061da546Spatrick     // Receive and OK packet when the breakpoint successfully placed
2708*061da546Spatrick     if (response.IsOKResponse())
2709*061da546Spatrick       return 0;
2710*061da546Spatrick 
2711*061da546Spatrick     // Status while setting breakpoint, send back specific error
2712*061da546Spatrick     if (response.IsErrorResponse())
2713*061da546Spatrick       return response.GetError();
2714*061da546Spatrick 
2715*061da546Spatrick     // Empty packet informs us that breakpoint is not supported
2716*061da546Spatrick     if (response.IsUnsupportedResponse()) {
2717*061da546Spatrick       // Disable this breakpoint type since it is unsupported
2718*061da546Spatrick       switch (type) {
2719*061da546Spatrick       case eBreakpointSoftware:
2720*061da546Spatrick         m_supports_z0 = false;
2721*061da546Spatrick         break;
2722*061da546Spatrick       case eBreakpointHardware:
2723*061da546Spatrick         m_supports_z1 = false;
2724*061da546Spatrick         break;
2725*061da546Spatrick       case eWatchpointWrite:
2726*061da546Spatrick         m_supports_z2 = false;
2727*061da546Spatrick         break;
2728*061da546Spatrick       case eWatchpointRead:
2729*061da546Spatrick         m_supports_z3 = false;
2730*061da546Spatrick         break;
2731*061da546Spatrick       case eWatchpointReadWrite:
2732*061da546Spatrick         m_supports_z4 = false;
2733*061da546Spatrick         break;
2734*061da546Spatrick       case eStoppointInvalid:
2735*061da546Spatrick         return UINT8_MAX;
2736*061da546Spatrick       }
2737*061da546Spatrick     }
2738*061da546Spatrick   }
2739*061da546Spatrick   // Signal generic failure
2740*061da546Spatrick   return UINT8_MAX;
2741*061da546Spatrick }
2742*061da546Spatrick 
2743*061da546Spatrick size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2744*061da546Spatrick     std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
2745*061da546Spatrick   thread_ids.clear();
2746*061da546Spatrick 
2747*061da546Spatrick   Lock lock(*this, false);
2748*061da546Spatrick   if (lock) {
2749*061da546Spatrick     sequence_mutex_unavailable = false;
2750*061da546Spatrick     StringExtractorGDBRemote response;
2751*061da546Spatrick 
2752*061da546Spatrick     PacketResult packet_result;
2753*061da546Spatrick     for (packet_result =
2754*061da546Spatrick              SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
2755*061da546Spatrick          packet_result == PacketResult::Success && response.IsNormalResponse();
2756*061da546Spatrick          packet_result =
2757*061da546Spatrick              SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
2758*061da546Spatrick       char ch = response.GetChar();
2759*061da546Spatrick       if (ch == 'l')
2760*061da546Spatrick         break;
2761*061da546Spatrick       if (ch == 'm') {
2762*061da546Spatrick         do {
2763*061da546Spatrick           tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
2764*061da546Spatrick 
2765*061da546Spatrick           if (tid != LLDB_INVALID_THREAD_ID) {
2766*061da546Spatrick             thread_ids.push_back(tid);
2767*061da546Spatrick           }
2768*061da546Spatrick           ch = response.GetChar(); // Skip the command separator
2769*061da546Spatrick         } while (ch == ',');       // Make sure we got a comma separator
2770*061da546Spatrick       }
2771*061da546Spatrick     }
2772*061da546Spatrick 
2773*061da546Spatrick     /*
2774*061da546Spatrick      * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2775*061da546Spatrick      * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2776*061da546Spatrick      * could
2777*061da546Spatrick      * be as simple as 'S05'. There is no packet which can give us pid and/or
2778*061da546Spatrick      * tid.
2779*061da546Spatrick      * Assume pid=tid=1 in such cases.
2780*061da546Spatrick     */
2781*061da546Spatrick     if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
2782*061da546Spatrick         thread_ids.size() == 0 && IsConnected()) {
2783*061da546Spatrick       thread_ids.push_back(1);
2784*061da546Spatrick     }
2785*061da546Spatrick   } else {
2786*061da546Spatrick #if !defined(LLDB_CONFIGURATION_DEBUG)
2787*061da546Spatrick     Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2788*061da546Spatrick                                                            GDBR_LOG_PACKETS));
2789*061da546Spatrick     LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending "
2790*061da546Spatrick                    "packet 'qfThreadInfo'");
2791*061da546Spatrick #endif
2792*061da546Spatrick     sequence_mutex_unavailable = true;
2793*061da546Spatrick   }
2794*061da546Spatrick   return thread_ids.size();
2795*061da546Spatrick }
2796*061da546Spatrick 
2797*061da546Spatrick lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
2798*061da546Spatrick   StringExtractorGDBRemote response;
2799*061da546Spatrick   if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
2800*061da546Spatrick           PacketResult::Success ||
2801*061da546Spatrick       !response.IsNormalResponse())
2802*061da546Spatrick     return LLDB_INVALID_ADDRESS;
2803*061da546Spatrick   return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2804*061da546Spatrick }
2805*061da546Spatrick 
2806*061da546Spatrick lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
2807*061da546Spatrick     const char *command, // Shouldn't be NULL
2808*061da546Spatrick     const FileSpec &
2809*061da546Spatrick         working_dir, // Pass empty FileSpec to use the current working directory
2810*061da546Spatrick     int *status_ptr, // Pass NULL if you don't want the process exit status
2811*061da546Spatrick     int *signo_ptr,  // Pass NULL if you don't want the signal that caused the
2812*061da546Spatrick                      // process to exit
2813*061da546Spatrick     std::string
2814*061da546Spatrick         *command_output, // Pass NULL if you don't want the command output
2815*061da546Spatrick     const Timeout<std::micro> &timeout) {
2816*061da546Spatrick   lldb_private::StreamString stream;
2817*061da546Spatrick   stream.PutCString("qPlatform_shell:");
2818*061da546Spatrick   stream.PutBytesAsRawHex8(command, strlen(command));
2819*061da546Spatrick   stream.PutChar(',');
2820*061da546Spatrick   uint32_t timeout_sec = UINT32_MAX;
2821*061da546Spatrick   if (timeout) {
2822*061da546Spatrick     // TODO: Use chrono version of std::ceil once c++17 is available.
2823*061da546Spatrick     timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2824*061da546Spatrick   }
2825*061da546Spatrick   stream.PutHex32(timeout_sec);
2826*061da546Spatrick   if (working_dir) {
2827*061da546Spatrick     std::string path{working_dir.GetPath(false)};
2828*061da546Spatrick     stream.PutChar(',');
2829*061da546Spatrick     stream.PutStringAsRawHex8(path);
2830*061da546Spatrick   }
2831*061da546Spatrick   StringExtractorGDBRemote response;
2832*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2833*061da546Spatrick       PacketResult::Success) {
2834*061da546Spatrick     if (response.GetChar() != 'F')
2835*061da546Spatrick       return Status("malformed reply");
2836*061da546Spatrick     if (response.GetChar() != ',')
2837*061da546Spatrick       return Status("malformed reply");
2838*061da546Spatrick     uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2839*061da546Spatrick     if (exitcode == UINT32_MAX)
2840*061da546Spatrick       return Status("unable to run remote process");
2841*061da546Spatrick     else if (status_ptr)
2842*061da546Spatrick       *status_ptr = exitcode;
2843*061da546Spatrick     if (response.GetChar() != ',')
2844*061da546Spatrick       return Status("malformed reply");
2845*061da546Spatrick     uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2846*061da546Spatrick     if (signo_ptr)
2847*061da546Spatrick       *signo_ptr = signo;
2848*061da546Spatrick     if (response.GetChar() != ',')
2849*061da546Spatrick       return Status("malformed reply");
2850*061da546Spatrick     std::string output;
2851*061da546Spatrick     response.GetEscapedBinaryData(output);
2852*061da546Spatrick     if (command_output)
2853*061da546Spatrick       command_output->assign(output);
2854*061da546Spatrick     return Status();
2855*061da546Spatrick   }
2856*061da546Spatrick   return Status("unable to send packet");
2857*061da546Spatrick }
2858*061da546Spatrick 
2859*061da546Spatrick Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
2860*061da546Spatrick                                                    uint32_t file_permissions) {
2861*061da546Spatrick   std::string path{file_spec.GetPath(false)};
2862*061da546Spatrick   lldb_private::StreamString stream;
2863*061da546Spatrick   stream.PutCString("qPlatform_mkdir:");
2864*061da546Spatrick   stream.PutHex32(file_permissions);
2865*061da546Spatrick   stream.PutChar(',');
2866*061da546Spatrick   stream.PutStringAsRawHex8(path);
2867*061da546Spatrick   llvm::StringRef packet = stream.GetString();
2868*061da546Spatrick   StringExtractorGDBRemote response;
2869*061da546Spatrick 
2870*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, false) !=
2871*061da546Spatrick       PacketResult::Success)
2872*061da546Spatrick     return Status("failed to send '%s' packet", packet.str().c_str());
2873*061da546Spatrick 
2874*061da546Spatrick   if (response.GetChar() != 'F')
2875*061da546Spatrick     return Status("invalid response to '%s' packet", packet.str().c_str());
2876*061da546Spatrick 
2877*061da546Spatrick   return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
2878*061da546Spatrick }
2879*061da546Spatrick 
2880*061da546Spatrick Status
2881*061da546Spatrick GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
2882*061da546Spatrick                                                  uint32_t file_permissions) {
2883*061da546Spatrick   std::string path{file_spec.GetPath(false)};
2884*061da546Spatrick   lldb_private::StreamString stream;
2885*061da546Spatrick   stream.PutCString("qPlatform_chmod:");
2886*061da546Spatrick   stream.PutHex32(file_permissions);
2887*061da546Spatrick   stream.PutChar(',');
2888*061da546Spatrick   stream.PutStringAsRawHex8(path);
2889*061da546Spatrick   llvm::StringRef packet = stream.GetString();
2890*061da546Spatrick   StringExtractorGDBRemote response;
2891*061da546Spatrick 
2892*061da546Spatrick   if (SendPacketAndWaitForResponse(packet, response, false) !=
2893*061da546Spatrick       PacketResult::Success)
2894*061da546Spatrick     return Status("failed to send '%s' packet", stream.GetData());
2895*061da546Spatrick 
2896*061da546Spatrick   if (response.GetChar() != 'F')
2897*061da546Spatrick     return Status("invalid response to '%s' packet", stream.GetData());
2898*061da546Spatrick 
2899*061da546Spatrick   return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
2900*061da546Spatrick }
2901*061da546Spatrick 
2902*061da546Spatrick static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
2903*061da546Spatrick                                           uint64_t fail_result, Status &error) {
2904*061da546Spatrick   response.SetFilePos(0);
2905*061da546Spatrick   if (response.GetChar() != 'F')
2906*061da546Spatrick     return fail_result;
2907*061da546Spatrick   int32_t result = response.GetS32(-2);
2908*061da546Spatrick   if (result == -2)
2909*061da546Spatrick     return fail_result;
2910*061da546Spatrick   if (response.GetChar() == ',') {
2911*061da546Spatrick     int result_errno = response.GetS32(-2);
2912*061da546Spatrick     if (result_errno != -2)
2913*061da546Spatrick       error.SetError(result_errno, eErrorTypePOSIX);
2914*061da546Spatrick     else
2915*061da546Spatrick       error.SetError(-1, eErrorTypeGeneric);
2916*061da546Spatrick   } else
2917*061da546Spatrick     error.Clear();
2918*061da546Spatrick   return result;
2919*061da546Spatrick }
2920*061da546Spatrick lldb::user_id_t
2921*061da546Spatrick GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
2922*061da546Spatrick                                        File::OpenOptions flags, mode_t mode,
2923*061da546Spatrick                                        Status &error) {
2924*061da546Spatrick   std::string path(file_spec.GetPath(false));
2925*061da546Spatrick   lldb_private::StreamString stream;
2926*061da546Spatrick   stream.PutCString("vFile:open:");
2927*061da546Spatrick   if (path.empty())
2928*061da546Spatrick     return UINT64_MAX;
2929*061da546Spatrick   stream.PutStringAsRawHex8(path);
2930*061da546Spatrick   stream.PutChar(',');
2931*061da546Spatrick   stream.PutHex32(flags);
2932*061da546Spatrick   stream.PutChar(',');
2933*061da546Spatrick   stream.PutHex32(mode);
2934*061da546Spatrick   StringExtractorGDBRemote response;
2935*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2936*061da546Spatrick       PacketResult::Success) {
2937*061da546Spatrick     return ParseHostIOPacketResponse(response, UINT64_MAX, error);
2938*061da546Spatrick   }
2939*061da546Spatrick   return UINT64_MAX;
2940*061da546Spatrick }
2941*061da546Spatrick 
2942*061da546Spatrick bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
2943*061da546Spatrick                                              Status &error) {
2944*061da546Spatrick   lldb_private::StreamString stream;
2945*061da546Spatrick   stream.Printf("vFile:close:%i", (int)fd);
2946*061da546Spatrick   StringExtractorGDBRemote response;
2947*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2948*061da546Spatrick       PacketResult::Success) {
2949*061da546Spatrick     return ParseHostIOPacketResponse(response, -1, error) == 0;
2950*061da546Spatrick   }
2951*061da546Spatrick   return false;
2952*061da546Spatrick }
2953*061da546Spatrick 
2954*061da546Spatrick // Extension of host I/O packets to get the file size.
2955*061da546Spatrick lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
2956*061da546Spatrick     const lldb_private::FileSpec &file_spec) {
2957*061da546Spatrick   std::string path(file_spec.GetPath(false));
2958*061da546Spatrick   lldb_private::StreamString stream;
2959*061da546Spatrick   stream.PutCString("vFile:size:");
2960*061da546Spatrick   stream.PutStringAsRawHex8(path);
2961*061da546Spatrick   StringExtractorGDBRemote response;
2962*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2963*061da546Spatrick       PacketResult::Success) {
2964*061da546Spatrick     if (response.GetChar() != 'F')
2965*061da546Spatrick       return UINT64_MAX;
2966*061da546Spatrick     uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2967*061da546Spatrick     return retcode;
2968*061da546Spatrick   }
2969*061da546Spatrick   return UINT64_MAX;
2970*061da546Spatrick }
2971*061da546Spatrick 
2972*061da546Spatrick Status
2973*061da546Spatrick GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
2974*061da546Spatrick                                                  uint32_t &file_permissions) {
2975*061da546Spatrick   std::string path{file_spec.GetPath(false)};
2976*061da546Spatrick   Status error;
2977*061da546Spatrick   lldb_private::StreamString stream;
2978*061da546Spatrick   stream.PutCString("vFile:mode:");
2979*061da546Spatrick   stream.PutStringAsRawHex8(path);
2980*061da546Spatrick   StringExtractorGDBRemote response;
2981*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
2982*061da546Spatrick       PacketResult::Success) {
2983*061da546Spatrick     if (response.GetChar() != 'F') {
2984*061da546Spatrick       error.SetErrorStringWithFormat("invalid response to '%s' packet",
2985*061da546Spatrick                                      stream.GetData());
2986*061da546Spatrick     } else {
2987*061da546Spatrick       const uint32_t mode = response.GetS32(-1);
2988*061da546Spatrick       if (static_cast<int32_t>(mode) == -1) {
2989*061da546Spatrick         if (response.GetChar() == ',') {
2990*061da546Spatrick           int response_errno = response.GetS32(-1);
2991*061da546Spatrick           if (response_errno > 0)
2992*061da546Spatrick             error.SetError(response_errno, lldb::eErrorTypePOSIX);
2993*061da546Spatrick           else
2994*061da546Spatrick             error.SetErrorToGenericError();
2995*061da546Spatrick         } else
2996*061da546Spatrick           error.SetErrorToGenericError();
2997*061da546Spatrick       } else {
2998*061da546Spatrick         file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
2999*061da546Spatrick       }
3000*061da546Spatrick     }
3001*061da546Spatrick   } else {
3002*061da546Spatrick     error.SetErrorStringWithFormat("failed to send '%s' packet",
3003*061da546Spatrick                                    stream.GetData());
3004*061da546Spatrick   }
3005*061da546Spatrick   return error;
3006*061da546Spatrick }
3007*061da546Spatrick 
3008*061da546Spatrick uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
3009*061da546Spatrick                                                 uint64_t offset, void *dst,
3010*061da546Spatrick                                                 uint64_t dst_len,
3011*061da546Spatrick                                                 Status &error) {
3012*061da546Spatrick   lldb_private::StreamString stream;
3013*061da546Spatrick   stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
3014*061da546Spatrick                 offset);
3015*061da546Spatrick   StringExtractorGDBRemote response;
3016*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
3017*061da546Spatrick       PacketResult::Success) {
3018*061da546Spatrick     if (response.GetChar() != 'F')
3019*061da546Spatrick       return 0;
3020*061da546Spatrick     uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
3021*061da546Spatrick     if (retcode == UINT32_MAX)
3022*061da546Spatrick       return retcode;
3023*061da546Spatrick     const char next = (response.Peek() ? *response.Peek() : 0);
3024*061da546Spatrick     if (next == ',')
3025*061da546Spatrick       return 0;
3026*061da546Spatrick     if (next == ';') {
3027*061da546Spatrick       response.GetChar(); // skip the semicolon
3028*061da546Spatrick       std::string buffer;
3029*061da546Spatrick       if (response.GetEscapedBinaryData(buffer)) {
3030*061da546Spatrick         const uint64_t data_to_write =
3031*061da546Spatrick             std::min<uint64_t>(dst_len, buffer.size());
3032*061da546Spatrick         if (data_to_write > 0)
3033*061da546Spatrick           memcpy(dst, &buffer[0], data_to_write);
3034*061da546Spatrick         return data_to_write;
3035*061da546Spatrick       }
3036*061da546Spatrick     }
3037*061da546Spatrick   }
3038*061da546Spatrick   return 0;
3039*061da546Spatrick }
3040*061da546Spatrick 
3041*061da546Spatrick uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
3042*061da546Spatrick                                                  uint64_t offset,
3043*061da546Spatrick                                                  const void *src,
3044*061da546Spatrick                                                  uint64_t src_len,
3045*061da546Spatrick                                                  Status &error) {
3046*061da546Spatrick   lldb_private::StreamGDBRemote stream;
3047*061da546Spatrick   stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3048*061da546Spatrick   stream.PutEscapedBytes(src, src_len);
3049*061da546Spatrick   StringExtractorGDBRemote response;
3050*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
3051*061da546Spatrick       PacketResult::Success) {
3052*061da546Spatrick     if (response.GetChar() != 'F') {
3053*061da546Spatrick       error.SetErrorStringWithFormat("write file failed");
3054*061da546Spatrick       return 0;
3055*061da546Spatrick     }
3056*061da546Spatrick     uint64_t bytes_written = response.GetU64(UINT64_MAX);
3057*061da546Spatrick     if (bytes_written == UINT64_MAX) {
3058*061da546Spatrick       error.SetErrorToGenericError();
3059*061da546Spatrick       if (response.GetChar() == ',') {
3060*061da546Spatrick         int response_errno = response.GetS32(-1);
3061*061da546Spatrick         if (response_errno > 0)
3062*061da546Spatrick           error.SetError(response_errno, lldb::eErrorTypePOSIX);
3063*061da546Spatrick       }
3064*061da546Spatrick       return 0;
3065*061da546Spatrick     }
3066*061da546Spatrick     return bytes_written;
3067*061da546Spatrick   } else {
3068*061da546Spatrick     error.SetErrorString("failed to send vFile:pwrite packet");
3069*061da546Spatrick   }
3070*061da546Spatrick   return 0;
3071*061da546Spatrick }
3072*061da546Spatrick 
3073*061da546Spatrick Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
3074*061da546Spatrick                                                    const FileSpec &dst) {
3075*061da546Spatrick   std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
3076*061da546Spatrick   Status error;
3077*061da546Spatrick   lldb_private::StreamGDBRemote stream;
3078*061da546Spatrick   stream.PutCString("vFile:symlink:");
3079*061da546Spatrick   // the unix symlink() command reverses its parameters where the dst if first,
3080*061da546Spatrick   // so we follow suit here
3081*061da546Spatrick   stream.PutStringAsRawHex8(dst_path);
3082*061da546Spatrick   stream.PutChar(',');
3083*061da546Spatrick   stream.PutStringAsRawHex8(src_path);
3084*061da546Spatrick   StringExtractorGDBRemote response;
3085*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
3086*061da546Spatrick       PacketResult::Success) {
3087*061da546Spatrick     if (response.GetChar() == 'F') {
3088*061da546Spatrick       uint32_t result = response.GetU32(UINT32_MAX);
3089*061da546Spatrick       if (result != 0) {
3090*061da546Spatrick         error.SetErrorToGenericError();
3091*061da546Spatrick         if (response.GetChar() == ',') {
3092*061da546Spatrick           int response_errno = response.GetS32(-1);
3093*061da546Spatrick           if (response_errno > 0)
3094*061da546Spatrick             error.SetError(response_errno, lldb::eErrorTypePOSIX);
3095*061da546Spatrick         }
3096*061da546Spatrick       }
3097*061da546Spatrick     } else {
3098*061da546Spatrick       // Should have returned with 'F<result>[,<errno>]'
3099*061da546Spatrick       error.SetErrorStringWithFormat("symlink failed");
3100*061da546Spatrick     }
3101*061da546Spatrick   } else {
3102*061da546Spatrick     error.SetErrorString("failed to send vFile:symlink packet");
3103*061da546Spatrick   }
3104*061da546Spatrick   return error;
3105*061da546Spatrick }
3106*061da546Spatrick 
3107*061da546Spatrick Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
3108*061da546Spatrick   std::string path{file_spec.GetPath(false)};
3109*061da546Spatrick   Status error;
3110*061da546Spatrick   lldb_private::StreamGDBRemote stream;
3111*061da546Spatrick   stream.PutCString("vFile:unlink:");
3112*061da546Spatrick   // the unix symlink() command reverses its parameters where the dst if first,
3113*061da546Spatrick   // so we follow suit here
3114*061da546Spatrick   stream.PutStringAsRawHex8(path);
3115*061da546Spatrick   StringExtractorGDBRemote response;
3116*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
3117*061da546Spatrick       PacketResult::Success) {
3118*061da546Spatrick     if (response.GetChar() == 'F') {
3119*061da546Spatrick       uint32_t result = response.GetU32(UINT32_MAX);
3120*061da546Spatrick       if (result != 0) {
3121*061da546Spatrick         error.SetErrorToGenericError();
3122*061da546Spatrick         if (response.GetChar() == ',') {
3123*061da546Spatrick           int response_errno = response.GetS32(-1);
3124*061da546Spatrick           if (response_errno > 0)
3125*061da546Spatrick             error.SetError(response_errno, lldb::eErrorTypePOSIX);
3126*061da546Spatrick         }
3127*061da546Spatrick       }
3128*061da546Spatrick     } else {
3129*061da546Spatrick       // Should have returned with 'F<result>[,<errno>]'
3130*061da546Spatrick       error.SetErrorStringWithFormat("unlink failed");
3131*061da546Spatrick     }
3132*061da546Spatrick   } else {
3133*061da546Spatrick     error.SetErrorString("failed to send vFile:unlink packet");
3134*061da546Spatrick   }
3135*061da546Spatrick   return error;
3136*061da546Spatrick }
3137*061da546Spatrick 
3138*061da546Spatrick // Extension of host I/O packets to get whether a file exists.
3139*061da546Spatrick bool GDBRemoteCommunicationClient::GetFileExists(
3140*061da546Spatrick     const lldb_private::FileSpec &file_spec) {
3141*061da546Spatrick   std::string path(file_spec.GetPath(false));
3142*061da546Spatrick   lldb_private::StreamString stream;
3143*061da546Spatrick   stream.PutCString("vFile:exists:");
3144*061da546Spatrick   stream.PutStringAsRawHex8(path);
3145*061da546Spatrick   StringExtractorGDBRemote response;
3146*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
3147*061da546Spatrick       PacketResult::Success) {
3148*061da546Spatrick     if (response.GetChar() != 'F')
3149*061da546Spatrick       return false;
3150*061da546Spatrick     if (response.GetChar() != ',')
3151*061da546Spatrick       return false;
3152*061da546Spatrick     bool retcode = (response.GetChar() != '0');
3153*061da546Spatrick     return retcode;
3154*061da546Spatrick   }
3155*061da546Spatrick   return false;
3156*061da546Spatrick }
3157*061da546Spatrick 
3158*061da546Spatrick bool GDBRemoteCommunicationClient::CalculateMD5(
3159*061da546Spatrick     const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
3160*061da546Spatrick   std::string path(file_spec.GetPath(false));
3161*061da546Spatrick   lldb_private::StreamString stream;
3162*061da546Spatrick   stream.PutCString("vFile:MD5:");
3163*061da546Spatrick   stream.PutStringAsRawHex8(path);
3164*061da546Spatrick   StringExtractorGDBRemote response;
3165*061da546Spatrick   if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
3166*061da546Spatrick       PacketResult::Success) {
3167*061da546Spatrick     if (response.GetChar() != 'F')
3168*061da546Spatrick       return false;
3169*061da546Spatrick     if (response.GetChar() != ',')
3170*061da546Spatrick       return false;
3171*061da546Spatrick     if (response.Peek() && *response.Peek() == 'x')
3172*061da546Spatrick       return false;
3173*061da546Spatrick     low = response.GetHexMaxU64(false, UINT64_MAX);
3174*061da546Spatrick     high = response.GetHexMaxU64(false, UINT64_MAX);
3175*061da546Spatrick     return true;
3176*061da546Spatrick   }
3177*061da546Spatrick   return false;
3178*061da546Spatrick }
3179*061da546Spatrick 
3180*061da546Spatrick bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
3181*061da546Spatrick   // Some targets have issues with g/G packets and we need to avoid using them
3182*061da546Spatrick   if (m_avoid_g_packets == eLazyBoolCalculate) {
3183*061da546Spatrick     if (process) {
3184*061da546Spatrick       m_avoid_g_packets = eLazyBoolNo;
3185*061da546Spatrick       const ArchSpec &arch = process->GetTarget().GetArchitecture();
3186*061da546Spatrick       if (arch.IsValid() &&
3187*061da546Spatrick           arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3188*061da546Spatrick           arch.GetTriple().getOS() == llvm::Triple::IOS &&
3189*061da546Spatrick           (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
3190*061da546Spatrick            arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3191*061da546Spatrick         m_avoid_g_packets = eLazyBoolYes;
3192*061da546Spatrick         uint32_t gdb_server_version = GetGDBServerProgramVersion();
3193*061da546Spatrick         if (gdb_server_version != 0) {
3194*061da546Spatrick           const char *gdb_server_name = GetGDBServerProgramName();
3195*061da546Spatrick           if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3196*061da546Spatrick             if (gdb_server_version >= 310)
3197*061da546Spatrick               m_avoid_g_packets = eLazyBoolNo;
3198*061da546Spatrick           }
3199*061da546Spatrick         }
3200*061da546Spatrick       }
3201*061da546Spatrick     }
3202*061da546Spatrick   }
3203*061da546Spatrick   return m_avoid_g_packets == eLazyBoolYes;
3204*061da546Spatrick }
3205*061da546Spatrick 
3206*061da546Spatrick DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
3207*061da546Spatrick                                                         uint32_t reg) {
3208*061da546Spatrick   StreamString payload;
3209*061da546Spatrick   payload.Printf("p%x", reg);
3210*061da546Spatrick   StringExtractorGDBRemote response;
3211*061da546Spatrick   if (SendThreadSpecificPacketAndWaitForResponse(
3212*061da546Spatrick           tid, std::move(payload), response, false) != PacketResult::Success ||
3213*061da546Spatrick       !response.IsNormalResponse())
3214*061da546Spatrick     return nullptr;
3215*061da546Spatrick 
3216*061da546Spatrick   DataBufferSP buffer_sp(
3217*061da546Spatrick       new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3218*061da546Spatrick   response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3219*061da546Spatrick   return buffer_sp;
3220*061da546Spatrick }
3221*061da546Spatrick 
3222*061da546Spatrick DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
3223*061da546Spatrick   StreamString payload;
3224*061da546Spatrick   payload.PutChar('g');
3225*061da546Spatrick   StringExtractorGDBRemote response;
3226*061da546Spatrick   if (SendThreadSpecificPacketAndWaitForResponse(
3227*061da546Spatrick           tid, std::move(payload), response, false) != PacketResult::Success ||
3228*061da546Spatrick       !response.IsNormalResponse())
3229*061da546Spatrick     return nullptr;
3230*061da546Spatrick 
3231*061da546Spatrick   DataBufferSP buffer_sp(
3232*061da546Spatrick       new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3233*061da546Spatrick   response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3234*061da546Spatrick   return buffer_sp;
3235*061da546Spatrick }
3236*061da546Spatrick 
3237*061da546Spatrick bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
3238*061da546Spatrick                                                  uint32_t reg_num,
3239*061da546Spatrick                                                  llvm::ArrayRef<uint8_t> data) {
3240*061da546Spatrick   StreamString payload;
3241*061da546Spatrick   payload.Printf("P%x=", reg_num);
3242*061da546Spatrick   payload.PutBytesAsRawHex8(data.data(), data.size(),
3243*061da546Spatrick                             endian::InlHostByteOrder(),
3244*061da546Spatrick                             endian::InlHostByteOrder());
3245*061da546Spatrick   StringExtractorGDBRemote response;
3246*061da546Spatrick   return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3247*061da546Spatrick                                                     response, false) ==
3248*061da546Spatrick              PacketResult::Success &&
3249*061da546Spatrick          response.IsOKResponse();
3250*061da546Spatrick }
3251*061da546Spatrick 
3252*061da546Spatrick bool GDBRemoteCommunicationClient::WriteAllRegisters(
3253*061da546Spatrick     lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3254*061da546Spatrick   StreamString payload;
3255*061da546Spatrick   payload.PutChar('G');
3256*061da546Spatrick   payload.PutBytesAsRawHex8(data.data(), data.size(),
3257*061da546Spatrick                             endian::InlHostByteOrder(),
3258*061da546Spatrick                             endian::InlHostByteOrder());
3259*061da546Spatrick   StringExtractorGDBRemote response;
3260*061da546Spatrick   return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
3261*061da546Spatrick                                                     response, false) ==
3262*061da546Spatrick              PacketResult::Success &&
3263*061da546Spatrick          response.IsOKResponse();
3264*061da546Spatrick }
3265*061da546Spatrick 
3266*061da546Spatrick bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
3267*061da546Spatrick                                                      uint32_t &save_id) {
3268*061da546Spatrick   save_id = 0; // Set to invalid save ID
3269*061da546Spatrick   if (m_supports_QSaveRegisterState == eLazyBoolNo)
3270*061da546Spatrick     return false;
3271*061da546Spatrick 
3272*061da546Spatrick   m_supports_QSaveRegisterState = eLazyBoolYes;
3273*061da546Spatrick   StreamString payload;
3274*061da546Spatrick   payload.PutCString("QSaveRegisterState");
3275*061da546Spatrick   StringExtractorGDBRemote response;
3276*061da546Spatrick   if (SendThreadSpecificPacketAndWaitForResponse(
3277*061da546Spatrick           tid, std::move(payload), response, false) != PacketResult::Success)
3278*061da546Spatrick     return false;
3279*061da546Spatrick 
3280*061da546Spatrick   if (response.IsUnsupportedResponse())
3281*061da546Spatrick     m_supports_QSaveRegisterState = eLazyBoolNo;
3282*061da546Spatrick 
3283*061da546Spatrick   const uint32_t response_save_id = response.GetU32(0);
3284*061da546Spatrick   if (response_save_id == 0)
3285*061da546Spatrick     return false;
3286*061da546Spatrick 
3287*061da546Spatrick   save_id = response_save_id;
3288*061da546Spatrick   return true;
3289*061da546Spatrick }
3290*061da546Spatrick 
3291*061da546Spatrick bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
3292*061da546Spatrick                                                         uint32_t save_id) {
3293*061da546Spatrick   // We use the "m_supports_QSaveRegisterState" variable here because the
3294*061da546Spatrick   // QSaveRegisterState and QRestoreRegisterState packets must both be
3295*061da546Spatrick   // supported in order to be useful
3296*061da546Spatrick   if (m_supports_QSaveRegisterState == eLazyBoolNo)
3297*061da546Spatrick     return false;
3298*061da546Spatrick 
3299*061da546Spatrick   StreamString payload;
3300*061da546Spatrick   payload.Printf("QRestoreRegisterState:%u", save_id);
3301*061da546Spatrick   StringExtractorGDBRemote response;
3302*061da546Spatrick   if (SendThreadSpecificPacketAndWaitForResponse(
3303*061da546Spatrick           tid, std::move(payload), response, false) != PacketResult::Success)
3304*061da546Spatrick     return false;
3305*061da546Spatrick 
3306*061da546Spatrick   if (response.IsOKResponse())
3307*061da546Spatrick     return true;
3308*061da546Spatrick 
3309*061da546Spatrick   if (response.IsUnsupportedResponse())
3310*061da546Spatrick     m_supports_QSaveRegisterState = eLazyBoolNo;
3311*061da546Spatrick   return false;
3312*061da546Spatrick }
3313*061da546Spatrick 
3314*061da546Spatrick bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
3315*061da546Spatrick   if (!GetSyncThreadStateSupported())
3316*061da546Spatrick     return false;
3317*061da546Spatrick 
3318*061da546Spatrick   StreamString packet;
3319*061da546Spatrick   StringExtractorGDBRemote response;
3320*061da546Spatrick   packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3321*061da546Spatrick   return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
3322*061da546Spatrick              GDBRemoteCommunication::PacketResult::Success &&
3323*061da546Spatrick          response.IsOKResponse();
3324*061da546Spatrick }
3325*061da546Spatrick 
3326*061da546Spatrick lldb::user_id_t
3327*061da546Spatrick GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
3328*061da546Spatrick                                                    Status &error) {
3329*061da546Spatrick   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3330*061da546Spatrick   lldb::user_id_t ret_uid = LLDB_INVALID_UID;
3331*061da546Spatrick 
3332*061da546Spatrick   StreamGDBRemote escaped_packet;
3333*061da546Spatrick   escaped_packet.PutCString("jTraceStart:");
3334*061da546Spatrick 
3335*061da546Spatrick   StructuredData::Dictionary json_packet;
3336*061da546Spatrick   json_packet.AddIntegerItem("type", options.getType());
3337*061da546Spatrick   json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
3338*061da546Spatrick   json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
3339*061da546Spatrick 
3340*061da546Spatrick   if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3341*061da546Spatrick     json_packet.AddIntegerItem("threadid", options.getThreadID());
3342*061da546Spatrick 
3343*061da546Spatrick   StructuredData::DictionarySP custom_params = options.getTraceParams();
3344*061da546Spatrick   if (custom_params)
3345*061da546Spatrick     json_packet.AddItem("params", custom_params);
3346*061da546Spatrick 
3347*061da546Spatrick   StreamString json_string;
3348*061da546Spatrick   json_packet.Dump(json_string, false);
3349*061da546Spatrick   escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3350*061da546Spatrick 
3351*061da546Spatrick   StringExtractorGDBRemote response;
3352*061da546Spatrick   if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3353*061da546Spatrick                                    true) ==
3354*061da546Spatrick       GDBRemoteCommunication::PacketResult::Success) {
3355*061da546Spatrick     if (!response.IsNormalResponse()) {
3356*061da546Spatrick       error = response.GetStatus();
3357*061da546Spatrick       LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
3358*061da546Spatrick     } else {
3359*061da546Spatrick       ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
3360*061da546Spatrick     }
3361*061da546Spatrick   } else {
3362*061da546Spatrick     LLDB_LOG(log, "failed to send packet");
3363*061da546Spatrick     error.SetErrorStringWithFormat("failed to send packet: '%s'",
3364*061da546Spatrick                                    escaped_packet.GetData());
3365*061da546Spatrick   }
3366*061da546Spatrick   return ret_uid;
3367*061da546Spatrick }
3368*061da546Spatrick 
3369*061da546Spatrick Status
3370*061da546Spatrick GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
3371*061da546Spatrick                                                   lldb::tid_t thread_id) {
3372*061da546Spatrick   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3373*061da546Spatrick   StringExtractorGDBRemote response;
3374*061da546Spatrick   Status error;
3375*061da546Spatrick 
3376*061da546Spatrick   StructuredData::Dictionary json_packet;
3377*061da546Spatrick   StreamGDBRemote escaped_packet;
3378*061da546Spatrick   StreamString json_string;
3379*061da546Spatrick   escaped_packet.PutCString("jTraceStop:");
3380*061da546Spatrick 
3381*061da546Spatrick   json_packet.AddIntegerItem("traceid", uid);
3382*061da546Spatrick 
3383*061da546Spatrick   if (thread_id != LLDB_INVALID_THREAD_ID)
3384*061da546Spatrick     json_packet.AddIntegerItem("threadid", thread_id);
3385*061da546Spatrick 
3386*061da546Spatrick   json_packet.Dump(json_string, false);
3387*061da546Spatrick 
3388*061da546Spatrick   escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3389*061da546Spatrick 
3390*061da546Spatrick   if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3391*061da546Spatrick                                    true) ==
3392*061da546Spatrick       GDBRemoteCommunication::PacketResult::Success) {
3393*061da546Spatrick     if (!response.IsOKResponse()) {
3394*061da546Spatrick       error = response.GetStatus();
3395*061da546Spatrick       LLDB_LOG(log, "stop tracing failed");
3396*061da546Spatrick     }
3397*061da546Spatrick   } else {
3398*061da546Spatrick     LLDB_LOG(log, "failed to send packet");
3399*061da546Spatrick     error.SetErrorStringWithFormat(
3400*061da546Spatrick         "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
3401*061da546Spatrick         response.GetError());
3402*061da546Spatrick   }
3403*061da546Spatrick   return error;
3404*061da546Spatrick }
3405*061da546Spatrick 
3406*061da546Spatrick Status GDBRemoteCommunicationClient::SendGetDataPacket(
3407*061da546Spatrick     lldb::user_id_t uid, lldb::tid_t thread_id,
3408*061da546Spatrick     llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
3409*061da546Spatrick 
3410*061da546Spatrick   StreamGDBRemote escaped_packet;
3411*061da546Spatrick   escaped_packet.PutCString("jTraceBufferRead:");
3412*061da546Spatrick   return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3413*061da546Spatrick }
3414*061da546Spatrick 
3415*061da546Spatrick Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
3416*061da546Spatrick     lldb::user_id_t uid, lldb::tid_t thread_id,
3417*061da546Spatrick     llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
3418*061da546Spatrick 
3419*061da546Spatrick   StreamGDBRemote escaped_packet;
3420*061da546Spatrick   escaped_packet.PutCString("jTraceMetaRead:");
3421*061da546Spatrick   return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
3422*061da546Spatrick }
3423*061da546Spatrick 
3424*061da546Spatrick Status
3425*061da546Spatrick GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
3426*061da546Spatrick                                                        TraceOptions &options) {
3427*061da546Spatrick   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3428*061da546Spatrick   StringExtractorGDBRemote response;
3429*061da546Spatrick   Status error;
3430*061da546Spatrick 
3431*061da546Spatrick   StreamString json_string;
3432*061da546Spatrick   StreamGDBRemote escaped_packet;
3433*061da546Spatrick   escaped_packet.PutCString("jTraceConfigRead:");
3434*061da546Spatrick 
3435*061da546Spatrick   StructuredData::Dictionary json_packet;
3436*061da546Spatrick   json_packet.AddIntegerItem("traceid", uid);
3437*061da546Spatrick 
3438*061da546Spatrick   if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
3439*061da546Spatrick     json_packet.AddIntegerItem("threadid", options.getThreadID());
3440*061da546Spatrick 
3441*061da546Spatrick   json_packet.Dump(json_string, false);
3442*061da546Spatrick   escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3443*061da546Spatrick 
3444*061da546Spatrick   if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3445*061da546Spatrick                                    true) ==
3446*061da546Spatrick       GDBRemoteCommunication::PacketResult::Success) {
3447*061da546Spatrick     if (response.IsNormalResponse()) {
3448*061da546Spatrick       uint64_t type = std::numeric_limits<uint64_t>::max();
3449*061da546Spatrick       uint64_t buffersize = std::numeric_limits<uint64_t>::max();
3450*061da546Spatrick       uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
3451*061da546Spatrick 
3452*061da546Spatrick       auto json_object = StructuredData::ParseJSON(response.Peek());
3453*061da546Spatrick 
3454*061da546Spatrick       if (!json_object ||
3455*061da546Spatrick           json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
3456*061da546Spatrick         error.SetErrorString("Invalid Configuration obtained");
3457*061da546Spatrick         return error;
3458*061da546Spatrick       }
3459*061da546Spatrick 
3460*061da546Spatrick       auto json_dict = json_object->GetAsDictionary();
3461*061da546Spatrick 
3462*061da546Spatrick       json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
3463*061da546Spatrick                                                    metabuffersize);
3464*061da546Spatrick       options.setMetaDataBufferSize(metabuffersize);
3465*061da546Spatrick 
3466*061da546Spatrick       json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
3467*061da546Spatrick       options.setTraceBufferSize(buffersize);
3468*061da546Spatrick 
3469*061da546Spatrick       json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
3470*061da546Spatrick       options.setType(static_cast<lldb::TraceType>(type));
3471*061da546Spatrick 
3472*061da546Spatrick       StructuredData::ObjectSP custom_params_sp =
3473*061da546Spatrick           json_dict->GetValueForKey("params");
3474*061da546Spatrick       if (custom_params_sp) {
3475*061da546Spatrick         if (custom_params_sp->GetType() !=
3476*061da546Spatrick             lldb::eStructuredDataTypeDictionary) {
3477*061da546Spatrick           error.SetErrorString("Invalid Configuration obtained");
3478*061da546Spatrick           return error;
3479*061da546Spatrick         } else
3480*061da546Spatrick           options.setTraceParams(
3481*061da546Spatrick               static_pointer_cast<StructuredData::Dictionary>(
3482*061da546Spatrick                   custom_params_sp));
3483*061da546Spatrick       }
3484*061da546Spatrick     } else {
3485*061da546Spatrick       error = response.GetStatus();
3486*061da546Spatrick     }
3487*061da546Spatrick   } else {
3488*061da546Spatrick     LLDB_LOG(log, "failed to send packet");
3489*061da546Spatrick     error.SetErrorStringWithFormat("failed to send packet: '%s'",
3490*061da546Spatrick                                    escaped_packet.GetData());
3491*061da546Spatrick   }
3492*061da546Spatrick   return error;
3493*061da546Spatrick }
3494*061da546Spatrick 
3495*061da546Spatrick Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
3496*061da546Spatrick     StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
3497*061da546Spatrick     llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
3498*061da546Spatrick   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3499*061da546Spatrick   Status error;
3500*061da546Spatrick 
3501*061da546Spatrick   StructuredData::Dictionary json_packet;
3502*061da546Spatrick 
3503*061da546Spatrick   json_packet.AddIntegerItem("traceid", uid);
3504*061da546Spatrick   json_packet.AddIntegerItem("offset", offset);
3505*061da546Spatrick   json_packet.AddIntegerItem("buffersize", buffer.size());
3506*061da546Spatrick 
3507*061da546Spatrick   if (thread_id != LLDB_INVALID_THREAD_ID)
3508*061da546Spatrick     json_packet.AddIntegerItem("threadid", thread_id);
3509*061da546Spatrick 
3510*061da546Spatrick   StreamString json_string;
3511*061da546Spatrick   json_packet.Dump(json_string, false);
3512*061da546Spatrick 
3513*061da546Spatrick   packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
3514*061da546Spatrick   StringExtractorGDBRemote response;
3515*061da546Spatrick   if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
3516*061da546Spatrick       GDBRemoteCommunication::PacketResult::Success) {
3517*061da546Spatrick     if (response.IsNormalResponse()) {
3518*061da546Spatrick       size_t filled_size = response.GetHexBytesAvail(buffer);
3519*061da546Spatrick       buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
3520*061da546Spatrick     } else {
3521*061da546Spatrick       error = response.GetStatus();
3522*061da546Spatrick       buffer = buffer.slice(buffer.size());
3523*061da546Spatrick     }
3524*061da546Spatrick   } else {
3525*061da546Spatrick     LLDB_LOG(log, "failed to send packet");
3526*061da546Spatrick     error.SetErrorStringWithFormat("failed to send packet: '%s'",
3527*061da546Spatrick                                    packet.GetData());
3528*061da546Spatrick     buffer = buffer.slice(buffer.size());
3529*061da546Spatrick   }
3530*061da546Spatrick   return error;
3531*061da546Spatrick }
3532*061da546Spatrick 
3533*061da546Spatrick bool GDBRemoteCommunicationClient::GetModuleInfo(
3534*061da546Spatrick     const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3535*061da546Spatrick     ModuleSpec &module_spec) {
3536*061da546Spatrick   if (!m_supports_qModuleInfo)
3537*061da546Spatrick     return false;
3538*061da546Spatrick 
3539*061da546Spatrick   std::string module_path = module_file_spec.GetPath(false);
3540*061da546Spatrick   if (module_path.empty())
3541*061da546Spatrick     return false;
3542*061da546Spatrick 
3543*061da546Spatrick   StreamString packet;
3544*061da546Spatrick   packet.PutCString("qModuleInfo:");
3545*061da546Spatrick   packet.PutStringAsRawHex8(module_path);
3546*061da546Spatrick   packet.PutCString(";");
3547*061da546Spatrick   const auto &triple = arch_spec.GetTriple().getTriple();
3548*061da546Spatrick   packet.PutStringAsRawHex8(triple);
3549*061da546Spatrick 
3550*061da546Spatrick   StringExtractorGDBRemote response;
3551*061da546Spatrick   if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
3552*061da546Spatrick       PacketResult::Success)
3553*061da546Spatrick     return false;
3554*061da546Spatrick 
3555*061da546Spatrick   if (response.IsErrorResponse())
3556*061da546Spatrick     return false;
3557*061da546Spatrick 
3558*061da546Spatrick   if (response.IsUnsupportedResponse()) {
3559*061da546Spatrick     m_supports_qModuleInfo = false;
3560*061da546Spatrick     return false;
3561*061da546Spatrick   }
3562*061da546Spatrick 
3563*061da546Spatrick   llvm::StringRef name;
3564*061da546Spatrick   llvm::StringRef value;
3565*061da546Spatrick 
3566*061da546Spatrick   module_spec.Clear();
3567*061da546Spatrick   module_spec.GetFileSpec() = module_file_spec;
3568*061da546Spatrick 
3569*061da546Spatrick   while (response.GetNameColonValue(name, value)) {
3570*061da546Spatrick     if (name == "uuid" || name == "md5") {
3571*061da546Spatrick       StringExtractor extractor(value);
3572*061da546Spatrick       std::string uuid;
3573*061da546Spatrick       extractor.GetHexByteString(uuid);
3574*061da546Spatrick       module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2);
3575*061da546Spatrick     } else if (name == "triple") {
3576*061da546Spatrick       StringExtractor extractor(value);
3577*061da546Spatrick       std::string triple;
3578*061da546Spatrick       extractor.GetHexByteString(triple);
3579*061da546Spatrick       module_spec.GetArchitecture().SetTriple(triple.c_str());
3580*061da546Spatrick     } else if (name == "file_offset") {
3581*061da546Spatrick       uint64_t ival = 0;
3582*061da546Spatrick       if (!value.getAsInteger(16, ival))
3583*061da546Spatrick         module_spec.SetObjectOffset(ival);
3584*061da546Spatrick     } else if (name == "file_size") {
3585*061da546Spatrick       uint64_t ival = 0;
3586*061da546Spatrick       if (!value.getAsInteger(16, ival))
3587*061da546Spatrick         module_spec.SetObjectSize(ival);
3588*061da546Spatrick     } else if (name == "file_path") {
3589*061da546Spatrick       StringExtractor extractor(value);
3590*061da546Spatrick       std::string path;
3591*061da546Spatrick       extractor.GetHexByteString(path);
3592*061da546Spatrick       module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
3593*061da546Spatrick     }
3594*061da546Spatrick   }
3595*061da546Spatrick 
3596*061da546Spatrick   return true;
3597*061da546Spatrick }
3598*061da546Spatrick 
3599*061da546Spatrick static llvm::Optional<ModuleSpec>
3600*061da546Spatrick ParseModuleSpec(StructuredData::Dictionary *dict) {
3601*061da546Spatrick   ModuleSpec result;
3602*061da546Spatrick   if (!dict)
3603*061da546Spatrick     return llvm::None;
3604*061da546Spatrick 
3605*061da546Spatrick   llvm::StringRef string;
3606*061da546Spatrick   uint64_t integer;
3607*061da546Spatrick 
3608*061da546Spatrick   if (!dict->GetValueForKeyAsString("uuid", string))
3609*061da546Spatrick     return llvm::None;
3610*061da546Spatrick   if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
3611*061da546Spatrick       string.size())
3612*061da546Spatrick     return llvm::None;
3613*061da546Spatrick 
3614*061da546Spatrick   if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3615*061da546Spatrick     return llvm::None;
3616*061da546Spatrick   result.SetObjectOffset(integer);
3617*061da546Spatrick 
3618*061da546Spatrick   if (!dict->GetValueForKeyAsInteger("file_size", integer))
3619*061da546Spatrick     return llvm::None;
3620*061da546Spatrick   result.SetObjectSize(integer);
3621*061da546Spatrick 
3622*061da546Spatrick   if (!dict->GetValueForKeyAsString("triple", string))
3623*061da546Spatrick     return llvm::None;
3624*061da546Spatrick   result.GetArchitecture().SetTriple(string);
3625*061da546Spatrick 
3626*061da546Spatrick   if (!dict->GetValueForKeyAsString("file_path", string))
3627*061da546Spatrick     return llvm::None;
3628*061da546Spatrick   result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
3629*061da546Spatrick 
3630*061da546Spatrick   return result;
3631*061da546Spatrick }
3632*061da546Spatrick 
3633*061da546Spatrick llvm::Optional<std::vector<ModuleSpec>>
3634*061da546Spatrick GDBRemoteCommunicationClient::GetModulesInfo(
3635*061da546Spatrick     llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
3636*061da546Spatrick   namespace json = llvm::json;
3637*061da546Spatrick 
3638*061da546Spatrick   if (!m_supports_jModulesInfo)
3639*061da546Spatrick     return llvm::None;
3640*061da546Spatrick 
3641*061da546Spatrick   json::Array module_array;
3642*061da546Spatrick   for (const FileSpec &module_file_spec : module_file_specs) {
3643*061da546Spatrick     module_array.push_back(
3644*061da546Spatrick         json::Object{{"file", module_file_spec.GetPath(false)},
3645*061da546Spatrick                      {"triple", triple.getTriple()}});
3646*061da546Spatrick   }
3647*061da546Spatrick   StreamString unescaped_payload;
3648*061da546Spatrick   unescaped_payload.PutCString("jModulesInfo:");
3649*061da546Spatrick   unescaped_payload.AsRawOstream() << std::move(module_array);
3650*061da546Spatrick 
3651*061da546Spatrick   StreamGDBRemote payload;
3652*061da546Spatrick   payload.PutEscapedBytes(unescaped_payload.GetString().data(),
3653*061da546Spatrick                           unescaped_payload.GetSize());
3654*061da546Spatrick 
3655*061da546Spatrick   // Increase the timeout for jModulesInfo since this packet can take longer.
3656*061da546Spatrick   ScopedTimeout timeout(*this, std::chrono::seconds(10));
3657*061da546Spatrick 
3658*061da546Spatrick   StringExtractorGDBRemote response;
3659*061da546Spatrick   if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
3660*061da546Spatrick           PacketResult::Success ||
3661*061da546Spatrick       response.IsErrorResponse())
3662*061da546Spatrick     return llvm::None;
3663*061da546Spatrick 
3664*061da546Spatrick   if (response.IsUnsupportedResponse()) {
3665*061da546Spatrick     m_supports_jModulesInfo = false;
3666*061da546Spatrick     return llvm::None;
3667*061da546Spatrick   }
3668*061da546Spatrick 
3669*061da546Spatrick   StructuredData::ObjectSP response_object_sp =
3670*061da546Spatrick       StructuredData::ParseJSON(response.GetStringRef());
3671*061da546Spatrick   if (!response_object_sp)
3672*061da546Spatrick     return llvm::None;
3673*061da546Spatrick 
3674*061da546Spatrick   StructuredData::Array *response_array = response_object_sp->GetAsArray();
3675*061da546Spatrick   if (!response_array)
3676*061da546Spatrick     return llvm::None;
3677*061da546Spatrick 
3678*061da546Spatrick   std::vector<ModuleSpec> result;
3679*061da546Spatrick   for (size_t i = 0; i < response_array->GetSize(); ++i) {
3680*061da546Spatrick     if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
3681*061da546Spatrick             response_array->GetItemAtIndex(i)->GetAsDictionary()))
3682*061da546Spatrick       result.push_back(*module_spec);
3683*061da546Spatrick   }
3684*061da546Spatrick 
3685*061da546Spatrick   return result;
3686*061da546Spatrick }
3687*061da546Spatrick 
3688*061da546Spatrick // query the target remote for extended information using the qXfer packet
3689*061da546Spatrick //
3690*061da546Spatrick // example: object='features', annex='target.xml', out=<xml output> return:
3691*061da546Spatrick // 'true'  on success
3692*061da546Spatrick //          'false' on failure (err set)
3693*061da546Spatrick bool GDBRemoteCommunicationClient::ReadExtFeature(
3694*061da546Spatrick     const lldb_private::ConstString object,
3695*061da546Spatrick     const lldb_private::ConstString annex, std::string &out,
3696*061da546Spatrick     lldb_private::Status &err) {
3697*061da546Spatrick 
3698*061da546Spatrick   std::stringstream output;
3699*061da546Spatrick   StringExtractorGDBRemote chunk;
3700*061da546Spatrick 
3701*061da546Spatrick   uint64_t size = GetRemoteMaxPacketSize();
3702*061da546Spatrick   if (size == 0)
3703*061da546Spatrick     size = 0x1000;
3704*061da546Spatrick   size = size - 1; // Leave space for the 'm' or 'l' character in the response
3705*061da546Spatrick   int offset = 0;
3706*061da546Spatrick   bool active = true;
3707*061da546Spatrick 
3708*061da546Spatrick   // loop until all data has been read
3709*061da546Spatrick   while (active) {
3710*061da546Spatrick 
3711*061da546Spatrick     // send query extended feature packet
3712*061da546Spatrick     std::stringstream packet;
3713*061da546Spatrick     packet << "qXfer:" << object.AsCString("")
3714*061da546Spatrick            << ":read:" << annex.AsCString("") << ":" << std::hex << offset
3715*061da546Spatrick            << "," << std::hex << size;
3716*061da546Spatrick 
3717*061da546Spatrick     GDBRemoteCommunication::PacketResult res =
3718*061da546Spatrick         SendPacketAndWaitForResponse(packet.str(), chunk, false);
3719*061da546Spatrick 
3720*061da546Spatrick     if (res != GDBRemoteCommunication::PacketResult::Success) {
3721*061da546Spatrick       err.SetErrorString("Error sending $qXfer packet");
3722*061da546Spatrick       return false;
3723*061da546Spatrick     }
3724*061da546Spatrick 
3725*061da546Spatrick     const std::string &str = chunk.GetStringRef();
3726*061da546Spatrick     if (str.length() == 0) {
3727*061da546Spatrick       // should have some data in chunk
3728*061da546Spatrick       err.SetErrorString("Empty response from $qXfer packet");
3729*061da546Spatrick       return false;
3730*061da546Spatrick     }
3731*061da546Spatrick 
3732*061da546Spatrick     // check packet code
3733*061da546Spatrick     switch (str[0]) {
3734*061da546Spatrick     // last chunk
3735*061da546Spatrick     case ('l'):
3736*061da546Spatrick       active = false;
3737*061da546Spatrick       LLVM_FALLTHROUGH;
3738*061da546Spatrick 
3739*061da546Spatrick     // more chunks
3740*061da546Spatrick     case ('m'):
3741*061da546Spatrick       if (str.length() > 1)
3742*061da546Spatrick         output << &str[1];
3743*061da546Spatrick       offset += str.length() - 1;
3744*061da546Spatrick       break;
3745*061da546Spatrick 
3746*061da546Spatrick     // unknown chunk
3747*061da546Spatrick     default:
3748*061da546Spatrick       err.SetErrorString("Invalid continuation code from $qXfer packet");
3749*061da546Spatrick       return false;
3750*061da546Spatrick     }
3751*061da546Spatrick   }
3752*061da546Spatrick 
3753*061da546Spatrick   out = output.str();
3754*061da546Spatrick   err.Success();
3755*061da546Spatrick   return true;
3756*061da546Spatrick }
3757*061da546Spatrick 
3758*061da546Spatrick // Notify the target that gdb is prepared to serve symbol lookup requests.
3759*061da546Spatrick //  packet: "qSymbol::"
3760*061da546Spatrick //  reply:
3761*061da546Spatrick //  OK                  The target does not need to look up any (more) symbols.
3762*061da546Spatrick //  qSymbol:<sym_name>  The target requests the value of symbol sym_name (hex
3763*061da546Spatrick //  encoded).
3764*061da546Spatrick //                      LLDB may provide the value by sending another qSymbol
3765*061da546Spatrick //                      packet
3766*061da546Spatrick //                      in the form of"qSymbol:<sym_value>:<sym_name>".
3767*061da546Spatrick //
3768*061da546Spatrick //  Three examples:
3769*061da546Spatrick //
3770*061da546Spatrick //  lldb sends:    qSymbol::
3771*061da546Spatrick //  lldb receives: OK
3772*061da546Spatrick //     Remote gdb stub does not need to know the addresses of any symbols, lldb
3773*061da546Spatrick //     does not
3774*061da546Spatrick //     need to ask again in this session.
3775*061da546Spatrick //
3776*061da546Spatrick //  lldb sends:    qSymbol::
3777*061da546Spatrick //  lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3778*061da546Spatrick //  lldb sends:    qSymbol::64697370617463685f71756575655f6f666673657473
3779*061da546Spatrick //  lldb receives: OK
3780*061da546Spatrick //     Remote gdb stub asks for address of 'dispatch_queue_offsets'.  lldb does
3781*061da546Spatrick //     not know
3782*061da546Spatrick //     the address at this time.  lldb needs to send qSymbol:: again when it has
3783*061da546Spatrick //     more
3784*061da546Spatrick //     solibs loaded.
3785*061da546Spatrick //
3786*061da546Spatrick //  lldb sends:    qSymbol::
3787*061da546Spatrick //  lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3788*061da546Spatrick //  lldb sends:    qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
3789*061da546Spatrick //  lldb receives: OK
3790*061da546Spatrick //     Remote gdb stub asks for address of 'dispatch_queue_offsets'.  lldb says
3791*061da546Spatrick //     that it
3792*061da546Spatrick //     is at address 0x2bc97554.  Remote gdb stub sends 'OK' indicating that it
3793*061da546Spatrick //     does not
3794*061da546Spatrick //     need any more symbols.  lldb does not need to ask again in this session.
3795*061da546Spatrick 
3796*061da546Spatrick void GDBRemoteCommunicationClient::ServeSymbolLookups(
3797*061da546Spatrick     lldb_private::Process *process) {
3798*061da546Spatrick   // Set to true once we've resolved a symbol to an address for the remote
3799*061da546Spatrick   // stub. If we get an 'OK' response after this, the remote stub doesn't need
3800*061da546Spatrick   // any more symbols and we can stop asking.
3801*061da546Spatrick   bool symbol_response_provided = false;
3802*061da546Spatrick 
3803*061da546Spatrick   // Is this the initial qSymbol:: packet?
3804*061da546Spatrick   bool first_qsymbol_query = true;
3805*061da546Spatrick 
3806*061da546Spatrick   if (m_supports_qSymbol && !m_qSymbol_requests_done) {
3807*061da546Spatrick     Lock lock(*this, false);
3808*061da546Spatrick     if (lock) {
3809*061da546Spatrick       StreamString packet;
3810*061da546Spatrick       packet.PutCString("qSymbol::");
3811*061da546Spatrick       StringExtractorGDBRemote response;
3812*061da546Spatrick       while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
3813*061da546Spatrick              PacketResult::Success) {
3814*061da546Spatrick         if (response.IsOKResponse()) {
3815*061da546Spatrick           if (symbol_response_provided || first_qsymbol_query) {
3816*061da546Spatrick             m_qSymbol_requests_done = true;
3817*061da546Spatrick           }
3818*061da546Spatrick 
3819*061da546Spatrick           // We are done serving symbols requests
3820*061da546Spatrick           return;
3821*061da546Spatrick         }
3822*061da546Spatrick         first_qsymbol_query = false;
3823*061da546Spatrick 
3824*061da546Spatrick         if (response.IsUnsupportedResponse()) {
3825*061da546Spatrick           // qSymbol is not supported by the current GDB server we are
3826*061da546Spatrick           // connected to
3827*061da546Spatrick           m_supports_qSymbol = false;
3828*061da546Spatrick           return;
3829*061da546Spatrick         } else {
3830*061da546Spatrick           llvm::StringRef response_str(response.GetStringRef());
3831*061da546Spatrick           if (response_str.startswith("qSymbol:")) {
3832*061da546Spatrick             response.SetFilePos(strlen("qSymbol:"));
3833*061da546Spatrick             std::string symbol_name;
3834*061da546Spatrick             if (response.GetHexByteString(symbol_name)) {
3835*061da546Spatrick               if (symbol_name.empty())
3836*061da546Spatrick                 return;
3837*061da546Spatrick 
3838*061da546Spatrick               addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
3839*061da546Spatrick               lldb_private::SymbolContextList sc_list;
3840*061da546Spatrick               process->GetTarget().GetImages().FindSymbolsWithNameAndType(
3841*061da546Spatrick                   ConstString(symbol_name), eSymbolTypeAny, sc_list);
3842*061da546Spatrick               if (!sc_list.IsEmpty()) {
3843*061da546Spatrick                 const size_t num_scs = sc_list.GetSize();
3844*061da546Spatrick                 for (size_t sc_idx = 0;
3845*061da546Spatrick                      sc_idx < num_scs &&
3846*061da546Spatrick                      symbol_load_addr == LLDB_INVALID_ADDRESS;
3847*061da546Spatrick                      ++sc_idx) {
3848*061da546Spatrick                   SymbolContext sc;
3849*061da546Spatrick                   if (sc_list.GetContextAtIndex(sc_idx, sc)) {
3850*061da546Spatrick                     if (sc.symbol) {
3851*061da546Spatrick                       switch (sc.symbol->GetType()) {
3852*061da546Spatrick                       case eSymbolTypeInvalid:
3853*061da546Spatrick                       case eSymbolTypeAbsolute:
3854*061da546Spatrick                       case eSymbolTypeUndefined:
3855*061da546Spatrick                       case eSymbolTypeSourceFile:
3856*061da546Spatrick                       case eSymbolTypeHeaderFile:
3857*061da546Spatrick                       case eSymbolTypeObjectFile:
3858*061da546Spatrick                       case eSymbolTypeCommonBlock:
3859*061da546Spatrick                       case eSymbolTypeBlock:
3860*061da546Spatrick                       case eSymbolTypeLocal:
3861*061da546Spatrick                       case eSymbolTypeParam:
3862*061da546Spatrick                       case eSymbolTypeVariable:
3863*061da546Spatrick                       case eSymbolTypeVariableType:
3864*061da546Spatrick                       case eSymbolTypeLineEntry:
3865*061da546Spatrick                       case eSymbolTypeLineHeader:
3866*061da546Spatrick                       case eSymbolTypeScopeBegin:
3867*061da546Spatrick                       case eSymbolTypeScopeEnd:
3868*061da546Spatrick                       case eSymbolTypeAdditional:
3869*061da546Spatrick                       case eSymbolTypeCompiler:
3870*061da546Spatrick                       case eSymbolTypeInstrumentation:
3871*061da546Spatrick                       case eSymbolTypeTrampoline:
3872*061da546Spatrick                         break;
3873*061da546Spatrick 
3874*061da546Spatrick                       case eSymbolTypeCode:
3875*061da546Spatrick                       case eSymbolTypeResolver:
3876*061da546Spatrick                       case eSymbolTypeData:
3877*061da546Spatrick                       case eSymbolTypeRuntime:
3878*061da546Spatrick                       case eSymbolTypeException:
3879*061da546Spatrick                       case eSymbolTypeObjCClass:
3880*061da546Spatrick                       case eSymbolTypeObjCMetaClass:
3881*061da546Spatrick                       case eSymbolTypeObjCIVar:
3882*061da546Spatrick                       case eSymbolTypeReExported:
3883*061da546Spatrick                         symbol_load_addr =
3884*061da546Spatrick                             sc.symbol->GetLoadAddress(&process->GetTarget());
3885*061da546Spatrick                         break;
3886*061da546Spatrick                       }
3887*061da546Spatrick                     }
3888*061da546Spatrick                   }
3889*061da546Spatrick                 }
3890*061da546Spatrick               }
3891*061da546Spatrick               // This is the normal path where our symbol lookup was successful
3892*061da546Spatrick               // and we want to send a packet with the new symbol value and see
3893*061da546Spatrick               // if another lookup needs to be done.
3894*061da546Spatrick 
3895*061da546Spatrick               // Change "packet" to contain the requested symbol value and name
3896*061da546Spatrick               packet.Clear();
3897*061da546Spatrick               packet.PutCString("qSymbol:");
3898*061da546Spatrick               if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
3899*061da546Spatrick                 packet.Printf("%" PRIx64, symbol_load_addr);
3900*061da546Spatrick                 symbol_response_provided = true;
3901*061da546Spatrick               } else {
3902*061da546Spatrick                 symbol_response_provided = false;
3903*061da546Spatrick               }
3904*061da546Spatrick               packet.PutCString(":");
3905*061da546Spatrick               packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
3906*061da546Spatrick               continue; // go back to the while loop and send "packet" and wait
3907*061da546Spatrick                         // for another response
3908*061da546Spatrick             }
3909*061da546Spatrick           }
3910*061da546Spatrick         }
3911*061da546Spatrick       }
3912*061da546Spatrick       // If we make it here, the symbol request packet response wasn't valid or
3913*061da546Spatrick       // our symbol lookup failed so we must abort
3914*061da546Spatrick       return;
3915*061da546Spatrick 
3916*061da546Spatrick     } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
3917*061da546Spatrick                    GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
3918*061da546Spatrick       LLDB_LOGF(log,
3919*061da546Spatrick                 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
3920*061da546Spatrick                 __FUNCTION__);
3921*061da546Spatrick     }
3922*061da546Spatrick   }
3923*061da546Spatrick }
3924*061da546Spatrick 
3925*061da546Spatrick StructuredData::Array *
3926*061da546Spatrick GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
3927*061da546Spatrick   if (!m_supported_async_json_packets_is_valid) {
3928*061da546Spatrick     // Query the server for the array of supported asynchronous JSON packets.
3929*061da546Spatrick     m_supported_async_json_packets_is_valid = true;
3930*061da546Spatrick 
3931*061da546Spatrick     Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3932*061da546Spatrick 
3933*061da546Spatrick     // Poll it now.
3934*061da546Spatrick     StringExtractorGDBRemote response;
3935*061da546Spatrick     const bool send_async = false;
3936*061da546Spatrick     if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
3937*061da546Spatrick                                      send_async) == PacketResult::Success) {
3938*061da546Spatrick       m_supported_async_json_packets_sp =
3939*061da546Spatrick           StructuredData::ParseJSON(response.GetStringRef());
3940*061da546Spatrick       if (m_supported_async_json_packets_sp &&
3941*061da546Spatrick           !m_supported_async_json_packets_sp->GetAsArray()) {
3942*061da546Spatrick         // We were returned something other than a JSON array.  This is
3943*061da546Spatrick         // invalid.  Clear it out.
3944*061da546Spatrick         LLDB_LOGF(log,
3945*061da546Spatrick                   "GDBRemoteCommunicationClient::%s(): "
3946*061da546Spatrick                   "QSupportedAsyncJSONPackets returned invalid "
3947*061da546Spatrick                   "result: %s",
3948*061da546Spatrick                   __FUNCTION__, response.GetStringRef().data());
3949*061da546Spatrick         m_supported_async_json_packets_sp.reset();
3950*061da546Spatrick       }
3951*061da546Spatrick     } else {
3952*061da546Spatrick       LLDB_LOGF(log,
3953*061da546Spatrick                 "GDBRemoteCommunicationClient::%s(): "
3954*061da546Spatrick                 "QSupportedAsyncJSONPackets unsupported",
3955*061da546Spatrick                 __FUNCTION__);
3956*061da546Spatrick     }
3957*061da546Spatrick 
3958*061da546Spatrick     if (log && m_supported_async_json_packets_sp) {
3959*061da546Spatrick       StreamString stream;
3960*061da546Spatrick       m_supported_async_json_packets_sp->Dump(stream);
3961*061da546Spatrick       LLDB_LOGF(log,
3962*061da546Spatrick                 "GDBRemoteCommunicationClient::%s(): supported async "
3963*061da546Spatrick                 "JSON packets: %s",
3964*061da546Spatrick                 __FUNCTION__, stream.GetData());
3965*061da546Spatrick     }
3966*061da546Spatrick   }
3967*061da546Spatrick 
3968*061da546Spatrick   return m_supported_async_json_packets_sp
3969*061da546Spatrick              ? m_supported_async_json_packets_sp->GetAsArray()
3970*061da546Spatrick              : nullptr;
3971*061da546Spatrick }
3972*061da546Spatrick 
3973*061da546Spatrick Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
3974*061da546Spatrick     llvm::ArrayRef<int32_t> signals) {
3975*061da546Spatrick   // Format packet:
3976*061da546Spatrick   // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
3977*061da546Spatrick   auto range = llvm::make_range(signals.begin(), signals.end());
3978*061da546Spatrick   std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
3979*061da546Spatrick 
3980*061da546Spatrick   StringExtractorGDBRemote response;
3981*061da546Spatrick   auto send_status = SendPacketAndWaitForResponse(packet, response, false);
3982*061da546Spatrick 
3983*061da546Spatrick   if (send_status != GDBRemoteCommunication::PacketResult::Success)
3984*061da546Spatrick     return Status("Sending QPassSignals packet failed");
3985*061da546Spatrick 
3986*061da546Spatrick   if (response.IsOKResponse()) {
3987*061da546Spatrick     return Status();
3988*061da546Spatrick   } else {
3989*061da546Spatrick     return Status("Unknown error happened during sending QPassSignals packet.");
3990*061da546Spatrick   }
3991*061da546Spatrick }
3992*061da546Spatrick 
3993*061da546Spatrick Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
3994*061da546Spatrick     ConstString type_name, const StructuredData::ObjectSP &config_sp) {
3995*061da546Spatrick   Status error;
3996*061da546Spatrick 
3997*061da546Spatrick   if (type_name.GetLength() == 0) {
3998*061da546Spatrick     error.SetErrorString("invalid type_name argument");
3999*061da546Spatrick     return error;
4000*061da546Spatrick   }
4001*061da546Spatrick 
4002*061da546Spatrick   // Build command: Configure{type_name}: serialized config data.
4003*061da546Spatrick   StreamGDBRemote stream;
4004*061da546Spatrick   stream.PutCString("QConfigure");
4005*061da546Spatrick   stream.PutCString(type_name.AsCString());
4006*061da546Spatrick   stream.PutChar(':');
4007*061da546Spatrick   if (config_sp) {
4008*061da546Spatrick     // Gather the plain-text version of the configuration data.
4009*061da546Spatrick     StreamString unescaped_stream;
4010*061da546Spatrick     config_sp->Dump(unescaped_stream);
4011*061da546Spatrick     unescaped_stream.Flush();
4012*061da546Spatrick 
4013*061da546Spatrick     // Add it to the stream in escaped fashion.
4014*061da546Spatrick     stream.PutEscapedBytes(unescaped_stream.GetString().data(),
4015*061da546Spatrick                            unescaped_stream.GetSize());
4016*061da546Spatrick   }
4017*061da546Spatrick   stream.Flush();
4018*061da546Spatrick 
4019*061da546Spatrick   // Send the packet.
4020*061da546Spatrick   const bool send_async = false;
4021*061da546Spatrick   StringExtractorGDBRemote response;
4022*061da546Spatrick   auto result =
4023*061da546Spatrick       SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
4024*061da546Spatrick   if (result == PacketResult::Success) {
4025*061da546Spatrick     // We failed if the config result comes back other than OK.
4026*061da546Spatrick     if (strcmp(response.GetStringRef().data(), "OK") == 0) {
4027*061da546Spatrick       // Okay!
4028*061da546Spatrick       error.Clear();
4029*061da546Spatrick     } else {
4030*061da546Spatrick       error.SetErrorStringWithFormat("configuring StructuredData feature "
4031*061da546Spatrick                                      "%s failed with error %s",
4032*061da546Spatrick                                      type_name.AsCString(),
4033*061da546Spatrick                                      response.GetStringRef().data());
4034*061da546Spatrick     }
4035*061da546Spatrick   } else {
4036*061da546Spatrick     // Can we get more data here on the failure?
4037*061da546Spatrick     error.SetErrorStringWithFormat("configuring StructuredData feature %s "
4038*061da546Spatrick                                    "failed when sending packet: "
4039*061da546Spatrick                                    "PacketResult=%d",
4040*061da546Spatrick                                    type_name.AsCString(), (int)result);
4041*061da546Spatrick   }
4042*061da546Spatrick   return error;
4043*061da546Spatrick }
4044*061da546Spatrick 
4045*061da546Spatrick void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
4046*061da546Spatrick   GDBRemoteClientBase::OnRunPacketSent(first);
4047*061da546Spatrick   m_curr_tid = LLDB_INVALID_THREAD_ID;
4048*061da546Spatrick }
4049