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