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