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