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