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

source code of lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp