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