LLDB mainline
GDBRemoteCommunicationClient.cpp
Go to the documentation of this file.
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
10
11#include <cmath>
12#include <sys/stat.h>
13
14#include <numeric>
15#include <optional>
16#include <sstream>
17
19#include "lldb/Host/HostInfo.h"
20#include "lldb/Host/SafeMachO.h"
21#include "lldb/Host/XML.h"
22#include "lldb/Symbol/Symbol.h"
24#include "lldb/Target/Target.h"
26#include "lldb/Utility/Args.h"
30#include "lldb/Utility/Log.h"
31#include "lldb/Utility/State.h"
33
34#include "ProcessGDBRemote.h"
35#include "ProcessGDBRemoteLog.h"
36#include "lldb/Host/Config.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;
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 "QOffsets({0}, [{1:@[x]}])", offsets.segments,
56 llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));
57}
58
59// GDBRemoteCommunicationClient constructor
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
81 if (IsConnected())
82 Disconnect();
83}
84
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...
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
127 }
129}
130
134 }
136}
137
141 }
143}
144
148 }
150}
151
155 }
157}
158
162 }
164}
165
169 }
171}
172
176 }
178}
179
183 }
185}
186
191}
192
194 if (m_max_packet_size == 0) {
196 }
197 return m_max_packet_size;
198}
199
202 m_send_acks = true;
204
205 // This is the first real packet that we'll send in a debug session and it
206 // may take a little longer than normal to receive a reply. Wait at least
207 // 6 seconds for a reply to this packet.
208
209 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
210
212 if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==
214 if (response.IsOKResponse()) {
215 m_send_acks = false;
217 }
218 return true;
219 }
220 }
221 return false;
222}
223
227
229 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) ==
231 if (response.IsOKResponse())
233 }
234 }
235}
236
240
242 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) ==
244 if (response.IsOKResponse())
246 }
247 }
249}
250
254
256 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) ==
258 if (response.IsOKResponse())
260 }
261 }
263}
264
266 if (!did_exec) {
267 // Hard reset everything, this is when we first connect to a GDB server
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;
308 m_supports_qSymbol = true;
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();
319 m_default_packet_timeout = seconds(0);
322 m_qSupported_response.clear();
326 }
327
328 // These flags should be reset when we first connect to a GDB server and when
329 // our inferior process execs
332}
333
335 // Clear out any capabilities we expect to see in the qSupported response
349
350 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
351 // not, we assume no limit
352
353 // build the qSupported packet
354 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",
355 "multiprocess+", "fork-events+",
356 "vfork-events+"};
357 StreamString packet;
358 packet.PutCString("qSupported");
359 for (uint32_t i = 0; i < features.size(); ++i) {
360 packet.PutCString(i == 0 ? ":" : ";");
361 packet.PutCString(features[i]);
362 }
363
365 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
367 // Hang on to the qSupported packet, so that platforms can do custom
368 // configuration of the transport before attaching/launching the process.
369 m_qSupported_response = response.GetStringRef().str();
370
371 for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) {
372 if (x == "qXfer:auxv:read+")
374 else if (x == "qXfer:libraries-svr4:read+")
376 else if (x == "augmented-libraries-svr4-read") {
379 } else if (x == "qXfer:libraries:read+")
381 else if (x == "qXfer:features:read+")
383 else if (x == "qXfer:memory-map:read+")
385 else if (x == "qXfer:siginfo:read+")
387 else if (x == "qEcho")
389 else if (x == "QPassSignals+")
391 else if (x == "multiprocess+")
393 else if (x == "memory-tagging+")
395 else if (x == "qSaveCore+")
397 else if (x == "native-signals+")
399 // Look for a list of compressions in the features list e.g.
400 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
401 // deflate,lzma
402 else if (x.consume_front("SupportedCompressions=")) {
403 llvm::SmallVector<llvm::StringRef, 4> compressions;
404 x.split(compressions, ',');
405 if (!compressions.empty())
406 MaybeEnableCompression(compressions);
407 } else if (x.consume_front("SupportedWatchpointTypes=")) {
408 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
409 x.split(watchpoint_types, ',');
410 m_watchpoint_types = eWatchpointHardwareFeatureUnknown;
411 for (auto wp_type : watchpoint_types) {
412 if (wp_type == "x86_64")
413 m_watchpoint_types |= eWatchpointHardwareX86;
414 if (wp_type == "aarch64-mask")
415 m_watchpoint_types |= eWatchpointHardwareArmMASK;
416 if (wp_type == "aarch64-bas")
417 m_watchpoint_types |= eWatchpointHardwareArmBAS;
418 }
419 } else if (x.consume_front("PacketSize=")) {
420 StringExtractorGDBRemote packet_response(x);
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
426 LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
427 }
428 }
429 }
430 }
431}
432
437 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) ==
439 if (response.IsOKResponse())
441 }
442 }
444}
454 if (SendPacketAndWaitForResponse("vCont?", response) ==
456 const char *response_cstr = response.GetStringRef().data();
457 if (::strstr(response_cstr, ";c"))
459
460 if (::strstr(response_cstr, ";C"))
462
463 if (::strstr(response_cstr, ";s"))
465
466 if (::strstr(response_cstr, ";S"))
468
474 }
475
481 }
482 }
483 }
484
485 switch (flavor) {
486 case 'a':
488 case 'A':
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
506 lldb::tid_t tid, StreamString &&payload,
507 StringExtractorGDBRemote &response) {
508 Lock lock(*this);
509 if (!lock) {
511 LLDB_LOGF(log,
512 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
513 "for %s packet.",
514 __FUNCTION__, payload.GetData());
516 }
517
519 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
520 else {
521 if (!SetCurrentThread(tid))
523 }
524
525 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
526}
527
528// Check if the target supports 'p' packet. It sends out a 'p' packet and
529// checks the response. A normal packet will tell us that support is available.
530//
531// Takes a valid thread ID because p needs to apply to a thread.
535 return m_supports_p;
536}
537
539 lldb::tid_t tid, llvm::StringRef packetStr) {
540 StreamString payload;
541 payload.PutCString(packetStr);
544 tid, std::move(payload), response) == PacketResult::Success &&
545 response.IsNormalResponse()) {
546 return eLazyBoolYes;
547 }
548 return eLazyBoolNo;
549}
550
553}
554
556 // Get information on all threads at one using the "jThreadsInfo" packet
557 StructuredData::ObjectSP object_sp;
558
562 if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==
564 if (response.IsUnsupportedResponse()) {
566 } else if (!response.Empty()) {
567 object_sp = StructuredData::ParseJSON(response.GetStringRef());
568 }
569 }
570 }
571 return object_sp;
572}
573
578 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) ==
580 if (response.IsOKResponse()) {
582 }
583 }
584 }
586}
587
591 // We try to enable error strings in remote packets but if we fail, we just
592 // work in the older way.
594 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==
596 if (response.IsOKResponse()) {
598 }
599 }
600 }
601}
602
607 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
608 response) == PacketResult::Success) {
609 if (response.IsOKResponse()) {
611 }
612 }
613 }
615}
616
621 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) ==
623 if (response.IsOKResponse()) {
625 }
626 }
627 }
629}
630
635 if (SendPacketAndWaitForResponse("jGetDyldProcessState", response) ==
637 if (!response.IsUnsupportedResponse())
639 }
640 }
642}
643
647 }
649}
650
652 size_t len,
653 int32_t type) {
654 StreamString packet;
655 packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);
657
658 Log *log = GetLog(GDBRLog::Memory);
659
660 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
662 !response.IsNormalResponse()) {
663 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
664 __FUNCTION__);
665 return nullptr;
666 }
667
668 // We are expecting
669 // m<hex encoded bytes>
670
671 if (response.GetChar() != 'm') {
672 LLDB_LOGF(log,
673 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
674 "begin with \"m\"",
675 __FUNCTION__);
676 return nullptr;
677 }
678
679 size_t expected_bytes = response.GetBytesLeft() / 2;
680 WritableDataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
681 size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
682 // Check both because in some situations chars are consumed even
683 // if the decoding fails.
684 if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {
685 LLDB_LOGF(
686 log,
687 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
688 __FUNCTION__);
689 return nullptr;
690 }
691
692 return buffer_sp;
693}
694
696 lldb::addr_t addr, size_t len, int32_t type,
697 const std::vector<uint8_t> &tags) {
698 // Format QMemTags:address,length:type:tags
699 StreamString packet;
700 packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);
701 packet.PutBytesAsRawHex8(tags.data(), tags.size());
702
703 Status status;
705 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
707 !response.IsOKResponse()) {
708 status.SetErrorString("QMemTags packet failed");
709 }
710 return status;
711}
712
717 char packet[256];
718 snprintf(packet, sizeof(packet), "x0,0");
719 if (SendPacketAndWaitForResponse(packet, response) ==
721 if (response.IsOKResponse())
723 }
724 }
725 return m_supports_x;
726}
727
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);
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.
745 if (response.GetChar() == 'Q') {
746 if (response.GetChar() == 'C') {
748 response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
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.
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).
767 m_curr_pid_run = m_curr_pid = ids.front().second;
769 return m_curr_pid;
770 }
771 }
772 }
773
775}
776
778 if (!args.GetArgumentAtIndex(0))
779 return llvm::createStringError(llvm::inconvertibleErrorCode(),
780 "Nothing to launch");
781 // try vRun first
782 if (m_supports_vRun) {
783 StreamString packet;
784 packet.PutCString("vRun");
785 for (const Args::ArgEntry &arg : args) {
786 packet.PutChar(';');
787 packet.PutStringAsRawHex8(arg.ref());
788 }
789
791 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
793 return llvm::createStringError(llvm::inconvertibleErrorCode(),
794 "Sending vRun packet failed");
795
796 if (response.IsErrorResponse())
797 return response.GetStatus().ToError();
798
799 // vRun replies with a stop reason packet
800 // FIXME: right now we just discard the packet and LLDB queries
801 // for stop reason again
802 if (!response.IsUnsupportedResponse())
803 return llvm::Error::success();
804
805 m_supports_vRun = false;
806 }
807
808 // fallback to A
809 StreamString packet;
810 packet.PutChar('A');
811 llvm::ListSeparator LS(",");
812 for (const auto &arg : llvm::enumerate(args)) {
813 packet << LS;
814 packet.Format("{0},{1},", arg.value().ref().size() * 2, arg.index());
815 packet.PutStringAsRawHex8(arg.value().ref());
816 }
817
819 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
821 return llvm::createStringError(llvm::inconvertibleErrorCode(),
822 "Sending A packet failed");
823 }
824 if (!response.IsOKResponse())
825 return response.GetStatus().ToError();
826
827 if (SendPacketAndWaitForResponse("qLaunchSuccess", response) !=
829 return llvm::createStringError(llvm::inconvertibleErrorCode(),
830 "Sending qLaunchSuccess packet failed");
831 }
832 if (response.IsOKResponse())
833 return llvm::Error::success();
834 if (response.GetChar() == 'E') {
835 return llvm::createStringError(llvm::inconvertibleErrorCode(),
836 response.GetStringRef().substr(1));
837 }
838 return llvm::createStringError(llvm::inconvertibleErrorCode(),
839 "unknown error occurred launching process");
840}
841
843 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
844 for (const auto &kv : env)
845 vec.emplace_back(kv.first(), kv.second);
846 llvm::sort(vec, llvm::less_first());
847 for (const auto &[k, v] : vec) {
848 int r = SendEnvironmentPacket((k + "=" + v).str().c_str());
849 if (r != 0)
850 return r;
851 }
852 return 0;
853}
854
856 char const *name_equal_value) {
857 if (name_equal_value && name_equal_value[0]) {
858 bool send_hex_encoding = false;
859 for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
860 ++p) {
861 if (llvm::isPrint(*p)) {
862 switch (*p) {
863 case '$':
864 case '#':
865 case '*':
866 case '}':
867 send_hex_encoding = true;
868 break;
869 default:
870 break;
871 }
872 } else {
873 // We have non printable characters, lets hex encode this...
874 send_hex_encoding = true;
875 }
876 }
877
879 // Prefer sending unencoded, if possible and the server supports it.
880 if (!send_hex_encoding && m_supports_QEnvironment) {
881 StreamString packet;
882 packet.Printf("QEnvironment:%s", name_equal_value);
883 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
885 return -1;
886
887 if (response.IsOKResponse())
888 return 0;
889 if (response.IsUnsupportedResponse())
891 else {
892 uint8_t error = response.GetError();
893 if (error)
894 return error;
895 return -1;
896 }
897 }
898
900 StreamString packet;
901 packet.PutCString("QEnvironmentHexEncoded:");
902 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
903 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
905 return -1;
906
907 if (response.IsOKResponse())
908 return 0;
909 if (response.IsUnsupportedResponse())
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
923 if (arch && arch[0]) {
924 StreamString packet;
925 packet.Printf("QLaunchArch:%s", arch);
927 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
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
940 char const *data, bool *was_supported) {
941 if (data && *data != '\0') {
942 StreamString packet;
943 packet.Printf("QSetProcessEvent:%s", data);
945 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
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
968 GetHostInfo();
969 return m_os_version;
970}
971
973 GetHostInfo();
975}
976
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>
987 if (GetHostInfo()) {
988 if (!m_os_kernel.empty())
989 return m_os_kernel;
990 }
991 return std::nullopt;
992}
993
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
1006 if (GetHostInfo())
1007 return m_host_arch;
1008 return ArchSpec();
1009}
1010
1015 return m_process_arch;
1016}
1017
1019 UUID &uuid, addr_t &value, bool &value_is_offset) {
1022
1023 // Return true if we have a UUID or an address/offset of the
1024 // main standalone / firmware binary being used.
1027 return false;
1028
1031 value_is_offset = m_process_standalone_value_is_offset;
1032 return true;
1033}
1034
1035std::vector<addr_t>
1039 return m_binary_addresses;
1040}
1041
1044 m_gdb_server_name.clear();
1047
1048 StringExtractorGDBRemote response;
1049 if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==
1051 if (response.IsNormalResponse()) {
1052 llvm::StringRef name, value;
1053 bool success = false;
1054 while (response.GetNameColonValue(name, value)) {
1055 if (name.equals("name")) {
1056 success = true;
1057 m_gdb_server_name = std::string(value);
1058 } else if (name.equals("version")) {
1059 llvm::StringRef major, minor;
1060 std::tie(major, minor) = value.split('.');
1061 if (!major.getAsInteger(0, m_gdb_server_version))
1062 success = true;
1063 }
1064 }
1065 if (success)
1067 }
1068 }
1069 }
1071}
1072
1074 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1076 llvm::StringRef avail_name;
1077
1078#if defined(HAVE_LIBCOMPRESSION)
1079 if (avail_type == CompressionType::None) {
1080 for (auto compression : supported_compressions) {
1081 if (compression == "lzfse") {
1082 avail_type = CompressionType::LZFSE;
1083 avail_name = compression;
1084 break;
1085 }
1086 }
1087 }
1088#endif
1089
1090#if defined(HAVE_LIBCOMPRESSION)
1091 if (avail_type == CompressionType::None) {
1092 for (auto compression : supported_compressions) {
1093 if (compression == "zlib-deflate") {
1094 avail_type = CompressionType::ZlibDeflate;
1095 avail_name = compression;
1096 break;
1097 }
1098 }
1099 }
1100#endif
1101
1102#if LLVM_ENABLE_ZLIB
1103 if (avail_type == CompressionType::None) {
1104 for (auto compression : supported_compressions) {
1105 if (compression == "zlib-deflate") {
1106 avail_type = CompressionType::ZlibDeflate;
1107 avail_name = compression;
1108 break;
1109 }
1110 }
1111 }
1112#endif
1113
1114#if defined(HAVE_LIBCOMPRESSION)
1115 if (avail_type == CompressionType::None) {
1116 for (auto compression : supported_compressions) {
1117 if (compression == "lz4") {
1118 avail_type = CompressionType::LZ4;
1119 avail_name = compression;
1120 break;
1121 }
1122 }
1123 }
1124#endif
1125
1126#if defined(HAVE_LIBCOMPRESSION)
1127 if (avail_type == CompressionType::None) {
1128 for (auto compression : supported_compressions) {
1129 if (compression == "lzma") {
1130 avail_type = CompressionType::LZMA;
1131 avail_name = compression;
1132 break;
1133 }
1134 }
1135 }
1136#endif
1137
1138 if (avail_type != CompressionType::None) {
1139 StringExtractorGDBRemote response;
1140 std::string packet = "QEnableCompression:type:" + avail_name.str() + ";";
1141 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
1142 return;
1143
1144 if (response.IsOKResponse()) {
1145 m_compression_type = avail_type;
1146 }
1147 }
1148}
1149
1151 if (GetGDBServerVersion()) {
1152 if (!m_gdb_server_name.empty())
1153 return m_gdb_server_name.c_str();
1154 }
1155 return nullptr;
1156}
1157
1159 if (GetGDBServerVersion())
1160 return m_gdb_server_version;
1161 return 0;
1162}
1163
1165 StringExtractorGDBRemote response;
1167 return false;
1168
1169 if (!response.IsNormalResponse())
1170 return false;
1171
1172 if (response.GetChar() == 'Q' && response.GetChar() == 'C') {
1173 auto pid_tid = response.GetPidTid(0);
1174 if (!pid_tid)
1175 return false;
1176
1177 lldb::pid_t pid = pid_tid->first;
1178 // invalid
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;
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("iossimulator") || value.equals("tvossimulator") ||
1196 value.equals("watchossimulator") || value.equals("xrossimulator") ||
1197 value.equals("visionossimulator")) {
1198 environment = "simulator";
1199 os_name = value.drop_back(environment.size()).str();
1200 } else if (value.equals("maccatalyst")) {
1201 os_name = "ios";
1202 environment = "macabi";
1203 } else {
1204 os_name = value.str();
1205 }
1206}
1207
1209 Log *log = GetLog(GDBRLog::Process);
1210
1211 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
1212 // host info computation can require DNS traffic and shelling out to external processes.
1213 // Increase the timeout to account for that.
1214 ScopedTimeout timeout(*this, seconds(10));
1216 StringExtractorGDBRemote response;
1217 if (SendPacketAndWaitForResponse("qHostInfo", response) ==
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("cputype")) {
1234 // exception type in big endian hex
1235 if (!value.getAsInteger(0, cpu))
1236 ++num_keys_decoded;
1237 } else if (name.equals("cpusubtype")) {
1238 // exception count in big endian hex
1239 if (!value.getAsInteger(0, sub))
1240 ++num_keys_decoded;
1241 } else if (name.equals("arch")) {
1242 arch_name = std::string(value);
1243 ++num_keys_decoded;
1244 } else if (name.equals("triple")) {
1245 StringExtractor extractor(value);
1246 extractor.GetHexByteString(triple);
1247 ++num_keys_decoded;
1248 } else if (name.equals("distribution_id")) {
1249 StringExtractor extractor(value);
1251 ++num_keys_decoded;
1252 } else if (name.equals("os_build")) {
1253 StringExtractor extractor(value);
1254 extractor.GetHexByteString(m_os_build);
1255 ++num_keys_decoded;
1256 } else if (name.equals("hostname")) {
1257 StringExtractor extractor(value);
1258 extractor.GetHexByteString(m_hostname);
1259 ++num_keys_decoded;
1260 } else if (name.equals("os_kernel")) {
1261 StringExtractor extractor(value);
1262 extractor.GetHexByteString(m_os_kernel);
1263 ++num_keys_decoded;
1264 } else if (name.equals("ostype")) {
1265 ParseOSType(value, os_name, environment);
1266 ++num_keys_decoded;
1267 } else if (name.equals("vendor")) {
1268 vendor_name = std::string(value);
1269 ++num_keys_decoded;
1270 } else if (name.equals("endian")) {
1271 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1272 .Case("little", eByteOrderLittle)
1273 .Case("big", eByteOrderBig)
1274 .Case("pdp", eByteOrderPDP)
1275 .Default(eByteOrderInvalid);
1276 if (byte_order != eByteOrderInvalid)
1277 ++num_keys_decoded;
1278 } else if (name.equals("ptrsize")) {
1279 if (!value.getAsInteger(0, pointer_byte_size))
1280 ++num_keys_decoded;
1281 } else if (name.equals("addressing_bits")) {
1282 if (!value.getAsInteger(0, m_low_mem_addressing_bits)) {
1283 ++num_keys_decoded;
1284 }
1285 } else if (name.equals("high_mem_addressing_bits")) {
1286 if (!value.getAsInteger(0, m_high_mem_addressing_bits))
1287 ++num_keys_decoded;
1288 } else if (name.equals("low_mem_addressing_bits")) {
1289 if (!value.getAsInteger(0, m_low_mem_addressing_bits))
1290 ++num_keys_decoded;
1291 } else if (name.equals("os_version") ||
1292 name.equals("version")) // Older debugserver binaries used
1293 // the "version" key instead of
1294 // "os_version"...
1295 {
1296 if (!m_os_version.tryParse(value))
1297 ++num_keys_decoded;
1298 } else if (name.equals("maccatalyst_version")) {
1299 if (!m_maccatalyst_version.tryParse(value))
1300 ++num_keys_decoded;
1301 } else if (name.equals("watchpoint_exceptions_received")) {
1303 llvm::StringSwitch<LazyBool>(value)
1304 .Case("before", eLazyBoolNo)
1305 .Case("after", eLazyBoolYes)
1306 .Default(eLazyBoolCalculate);
1308 ++num_keys_decoded;
1309 } else if (name.equals("default_packet_timeout")) {
1310 uint32_t timeout_seconds;
1311 if (!value.getAsInteger(0, timeout_seconds)) {
1312 m_default_packet_timeout = seconds(timeout_seconds);
1314 ++num_keys_decoded;
1315 }
1316 } else if (name.equals("vm-page-size")) {
1317 int page_size;
1318 if (!value.getAsInteger(0, page_size)) {
1319 m_target_vm_page_size = page_size;
1320 ++num_keys_decoded;
1321 }
1322 }
1323 }
1324
1325 if (num_keys_decoded > 0)
1327
1328 if (triple.empty()) {
1329 if (arch_name.empty()) {
1330 if (cpu != LLDB_INVALID_CPUTYPE) {
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__,
1401 : "<null-arch-name>",
1402 m_host_arch.GetTriple().getTriple().c_str(),
1403 triple.c_str());
1404 }
1405 }
1406 }
1407 }
1409}
1410
1412 size_t data_len) {
1413 StreamString packet;
1414 packet.PutCString("I");
1415 packet.PutBytesAsRawHex8(data, data_len);
1416 StringExtractorGDBRemote response;
1417 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1419 return 0;
1420 }
1421 return response.GetError();
1422}
1423
1427 GetHostInfo();
1428 return m_host_arch;
1429}
1430
1432 AddressableBits addressable_bits;
1434 GetHostInfo();
1435
1438 else
1441 return addressable_bits;
1442}
1443
1446 GetHostInfo();
1448}
1449
1451 uint32_t permissions) {
1454 char packet[64];
1455 const int packet_len = ::snprintf(
1456 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1457 permissions & lldb::ePermissionsReadable ? "r" : "",
1458 permissions & lldb::ePermissionsWritable ? "w" : "",
1459 permissions & lldb::ePermissionsExecutable ? "x" : "");
1460 assert(packet_len < (int)sizeof(packet));
1461 UNUSED_IF_ASSERT_DISABLED(packet_len);
1462 StringExtractorGDBRemote response;
1463 if (SendPacketAndWaitForResponse(packet, response) ==
1465 if (response.IsUnsupportedResponse())
1467 else if (!response.IsErrorResponse())
1468 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1469 } else {
1471 }
1472 }
1473 return LLDB_INVALID_ADDRESS;
1474}
1475
1479 char packet[64];
1480 const int packet_len =
1481 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1482 assert(packet_len < (int)sizeof(packet));
1483 UNUSED_IF_ASSERT_DISABLED(packet_len);
1484 StringExtractorGDBRemote response;
1485 if (SendPacketAndWaitForResponse(packet, response) ==
1487 if (response.IsUnsupportedResponse())
1489 else if (response.IsOKResponse())
1490 return true;
1491 } else {
1493 }
1494 }
1495 return false;
1496}
1497
1499 lldb::pid_t pid) {
1500 Status error;
1502
1503 packet.PutChar('D');
1504 if (keep_stopped) {
1506 char packet[64];
1507 const int packet_len =
1508 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1509 assert(packet_len < (int)sizeof(packet));
1510 UNUSED_IF_ASSERT_DISABLED(packet_len);
1511 StringExtractorGDBRemote response;
1512 if (SendPacketAndWaitForResponse(packet, response) ==
1514 response.IsOKResponse()) {
1516 } else {
1518 }
1519 }
1520
1522 error.SetErrorString("Stays stopped not supported by this target.");
1523 return error;
1524 } else {
1525 packet.PutChar('1');
1526 }
1527 }
1528
1530 // Some servers (e.g. qemu) require specifying the PID even if only a single
1531 // process is running.
1532 if (pid == LLDB_INVALID_PROCESS_ID)
1533 pid = GetCurrentProcessID();
1534 packet.PutChar(';');
1535 packet.PutHex64(pid);
1536 } else if (pid != LLDB_INVALID_PROCESS_ID) {
1537 error.SetErrorString("Multiprocess extension not supported by the server.");
1538 return error;
1539 }
1540
1541 StringExtractorGDBRemote response;
1542 PacketResult packet_result =
1543 SendPacketAndWaitForResponse(packet.GetString(), response);
1544 if (packet_result != PacketResult::Success)
1545 error.SetErrorString("Sending isconnect packet failed.");
1546 return error;
1547}
1548
1550 lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
1551 Status error;
1552 region_info.Clear();
1553
1556 char packet[64];
1557 const int packet_len = ::snprintf(
1558 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1559 assert(packet_len < (int)sizeof(packet));
1560 UNUSED_IF_ASSERT_DISABLED(packet_len);
1561 StringExtractorGDBRemote response;
1562 if (SendPacketAndWaitForResponse(packet, response) ==
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("start")) {
1572 if (!value.getAsInteger(16, addr_value))
1573 region_info.GetRange().SetRangeBase(addr_value);
1574 } else if (name.equals("size")) {
1575 if (!value.getAsInteger(16, addr_value)) {
1576 region_info.GetRange().SetByteSize(addr_value);
1577 if (region_info.GetRange().GetRangeEnd() <
1578 region_info.GetRange().GetRangeBase()) {
1579 // Range size overflowed, truncate it.
1581 }
1582 }
1583 } else if (name.equals("permissions") &&
1584 region_info.GetRange().IsValid()) {
1585 saw_permissions = true;
1586 if (region_info.GetRange().Contains(addr)) {
1587 if (value.contains('r'))
1589 else
1591
1592 if (value.contains('w'))
1594 else
1596
1597 if (value.contains('x'))
1599 else
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
1609 region_info.SetMapped(MemoryRegionInfo::eNo);
1610 }
1611 } else if (name.equals("name")) {
1612 StringExtractorGDBRemote name_extractor(value);
1613 std::string name;
1614 name_extractor.GetHexByteString(name);
1615 region_info.SetName(name.c_str());
1616 } else if (name.equals("flags")) {
1618
1619 llvm::StringRef flags = value;
1620 llvm::StringRef flag;
1621 while (flags.size()) {
1622 flags = flags.ltrim();
1623 std::tie(flag, flags) = flags.split(' ');
1624 // To account for trailing whitespace
1625 if (flag.size()) {
1626 if (flag == "mt") {
1628 break;
1629 }
1630 }
1631 }
1632 } else if (name.equals("type")) {
1633 std::string comma_sep_str = value.str();
1634 size_t comma_pos;
1635 while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) {
1636 comma_sep_str[comma_pos] = '\0';
1637 if (comma_sep_str == "stack") {
1639 }
1640 }
1641 // handle final (or only) type of "stack"
1642 if (comma_sep_str == "stack") {
1644 }
1645 } else if (name.equals("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(error_string);
1650 error.SetErrorString(error_string.c_str());
1651 } else if (name.equals("dirty-pages")) {
1652 std::vector<addr_t> dirty_page_list;
1653 for (llvm::StringRef x : llvm::split(value, ',')) {
1654 addr_t page;
1655 x.consume_front("0x");
1656 if (llvm::to_integer(x, page, 16))
1657 dirty_page_list.push_back(page);
1658 }
1659 region_info.SetDirtyPageList(dirty_page_list);
1660 }
1661 }
1662
1663 if (m_target_vm_page_size != 0)
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) {
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 {
1681 }
1682 }
1683
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, 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
1715 lldb::addr_t addr, MemoryRegionInfo &region) {
1717 if (!error.Success())
1718 return error;
1719 for (const auto &map_region : m_qXfer_memory_map) {
1720 if (map_region.GetRange().Contains(addr)) {
1721 region = map_region;
1722 return error;
1723 }
1724 }
1725 error.SetErrorString("Region not found");
1726 return error;
1727}
1728
1730
1731 Status error;
1732
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
1743 error.SetErrorString("Memory map is not supported");
1744 return error;
1745 }
1746
1747 llvm::Expected<std::string> xml = ReadExtFeature("memory-map", "");
1748 if (!xml)
1749 return Status(xml.takeError());
1750
1751 XMLDocument xml_document;
1752
1753 if (!xml_document.ParseMemory(xml->c_str(), xml->size())) {
1754 error.SetErrorString("Failed to parse memory map xml");
1755 return error;
1756 }
1757
1758 XMLNode map_node = xml_document.GetRootElement("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([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("type", "");
1772 uint64_t start;
1773 uint64_t length;
1774 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1775 return true;
1776 if (!memory_node.GetAttributeValueAsUnsigned("length", 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(region);
1784 } else if (type == "ram") {
1785 region.SetReadable(MemoryRegionInfo::eYes);
1786 region.SetWritable(MemoryRegionInfo::eYes);
1787 this->m_qXfer_memory_map.push_back(region);
1788 } else if (type == "flash") {
1789 region.SetFlash(MemoryRegionInfo::eYes);
1790 memory_node.ForEachChildElement(
1791 [&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", "");
1797 if (propname == "blocksize") {
1798 uint64_t blocksize;
1799 if (prop_node.GetElementTextAsUnsigned(blocksize))
1800 region.SetBlocksize(blocksize);
1801 }
1802 return true;
1803 });
1804 this->m_qXfer_memory_map.push_back(region);
1805 }
1806 return true;
1807 });
1808
1810
1811 return error;
1812}
1813
1817 }
1818
1819 std::optional<uint32_t> num;
1821 StringExtractorGDBRemote response;
1822 if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==
1825 llvm::StringRef name;
1826 llvm::StringRef value;
1827 while (response.GetNameColonValue(name, value)) {
1828 if (name.equals("num")) {
1829 value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1831 }
1832 }
1833 if (!num) {
1835 }
1836 } else {
1838 }
1839 }
1840
1841 return num;
1842}
1843
1844WatchpointHardwareFeature
1846 return m_watchpoint_types;
1847}
1848
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.
1858 return false;
1860 return true;
1861 }
1862
1863 return std::nullopt;
1864}
1865
1867 if (file_spec) {
1868 std::string path{file_spec.GetPath(false)};
1869 StreamString packet;
1870 packet.PutCString("QSetSTDIN:");
1871 packet.PutStringAsRawHex8(path);
1872
1873 StringExtractorGDBRemote response;
1874 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
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
1887 if (file_spec) {
1888 std::string path{file_spec.GetPath(false)};
1889 StreamString packet;
1890 packet.PutCString("QSetSTDOUT:");
1891 packet.PutStringAsRawHex8(path);
1892
1893 StringExtractorGDBRemote response;
1894 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
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
1907 if (file_spec) {
1908 std::string path{file_spec.GetPath(false)};
1909 StreamString packet;
1910 packet.PutCString("QSetSTDERR:");
1911 packet.PutStringAsRawHex8(path);
1912
1913 StringExtractorGDBRemote response;
1914 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
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
1927 StringExtractorGDBRemote response;
1928 if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==
1930 if (response.IsUnsupportedResponse())
1931 return false;
1932 if (response.IsErrorResponse())
1933 return false;
1934 std::string cwd;
1935 response.GetHexByteString(cwd);
1936 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
1937 return !cwd.empty();
1938 }
1939 return false;
1940}
1941
1943 if (working_dir) {
1944 std::string path{working_dir.GetPath(false)};
1945 StreamString packet;
1946 packet.PutCString("QSetWorkingDir:");
1947 packet.PutStringAsRawHex8(path);
1948
1949 StringExtractorGDBRemote response;
1950 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
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
1963 char packet[32];
1964 const int packet_len =
1965 ::snprintf(packet, sizeof(packet), "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(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
1980 char packet[32];
1981 const int packet_len = ::snprintf(packet, sizeof(packet),
1982 "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(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
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("pid")) {
2011 value.getAsInteger(0, pid);
2012 process_info.SetProcessID(pid);
2013 } else if (name.equals("ppid")) {
2015 value.getAsInteger(0, pid);
2016 process_info.SetParentProcessID(pid);
2017 } else if (name.equals("uid")) {
2018 uint32_t uid = UINT32_MAX;
2019 value.getAsInteger(0, uid);
2020 process_info.SetUserID(uid);
2021 } else if (name.equals("euid")) {
2022 uint32_t uid = UINT32_MAX;
2023 value.getAsInteger(0, uid);
2024 process_info.SetEffectiveUserID(uid);
2025 } else if (name.equals("gid")) {
2026 uint32_t gid = UINT32_MAX;
2027 value.getAsInteger(0, gid);
2028 process_info.SetGroupID(gid);
2029 } else if (name.equals("egid")) {
2030 uint32_t gid = UINT32_MAX;
2031 value.getAsInteger(0, gid);
2032 process_info.SetEffectiveGroupID(gid);
2033 } else if (name.equals("triple")) {
2034 StringExtractor extractor(value);
2035 std::string triple;
2036 extractor.GetHexByteString(triple);
2037 process_info.GetArchitecture().SetTriple(triple.c_str());
2038 } else if (name.equals("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(name);
2044 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
2045 } else if (name.equals("args")) {
2046 llvm::StringRef encoded_args(value), hex_arg;
2047
2048 bool is_arg0 = true;
2049 while (!encoded_args.empty()) {
2050 std::tie(hex_arg, encoded_args) = encoded_args.split('-');
2051 std::string arg;
2052 StringExtractor extractor(hex_arg);
2053 if (extractor.GetHexByteString(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);
2063 is_arg0 = false;
2064 }
2065 } else if (name.equals("cputype")) {
2066 value.getAsInteger(0, cpu);
2067 } else if (name.equals("cpusubtype")) {
2068 value.getAsInteger(0, sub);
2069 } else if (name.equals("vendor")) {
2070 vendor = std::string(value);
2071 } else if (name.equals("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") {
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
2094 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
2095 process_info.Clear();
2096
2098 char packet[32];
2099 const int packet_len =
2100 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
2101 assert(packet_len < (int)sizeof(packet));
2102 UNUSED_IF_ASSERT_DISABLED(packet_len);
2103 StringExtractorGDBRemote response;
2104 if (SendPacketAndWaitForResponse(packet, response) ==
2106 return DecodeProcessInfoResponse(response, process_info);
2107 } else {
2109 return false;
2110 }
2111 }
2112 return false;
2113}
2114
2117
2118 if (allow_lazy) {
2120 return true;
2122 return false;
2123 }
2124
2125 GetHostInfo();
2126
2127 StringExtractorGDBRemote response;
2128 if (SendPacketAndWaitForResponse("qProcessInfo", response) ==
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;
2146 while (response.GetNameColonValue(name, value)) {
2147 if (name.equals("cputype")) {
2148 if (!value.getAsInteger(16, cpu))
2149 ++num_keys_decoded;
2150 } else if (name.equals("cpusubtype")) {
2151 if (!value.getAsInteger(16, 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("triple")) {
2166 StringExtractor extractor(value);
2167 extractor.GetHexByteString(triple);
2168 ++num_keys_decoded;
2169 } else if (name.equals("ostype")) {
2170 ParseOSType(value, os_name, environment);
2171 ++num_keys_decoded;
2172 } else if (name.equals("vendor")) {
2173 vendor_name = std::string(value);
2174 ++num_keys_decoded;
2175 } else if (name.equals("endian")) {
2176 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2177 .Case("little", eByteOrderLittle)
2178 .Case("big", eByteOrderBig)
2179 .Case("pdp", eByteOrderPDP)
2180 .Default(eByteOrderInvalid);
2181 if (byte_order != eByteOrderInvalid)
2182 ++num_keys_decoded;
2183 } else if (name.equals("ptrsize")) {
2184 if (!value.getAsInteger(16, pointer_byte_size))
2185 ++num_keys_decoded;
2186 } else if (name.equals("pid")) {
2187 if (!value.getAsInteger(16, pid))
2188 ++num_keys_decoded;
2189 } else if (name.equals("elf_abi")) {
2190 elf_abi = std::string(value);
2191 ++num_keys_decoded;
2192 } else if (name.equals("main-binary-uuid")) {
2194 ++num_keys_decoded;
2195 } else if (name.equals("main-binary-slide")) {
2196 StringExtractor extractor(value);
2198 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
2201 ++num_keys_decoded;
2202 }
2203 } else if (name.equals("main-binary-address")) {
2204 StringExtractor extractor(value);
2206 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
2209 ++num_keys_decoded;
2210 }
2211 } else if (name.equals("binary-addresses")) {
2212 m_binary_addresses.clear();
2213 ++num_keys_decoded;
2214 for (llvm::StringRef x : llvm::split(value, ',')) {
2215 addr_t vmaddr;
2216 x.consume_front("0x");
2217 if (llvm::to_integer(x, vmaddr, 16))
2218 m_binary_addresses.push_back(vmaddr);
2219 }
2220 }
2221 }
2222 if (num_keys_decoded > 0)
2224 if (pid != LLDB_INVALID_PROCESS_ID) {
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:
2248 break;
2249 case llvm::Triple::ELF:
2251 break;
2252 case llvm::Triple::COFF:
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 {
2281 }
2282
2283 return false;
2284}
2285
2287 const ProcessInstanceInfoMatch &match_info,
2288 ProcessInstanceInfoList &process_infos) {
2289 process_infos.clear();
2290
2292 StreamString packet;
2293 packet.PutCString("qfProcessInfo");
2294 if (!match_info.MatchAllProcesses()) {
2295 packet.PutChar(':');
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("name_match:equals;");
2308 break;
2309
2311 packet.PutCString("name_match:contains;");
2312 break;
2313
2315 packet.PutCString("name_match:starts_with;");
2316 break;
2317
2319 packet.PutCString("name_match:ends_with;");
2320 break;
2321
2323 packet.PutCString("name_match:regex;");
2324 break;
2325 }
2326 if (has_name_match) {
2327 packet.PutCString("name:");
2328 packet.PutBytesAsRawHex8(name, ::strlen(name));
2329 packet.PutChar(';');
2330 }
2331 }
2332
2333 if (match_info.GetProcessInfo().ProcessIDIsValid())
2334 packet.Printf("pid:%" PRIu64 ";",
2335 match_info.GetProcessInfo().GetProcessID());
2336 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2337 packet.Printf("parent_pid:%" PRIu64 ";",
2338 match_info.GetProcessInfo().GetParentProcessID());
2339 if (match_info.GetProcessInfo().UserIDIsValid())
2340 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2341 if (match_info.GetProcessInfo().GroupIDIsValid())
2342 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2343 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2344 packet.Printf("euid:%u;",
2345 match_info.GetProcessInfo().GetEffectiveUserID());
2346 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2347 packet.Printf("egid:%u;",
2348 match_info.GetProcessInfo().GetEffectiveGroupID());
2349 packet.Printf("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("triple:");
2355 packet.PutCString(triple.getTriple());
2356 packet.PutChar(';');
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(packet.GetString(), response) ==
2365 do {
2366 ProcessInstanceInfo process_info;
2367 if (!DecodeProcessInfoResponse(response, process_info))
2368 break;
2369 process_infos.push_back(process_info);
2370 response = StringExtractorGDBRemote();
2371 } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==
2373 } else {
2375 return 0;
2376 }
2377 }
2378 return process_infos.size();
2379}
2380
2382 std::string &name) {
2384 char packet[32];
2385 const int packet_len =
2386 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2387 assert(packet_len < (int)sizeof(packet));
2388 UNUSED_IF_ASSERT_DISABLED(packet_len);
2389 StringExtractorGDBRemote response;
2390 if (SendPacketAndWaitForResponse(packet, response) ==
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(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
2409 std::string &name) {
2411 char packet[32];
2412 const int packet_len =
2413 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2414 assert(packet_len < (int)sizeof(packet));
2415 UNUSED_IF_ASSERT_DISABLED(packet_len);
2416 StringExtractorGDBRemote response;
2417 if (SendPacketAndWaitForResponse(packet, response) ==
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(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("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("abcdefghijklmnopqrstuvwxyz");
2443 bytes_left -= 26;
2444 } else {
2445 packet.Printf("%*.*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(std::begin(v), std::end(v), 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(accum / (v.size() - 1)));
2466}
2467
2469 uint32_t max_send,
2470 uint32_t max_recv,
2471 uint64_t recv_amount,
2472 bool json, Stream &strm) {
2473
2474 if (SendSpeedTestPacket(0, 0)) {
2475 StreamString packet;
2476 if (json)
2477 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2478 "\"results\" : [",
2479 num_packets);
2480 else
2481 strm.Printf("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(packet.GetString(), response);
2502 const auto packet_end_time = steady_clock::now();
2503 packet_times.push_back(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(packet_times);
2514 if (json) {
2515 strm.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 result_idx > 0 ? "," : "", send_size, recv_size,
2519 total_time, standard_deviation);
2520 ++result_idx;
2521 } else {
2522 strm.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 send_size, recv_size, duration<float>(total_time),
2526 packets_per_second, duration<float>(average_per_packet),
2527 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("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2536 ": %" PRIu64 ",\n \"results\" : [",
2537 recv_amount);
2538 else
2539 strm.Printf("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(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("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2573 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2574 result_idx > 0 ? "," : "", send_size, recv_size,
2575 total_time);
2576 ++result_idx;
2577 } else {
2578 strm.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 send_size, recv_size, packet_count, k_recv_amount_mb,
2582 duration<float>(total_time), mb_second,
2583 packets_per_second, duration<float>(average_per_packet));
2584 }
2585 strm.Flush();
2586 }
2587 }
2588 if (json)
2589 strm.Printf("\n ]\n }\n}\n");
2590 else
2591 strm.EOL();
2592 }
2593}
2594
2596 uint32_t recv_size) {
2597 StreamString packet;
2598 packet.Printf("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("abcdefghijklmnopqrstuvwxyz");
2603 bytes_left -= 26;
2604 } else {
2605 packet.Printf("%*.*s;", bytes_left, bytes_left,
2606 "abcdefghijklmnopqrstuvwxyz");
2607 bytes_left = 0;
2608 }
2609 }
2610
2611 StringExtractorGDBRemote response;
2612 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
2614}
2615
2617 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2618 std::string &socket_name) {
2620 port = 0;
2621 socket_name.clear();
2622
2623 StringExtractorGDBRemote response;
2624 StreamString stream;
2625 stream.PutCString("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(hostname)) {
2631 // Make the GDB server we launch only accept connections from this host
2632 stream.Printf("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("host:*;");
2637 }
2638 }
2639 // give the process a few seconds to startup
2640 ScopedTimeout timeout(*this, seconds(10));
2641
2642 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
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("port"))
2651 value.getAsInteger(0, port);
2652 else if (name.equals("pid"))
2653 value.getAsInteger(0, pid);
2654 else if (name.compare("socket_name") == 0) {
2655 StringExtractor extractor(value);
2656 extractor.GetHexByteString(socket_name);
2657 }
2658 }
2659 return true;
2660 }
2661 return false;
2662}
2663
2665 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2666 connection_urls.clear();
2667
2668 StringExtractorGDBRemote response;
2669 if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=
2671 return 0;
2672
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 =
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(llvm::StringRef("port")))
2692 port = port_osp->GetUnsignedIntegerValue(0);
2693
2694 std::string socket_name;
2695 if (StructuredData::ObjectSP socket_name_osp =
2696 element->GetValueForKey(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(port, socket_name);
2701 }
2702 return connection_urls.size();
2703}
2704
2706 StreamString stream;
2707 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
2708
2709 StringExtractorGDBRemote response;
2710 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2712 if (response.IsOKResponse())
2713 return true;
2714 }
2715 return false;
2716}
2717
2719 uint64_t tid, uint64_t pid, char op) {
2721 packet.PutChar('H');
2722 packet.PutChar(op);
2723
2724 if (pid != LLDB_INVALID_PROCESS_ID)
2725 packet.Printf("p%" PRIx64 ".", pid);
2726
2727 if (tid == UINT64_MAX)
2728 packet.PutCString("-1");
2729 else
2730 packet.Printf("%" PRIx64, tid);
2731
2732 StringExtractorGDBRemote response;
2733 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2735 if (response.IsOKResponse())
2736 return {{pid, 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 {{1, 1}};
2747 }
2748 return std::nullopt;
2749}
2750
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, '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
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, '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
2782 StringExtractorGDBRemote &response) {
2784 return response.IsNormalResponse();
2785 return false;
2786}
2787
2789 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2791 char packet[256];
2792 int packet_len =
2793 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2794 assert(packet_len < (int)sizeof(packet));
2795 UNUSED_IF_ASSERT_DISABLED(packet_len);
2796 if (SendPacketAndWaitForResponse(packet, response) ==
2798 if (response.IsUnsupportedResponse())
2800 else if (response.IsNormalResponse())
2801 return true;
2802 else
2803 return false;
2804 } else {
2806 }
2807 }
2808 return false;
2809}
2810
2812 GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
2813 std::chrono::seconds timeout) {
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(packet, sizeof(packet), "%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)
2833 // Try to send the breakpoint packet, and check that it was correctly sent
2834 if (SendPacketAndWaitForResponse(packet, response, timeout) ==
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) {
2849 m_supports_z0 = false;
2850 break;
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;
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>>
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("qfThreadInfo", response);
2885 packet_result == PacketResult::Success && response.IsNormalResponse();
2886 packet_result =
2887 SendPacketAndWaitForResponseNoLock("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(*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(1, 1);
2918 }
2919 } else {
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
2930 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
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 &&
2944 thread_ids.push_back(id.second);
2945 }
2946
2947 return thread_ids.size();
2948}
2949
2951 StringExtractorGDBRemote response;
2952 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=
2954 !response.IsNormalResponse())
2955 return LLDB_INVALID_ADDRESS;
2956 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2957}
2958
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) {
2970 stream.PutCString("qPlatform_shell:");
2971 stream.PutBytesAsRawHex8(command.data(), command.size());
2972 stream.PutChar(',');
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(std::chrono::duration<double>(*timeout).count());
2977 }
2978 stream.PutHex32(timeout_sec);
2979 if (working_dir) {
2980 std::string path{working_dir.GetPath(false)};
2981 stream.PutChar(',');
2982 stream.PutStringAsRawHex8(path);
2983 }
2984 StringExtractorGDBRemote response;
2985 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
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(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(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(output);
3005 if (command_output)
3006 command_output->assign(output);
3007 return Status();
3008 }
3009 return Status("unable to send packet");
3010}
3011
3013 uint32_t file_permissions) {
3014 std::string path{file_spec.GetPath(false)};
3016 stream.PutCString("qPlatform_mkdir:");
3017 stream.PutHex32(file_permissions);
3018 stream.PutChar(',');
3019 stream.PutStringAsRawHex8(path);
3020 llvm::StringRef packet = stream.GetString();
3021 StringExtractorGDBRemote response;
3022
3023 if (SendPacketAndWaitForResponse(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(false, UINT32_MAX), eErrorTypePOSIX);
3030}
3031
3032Status
3034 uint32_t file_permissions) {
3035 std::string path{file_spec.GetPath(false)};
3037 stream.PutCString("qPlatform_chmod:");
3038 stream.PutHex32(file_permissions);
3039 stream.PutChar(',');
3040 stream.PutStringAsRawHex8(path);
3041 llvm::StringRef packet = stream.GetString();
3042 StringExtractorGDBRemote response;
3043
3044 if (SendPacketAndWaitForResponse(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(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
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(-2, 16);
3070 if (result == -2)
3071 return fail_result;
3072 if (response.GetChar() == ',') {
3073 int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3074 if (result_errno != -1)
3075 error.SetError(result_errno, eErrorTypePOSIX);
3076 else
3077 error.SetError(-1, eErrorTypeGeneric);
3078 } else
3079 error.Clear();
3080 return result;
3081}
3084 File::OpenOptions flags, mode_t mode,
3085 Status &error) {
3086 std::string path(file_spec.GetPath(false));
3088 stream.PutCString("vFile:open:");
3089 if (path.empty())
3090 return UINT64_MAX;
3091 stream.PutStringAsRawHex8(path);
3092 stream.PutChar(',');
3093 stream.PutHex32(flags);
3094 stream.PutChar(',');
3095 stream.PutHex32(mode);
3096 StringExtractorGDBRemote response;
3097 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3099 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
3100 }
3101 return UINT64_MAX;
3102}
3103
3105 Status &error) {
3107 stream.Printf("vFile:close:%x", (int)fd);
3108 StringExtractorGDBRemote response;
3109 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3111 return ParseHostIOPacketResponse(response, -1, error) == 0;
3112 }
3113 return false;
3114}
3115
3116std::optional<GDBRemoteFStatData>
3119 stream.Printf("vFile:fstat:%" PRIx64, fd);
3120 StringExtractorGDBRemote response;
3121 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3123 if (response.GetChar() != 'F')
3124 return std::nullopt;
3125 int64_t size = response.GetS64(-1, 16);
3126 if (size > 0 && response.GetChar() == ';') {
3127 std::string buffer;
3128 if (response.GetEscapedBinaryData(buffer)) {
3130 if (buffer.size() != sizeof(out))
3131 return std::nullopt;
3132 memcpy(&out, buffer.data(), sizeof(out));
3133 return out;
3134 }
3135 }
3136 }
3137 return std::nullopt;
3138}
3139
3140std::optional<GDBRemoteFStatData>
3142 Status 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.
3153 const lldb_private::FileSpec &file_spec) {
3155 std::string path(file_spec.GetPath(false));
3157 stream.PutCString("vFile:size:");
3158 stream.PutStringAsRawHex8(path);
3159 StringExtractorGDBRemote response;
3160 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
3162 return UINT64_MAX;
3163
3164 if (!response.IsUnsupportedResponse()) {
3165 if (response.GetChar() != 'F')
3166 return UINT64_MAX;
3167 uint32_t retcode = response.GetHexMaxU64(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
3179 CompletionRequest &request, bool only_dir) {
3181 stream.PutCString("qPathComplete:");
3182 stream.PutHex32(only_dir ? 1 : 0);
3183 stream.PutChar(',');
3185 StringExtractorGDBRemote response;
3186 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
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(0, false)) != '\0')
3195 strm.PutChar(ch);
3196 request.AddCompletion(strm.GetString());
3197 if (response.GetChar() != ',')
3198 break;
3199 }
3200 }
3201}
3202
3203Status
3205 uint32_t &file_permissions) {
3207 std::string path{file_spec.GetPath(false)};
3208 Status error;
3210 stream.PutCString("vFile:mode:");
3211 stream.PutStringAsRawHex8(path);
3212 StringExtractorGDBRemote response;
3213 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
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(-1, 16);
3225 if (static_cast<int32_t>(mode) == -1) {
3226 if (response.GetChar() == ',') {
3227 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3228 if (response_errno > 0)
3229 error.SetError(response_errno, 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
3253 uint64_t offset, void *dst,
3254 uint64_t dst_len,
3255 Status &error) {
3257 stream.Printf("vFile:pread:%x,%" PRIx64 ",%" PRIx64, (int)fd, dst_len,
3258 offset);
3259 StringExtractorGDBRemote response;
3260 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3262 if (response.GetChar() != 'F')
3263 return 0;
3264 int64_t retcode = response.GetS64(-1, 16);
3265 if (retcode == -1) {
3266 error.SetErrorToGenericError();
3267 if (response.GetChar() == ',') {
3268 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3269 if (response_errno > 0)
3270 error.SetError(response_errno, 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(buffer)) {
3281 const uint64_t data_to_write =
3282 std::min<uint64_t>(dst_len, buffer.size());
3283 if (data_to_write > 0)
3284 memcpy(dst, &buffer[0], data_to_write);
3285 return data_to_write;
3286 }
3287 }
3288 }
3289 return 0;
3290}
3291
3293 uint64_t offset,
3294 const void *src,
3295 uint64_t src_len,
3296 Status &error) {
3298 stream.Printf("vFile:pwrite:%x,%" PRIx64 ",", (int)fd, offset);
3299 stream.PutEscapedBytes(src, src_len);
3300 StringExtractorGDBRemote response;
3301 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3303 if (response.GetChar() != 'F') {
3304 error.SetErrorStringWithFormat("write file failed");
3305 return 0;
3306 }
3307 int64_t bytes_written = response.GetS64(-1, 16);
3308 if (bytes_written == -1) {
3309 error.SetErrorToGenericError();
3310 if (response.GetChar() == ',') {
3311 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3312 if (response_errno > 0)
3313 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3314 }
3315 return -1;
3316 }
3317 return bytes_written;
3318 } else {
3319 error.SetErrorString("failed to send vFile:pwrite packet");
3320 }
3321 return 0;
3322}
3323
3325 const FileSpec &dst) {
3326 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
3327 Status error;
3329 stream.PutCString("vFile:symlink:");
3330 // the unix symlink() command reverses its parameters where the dst if first,
3331 // so we follow suit here
3332 stream.PutStringAsRawHex8(dst_path);
3333 stream.PutChar(',');
3334 stream.PutStringAsRawHex8(src_path);
3335 StringExtractorGDBRemote response;
3336 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3338 if (response.GetChar() == 'F') {
3339 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
3340 if (result != 0) {
3341 error.SetErrorToGenericError();
3342 if (response.GetChar() == ',') {
3343 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3344 if (response_errno > 0)
3345 error.SetError(response_errno, 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
3359 std::string path{file_spec.GetPath(false)};
3360 Status error;
3362 stream.PutCString("vFile:unlink:");
3363 // the unix symlink() command reverses its parameters where the dst if first,
3364 // so we follow suit here
3365 stream.PutStringAsRawHex8(path);
3366 StringExtractorGDBRemote response;
3367 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3369 if (response.GetChar() == 'F') {
3370 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
3371 if (result != 0) {
3372 error.SetErrorToGenericError();
3373 if (response.GetChar() == ',') {
3374 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3375 if (response_errno > 0)
3376 error.SetError(response_errno, 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.
3391 const lldb_private::FileSpec &file_spec) {
3393 std::string path(file_spec.GetPath(false));
3395 stream.PutCString("vFile:exists:");
3396 stream.PutStringAsRawHex8(path);
3397 StringExtractorGDBRemote response;
3398 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
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;
3415 if (fd == UINT64_MAX)
3416 return false;
3417 CloseFile(fd, error);
3418 return true;
3419}
3420
3422 const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
3423 std::string path(file_spec.GetPath(false));
3425 stream.PutCString("vFile:MD5:");
3426 stream.PutStringAsRawHex8(path);
3427 StringExtractorGDBRemote response;
3428 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
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 low = response.GetHexMaxU64(false, UINT64_MAX);
3437 high = response.GetHexMaxU64(false, UINT64_MAX);
3438 return true;
3439 }
3440 return false;
3441}
3442
3444 // Some targets have issues with g/G packets and we need to avoid using them
3446 if (process) {
3448 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3449 if (arch.IsValid() &&
3450 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3451 arch.GetTriple().getOS() == llvm::Triple::IOS &&
3452 (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
3453 arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3455 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3456 if (gdb_server_version != 0) {
3457 const char *gdb_server_name = GetGDBServerProgramName();
3458 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3459 if (gdb_server_version >= 310)
3461 }
3462 }
3463 }
3464 }
3465 }
3467}
3468
3470 uint32_t reg) {
3471 StreamString payload;
3472 payload.Printf("p%x", reg);
3473 StringExtractorGDBRemote response;
3475 tid, std::move(payload), response) != PacketResult::Success ||
3476 !response.IsNormalResponse())
3477 return nullptr;
3478
3479 WritableDataBufferSP buffer_sp(
3480 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3481 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3482 return buffer_sp;
3483}
3484
3486 StreamString payload;
3487 payload.PutChar('g');
3488 StringExtractorGDBRemote response;
3490 tid, std::move(payload), response) != PacketResult::Success ||
3491 !response.IsNormalResponse())
3492 return nullptr;
3493
3494 WritableDataBufferSP buffer_sp(
3495 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3496 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3497 return buffer_sp;
3498}
3499
3501 uint32_t reg_num,
3502 llvm::ArrayRef<uint8_t> data) {
3503 StreamString payload;
3504 payload.Printf("P%x=", reg_num);
3505 payload.PutBytesAsRawHex8(data.data(), data.size(),
3508 StringExtractorGDBRemote response;
3510 tid, std::move(payload), response) == PacketResult::Success &&
3511 response.IsOKResponse();
3512}
3513
3515 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3516 StreamString payload;
3517 payload.PutChar('G');
3518 payload.PutBytesAsRawHex8(data.data(), data.size(),
3521 StringExtractorGDBRemote response;
3523 tid, std::move(payload), response) == PacketResult::Success &&
3524 response.IsOKResponse();
3525}
3526
3528 uint32_t &save_id) {
3529 save_id = 0; // Set to invalid save ID
3531 return false;
3532
3534 StreamString payload;
3535 payload.PutCString("QSaveRegisterState");
3536 StringExtractorGDBRemote response;
3538 tid, std::move(payload), response) != PacketResult::Success)
3539 return false;
3540
3541 if (response.IsUnsupportedResponse())
3543
3544 const uint32_t response_save_id = response.GetU32(0);
3545 if (response_save_id == 0)
3546 return false;
3547
3548 save_id = response_save_id;
3549 return true;
3550}
3551
3553 uint32_t save_id) {
3554 // We use the "m_supports_QSaveRegisterState" variable here because the
3555 // QSaveRegisterState and QRestoreRegisterState packets must both be
3556 // supported in order to be useful
3558 return false;
3559
3560 StreamString payload;
3561 payload.Printf("QRestoreRegisterState:%u", save_id);
3562 StringExtractorGDBRemote response;
3564 tid, std::move(payload), response) != PacketResult::Success)
3565 return false;
3566
3567 if (response.IsOKResponse())
3568 return true;
3569
3570 if (response.IsUnsupportedResponse())
3572 return false;
3573}
3574
3577 return false;
3578
3579 StreamString packet;
3580 StringExtractorGDBRemote response;
3581 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3582 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
3584 response.IsOKResponse();
3585}
3586
3587llvm::Expected<TraceSupportedResponse>
3589 Log *log = GetLog(GDBRLog::Process);
3590
3591 StreamGDBRemote escaped_packet;
3592 escaped_packet.PutCString("jLLDBTraceSupported");
3593
3594 StringExtractorGDBRemote response;
3595 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3596 timeout) ==
3598 if (response.IsErrorResponse())
3599 return response.GetStatus().ToError();
3600 if (response.IsUnsupportedResponse())
3601 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3602 "jLLDBTraceSupported is unsupported");
3603
3604 return llvm::json::parse<TraceSupportedResponse>(response.Peek(),
3605 "TraceSupportedResponse");
3606 }
3607 LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");
3608 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3609 "failed to send packet: jLLDBTraceSupported");
3610}
3611
3612llvm::Error
3614 std::chrono::seconds timeout) {
3615 Log *log = GetLog(GDBRLog::Process);
3616
3617 StreamGDBRemote escaped_packet;
3618 escaped_packet.PutCString("jLLDBTraceStop:");
3619
3620 std::string json_string;
3621 llvm::raw_string_ostream os(json_string);
3622 os << toJSON(request);
3623 os.flush();
3624
3625 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3626
3627 StringExtractorGDBRemote response;
3628 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3629 timeout) ==
3631 if (response.IsErrorResponse())
3632 return response.GetStatus().ToError();
3633 if (response.IsUnsupportedResponse())
3634 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3635 "jLLDBTraceStop is unsupported");
3636 if (response.IsOKResponse())
3637 return llvm::Error::success();
3638 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3639 "Invalid jLLDBTraceStart response");
3640 }
3641 LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");
3642 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3643 "failed to send packet: jLLDBTraceStop '%s'",
3644 escaped_packet.GetData());
3645}
3646
3647llvm::Error
3648GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
3649 std::chrono::seconds timeout) {
3650 Log *log = GetLog(GDBRLog::Process);
3651
3652 StreamGDBRemote escaped_packet;
3653 escaped_packet.PutCString("jLLDBTraceStart:");
3654
3655 std::string json_string;
3656 llvm::raw_string_ostream os(json_string);
3657 os << params;
3658 os.flush();
3659
3660 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3661
3662 StringExtractorGDBRemote response;
3663 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3664 timeout) ==
3666 if (response.IsErrorResponse())
3667 return response.GetStatus().ToError();
3668 if (response.IsUnsupportedResponse())
3669 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3670 "jLLDBTraceStart is unsupported");
3671 if (response.IsOKResponse())
3672 return llvm::Error::success();
3673 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3674 "Invalid jLLDBTraceStart response");
3675 }
3676 LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");
3677 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3678 "failed to send packet: jLLDBTraceStart '%s'",
3679 escaped_packet.GetData());
3680}
3681
3682llvm::Expected<std::string>
3684 std::chrono::seconds timeout) {
3685 Log *log = GetLog(GDBRLog::Process);
3686
3687 StreamGDBRemote escaped_packet;
3688 escaped_packet.PutCString("jLLDBTraceGetState:");
3689
3690 std::string json_string;
3691 llvm::raw_string_ostream os(json_string);
3692 os << toJSON(TraceGetStateRequest{type.str()});
3693 os.flush();
3694
3695 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3696
3697 StringExtractorGDBRemote response;
3698 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3699 timeout) ==
3701 if (response.IsErrorResponse())
3702 return response.GetStatus().ToError();
3703 if (response.IsUnsupportedResponse())
3704 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3705 "jLLDBTraceGetState is unsupported");
3706 return std::string(response.Peek());
3707 }
3708
3709 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");
3710 return llvm::createStringError(
3711 llvm::inconvertibleErrorCode(),
3712 "failed to send packet: jLLDBTraceGetState '%s'",
3713 escaped_packet.GetData());
3714}
3715
3716llvm::Expected<std::vector<uint8_t>>
3718 const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {
3719 Log *log = GetLog(GDBRLog::Process);
3720
3721 StreamGDBRemote escaped_packet;
3722 escaped_packet.PutCString("jLLDBTraceGetBinaryData:");
3723
3724 std::string json_string;
3725 llvm::raw_string_ostream os(json_string);
3726 os << toJSON(request);
3727 os.flush();
3728
3729 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3730
3731 StringExtractorGDBRemote response;
3732 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3733 timeout) ==
3735 if (response.IsErrorResponse())
3736 return response.GetStatus().ToError();
3737 std::string data;
3738 response.GetEscapedBinaryData(data);
3739 return std::vector<uint8_t>(data.begin(), data.end());
3740 }
3741 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");
3742 return llvm::createStringError(
3743 llvm::inconvertibleErrorCode(),
3744 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3745 escaped_packet.GetData());
3746}
3747
3749 StringExtractorGDBRemote response;
3750 if (SendPacketAndWaitForResponse("qOffsets", response) !=
3752 return std::nullopt;
3753 if (!response.IsNormalResponse())
3754 return std::nullopt;
3755
3756 QOffsets result;
3757 llvm::StringRef ref = response.GetStringRef();
3758 const auto &GetOffset = [&] {
3759 addr_t offset;
3760 if (ref.consumeInteger(16, offset))
3761 return false;
3762 result.offsets.push_back(offset);
3763 return true;
3764 };
3765
3766 if (ref.consume_front("Text=")) {
3767 result.segments = false;
3768 if (!GetOffset())
3769 return std::nullopt;
3770 if (!ref.consume_front(";Data=") || !GetOffset())
3771 return std::nullopt;
3772 if (ref.empty())
3773 return result;
3774 if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())
3775 return result;
3776 } else if (ref.consume_front("TextSeg=")) {
3777 result.segments = true;
3778 if (!GetOffset())
3779 return std::nullopt;
3780 if (ref.empty())
3781 return result;
3782 if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())
3783 return result;
3784 }
3785 return std::nullopt;
3786}
3787
3789 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3790 ModuleSpec &module_spec) {
3792 return false;
3793
3794 std::string module_path = module_file_spec.GetPath(false);
3795 if (module_path.empty())
3796 return false;
3797
3798 StreamString packet;
3799 packet.PutCString("qModuleInfo:");
3800 packet.PutStringAsRawHex8(module_path);
3801 packet.PutCString(";");
3802 const auto &triple = arch_spec.GetTriple().getTriple();
3803 packet.PutStringAsRawHex8(triple);
3804
3805 StringExtractorGDBRemote response;
3806 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
3808 return false;
3809
3810 if (response.IsErrorResponse())
3811 return false;
3812
3813 if (response.IsUnsupportedResponse()) {
3814 m_supports_qModuleInfo = false;
3815 return false;
3816 }
3817
3818 llvm::StringRef name;
3819 llvm::StringRef value;
3820
3821 module_spec.Clear();
3822 module_spec.GetFileSpec() = module_file_spec;
3823
3824 while (response.GetNameColonValue(name, value)) {
3825 if (name == "uuid" || name == "md5") {
3826 StringExtractor extractor(value);
3827 std::string uuid;
3828 extractor.GetHexByteString(uuid);
3829 module_spec.GetUUID().SetFromStringRef(uuid);
3830 } else if (name == "triple") {
3831 StringExtractor extractor(value);
3832 std::string triple;
3833 extractor.GetHexByteString(triple);
3834 module_spec.GetArchitecture().SetTriple(triple.c_str());
3835 } else if (name == "file_offset") {
3836 uint64_t ival = 0;
3837 if (!value.getAsInteger(16, ival))
3838 module_spec.SetObjectOffset(ival);
3839 } else if (name == "file_size") {
3840 uint64_t ival = 0;
3841 if (!value.getAsInteger(16, ival))
3842 module_spec.SetObjectSize(ival);
3843 } else if (name == "file_path") {
3844 StringExtractor extractor(value);
3845 std::string path;
3846 extractor.GetHexByteString(path);
3847 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
3848 }
3849 }
3850
3851 return true;
3852}
3853
3854static std::optional<ModuleSpec>
3856 ModuleSpec result;
3857 if (!dict)
3858 return std::nullopt;
3859
3860 llvm::StringRef string;
3861 uint64_t integer;
3862
3863 if (!dict->GetValueForKeyAsString("uuid", string))
3864 return std::nullopt;
3865 if (!result.GetUUID().SetFromStringRef(string))
3866 return std::nullopt;
3867
3868 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3869 return std::nullopt;
3870 result.SetObjectOffset(integer);
3871
3872 if (!dict->GetValueForKeyAsInteger("file_size", integer))
3873 return std::nullopt;
3874 result.SetObjectSize(integer);
3875
3876 if (!dict->GetValueForKeyAsString("triple", string))
3877 return std::nullopt;
3878 result.GetArchitecture().SetTriple(string);
3879
3880 if (!dict->GetValueForKeyAsString("file_path", string))
3881 return std::nullopt;
3882 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
3883
3884 return result;
3885}
3886
3887std::optional<std::vector<ModuleSpec>>
3889 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
3890 namespace json = llvm::json;
3891
3893 return std::nullopt;
3894
3895 json::Array module_array;
3896 for (const FileSpec &module_file_spec : module_file_specs) {
3897 module_array.push_back(
3898 json::Object{{"file", module_file_spec.GetPath(false)},
3899 {"triple", triple.getTriple()}});
3900 }
3901 StreamString unescaped_payload;
3902 unescaped_payload.PutCString("jModulesInfo:");
3903 unescaped_payload.AsRawOstream() << std::move(module_array);
3904
3905 StreamGDBRemote payload;
3906 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
3907 unescaped_payload.GetSize());
3908
3909 // Increase the timeout for jModulesInfo since this packet can take longer.
3910 ScopedTimeout timeout(*this, std::chrono::seconds(10));
3911
3912 StringExtractorGDBRemote response;
3913 if (SendPacketAndWaitForResponse(payload.GetString(), response) !=
3915 response.IsErrorResponse())
3916 return std::nullopt;
3917
3918 if (response.IsUnsupportedResponse()) {
3920 return std::nullopt;
3921 }
3922
3923 StructuredData::ObjectSP response_object_sp =
3925 if (!response_object_sp)
3926 return std::nullopt;
3927
3928 StructuredData::Array *response_array = response_object_sp->GetAsArray();
3929 if (!response_array)
3930 return std::nullopt;
3931
3932 std::vector<ModuleSpec> result;
3933 for (size_t i = 0; i < response_array->GetSize(); ++i) {
3934 if (std::optional<ModuleSpec> module_spec = ParseModuleSpec(
3935 response_array->GetItemAtIndex(i)->GetAsDictionary()))
3936 result.push_back(*module_spec);
3937 }
3938
3939 return result;
3940}
3941
3942// query the target remote for extended information using the qXfer packet
3943//
3944// example: object='features', annex='target.xml'
3945// return: <xml output> or error
3946llvm::Expected<std::string>
3948 llvm::StringRef annex) {
3949
3950 std::string output;
3951 llvm::raw_string_ostream output_stream(output);
3953
3954 uint64_t size = GetRemoteMaxPacketSize();
3955 if (size == 0)
3956 size = 0x1000;
3957 size = size - 1; // Leave space for the 'm' or 'l' character in the response
3958 int offset = 0;
3959 bool active = true;
3960
3961 // loop until all data has been read
3962 while (active) {
3963
3964 // send query extended feature packet
3965 std::string packet =
3966 ("qXfer:" + object + ":read:" + annex + ":" +
3967 llvm::Twine::utohexstr(offset) + "," + llvm::Twine::utohexstr(size))
3968 .str();
3969
3971 SendPacketAndWaitForResponse(packet, chunk);
3972
3974 chunk.GetStringRef().empty()) {
3975 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3976 "Error sending $qXfer packet");
3977 }
3978
3979 // check packet code
3980 switch (chunk.GetStringRef()[0]) {
3981 // last chunk
3982 case ('l'):
3983 active = false;
3984 [[fallthrough]];
3985
3986 // more chunks
3987 case ('m'):
3988 output_stream << chunk.GetStringRef().drop_front();
3989 offset += chunk.GetStringRef().size() - 1;
3990 break;
3991
3992 // unknown chunk
3993 default:
3994 return llvm::createStringError(
3995 llvm::inconvertibleErrorCode(),
3996 "Invalid continuation code from $qXfer packet");
3997 }
3998 }
3999
4000 return output_stream.str();
4001}
4002
4003// Notify the target that gdb is prepared to serve symbol lookup requests.
4004// packet: "qSymbol::"
4005// reply:
4006// OK The target does not need to look up any (more) symbols.
4007// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
4008// encoded).
4009// LLDB may provide the value by sending another qSymbol
4010// packet
4011// in the form of"qSymbol:<sym_value>:<sym_name>".
4012//
4013// Three examples:
4014//
4015// lldb sends: qSymbol::
4016// lldb receives: OK
4017// Remote gdb stub does not need to know the addresses of any symbols, lldb
4018// does not
4019// need to ask again in this session.
4020//
4021// lldb sends: qSymbol::
4022// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4023// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
4024// lldb receives: OK
4025// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
4026// not know
4027// the address at this time. lldb needs to send qSymbol:: again when it has
4028// more
4029// solibs loaded.
4030//
4031// lldb sends: qSymbol::
4032// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4033// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
4034// lldb receives: OK
4035// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
4036// that it
4037// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
4038// does not
4039// need any more symbols. lldb does not need to ask again in this session.
4040
4042 lldb_private::Process *process) {
4043 // Set to true once we've resolved a symbol to an address for the remote
4044 // stub. If we get an 'OK' response after this, the remote stub doesn't need
4045 // any more symbols and we can stop asking.
4046 bool symbol_response_provided = false;
4047
4048 // Is this the initial qSymbol:: packet?
4049 bool first_qsymbol_query = true;
4050
4052 Lock lock(*this);
4053 if (lock) {
4054 StreamString packet;
4055 packet.PutCString("qSymbol::");
4056 StringExtractorGDBRemote response;
4057 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
4059 if (response.IsOKResponse()) {
4060 if (symbol_response_provided || first_qsymbol_query) {
4062 }
4063
4064 // We are done serving symbols requests
4065 return;
4066 }
4067 first_qsymbol_query = false;
4068
4069 if (response.IsUnsupportedResponse()) {
4070 // qSymbol is not supported by the current GDB server we are
4071 // connected to
4072 m_supports_qSymbol = false;
4073 return;
4074 } else {
4075 llvm::StringRef response_str(response.GetStringRef());
4076 if (response_str.starts_with("qSymbol:")) {
4077 response.SetFilePos(strlen("qSymbol:"));
4078 std::string symbol_name;
4079 if (response.GetHexByteString(symbol_name)) {
4080 if (symbol_name.empty())
4081 return;
4082
4083 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
4086 ConstString(symbol_name), eSymbolTypeAny, sc_list);
4087 for (const SymbolContext &sc : sc_list) {
4088 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
4089 break;
4090 if (sc.symbol) {
4091 switch (sc.symbol->GetType()) {
4092 case eSymbolTypeInvalid:
4099 case eSymbolTypeBlock:
4100 case eSymbolTypeLocal:
4101 case eSymbolTypeParam:
4112 break;
4113
4114 case eSymbolTypeCode:
4116 case eSymbolTypeData:
4117 case eSymbolTypeRuntime:
4123 symbol_load_addr =
4124 sc.symbol->GetLoadAddress(&process->GetTarget());
4125 break;
4126 }
4127 }
4128 }
4129 // This is the normal path where our symbol lookup was successful
4130 // and we want to send a packet with the new symbol value and see
4131 // if another lookup needs to be done.
4132
4133 // Change "packet" to contain the requested symbol value and name
4134 packet.Clear();
4135 packet.PutCString("qSymbol:");
4136 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
4137 packet.Printf("%" PRIx64, symbol_load_addr);
4138 symbol_response_provided = true;
4139 } else {
4140 symbol_response_provided = false;
4141 }
4142 packet.PutCString(":");
4143 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
4144 continue; // go back to the while loop and send "packet" and wait
4145 // for another response
4146 }
4147 }
4148 }
4149 }
4150 // If we make it here, the symbol request packet response wasn't valid or
4151 // our symbol lookup failed so we must abort
4152 return;
4153
4154 } else if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets)) {
4155 LLDB_LOGF(log,
4156 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4157 __FUNCTION__);
4158 }
4159 }
4160}
4161
4165 // Query the server for the array of supported asynchronous JSON packets.
4167
4168 Log *log = GetLog(GDBRLog::Process);
4169
4170 // Poll it now.
4171 StringExtractorGDBRemote response;
4172 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==
4177 !m_supported_async_json_packets_sp->GetAsArray()) {
4178 // We were returned something other than a JSON array. This is
4179 // invalid. Clear it out.
4180 LLDB_LOGF(log,
4181 "GDBRemoteCommunicationClient::%s(): "
4182 "QSupportedAsyncJSONPackets returned invalid "
4183 "result: %s",
4184 __FUNCTION__, response.GetStringRef().data());
4186 }
4187 } else {
4188 LLDB_LOGF(log,
4189 "GDBRemoteCommunicationClient::%s(): "
4190 "QSupportedAsyncJSONPackets unsupported",
4191 __FUNCTION__);
4192 }
4193
4195 StreamString stream;
4197 LLDB_LOGF(log,
4198 "GDBRemoteCommunicationClient::%s(): supported async "
4199 "JSON packets: %s",
4200 __FUNCTION__, stream.GetData());
4201 }
4202 }
4203
4205 ? m_supported_async_json_packets_sp->GetAsArray()
4206 : nullptr;
4207}
4208
4210 llvm::ArrayRef<int32_t> signals) {
4211 // Format packet:
4212 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
4213 auto range = llvm::make_range(signals.begin(), signals.end());
4214 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
4215
4216 StringExtractorGDBRemote response;
4217 auto send_status = SendPacketAndWaitForResponse(packet, response);
4218
4220 return Status("Sending QPassSignals packet failed");
4221
4222 if (response.IsOKResponse()) {
4223 return Status();
4224 } else {
4225 return Status("Unknown error happened during sending QPassSignals packet.");
4226 }
4227}
4228
4230 llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) {
4231 Status error;
4232
4233 if (type_name.empty()) {
4234 error.SetErrorString("invalid type_name argument");
4235 return error;
4236 }
4237
4238 // Build command: Configure{type_name}: serialized config data.
4239 StreamGDBRemote stream;
4240 stream.PutCString("QConfigure");
4241 stream.PutCString(type_name);
4242 stream.PutChar(':');
4243 if (config_sp) {
4244 // Gather the plain-text version of the configuration data.
4245 StreamString unescaped_stream;
4246 config_sp->Dump(unescaped_stream);
4247 unescaped_stream.Flush();
4248
4249 // Add it to the stream in escaped fashion.
4250 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
4251 unescaped_stream.GetSize());
4252 }
4253 stream.Flush();
4254
4255 // Send the packet.
4256 StringExtractorGDBRemote response;
4257 auto result = SendPacketAndWaitForResponse(stream.GetString(), response);
4258 if (result == PacketResult::Success) {
4259 // We failed if the config result comes back other than OK.
4260 if (response.GetStringRef() == "OK") {
4261 // Okay!
4262 error.Clear();
4263 } else {
4264 error.SetErrorStringWithFormatv(
4265 "configuring StructuredData feature {0} failed with error {1}",
4266 type_name, response.GetStringRef());
4267 }
4268 } else {
4269 // Can we get more data here on the failure?
4270 error.SetErrorStringWithFormatv(
4271 "configuring StructuredData feature {0} failed when sending packet: "
4272 "PacketResult={1}",
4273 type_name, (int)result);
4274 }
4275 return error;
4276}
4277
4281}
4282
4287 return true;
4288
4289 // If the remote didn't indicate native-signal support explicitly,
4290 // check whether it is an old version of lldb-server.
4291 return GetThreadSuffixSupported();
4292}
4293
4295 StringExtractorGDBRemote response;
4296 GDBRemoteCommunication::ScopedTimeout(*this, seconds(3));
4297
4298 if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout()) !=
4300 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4301 "failed to send k packet");
4302
4303 char packet_cmd = response.GetChar(0);
4304 if (packet_cmd == 'W' || packet_cmd == 'X')
4305 return response.GetHexU8();
4306
4307 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4308 "unexpected response to k packet: %s",
4309 response.GetStringRef().str().c_str());
4310}
static llvm::raw_ostream & error(Stream &strm)
#define integer
duration< float > calculate_standard_deviation(const std::vector< duration< float > > &v)
static std::optional< ModuleSpec > ParseModuleSpec(StructuredData::Dictionary *dict)
static int gdb_errno_to_system(int err)
static void ParseOSType(llvm::StringRef value, std::string &os_name, std::string &environment)
static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, uint64_t fail_result, Status &error)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:342
#define LLDB_LOGF(log,...)
Definition: Log.h:349
static constexpr lldb::tid_t AllThreads
size_t GetEscapedBinaryData(std::string &str)
static constexpr lldb::pid_t AllProcesses
std::optional< std::pair< lldb::pid_t, lldb::tid_t > > GetPidTid(lldb::pid_t default_pid)
ResponseType GetResponseType() const
void SetFilePos(uint32_t idx)
int64_t GetS64(int64_t fail_value, int base=0)
uint32_t GetHexMaxU32(bool little_endian, uint32_t fail_value)
uint64_t GetHexMaxU64(bool little_endian, uint64_t fail_value)
size_t GetBytesLeft()
bool GetNameColonValue(llvm::StringRef &name, llvm::StringRef &value)
uint64_t GetU64(uint64_t fail_value, int base=0)
size_t GetHexBytesAvail(llvm::MutableArrayRef< uint8_t > dest)
size_t GetHexByteString(std::string &str)
uint8_t GetHexU8(uint8_t fail_value=0, bool set_eof_on_fail=true)
char GetChar(char fail_value='\0')
const char * Peek()
int32_t GetS32(int32_t fail_value, int base=0)
size_t GetHexBytes(llvm::MutableArrayRef< uint8_t > dest, uint8_t fail_fill_value)
llvm::StringRef GetStringRef() const
uint32_t GetU32(uint32_t fail_value, int base=0)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
Definition: ArchSpec.h:31
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:691
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:348
void Clear()
Clears the object state.
Definition: ArchSpec.cpp:542
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:450
void SetFlags(uint32_t flags)
Definition: ArchSpec.h:523
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition: ArchSpec.cpp:747
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
Definition: ArchSpec.cpp:851
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:738
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:683
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition: ArchSpec.cpp:552
A command line argument class.
Definition: Args.h:33
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
Definition: Args.cpp:322
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition: Args.cpp:263
void Clear()
Clear the arguments.
Definition: Args.cpp:378
bool IsConnected() const
Check if the connection is valid.
virtual lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
llvm::StringRef GetCursorArgumentPrefix() const
A uniqued constant string class.
Definition: ConstString.h:40
A subclass of DataBuffer that stores a data buffer on the heap.
A file utility class.
Definition: FileSpec.h:56
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:174
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
@ eOpenOptionReadOnly
Definition: File.h:51
void SetFlash(OptionalBool val)
void SetMapped(OptionalBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetMemoryTagged(OptionalBool val)
void SetReadable(OptionalBool val)
void SetExecutable(OptionalBool val)
void SetIsStackMemory(OptionalBool val)
void SetName(const char *name)
void SetWritable(OptionalBool val)
lldb::offset_t GetBlocksize() const
void SetDirtyPageList(std::vector< lldb::addr_t > pagelist)
OptionalBool GetFlash() const
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:527
void SetObjectSize(uint64_t object_size)
Definition: ModuleSpec.h:115
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:89
void SetObjectOffset(uint64_t object_offset)
Definition: ModuleSpec.h:109
void SetGroupID(uint32_t gid)
Definition: ProcessInfo.h:59
bool ProcessIDIsValid() const
Definition: ProcessInfo.h:71
void SetArg0(llvm::StringRef arg)
Definition: ProcessInfo.cpp:82
const char * GetName() const
Definition: ProcessInfo.cpp:45
lldb::pid_t GetProcessID() const
Definition: ProcessInfo.h:67
void SetProcessID(lldb::pid_t pid)
Definition: ProcessInfo.h:69
FileSpec & GetExecutableFile()
Definition: ProcessInfo.h:42
bool UserIDIsValid() const
Definition: ProcessInfo.h:53
uint32_t GetUserID() const
Definition: ProcessInfo.h:49
uint32_t GetGroupID() const
Definition: ProcessInfo.h:51
void SetUserID(uint32_t uid)
Definition: ProcessInfo.h:57
bool GroupIDIsValid() const
Definition: ProcessInfo.h:55
ArchSpec & GetArchitecture()
Definition: ProcessInfo.h:61
ProcessInstanceInfo & GetProcessInfo()
Definition: ProcessInfo.h:225
uint32_t GetEffectiveUserID() const
Definition: ProcessInfo.h:155
void SetEffectiveGroupID(uint32_t gid)
Definition: ProcessInfo.h:165
lldb::pid_t GetParentProcessID() const
Definition: ProcessInfo.h:167
uint32_t GetEffectiveGroupID() const
Definition: ProcessInfo.h:157
void SetParentProcessID(lldb::pid_t pid)
Definition: ProcessInfo.h:169
void SetEffectiveUserID(uint32_t uid)
Definition: ProcessInfo.h:163
A plug-in interface definition class for debugging a process.
Definition: Process.h:341
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1277
An error handling class.
Definition: Status.h:44
llvm::Error ToError() const
Definition: Status.cpp:89
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:247
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:233
bool Success() const
Test for success condition.
Definition: Status.cpp:279
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
Definition: GDBRemote.cpp:28
const char * GetData() const
Definition: StreamString.h:43
void Flush() override
Flush the stream.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void Format(const char *format, Args &&... args)
Definition: Stream.h:353
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition: Stream.h:401
size_t PutStringAsRawHex8(llvm::StringRef s)
Definition: Stream.cpp:410
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition: Stream.cpp:299
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:65
size_t PutChar(char ch)
Definition: Stream.cpp:131
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition: Stream.cpp:283
virtual void Flush()=0
Flush the stream.
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:155
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
Definition: Stream.cpp:383
ObjectSP GetItemAtIndex(size_t idx) const
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
ObjectSP GetValueForKey(llvm::StringRef key) const
uint64_t GetUnsignedIntegerValue(uint64_t fail_value=0)
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
Defines a list of symbol context objects.
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:972
const ArchSpec & GetArchitecture() const
Definition: Target.h:1014
bool SetFromStringRef(llvm::StringRef str)
Definition: UUID.cpp:97
bool IsValid() const
Definition: UUID.h:69