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