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