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
18#include "lldb/Core/Module.h"
20#include "lldb/Host/HostInfo.h"
21#include "lldb/Host/SafeMachO.h"
22#include "lldb/Host/XML.h"
23#include "lldb/Symbol/Symbol.h"
25#include "lldb/Target/Target.h"
28#include "lldb/Utility/Args.h"
32#include "lldb/Utility/Log.h"
33#include "lldb/Utility/State.h"
35
36#include "ProcessGDBRemote.h"
37#include "ProcessGDBRemoteLog.h"
38#include "lldb/Host/Config.h"
40
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
43#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_ZLIB
44#include "llvm/Support/ErrorExtras.h"
45#include "llvm/Support/JSON.h"
46#include "llvm/TargetParser/Triple.h"
47
48#if HAVE_LIBCOMPRESSION
49#include <compression.h>
50#endif
51
52using namespace lldb;
54using namespace lldb_private;
55using namespace std::chrono;
56
57llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,
58 const QOffsets &offsets) {
59 return os << llvm::formatv(
60 "QOffsets({0}, [{1:@[x]}])", offsets.segments,
61 llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));
62}
63
64// GDBRemoteCommunicationClient constructor
83
84// Destructor
89
92
93 // Start the read thread after we send the handshake ack since if we fail to
94 // send the handshake ack, there is no reason to continue...
95 std::chrono::steady_clock::time_point start_of_handshake =
96 std::chrono::steady_clock::now();
97 if (SendAck()) {
98 // The return value from QueryNoAckModeSupported() is true if the packet
99 // was sent and _any_ response (including UNIMPLEMENTED) was received), or
100 // false if no response was received. This quickly tells us if we have a
101 // live connection to a remote GDB server...
103 return true;
104 } else {
105 std::chrono::steady_clock::time_point end_of_handshake =
106 std::chrono::steady_clock::now();
107 auto handshake_timeout =
108 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
109 .count();
110 if (error_ptr) {
111 if (!IsConnected())
112 *error_ptr =
113 Status::FromErrorString("Connection shut down by remote side "
114 "while waiting for reply to initial "
115 "handshake packet");
116 else
118 "failed to get reply to handshake packet within timeout of "
119 "%.1f seconds",
120 handshake_timeout);
121 }
122 }
123 } else {
124 if (error_ptr)
125 *error_ptr = Status::FromErrorString("failed to send the handshake ack");
126 }
127 return false;
128}
129
136
143
150
157
164
171
178
185
192
198
205
211
217
223
229
235
241
242llvm::Expected<std::vector<AcceleratorActions>>
244 // Get the initial actions (e.g. breakpoints to set) requested by any
245 // accelerator plugins using the "jAcceleratorPluginInitialize" packet. This
246 // is sent once when a native process is launched or attached. The empty
247 // state (no plugins / no actions) is modelled as an empty vector; errors are
248 // returned to the caller to report.
250 return std::vector<AcceleratorActions>();
251
254 if (SendPacketAndWaitForResponse("jAcceleratorPluginInitialize", response) !=
256 return llvm::createStringError(
257 "failed to send jAcceleratorPluginInitialize packet");
258
259 if (response.IsUnsupportedResponse())
260 return std::vector<AcceleratorActions>();
261
262 if (response.IsErrorResponse())
263 return response.GetStatus().takeError();
264
265 llvm::Expected<std::vector<AcceleratorActions>> actions =
266 llvm::json::parse<std::vector<AcceleratorActions>>(response.Peek(),
267 "AcceleratorActions");
268 if (actions)
269 return actions;
270
271 // A bare JSON parse error (e.g. "missing comma at line 4") is meaningless on
272 // its own, so include both the full response and the parse error; the caller
273 // logs this and the user can spot the problem in the response.
274 return llvm::createStringErrorV(
275 "malformed jAcceleratorPluginInitialize response '{0}': {1}",
276 response.GetStringRef(), llvm::toString(actions.takeError()));
277}
278
283 return std::nullopt;
284 if (m_lldb_settings)
285 return m_lldb_settings;
286
289 if (SendPacketAndWaitForResponse("jLLDBSettings", response) !=
291 return std::nullopt;
292
293 if (response.IsUnsupportedResponse()) {
295 return std::nullopt;
296 }
297 if (response.IsErrorResponse())
298 return std::nullopt;
299
300 llvm::Expected<LLDBSettings> settings =
301 llvm::json::parse<LLDBSettings>(response.Peek(), "LLDBSettings");
302 if (!settings) {
304 LLDB_LOG_ERROR(log, settings.takeError(),
305 "malformed jLLDBSettings response '{1}': {0}",
306 response.GetStringRef());
307 return std::nullopt;
308 }
309
310 m_lldb_settings = std::move(*settings);
311 return m_lldb_settings;
312}
313
314llvm::Expected<AcceleratorBreakpointHitResponse>
316 const AcceleratorBreakpointHitArgs &args) {
317 StreamGDBRemote packet;
318 packet.PutCString("jAcceleratorPluginBreakpointHit:");
319 packet.PutAsJSON(args, /*hex_ascii=*/false);
320
322 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
324 return llvm::createStringError(
325 "failed to send jAcceleratorPluginBreakpointHit packet");
326
327 if (response.IsErrorResponse())
328 return response.GetStatus().takeError();
329
330 llvm::Expected<AcceleratorBreakpointHitResponse> hit_response =
331 llvm::json::parse<AcceleratorBreakpointHitResponse>(
332 response.Peek(), "AcceleratorBreakpointHitResponse");
333 if (hit_response)
334 return hit_response;
335
336 // A bare JSON parse error (e.g. "missing comma at line 4") is meaningless on
337 // its own, so include both the full response and the parse error; the caller
338 // logs this and the user can spot the problem in the response.
339 return llvm::createStringErrorV(
340 "malformed jAcceleratorPluginBreakpointHit response '{0}': {1}",
341 response.GetStringRef(), llvm::toString(hit_response.takeError()));
342}
343
346 m_send_acks = true;
348
349 // This is the first real packet that we'll send in a debug session and it
350 // may take a little longer than normal to receive a reply. Wait at least
351 // 6 seconds for a reply to this packet.
352
353 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
354
356 if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==
358 if (response.IsOKResponse()) {
359 m_send_acks = false;
361 }
362 return true;
363 }
364 }
365 return false;
366}
367
380
394
408
410 if (!did_exec) {
411 // Hard reset everything, this is when we first connect to a GDB server
440 m_x_packet_state.reset();
450 m_supports_z0 = true;
451 m_supports_z1 = true;
452 m_supports_z2 = true;
453 m_supports_z3 = true;
454 m_supports_z4 = true;
457 m_supports_qSymbol = true;
460 m_host_arch.Clear();
462 m_os_version = llvm::VersionTuple();
463 m_os_build.clear();
464 m_os_kernel.clear();
465 m_hostname.clear();
466 m_gdb_server_name.clear();
468 m_default_packet_timeout = seconds(0);
471 m_qSupported_response.clear();
478 }
479
480 // These flags should be reset when we first connect to a GDB server and when
481 // our inferior process execs
483 m_process_arch.Clear();
484 m_lldb_settings.reset();
485}
486
488 // Clear out any capabilities we expect to see in the qSupported response
503 m_x_packet_state.reset();
511
512 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
513 // not, we assume no limit
514
515 // build the qSupported packet
516 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",
517 "multiprocess+",
518 "fork-events+",
519 "vfork-events+",
520 "swbreak+",
521 "hwbreak+",
522 "qXfer:libraries:read+",
523 "qXfer:libraries-svr4:read+"};
524 StreamString packet;
525 packet.PutCString("qSupported");
526 for (uint32_t i = 0; i < features.size(); ++i) {
527 packet.PutCString(i == 0 ? ":" : ";");
528 packet.PutCString(features[i]);
529 }
530
532 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
534 // Hang on to the qSupported packet, so that platforms can do custom
535 // configuration of the transport before attaching/launching the process.
536 m_qSupported_response = response.GetStringRef().str();
537
538 for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) {
539 if (x == "qXfer:auxv:read+")
541 else if (x == "qXfer:libraries-svr4:read+")
543 else if (x == "augmented-libraries-svr4-read") {
546 } else if (x == "qXfer:libraries:read+")
548 else if (x == "qXfer:features:read+")
550 else if (x == "qXfer:memory-map:read+")
552 else if (x == "qXfer:siginfo:read+")
554 else if (x == "qEcho+")
556 else if (x == "QPassSignals+")
558 else if (x == "multiprocess+")
560 else if (x == "memory-tagging+")
562 else if (x == "qSaveCore+")
564 else if (x == "address-spaces+")
566 else if (x == "native-signals+")
568 else if (x == "binary-upload+")
570 else if (x == "ReverseContinue+")
572 else if (x == "ReverseStep+")
574 else if (x == "MultiMemRead+")
576 else if (x == "jMultiBreakpoint+")
578 else if (x == "accelerator-plugins+")
580 else if (x == "lldb-settings+")
582 else if (x == "qWasmInstance+")
584 // Look for a list of compressions in the features list e.g.
585 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
586 // deflate,lzma
587 else if (x.consume_front("SupportedCompressions=")) {
588 llvm::SmallVector<llvm::StringRef, 4> compressions;
589 x.split(compressions, ',');
590 if (!compressions.empty())
591 MaybeEnableCompression(compressions);
592 } else if (x.consume_front("SupportedWatchpointTypes=")) {
593 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
594 x.split(watchpoint_types, ',');
595 m_watchpoint_types = eWatchpointHardwareFeatureUnknown;
596 for (auto wp_type : watchpoint_types) {
597 if (wp_type == "x86_64")
598 m_watchpoint_types |= eWatchpointHardwareX86;
599 if (wp_type == "aarch64-mask")
600 m_watchpoint_types |= eWatchpointHardwareArmMASK;
601 if (wp_type == "aarch64-bas")
602 m_watchpoint_types |= eWatchpointHardwareArmBAS;
603 }
604 } else if (x.consume_front("PacketSize=")) {
605 StringExtractorGDBRemote packet_response(x);
607 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
608 if (m_max_packet_size == 0) {
609 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
611 LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
612 }
613 }
614 }
615 }
616}
617
630
632 assert(!flavor.empty());
641 if (SendPacketAndWaitForResponse("vCont?", response) ==
643 for (llvm::StringRef token : llvm::split(response.GetStringRef(), ';')) {
644 if (token == "c")
646 if (token == "C")
648 if (token == "s")
650 if (token == "S")
652 }
653
659 }
660
666 }
667 }
668 }
669
670 return llvm::StringSwitch<bool>(flavor)
671 .Case("a", m_supports_vCont_any)
672 .Case("A", m_supports_vCont_all)
673 .Case("c", m_supports_vCont_c)
674 .Case("C", m_supports_vCont_C)
675 .Case("s", m_supports_vCont_s)
676 .Case("S", m_supports_vCont_S)
677 .Default(false);
678}
679
682 lldb::tid_t tid, StreamString &&payload,
683 StringExtractorGDBRemote &response) {
684 Lock lock(*this);
685 if (!lock) {
687 LLDB_LOGF(log,
688 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
689 "for %s packet.",
690 __FUNCTION__, payload.GetData());
692 }
693
695 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
696 else {
697 if (!SetCurrentThread(tid))
699 }
700
701 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
702}
703
704// Check if the target supports 'p' packet. It sends out a 'p' packet and
705// checks the response. A normal packet will tell us that support is available.
706//
707// Takes a valid thread ID because p needs to apply to a thread.
713
715 lldb::tid_t tid, llvm::StringRef packetStr) {
716 StreamString payload;
717 payload.PutCString(packetStr);
720 tid, std::move(payload), response) == PacketResult::Success &&
721 response.IsNormalResponse()) {
722 return eLazyBoolYes;
723 }
724 return eLazyBoolNo;
725}
726
730
732 // Get information on all threads at one using the "jThreadsInfo" packet
733 StructuredData::ObjectSP object_sp;
734
738 if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==
740 if (response.IsUnsupportedResponse()) {
742 } else if (!response.Empty()) {
743 object_sp = StructuredData::ParseJSON(response.GetStringRef());
744 }
745 }
746 }
747 return object_sp;
748}
749
763
767 // We try to enable error strings in remote packets but if we fail, we just
768 // work in the older way.
770 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==
772 if (response.IsOKResponse()) {
774 }
775 }
776 }
777}
778
792
806
819
826
828 size_t len,
829 int32_t type) {
830 StreamString packet;
831 packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);
833
834 Log *log = GetLog(GDBRLog::Memory);
835
836 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
838 !response.IsNormalResponse()) {
839 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
840 __FUNCTION__);
841 return nullptr;
842 }
843
844 // We are expecting
845 // m<hex encoded bytes>
846
847 if (response.GetChar() != 'm') {
848 LLDB_LOGF(log,
849 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
850 "begin with \"m\"",
851 __FUNCTION__);
852 return nullptr;
853 }
854
855 size_t expected_bytes = response.GetBytesLeft() / 2;
856 WritableDataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
857 size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
858 // Check both because in some situations chars are consumed even
859 // if the decoding fails.
860 if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {
861 LLDB_LOGF(
862 log,
863 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
864 __FUNCTION__);
865 return nullptr;
866 }
867
868 return buffer_sp;
869}
870
872 lldb::addr_t addr, size_t len, int32_t type,
873 const std::vector<uint8_t> &tags) {
874 // Format QMemTags:address,length:type:tags
875 StreamString packet;
876 packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);
877 packet.PutBytesAsRawHex8(tags.data(), tags.size());
878
879 Status status;
881 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
883 !response.IsOKResponse()) {
884 status = Status::FromErrorString("QMemTags packet failed");
885 }
886 return status;
887}
888
904
906 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
907 return m_curr_pid;
908
909 // First try to retrieve the pid via the qProcessInfo request.
910 GetCurrentProcessInfo(allow_lazy);
912 // We really got it.
913 return m_curr_pid;
914 } else {
915 // If we don't get a response for qProcessInfo, check if $qC gives us a
916 // result. $qC only returns a real process id on older debugserver and
917 // lldb-platform stubs. The gdb remote protocol documents $qC as returning
918 // the thread id, which newer debugserver and lldb-gdbserver stubs return
919 // correctly.
922 if (response.GetChar() == 'Q') {
923 if (response.GetChar() == 'C') {
925 response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
928 return m_curr_pid;
929 }
930 }
931 }
932 }
933
934 // If we don't get a response for $qC, check if $qfThreadID gives us a
935 // result.
937 bool sequence_mutex_unavailable;
938 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
939 if (!ids.empty() && !sequence_mutex_unavailable) {
940 // If server returned an explicit PID, use that.
941 m_curr_pid_run = m_curr_pid = ids.front().first;
942 // Otherwise, use the TID of the first thread (Linux hack).
944 m_curr_pid_run = m_curr_pid = ids.front().second;
946 return m_curr_pid;
947 }
948 }
949 }
950
952}
953
955 if (!args.GetArgumentAtIndex(0))
956 return llvm::createStringError(llvm::inconvertibleErrorCode(),
957 "Nothing to launch");
958 // try vRun first
959 if (m_supports_vRun) {
960 StreamString packet;
961 packet.PutCString("vRun");
962 for (const Args::ArgEntry &arg : args) {
963 packet.PutChar(';');
964 packet.PutStringAsRawHex8(arg.ref());
965 }
966
968 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
970 return llvm::createStringError(llvm::inconvertibleErrorCode(),
971 "Sending vRun packet failed");
972
973 if (response.IsErrorResponse())
974 return response.GetStatus().ToError();
975
976 // vRun replies with a stop reason packet
977 // FIXME: right now we just discard the packet and LLDB queries
978 // for stop reason again
979 if (!response.IsUnsupportedResponse())
980 return llvm::Error::success();
981
982 m_supports_vRun = false;
983 }
984
985 // fallback to A
986 StreamString packet;
987 packet.PutChar('A');
988 llvm::ListSeparator LS(",");
989 for (const auto &arg : llvm::enumerate(args)) {
990 packet << LS;
991 packet.Format("{0},{1},", arg.value().ref().size() * 2, arg.index());
992 packet.PutStringAsRawHex8(arg.value().ref());
993 }
994
996 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
998 return llvm::createStringError(llvm::inconvertibleErrorCode(),
999 "Sending A packet failed");
1000 }
1001 if (!response.IsOKResponse())
1002 return response.GetStatus().ToError();
1003
1004 if (SendPacketAndWaitForResponse("qLaunchSuccess", response) !=
1006 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1007 "Sending qLaunchSuccess packet failed");
1008 }
1009 if (response.IsOKResponse())
1010 return llvm::Error::success();
1011 if (response.GetChar() == 'E') {
1012 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1013 response.GetStringRef().substr(1));
1014 }
1015 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1016 "unknown error occurred launching process");
1017}
1018
1020 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
1021 for (const auto &kv : env)
1022 vec.emplace_back(kv.first(), kv.second);
1023 llvm::sort(vec, llvm::less_first());
1024 for (const auto &[k, v] : vec) {
1025 int r = SendEnvironmentPacket((k + "=" + v).str().c_str());
1026 if (r != 0)
1027 return r;
1028 }
1029 return 0;
1030}
1031
1033 char const *name_equal_value) {
1034 if (name_equal_value && name_equal_value[0]) {
1035 bool send_hex_encoding = false;
1036 for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
1037 ++p) {
1038 if (llvm::isPrint(*p)) {
1039 switch (*p) {
1040 case '$':
1041 case '#':
1042 case '*':
1043 case '}':
1044 send_hex_encoding = true;
1045 break;
1046 default:
1047 break;
1048 }
1049 } else {
1050 // We have non printable characters, lets hex encode this...
1051 send_hex_encoding = true;
1052 }
1053 }
1054
1055 StringExtractorGDBRemote response;
1056 // Prefer sending unencoded, if possible and the server supports it.
1057 if (!send_hex_encoding && m_supports_QEnvironment) {
1058 StreamString packet;
1059 packet.Printf("QEnvironment:%s", name_equal_value);
1060 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
1062 return -1;
1063
1064 if (response.IsOKResponse())
1065 return 0;
1066 if (response.IsUnsupportedResponse())
1068 else {
1069 uint8_t error = response.GetError();
1070 if (error)
1071 return error;
1072 return -1;
1073 }
1074 }
1075
1077 StreamString packet;
1078 packet.PutCString("QEnvironmentHexEncoded:");
1079 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
1080 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
1082 return -1;
1083
1084 if (response.IsOKResponse())
1085 return 0;
1086 if (response.IsUnsupportedResponse())
1088 else {
1089 uint8_t error = response.GetError();
1090 if (error)
1091 return error;
1092 return -1;
1093 }
1094 }
1095 }
1096 return -1;
1097}
1098
1100 if (arch && arch[0]) {
1101 StreamString packet;
1102 packet.Printf("QLaunchArch:%s", arch);
1103 StringExtractorGDBRemote response;
1104 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1106 if (response.IsOKResponse())
1107 return 0;
1108 uint8_t error = response.GetError();
1109 if (error)
1110 return error;
1111 }
1112 }
1113 return -1;
1114}
1115
1117 char const *data, bool *was_supported) {
1118 if (data && *data != '\0') {
1119 StreamString packet;
1120 packet.Printf("QSetProcessEvent:%s", data);
1121 StringExtractorGDBRemote response;
1122 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1124 if (response.IsOKResponse()) {
1125 if (was_supported)
1126 *was_supported = true;
1127 return 0;
1128 } else if (response.IsUnsupportedResponse()) {
1129 if (was_supported)
1130 *was_supported = false;
1131 return -1;
1132 } else {
1133 uint8_t error = response.GetError();
1134 if (was_supported)
1135 *was_supported = true;
1136 if (error)
1137 return error;
1138 }
1139 }
1140 }
1141 return -1;
1142}
1143
1145 GetHostInfo();
1146 return m_os_version;
1147}
1148
1153
1155 if (GetHostInfo()) {
1156 if (!m_os_build.empty())
1157 return m_os_build;
1158 }
1159 return std::nullopt;
1160}
1161
1162std::optional<std::string>
1164 if (GetHostInfo()) {
1165 if (!m_os_kernel.empty())
1166 return m_os_kernel;
1167 }
1168 return std::nullopt;
1169}
1170
1172 if (GetHostInfo()) {
1173 if (!m_hostname.empty()) {
1174 s = m_hostname;
1175 return true;
1176 }
1177 }
1178 s.clear();
1179 return false;
1180}
1181
1187
1194
1196 UUID &uuid, addr_t &value, bool &value_is_offset) {
1199
1200 // Return true if we have a UUID or an address/offset of the
1201 // main standalone / firmware binary being used.
1202 if (!m_process_standalone_uuid.IsValid() &&
1204 return false;
1205
1208 value_is_offset = m_process_standalone_value_is_offset;
1209 return true;
1210}
1211
1212std::vector<addr_t>
1218
1219std::vector<AddressSpaceInfo> GDBRemoteCommunicationClient::GetAddressSpaces() {
1221 return {};
1222
1223 StringExtractorGDBRemote response;
1224 response.SetResponseValidatorToJSON();
1225 if (SendPacketAndWaitForResponse("jAddressSpacesInfo", response) !=
1227 return {};
1228
1229 if (response.IsUnsupportedResponse() || response.IsErrorResponse()) {
1231 return {};
1232 }
1233
1234 llvm::Expected<std::vector<AddressSpaceInfo>> info =
1235 llvm::json::parse<std::vector<AddressSpaceInfo>>(response.Peek(),
1236 "AddressSpaceInfo");
1237 if (info)
1238 return std::move(*info);
1239
1240 Log *log = GetLog(GDBRLog::Process);
1241 LLDB_LOG_ERROR(log, info.takeError(),
1242 "malformed jAddressSpacesInfo response '{1}': {0}",
1243 response.GetStringRef());
1244 return {};
1245}
1246
1249 m_gdb_server_name.clear();
1252
1253 StringExtractorGDBRemote response;
1254 if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==
1256 if (response.IsNormalResponse()) {
1257 llvm::StringRef name, value;
1258 bool success = false;
1259 while (response.GetNameColonValue(name, value)) {
1260 if (name == "name") {
1261 success = true;
1262 m_gdb_server_name = std::string(value);
1263 } else if (name == "version") {
1264 llvm::StringRef major, minor;
1265 std::tie(major, minor) = value.split('.');
1266 if (!major.getAsInteger(BASE_10, m_gdb_server_version))
1267 success = true;
1268 }
1269 }
1270 if (success)
1272 }
1273 }
1274 }
1276}
1277
1279 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1281 llvm::StringRef avail_name;
1282
1283#if HAVE_LIBCOMPRESSION
1284 if (avail_type == CompressionType::None) {
1285 for (auto compression : supported_compressions) {
1286 if (compression == "lzfse") {
1287 avail_type = CompressionType::LZFSE;
1288 avail_name = compression;
1289 break;
1290 }
1291 }
1292 }
1293 if (avail_type == CompressionType::None) {
1294 for (auto compression : supported_compressions) {
1295 if (compression == "zlib-deflate") {
1296 avail_type = CompressionType::ZlibDeflate;
1297 avail_name = compression;
1298 break;
1299 }
1300 }
1301 }
1302#endif
1303
1304#if LLVM_ENABLE_ZLIB
1305 if (avail_type == CompressionType::None) {
1306 for (auto compression : supported_compressions) {
1307 if (compression == "zlib-deflate") {
1308 avail_type = CompressionType::ZlibDeflate;
1309 avail_name = compression;
1310 break;
1311 }
1312 }
1313 }
1314#endif
1315
1316#if HAVE_LIBCOMPRESSION
1317 if (avail_type == CompressionType::None) {
1318 for (auto compression : supported_compressions) {
1319 if (compression == "lz4") {
1320 avail_type = CompressionType::LZ4;
1321 avail_name = compression;
1322 break;
1323 }
1324 }
1325 }
1326 if (avail_type == CompressionType::None) {
1327 for (auto compression : supported_compressions) {
1328 if (compression == "lzma") {
1329 avail_type = CompressionType::LZMA;
1330 avail_name = compression;
1331 break;
1332 }
1333 }
1334 }
1335#endif
1336
1337 if (avail_type != CompressionType::None) {
1338 StringExtractorGDBRemote response;
1339 std::string packet = "QEnableCompression:type:" + avail_name.str() + ";";
1340 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
1341 return;
1342
1343 if (response.IsOKResponse()) {
1344 m_compression_type = avail_type;
1345 }
1346 }
1347}
1348
1350 if (GetGDBServerVersion()) {
1351 if (!m_gdb_server_name.empty())
1352 return m_gdb_server_name.c_str();
1353 }
1354 return nullptr;
1355}
1356
1362
1364 StringExtractorGDBRemote response;
1366 return false;
1367
1368 if (!response.IsNormalResponse())
1369 return false;
1370
1371 if (response.GetChar() == 'Q' && response.GetChar() == 'C') {
1372 auto pid_tid = response.GetPidTid(0);
1373 if (!pid_tid)
1374 return false;
1375
1376 lldb::pid_t pid = pid_tid->first;
1377 // invalid
1379 return false;
1380
1381 // if we get pid as well, update m_curr_pid
1382 if (pid != 0) {
1383 m_curr_pid_run = m_curr_pid = pid;
1385 }
1386 tid = pid_tid->second;
1387 }
1388
1389 return true;
1390}
1391
1392static void ParseOSType(llvm::StringRef value, std::string &os_name,
1393 std::string &environment) {
1394 if (value == "iossimulator" || value == "tvossimulator" ||
1395 value == "watchossimulator" || value == "xrossimulator" ||
1396 value == "visionossimulator") {
1397 environment = "simulator";
1398 os_name = value.drop_back(environment.size()).str();
1399 } else if (value == "maccatalyst") {
1400 os_name = "ios";
1401 environment = "macabi";
1402 } else {
1403 os_name = value.str();
1404 }
1405}
1406
1408 Log *log = GetLog(GDBRLog::Process);
1409
1410 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
1411 // host info computation can require DNS traffic and shelling out to external processes.
1412 // Increase the timeout to account for that.
1413 ScopedTimeout timeout(*this, seconds(10));
1415 StringExtractorGDBRemote response;
1416 if (SendPacketAndWaitForResponse("qHostInfo", response) ==
1418 if (response.IsNormalResponse()) {
1419 llvm::StringRef name;
1420 llvm::StringRef value;
1421 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1422 uint32_t sub = 0;
1423 std::string arch_name;
1424 std::string os_name;
1425 std::string environment;
1426 std::string vendor_name;
1427 std::string triple;
1428 uint32_t pointer_byte_size = 0;
1429 ByteOrder byte_order = eByteOrderInvalid;
1430 uint32_t num_keys_decoded = 0;
1431 while (response.GetNameColonValue(name, value)) {
1432 if (name == "cputype") {
1433 // exception type in big endian hex
1434 if (!value.getAsInteger(BASE_10, cpu))
1435 ++num_keys_decoded;
1436 } else if (name == "cpusubtype") {
1437 // exception count in big endian hex
1438 if (!value.getAsInteger(BASE_10, sub))
1439 ++num_keys_decoded;
1440 } else if (name == "arch") {
1441 arch_name = std::string(value);
1442 ++num_keys_decoded;
1443 } else if (name == "triple") {
1444 StringExtractor extractor(value);
1445 extractor.GetHexByteString(triple);
1446 ++num_keys_decoded;
1447 } else if (name == "distribution_id") {
1448 StringExtractor extractor(value);
1450 ++num_keys_decoded;
1451 } else if (name == "os_build") {
1452 StringExtractor extractor(value);
1453 extractor.GetHexByteString(m_os_build);
1454 ++num_keys_decoded;
1455 } else if (name == "hostname") {
1456 StringExtractor extractor(value);
1457 extractor.GetHexByteString(m_hostname);
1458 ++num_keys_decoded;
1459 } else if (name == "os_kernel") {
1460 StringExtractor extractor(value);
1461 extractor.GetHexByteString(m_os_kernel);
1462 ++num_keys_decoded;
1463 } else if (name == "ostype") {
1464 ParseOSType(value, os_name, environment);
1465 ++num_keys_decoded;
1466 } else if (name == "vendor") {
1467 vendor_name = std::string(value);
1468 ++num_keys_decoded;
1469 } else if (name == "endian") {
1470 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1471 .Case("little", eByteOrderLittle)
1472 .Case("big", eByteOrderBig)
1473 .Case("pdp", eByteOrderPDP)
1474 .Default(eByteOrderInvalid);
1475 if (byte_order != eByteOrderInvalid)
1476 ++num_keys_decoded;
1477 } else if (name == "ptrsize") {
1478 if (!value.getAsInteger(BASE_10, pointer_byte_size))
1479 ++num_keys_decoded;
1480 } else if (name == "addressing_bits") {
1481 if (!value.getAsInteger(BASE_10, m_low_mem_addressing_bits)) {
1482 ++num_keys_decoded;
1483 }
1484 } else if (name == "high_mem_addressing_bits") {
1485 if (!value.getAsInteger(BASE_10, m_high_mem_addressing_bits))
1486 ++num_keys_decoded;
1487 } else if (name == "low_mem_addressing_bits") {
1488 if (!value.getAsInteger(BASE_10, m_low_mem_addressing_bits))
1489 ++num_keys_decoded;
1490 } else if (name == "os_version" ||
1491 name == "version") // Older debugserver binaries used
1492 // the "version" key instead of
1493 // "os_version"...
1494 {
1495 if (!m_os_version.tryParse(value))
1496 ++num_keys_decoded;
1497 } else if (name == "maccatalyst_version") {
1498 if (!m_maccatalyst_version.tryParse(value))
1499 ++num_keys_decoded;
1500 } else if (name == "watchpoint_exceptions_received") {
1502 llvm::StringSwitch<LazyBool>(value)
1503 .Case("before", eLazyBoolNo)
1504 .Case("after", eLazyBoolYes)
1505 .Default(eLazyBoolCalculate);
1507 ++num_keys_decoded;
1508 } else if (name == "default_packet_timeout") {
1509 uint32_t timeout_seconds;
1510 if (!value.getAsInteger(BASE_10, timeout_seconds)) {
1511 m_default_packet_timeout = seconds(timeout_seconds);
1513 ++num_keys_decoded;
1514 }
1515 } else if (name == "vm-page-size") {
1516 int page_size;
1517 if (!value.getAsInteger(BASE_10, page_size)) {
1518 m_target_vm_page_size = page_size;
1519 ++num_keys_decoded;
1520 }
1521 }
1522 }
1523
1524 if (num_keys_decoded > 0)
1526
1527 if (triple.empty()) {
1528 if (arch_name.empty()) {
1529 if (cpu != LLDB_INVALID_CPUTYPE) {
1530 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1531 if (pointer_byte_size) {
1532 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1533 }
1534 if (byte_order != eByteOrderInvalid) {
1535 assert(byte_order == m_host_arch.GetByteOrder());
1536 }
1537
1538 if (!vendor_name.empty())
1539 m_host_arch.GetTriple().setVendorName(
1540 llvm::StringRef(vendor_name));
1541 if (!os_name.empty())
1542 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1543 if (!environment.empty())
1544 m_host_arch.GetTriple().setEnvironmentName(environment);
1545 }
1546 } else {
1547 std::string triple;
1548 triple += arch_name;
1549 if (!vendor_name.empty() || !os_name.empty()) {
1550 triple += '-';
1551 if (vendor_name.empty())
1552 triple += "unknown";
1553 else
1554 triple += vendor_name;
1555 triple += '-';
1556 if (os_name.empty())
1557 triple += "unknown";
1558 else
1559 triple += os_name;
1560 }
1561 m_host_arch.SetTriple(triple.c_str());
1562
1563 llvm::Triple &host_triple = m_host_arch.GetTriple();
1564 if (host_triple.getVendor() == llvm::Triple::Apple &&
1565 host_triple.getOS() == llvm::Triple::Darwin) {
1566 switch (m_host_arch.GetMachine()) {
1567 case llvm::Triple::aarch64:
1568 case llvm::Triple::aarch64_32:
1569 case llvm::Triple::arm:
1570 case llvm::Triple::thumb:
1571 host_triple.setOS(llvm::Triple::IOS);
1572 break;
1573 default:
1574 host_triple.setOS(llvm::Triple::MacOSX);
1575 break;
1576 }
1577 }
1578 if (pointer_byte_size) {
1579 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1580 }
1581 if (byte_order != eByteOrderInvalid) {
1582 assert(byte_order == m_host_arch.GetByteOrder());
1583 }
1584 }
1585 } else {
1586 m_host_arch.SetTriple(triple.c_str());
1587 if (pointer_byte_size) {
1588 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1589 }
1590 if (byte_order != eByteOrderInvalid) {
1591 assert(byte_order == m_host_arch.GetByteOrder());
1592 }
1593
1594 LLDB_LOGF(log,
1595 "GDBRemoteCommunicationClient::%s parsed host "
1596 "architecture as %s, triple as %s from triple text %s",
1597 __FUNCTION__,
1598 m_host_arch.GetArchitectureName()
1599 ? m_host_arch.GetArchitectureName()
1600 : "<null-arch-name>",
1601 m_host_arch.GetTriple().getTriple().c_str(),
1602 triple.c_str());
1603 }
1604 }
1605 }
1606 }
1608}
1609
1611 const char *data, size_t data_len, std::chrono::seconds interrupt_timeout) {
1612 StreamString packet;
1613 packet.PutCString("I");
1614 packet.PutBytesAsRawHex8(data, data_len);
1615 StringExtractorGDBRemote response;
1616 if (SendPacketAndWaitForResponse(packet.GetString(), response,
1617 interrupt_timeout) ==
1619 return 0;
1620 }
1621 return response.GetError();
1622}
1623
1630
1643
1649
1651 uint32_t permissions) {
1654 char packet[64];
1655 const int packet_len = ::snprintf(
1656 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1657 permissions & lldb::ePermissionsReadable ? "r" : "",
1658 permissions & lldb::ePermissionsWritable ? "w" : "",
1659 permissions & lldb::ePermissionsExecutable ? "x" : "");
1660 assert(packet_len < (int)sizeof(packet));
1661 UNUSED_IF_ASSERT_DISABLED(packet_len);
1662 StringExtractorGDBRemote response;
1663 if (SendPacketAndWaitForResponse(packet, response) ==
1665 if (response.IsUnsupportedResponse())
1667 else if (!response.IsErrorResponse())
1668 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1669 } else {
1671 }
1672 }
1673 return LLDB_INVALID_ADDRESS;
1674}
1675
1679 char packet[64];
1680 const int packet_len =
1681 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1682 assert(packet_len < (int)sizeof(packet));
1683 UNUSED_IF_ASSERT_DISABLED(packet_len);
1684 StringExtractorGDBRemote response;
1685 if (SendPacketAndWaitForResponse(packet, response) ==
1687 if (response.IsUnsupportedResponse())
1689 else if (response.IsOKResponse())
1690 return true;
1691 } else {
1693 }
1694 }
1695 return false;
1696}
1697
1699 lldb::pid_t pid) {
1700 Status error;
1702
1703 packet.PutChar('D');
1704 if (keep_stopped) {
1706 char packet[64];
1707 const int packet_len =
1708 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1709 assert(packet_len < (int)sizeof(packet));
1710 UNUSED_IF_ASSERT_DISABLED(packet_len);
1711 StringExtractorGDBRemote response;
1712 if (SendPacketAndWaitForResponse(packet, response) ==
1714 response.IsOKResponse()) {
1716 } else {
1718 }
1719 }
1720
1723 "Stays stopped not supported by this target.");
1724 return error;
1725 } else {
1726 packet.PutChar('1');
1727 }
1728 }
1729
1731 // Some servers (e.g. qemu) require specifying the PID even if only a single
1732 // process is running.
1733 if (pid == LLDB_INVALID_PROCESS_ID)
1734 pid = GetCurrentProcessID();
1735 packet.PutChar(';');
1736 packet.PutHex64(pid);
1737 } else if (pid != LLDB_INVALID_PROCESS_ID) {
1739 "Multiprocess extension not supported by the server.");
1740 return error;
1741 }
1742
1743 StringExtractorGDBRemote response;
1744 PacketResult packet_result =
1745 SendPacketAndWaitForResponse(packet.GetString(), response);
1746 if (packet_result != PacketResult::Success)
1747 error = Status::FromErrorString("Sending disconnect packet failed.");
1748 return error;
1749}
1750
1752 lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
1753 Status error;
1754 region_info.Clear();
1755
1758 char packet[64];
1759 const int packet_len = ::snprintf(
1760 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1761 assert(packet_len < (int)sizeof(packet));
1762 UNUSED_IF_ASSERT_DISABLED(packet_len);
1763 StringExtractorGDBRemote response;
1764 if (SendPacketAndWaitForResponse(packet, response) ==
1767 llvm::StringRef name;
1768 llvm::StringRef value;
1769 addr_t addr_value = LLDB_INVALID_ADDRESS;
1770 bool success = true;
1771 bool saw_permissions = false;
1772 while (success && response.GetNameColonValue(name, value)) {
1773 if (name == "start") {
1774 if (!value.getAsInteger(BASE_16, addr_value))
1775 region_info.GetRange().SetRangeBase(addr_value);
1776 } else if (name == "size") {
1777 if (!value.getAsInteger(BASE_16, addr_value)) {
1778 region_info.GetRange().SetByteSize(addr_value);
1779 if (region_info.GetRange().GetRangeEnd() <
1780 region_info.GetRange().GetRangeBase()) {
1781 // Range size overflowed, truncate it.
1783 }
1784 }
1785 } else if (name == "permissions" && region_info.GetRange().IsValid()) {
1786 saw_permissions = true;
1787 if (region_info.GetRange().Contains(addr)) {
1788 if (value.contains('r'))
1789 region_info.SetReadable(eLazyBoolYes);
1790 else
1791 region_info.SetReadable(eLazyBoolNo);
1792
1793 if (value.contains('w'))
1794 region_info.SetWritable(eLazyBoolYes);
1795 else
1796 region_info.SetWritable(eLazyBoolNo);
1797
1798 if (value.contains('x'))
1799 region_info.SetExecutable(eLazyBoolYes);
1800 else
1801 region_info.SetExecutable(eLazyBoolNo);
1802
1803 region_info.SetMapped(eLazyBoolYes);
1804 } else {
1805 // The reported region does not contain this address -- we're
1806 // looking at an unmapped page
1807 region_info.SetReadable(eLazyBoolNo);
1808 region_info.SetWritable(eLazyBoolNo);
1809 region_info.SetExecutable(eLazyBoolNo);
1810 region_info.SetMapped(eLazyBoolNo);
1811 }
1812 } else if (name == "name") {
1813 StringExtractorGDBRemote name_extractor(value);
1814 std::string name;
1815 name_extractor.GetHexByteString(name);
1816 region_info.SetName(name.c_str());
1817 } else if (name == "flags") {
1818 region_info.SetMemoryTagged(eLazyBoolNo);
1819 region_info.SetIsShadowStack(eLazyBoolNo);
1820
1821 llvm::StringRef flags = value;
1822 llvm::StringRef flag;
1823 while (flags.size()) {
1824 flags = flags.ltrim();
1825 std::tie(flag, flags) = flags.split(' ');
1826 // To account for trailing whitespace
1827 if (flag.size()) {
1828 if (flag == "mt")
1829 region_info.SetMemoryTagged(eLazyBoolYes);
1830 else if (flag == "ss")
1831 region_info.SetIsShadowStack(eLazyBoolYes);
1832 }
1833 }
1834 } else if (name == "type") {
1835 for (llvm::StringRef entry : llvm::split(value, ',')) {
1836 if (entry == "stack")
1837 region_info.SetIsStackMemory(eLazyBoolYes);
1838 else if (entry == "heap")
1839 region_info.SetIsStackMemory(eLazyBoolNo);
1840 }
1841 } else if (name == "error") {
1842 StringExtractorGDBRemote error_extractor(value);
1843 std::string error_string;
1844 // Now convert the HEX bytes into a string value
1845 error_extractor.GetHexByteString(error_string);
1846 error = Status::FromErrorString(error_string.c_str());
1847 } else if (name == "dirty-pages") {
1848 std::vector<addr_t> dirty_page_list;
1849 for (llvm::StringRef x : llvm::split(value, ',')) {
1850 addr_t page;
1851 x.consume_front("0x");
1852 if (llvm::to_integer(x, page, 16))
1853 dirty_page_list.push_back(page);
1854 }
1855 region_info.SetDirtyPageList(dirty_page_list);
1856 } else if (name == "protection-key") {
1857 unsigned protection_key = 0;
1858 if (!value.getAsInteger(BASE_10, protection_key))
1859 region_info.SetProtectionKey(protection_key);
1860 }
1861 }
1862
1863 if (m_target_vm_page_size != 0)
1865
1866 if (region_info.GetRange().IsValid()) {
1867 // We got a valid address range back but no permissions -- which means
1868 // this is an unmapped page
1869 if (!saw_permissions) {
1870 region_info.SetReadable(eLazyBoolNo);
1871 region_info.SetWritable(eLazyBoolNo);
1872 region_info.SetExecutable(eLazyBoolNo);
1873 region_info.SetMapped(eLazyBoolNo);
1874 }
1875 } else {
1876 // We got an invalid address range back
1877 error = Status::FromErrorString("Server returned invalid range");
1878 }
1879 } else {
1881 }
1882 }
1883
1885 error = Status::FromErrorString("qMemoryRegionInfo is not supported");
1886 }
1887
1888 // Try qXfer:memory-map:read to get region information not included in
1889 // qMemoryRegionInfo
1890 MemoryRegionInfo qXfer_region_info;
1891 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1892
1893 if (error.Fail()) {
1894 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1895 // the qXfer result as a fallback
1896 if (qXfer_error.Success()) {
1897 region_info = qXfer_region_info;
1898 error.Clear();
1899 } else {
1900 region_info.Clear();
1901 }
1902 } else if (qXfer_error.Success()) {
1903 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
1904 // both regions are the same range, update the result to include the flash-
1905 // memory information that is specific to the qXfer result.
1906 if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1907 region_info.SetFlash(qXfer_region_info.GetFlash());
1908 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1909 }
1910 }
1911 return error;
1912}
1913
1915 lldb::addr_t addr, MemoryRegionInfo &region) {
1917 if (!error.Success())
1918 return error;
1919 for (const auto &map_region : m_qXfer_memory_map) {
1920 if (map_region.GetRange().Contains(addr)) {
1921 region = map_region;
1922 return error;
1923 }
1924 }
1925 error = Status::FromErrorString("Region not found");
1926 return error;
1927}
1928
1930
1931 Status error;
1932
1934 // Already loaded, return success
1935 return error;
1936
1937 if (!XMLDocument::XMLEnabled()) {
1938 error = Status::FromErrorString("XML is not supported");
1939 return error;
1940 }
1941
1943 error = Status::FromErrorString("Memory map is not supported");
1944 return error;
1945 }
1946
1947 llvm::Expected<std::string> xml = ReadExtFeature("memory-map", "");
1948 if (!xml)
1949 return Status::FromError(xml.takeError());
1950
1951 XMLDocument xml_document;
1952
1953 if (!xml_document.ParseMemory(xml->c_str(), xml->size())) {
1954 error = Status::FromErrorString("Failed to parse memory map xml");
1955 return error;
1956 }
1957
1958 XMLNode map_node = xml_document.GetRootElement("memory-map");
1959 if (!map_node) {
1960 error = Status::FromErrorString("Invalid root node in memory map xml");
1961 return error;
1962 }
1963
1964 m_qXfer_memory_map.clear();
1965
1966 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1967 if (!memory_node.IsElement())
1968 return true;
1969 if (memory_node.GetName() != "memory")
1970 return true;
1971 auto type = memory_node.GetAttributeValue("type", "");
1972 uint64_t start;
1973 uint64_t length;
1974 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1975 return true;
1976 if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1977 return true;
1978 MemoryRegionInfo region;
1979 region.GetRange().SetRangeBase(start);
1980 region.GetRange().SetByteSize(length);
1981 if (type == "rom") {
1982 region.SetReadable(eLazyBoolYes);
1983 this->m_qXfer_memory_map.push_back(region);
1984 } else if (type == "ram") {
1985 region.SetReadable(eLazyBoolYes);
1986 region.SetWritable(eLazyBoolYes);
1987 this->m_qXfer_memory_map.push_back(region);
1988 } else if (type == "flash") {
1989 region.SetFlash(eLazyBoolYes);
1990 memory_node.ForEachChildElement(
1991 [&region](const XMLNode &prop_node) -> bool {
1992 if (!prop_node.IsElement())
1993 return true;
1994 if (prop_node.GetName() != "property")
1995 return true;
1996 auto propname = prop_node.GetAttributeValue("name", "");
1997 if (propname == "blocksize") {
1998 uint64_t blocksize;
1999 if (prop_node.GetElementTextAsUnsigned(blocksize))
2000 region.SetBlocksize(blocksize);
2001 }
2002 return true;
2003 });
2004 this->m_qXfer_memory_map.push_back(region);
2005 }
2006 return true;
2007 });
2008
2010
2011 return error;
2012}
2013
2017 }
2018
2019 std::optional<uint32_t> num;
2021 StringExtractorGDBRemote response;
2022 if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==
2025 llvm::StringRef name;
2026 llvm::StringRef value;
2027 while (response.GetNameColonValue(name, value)) {
2028 if (name == "num") {
2029 value.getAsInteger(BASE_10, m_num_supported_hardware_watchpoints);
2031 }
2032 }
2033 if (!num) {
2035 }
2036 } else {
2038 }
2039 }
2040
2041 return num;
2042}
2043
2044WatchpointHardwareFeature
2048
2051 GetHostInfo();
2052
2053 // Process determines this by target CPU, but allow for the
2054 // remote stub to override it via the qHostInfo
2055 // watchpoint_exceptions_received key, if it is present.
2058 return false;
2060 return true;
2061 }
2062
2063 return std::nullopt;
2064}
2065
2067 if (file_spec) {
2068 std::string path{file_spec.GetPath(false)};
2069 StreamString packet;
2070 packet.PutCString("QSetSTDIN:");
2071 packet.PutStringAsRawHex8(path);
2072
2073 StringExtractorGDBRemote response;
2074 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2076 if (response.IsOKResponse())
2077 return 0;
2078 uint8_t error = response.GetError();
2079 if (error)
2080 return error;
2081 }
2082 }
2083 return -1;
2084}
2085
2087 if (file_spec) {
2088 std::string path{file_spec.GetPath(false)};
2089 StreamString packet;
2090 packet.PutCString("QSetSTDOUT:");
2091 packet.PutStringAsRawHex8(path);
2092
2093 StringExtractorGDBRemote response;
2094 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2096 if (response.IsOKResponse())
2097 return 0;
2098 uint8_t error = response.GetError();
2099 if (error)
2100 return error;
2101 }
2102 }
2103 return -1;
2104}
2105
2107 if (file_spec) {
2108 std::string path{file_spec.GetPath(false)};
2109 StreamString packet;
2110 packet.PutCString("QSetSTDERR:");
2111 packet.PutStringAsRawHex8(path);
2112
2113 StringExtractorGDBRemote response;
2114 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2116 if (response.IsOKResponse())
2117 return 0;
2118 uint8_t error = response.GetError();
2119 if (error)
2120 return error;
2121 }
2122 }
2123 return -1;
2124}
2125
2127 uint16_t rows) {
2128 // The size is only valid if both or none of the dimensions are zero.
2129 if ((cols == 0) != (rows == 0))
2130 return -1;
2131 StreamString packet;
2132 packet.Printf("QSetSTDIOWindowSize:cols=%u;rows=%u",
2133 static_cast<unsigned>(cols), static_cast<unsigned>(rows));
2134 StringExtractorGDBRemote response;
2135 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
2137 return -1;
2138 if (response.IsOKResponse())
2139 return 0;
2140 if (response.IsUnsupportedResponse())
2141 return 0;
2142 uint8_t error = response.GetError();
2143 return error ? error : -1;
2144}
2145
2147 StringExtractorGDBRemote response;
2148 if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==
2150 if (response.IsUnsupportedResponse())
2151 return false;
2152 if (response.IsErrorResponse())
2153 return false;
2154 std::string cwd;
2155 response.GetHexByteString(cwd);
2156 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
2157 return !cwd.empty();
2158 }
2159 return false;
2160}
2161
2163 if (working_dir) {
2164 std::string path{working_dir.GetPath(false)};
2165 StreamString packet;
2166 packet.PutCString("QSetWorkingDir:");
2167 packet.PutStringAsRawHex8(path);
2168
2169 StringExtractorGDBRemote response;
2170 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2172 if (response.IsOKResponse())
2173 return 0;
2174 uint8_t error = response.GetError();
2175 if (error)
2176 return error;
2177 }
2178 }
2179 return -1;
2180}
2181
2183 char packet[32];
2184 const int packet_len =
2185 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
2186 assert(packet_len < (int)sizeof(packet));
2187 UNUSED_IF_ASSERT_DISABLED(packet_len);
2188 StringExtractorGDBRemote response;
2189 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
2190 if (response.IsOKResponse())
2191 return 0;
2192 uint8_t error = response.GetError();
2193 if (error)
2194 return error;
2195 }
2196 return -1;
2197}
2198
2200 char packet[32];
2201 const int packet_len = ::snprintf(packet, sizeof(packet),
2202 "QSetDetachOnError:%i", enable ? 1 : 0);
2203 assert(packet_len < (int)sizeof(packet));
2204 UNUSED_IF_ASSERT_DISABLED(packet_len);
2205 StringExtractorGDBRemote response;
2206 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
2207 if (response.IsOKResponse())
2208 return 0;
2209 uint8_t error = response.GetError();
2210 if (error)
2211 return error;
2212 }
2213 return -1;
2214}
2215
2217 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
2218 if (response.IsNormalResponse()) {
2219 llvm::StringRef name;
2220 llvm::StringRef value;
2221 StringExtractor extractor;
2222
2223 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2224 uint32_t sub = 0;
2225 std::string vendor;
2226 std::string os_type;
2227
2228 while (response.GetNameColonValue(name, value)) {
2229 if (name == "pid") {
2231 value.getAsInteger(BASE_10, pid);
2232 process_info.SetProcessID(pid);
2233 } else if (name == "ppid") {
2235 value.getAsInteger(BASE_10, pid);
2236 process_info.SetParentProcessID(pid);
2237 } else if (name == "uid") {
2238 uint32_t uid = UINT32_MAX;
2239 value.getAsInteger(BASE_10, uid);
2240 process_info.SetUserID(uid);
2241 } else if (name == "euid") {
2242 uint32_t uid = UINT32_MAX;
2243 value.getAsInteger(BASE_10, uid);
2244 process_info.SetEffectiveUserID(uid);
2245 } else if (name == "gid") {
2246 uint32_t gid = UINT32_MAX;
2247 value.getAsInteger(BASE_10, gid);
2248 process_info.SetGroupID(gid);
2249 } else if (name == "egid") {
2250 uint32_t gid = UINT32_MAX;
2251 value.getAsInteger(BASE_10, gid);
2252 process_info.SetEffectiveGroupID(gid);
2253 } else if (name == "triple") {
2254 StringExtractor extractor(value);
2255 std::string triple;
2256 extractor.GetHexByteString(triple);
2257 process_info.GetArchitecture().SetTriple(triple.c_str());
2258 } else if (name == "name") {
2259 StringExtractor extractor(value);
2260 // The process name from ASCII hex bytes since we can't control the
2261 // characters in a process name
2262 std::string name;
2263 extractor.GetHexByteString(name);
2264 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
2265 } else if (name == "args") {
2266 llvm::StringRef encoded_args(value), hex_arg;
2267
2268 bool is_arg0 = true;
2269 while (!encoded_args.empty()) {
2270 std::tie(hex_arg, encoded_args) = encoded_args.split('-');
2271 std::string arg;
2272 StringExtractor extractor(hex_arg);
2273 if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
2274 // In case of wrong encoding, we discard all the arguments
2275 process_info.GetArguments().Clear();
2276 process_info.SetArg0("");
2277 break;
2278 }
2279 if (is_arg0)
2280 process_info.SetArg0(arg);
2281 else
2282 process_info.GetArguments().AppendArgument(arg);
2283 is_arg0 = false;
2284 }
2285 } else if (name == "cputype") {
2286 value.getAsInteger(BASE_10, cpu);
2287 } else if (name == "cpusubtype") {
2288 value.getAsInteger(BASE_10, sub);
2289 } else if (name == "vendor") {
2290 vendor = std::string(value);
2291 } else if (name == "ostype") {
2292 os_type = std::string(value);
2293 }
2294 }
2295
2296 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
2297 if (vendor == "apple") {
2299 sub);
2300 process_info.GetArchitecture().GetTriple().setVendorName(
2301 llvm::StringRef(vendor));
2302 process_info.GetArchitecture().GetTriple().setOSName(
2303 llvm::StringRef(os_type));
2304 }
2305 }
2306
2307 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
2308 return true;
2309 }
2310 return false;
2311}
2312
2314 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
2315 process_info.Clear();
2316
2318 char packet[32];
2319 const int packet_len =
2320 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
2321 assert(packet_len < (int)sizeof(packet));
2322 UNUSED_IF_ASSERT_DISABLED(packet_len);
2323 StringExtractorGDBRemote response;
2324 if (SendPacketAndWaitForResponse(packet, response) ==
2326 return DecodeProcessInfoResponse(response, process_info);
2327 } else {
2329 return false;
2330 }
2331 }
2332 return false;
2333}
2334
2337
2338 if (allow_lazy) {
2340 return true;
2342 return false;
2343 }
2344
2345 GetHostInfo();
2346
2347 StringExtractorGDBRemote response;
2348 if (SendPacketAndWaitForResponse("qProcessInfo", response) ==
2350 if (response.IsNormalResponse()) {
2351 llvm::StringRef name;
2352 llvm::StringRef value;
2353 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2354 uint32_t sub = 0;
2355 std::string os_name;
2356 std::string environment;
2357 std::string vendor_name;
2358 std::string triple;
2359 std::string elf_abi;
2360 uint32_t pointer_byte_size = 0;
2361 StringExtractor extractor;
2362 ByteOrder byte_order = eByteOrderInvalid;
2363 uint32_t num_keys_decoded = 0;
2365 while (response.GetNameColonValue(name, value)) {
2366 if (name == "cputype") {
2367 if (!value.getAsInteger(BASE_16, cpu))
2368 ++num_keys_decoded;
2369 } else if (name == "cpusubtype") {
2370 if (!value.getAsInteger(BASE_16, sub)) {
2371 ++num_keys_decoded;
2372 // Workaround for pre-2024 Apple debugserver, which always
2373 // returns arm64e on arm64e-capable hardware regardless of
2374 // what the process is. This can be deleted at some point
2375 // in the future.
2376 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2377 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2378 if (GetGDBServerVersion())
2379 if (m_gdb_server_version >= 1000 &&
2380 m_gdb_server_version <= 1504)
2381 sub = 0;
2382 }
2383 }
2384 } else if (name == "triple") {
2385 StringExtractor extractor(value);
2386 extractor.GetHexByteString(triple);
2387 ++num_keys_decoded;
2388 } else if (name == "ostype") {
2389 ParseOSType(value, os_name, environment);
2390 ++num_keys_decoded;
2391 } else if (name == "vendor") {
2392 vendor_name = std::string(value);
2393 ++num_keys_decoded;
2394 } else if (name == "endian") {
2395 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2396 .Case("little", eByteOrderLittle)
2397 .Case("big", eByteOrderBig)
2398 .Case("pdp", eByteOrderPDP)
2399 .Default(eByteOrderInvalid);
2400 if (byte_order != eByteOrderInvalid)
2401 ++num_keys_decoded;
2402 } else if (name == "ptrsize") {
2403 if (!value.getAsInteger(BASE_16, pointer_byte_size))
2404 ++num_keys_decoded;
2405 } else if (name == "pid") {
2406 if (!value.getAsInteger(BASE_16, pid))
2407 ++num_keys_decoded;
2408 } else if (name == "elf_abi") {
2409 elf_abi = std::string(value);
2410 ++num_keys_decoded;
2411 } else if (name == "main-binary-uuid") {
2412 m_process_standalone_uuid.SetFromStringRef(value);
2413 ++num_keys_decoded;
2414 } else if (name == "main-binary-slide") {
2415 StringExtractor extractor(value);
2417 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
2420 ++num_keys_decoded;
2421 }
2422 } else if (name == "main-binary-address") {
2423 StringExtractor extractor(value);
2425 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
2428 ++num_keys_decoded;
2429 }
2430 } else if (name == "binary-addresses") {
2431 m_binary_addresses.clear();
2432 ++num_keys_decoded;
2433 for (llvm::StringRef x : llvm::split(value, ',')) {
2434 addr_t vmaddr;
2435 x.consume_front("0x");
2436 if (llvm::to_integer(x, vmaddr, 16))
2437 m_binary_addresses.push_back(vmaddr);
2438 }
2439 }
2440 }
2441 if (num_keys_decoded > 0)
2443 if (pid != LLDB_INVALID_PROCESS_ID) {
2445 m_curr_pid_run = m_curr_pid = pid;
2446 }
2447
2448 // Set the ArchSpec from the triple if we have it.
2449 if (!triple.empty()) {
2450 m_process_arch.SetTriple(triple.c_str());
2451 m_process_arch.SetFlags(elf_abi);
2452 if (pointer_byte_size) {
2453 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2454 }
2455 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2456 !vendor_name.empty()) {
2457 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2458 if (!environment.empty())
2459 triple.setEnvironmentName(environment);
2460
2461 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2462 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2463 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2464 switch (triple.getObjectFormat()) {
2465 case llvm::Triple::MachO:
2466 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2467 break;
2468 case llvm::Triple::ELF:
2469 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2470 break;
2471 case llvm::Triple::COFF:
2472 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2473 break;
2474 case llvm::Triple::GOFF:
2475 case llvm::Triple::SPIRV:
2476 case llvm::Triple::Wasm:
2477 case llvm::Triple::XCOFF:
2478 case llvm::Triple::DXContainer:
2479 LLDB_LOGF(log, "error: not supported target architecture");
2480 return false;
2481 case llvm::Triple::UnknownObjectFormat:
2482 LLDB_LOGF(log, "error: failed to determine target architecture");
2483 return false;
2484 }
2485
2486 if (pointer_byte_size) {
2487 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2488 }
2489 if (byte_order != eByteOrderInvalid) {
2490 assert(byte_order == m_process_arch.GetByteOrder());
2491 }
2492 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2493 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2494 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2495 }
2496 return true;
2497 }
2498 } else {
2500 }
2501
2502 return false;
2503}
2504
2506 const ProcessInstanceInfoMatch &match_info,
2507 ProcessInstanceInfoList &process_infos) {
2508 process_infos.clear();
2509
2511 StreamString packet;
2512 packet.PutCString("qfProcessInfo");
2513 if (!match_info.MatchAllProcesses()) {
2514 packet.PutChar(':');
2515 llvm::StringRef name = match_info.GetProcessInfo().GetName();
2516 bool has_name_match = false;
2517 if (!name.empty()) {
2518 has_name_match = true;
2519 NameMatch name_match_type = match_info.GetNameMatchType();
2520 switch (name_match_type) {
2521 case NameMatch::Ignore:
2522 has_name_match = false;
2523 break;
2524
2525 case NameMatch::Equals:
2526 packet.PutCString("name_match:equals;");
2527 break;
2528
2530 packet.PutCString("name_match:contains;");
2531 break;
2532
2534 packet.PutCString("name_match:starts_with;");
2535 break;
2536
2538 packet.PutCString("name_match:ends_with;");
2539 break;
2540
2542 packet.PutCString("name_match:regex;");
2543 break;
2544 }
2545 if (has_name_match) {
2546 packet.PutCString("name:");
2547 packet.PutBytesAsRawHex8(name.data(), name.size());
2548 packet.PutChar(';');
2549 }
2550 }
2551
2552 if (match_info.GetProcessInfo().ProcessIDIsValid())
2553 packet.Printf("pid:%" PRIu64 ";",
2554 match_info.GetProcessInfo().GetProcessID());
2555 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2556 packet.Printf("parent_pid:%" PRIu64 ";",
2557 match_info.GetProcessInfo().GetParentProcessID());
2558 if (match_info.GetProcessInfo().UserIDIsValid())
2559 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2560 if (match_info.GetProcessInfo().GroupIDIsValid())
2561 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2562 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2563 packet.Printf("euid:%u;",
2564 match_info.GetProcessInfo().GetEffectiveUserID());
2565 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2566 packet.Printf("egid:%u;",
2567 match_info.GetProcessInfo().GetEffectiveGroupID());
2568 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
2569 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2570 const ArchSpec &match_arch =
2571 match_info.GetProcessInfo().GetArchitecture();
2572 const llvm::Triple &triple = match_arch.GetTriple();
2573 packet.PutCString("triple:");
2574 packet.PutCString(triple.getTriple());
2575 packet.PutChar(';');
2576 }
2577 }
2578 StringExtractorGDBRemote response;
2579 // Increase timeout as the first qfProcessInfo packet takes a long time on
2580 // Android. The value of 1min was arrived at empirically.
2581 ScopedTimeout timeout(*this, minutes(1));
2582 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2584 do {
2585 ProcessInstanceInfo process_info;
2586 if (!DecodeProcessInfoResponse(response, process_info))
2587 break;
2588 process_infos.push_back(process_info);
2589 response = StringExtractorGDBRemote();
2590 } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==
2592 } else {
2594 return 0;
2595 }
2596 }
2597 return process_infos.size();
2598}
2599
2601 std::string &name) {
2603 char packet[32];
2604 const int packet_len =
2605 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2606 assert(packet_len < (int)sizeof(packet));
2607 UNUSED_IF_ASSERT_DISABLED(packet_len);
2608 StringExtractorGDBRemote response;
2609 if (SendPacketAndWaitForResponse(packet, response) ==
2611 if (response.IsNormalResponse()) {
2612 // Make sure we parsed the right number of characters. The response is
2613 // the hex encoded user name and should make up the entire packet. If
2614 // there are any non-hex ASCII bytes, the length won't match below..
2615 if (response.GetHexByteString(name) * 2 ==
2616 response.GetStringRef().size())
2617 return true;
2618 }
2619 } else {
2620 m_supports_qUserName = false;
2621 return false;
2622 }
2623 }
2624 return false;
2625}
2626
2628 std::string &name) {
2630 char packet[32];
2631 const int packet_len =
2632 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2633 assert(packet_len < (int)sizeof(packet));
2634 UNUSED_IF_ASSERT_DISABLED(packet_len);
2635 StringExtractorGDBRemote response;
2636 if (SendPacketAndWaitForResponse(packet, response) ==
2638 if (response.IsNormalResponse()) {
2639 // Make sure we parsed the right number of characters. The response is
2640 // the hex encoded group name and should make up the entire packet. If
2641 // there are any non-hex ASCII bytes, the length won't match below..
2642 if (response.GetHexByteString(name) * 2 ==
2643 response.GetStringRef().size())
2644 return true;
2645 }
2646 } else {
2647 m_supports_qGroupName = false;
2648 return false;
2649 }
2650 }
2651 return false;
2652}
2653
2654static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2655 uint32_t recv_size) {
2656 packet.Clear();
2657 packet.Printf("qSpeedTest:response_size:%x;data:", recv_size);
2658 uint32_t bytes_left = send_size;
2659 while (bytes_left > 0) {
2660 if (bytes_left >= 26) {
2661 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2662 bytes_left -= 26;
2663 } else {
2664 packet.Printf("%*.*s;", bytes_left, bytes_left,
2665 "abcdefghijklmnopqrstuvwxyz");
2666 bytes_left = 0;
2667 }
2668 }
2669}
2670
2671duration<float>
2672calculate_standard_deviation(const std::vector<duration<float>> &v) {
2673 if (v.size() == 0)
2674 return duration<float>::zero();
2675 using Dur = duration<float>;
2676 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2677 Dur mean = sum / v.size();
2678 float accum = 0;
2679 for (auto d : v) {
2680 float delta = (d - mean).count();
2681 accum += delta * delta;
2682 };
2683
2684 return Dur(sqrtf(accum / (v.size() - 1)));
2685}
2686
2688 uint32_t max_send,
2689 uint32_t max_recv,
2690 uint64_t recv_amount,
2691 bool json, Stream &strm) {
2692
2693 if (SendSpeedTestPacket(0, 0)) {
2694 StreamString packet;
2695 if (json)
2696 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2697 "\"results\" : [",
2698 num_packets);
2699 else
2700 strm.Printf("Testing sending %u packets of various sizes:\n",
2701 num_packets);
2702 strm.Flush();
2703
2704 uint32_t result_idx = 0;
2705 uint32_t send_size;
2706 std::vector<duration<float>> packet_times;
2707
2708 for (send_size = 0; send_size <= max_send;
2709 send_size ? send_size *= 2 : send_size = 4) {
2710 for (uint32_t recv_size = 0; recv_size <= max_recv;
2711 recv_size ? recv_size *= 2 : recv_size = 4) {
2712 MakeSpeedTestPacket(packet, send_size, recv_size);
2713
2714 packet_times.clear();
2715 // Test how long it takes to send 'num_packets' packets
2716 const auto start_time = steady_clock::now();
2717 for (uint32_t i = 0; i < num_packets; ++i) {
2718 const auto packet_start_time = steady_clock::now();
2719 StringExtractorGDBRemote response;
2720 SendPacketAndWaitForResponse(packet.GetString(), response);
2721 const auto packet_end_time = steady_clock::now();
2722 packet_times.push_back(packet_end_time - packet_start_time);
2723 }
2724 const auto end_time = steady_clock::now();
2725 const auto total_time = end_time - start_time;
2726
2727 float packets_per_second =
2728 ((float)num_packets) / duration<float>(total_time).count();
2729 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2730 : duration<float>::zero();
2731 const duration<float> standard_deviation =
2732 calculate_standard_deviation(packet_times);
2733 if (json) {
2734 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2735 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2736 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2737 result_idx > 0 ? "," : "", send_size, recv_size,
2738 total_time, standard_deviation);
2739 ++result_idx;
2740 } else {
2741 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2742 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2743 "standard deviation of {5,10:ms+f6}\n",
2744 send_size, recv_size, duration<float>(total_time),
2745 packets_per_second, duration<float>(average_per_packet),
2746 standard_deviation);
2747 }
2748 strm.Flush();
2749 }
2750 }
2751
2752 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2753 if (json)
2754 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2755 ": %" PRIu64 ",\n \"results\" : [",
2756 recv_amount);
2757 else
2758 strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2759 "packet sizes:\n",
2760 k_recv_amount_mb);
2761 strm.Flush();
2762 send_size = 0;
2763 result_idx = 0;
2764 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2765 MakeSpeedTestPacket(packet, send_size, recv_size);
2766
2767 // If we have a receive size, test how long it takes to receive 4MB of
2768 // data
2769 if (recv_size > 0) {
2770 const auto start_time = steady_clock::now();
2771 uint32_t bytes_read = 0;
2772 uint32_t packet_count = 0;
2773 while (bytes_read < recv_amount) {
2774 StringExtractorGDBRemote response;
2775 SendPacketAndWaitForResponse(packet.GetString(), response);
2776 bytes_read += recv_size;
2777 ++packet_count;
2778 }
2779 const auto end_time = steady_clock::now();
2780 const auto total_time = end_time - start_time;
2781 float mb_second = ((float)recv_amount) /
2782 duration<float>(total_time).count() /
2783 (1024.0 * 1024.0);
2784 float packets_per_second =
2785 ((float)packet_count) / duration<float>(total_time).count();
2786 const auto average_per_packet = packet_count > 0
2787 ? total_time / packet_count
2788 : duration<float>::zero();
2789
2790 if (json) {
2791 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2792 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2793 result_idx > 0 ? "," : "", send_size, recv_size,
2794 total_time);
2795 ++result_idx;
2796 } else {
2797 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2798 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2799 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2800 send_size, recv_size, packet_count, k_recv_amount_mb,
2801 duration<float>(total_time), mb_second,
2802 packets_per_second, duration<float>(average_per_packet));
2803 }
2804 strm.Flush();
2805 }
2806 }
2807 if (json)
2808 strm.Printf("\n ]\n }\n}\n");
2809 else
2810 strm.EOL();
2811 }
2812}
2813
2815 uint32_t recv_size) {
2816 StreamString packet;
2817 MakeSpeedTestPacket(packet, send_size, recv_size);
2818
2819 StringExtractorGDBRemote response;
2820 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
2822}
2823
2825 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2826 std::string &socket_name) {
2828 port = 0;
2829 socket_name.clear();
2830
2831 StringExtractorGDBRemote response;
2832 StreamString stream;
2833 stream.PutCString("qLaunchGDBServer;");
2834 std::string hostname;
2835 if (remote_accept_hostname && remote_accept_hostname[0])
2836 hostname = remote_accept_hostname;
2837 else {
2838 if (HostInfo::GetHostname(hostname)) {
2839 // Make the GDB server we launch only accept connections from this host
2840 stream.Printf("host:%s;", hostname.c_str());
2841 } else {
2842 // Make the GDB server we launch accept connections from any host since
2843 // we can't figure out the hostname
2844 stream.Printf("host:*;");
2845 }
2846 }
2847 // give the process a few seconds to startup
2848 ScopedTimeout timeout(*this, seconds(10));
2849
2850 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2852 if (response.IsErrorResponse())
2853 return false;
2854
2855 llvm::StringRef name;
2856 llvm::StringRef value;
2857 while (response.GetNameColonValue(name, value)) {
2858 if (name == "port")
2859 value.getAsInteger(BASE_10, port);
2860 else if (name == "pid")
2861 value.getAsInteger(BASE_10, pid);
2862 else if (name.compare("socket_name") == 0) {
2863 StringExtractor extractor(value);
2864 extractor.GetHexByteString(socket_name);
2865 }
2866 }
2867 return true;
2868 }
2869 return false;
2870}
2871
2873 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2874 connection_urls.clear();
2875
2876 StringExtractorGDBRemote response;
2877 if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=
2879 return 0;
2880
2883 if (!data)
2884 return 0;
2885
2886 StructuredData::Array *array = data->GetAsArray();
2887 if (!array)
2888 return 0;
2889
2890 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2891 std::optional<StructuredData::Dictionary *> maybe_element =
2893 if (!maybe_element)
2894 continue;
2895
2896 StructuredData::Dictionary *element = *maybe_element;
2897 uint16_t port = 0;
2898 if (StructuredData::ObjectSP port_osp =
2899 element->GetValueForKey(llvm::StringRef("port")))
2900 port = port_osp->GetUnsignedIntegerValue(0);
2901
2902 std::string socket_name;
2903 if (StructuredData::ObjectSP socket_name_osp =
2904 element->GetValueForKey(llvm::StringRef("socket_name")))
2905 socket_name = std::string(socket_name_osp->GetStringValue());
2906
2907 if (port != 0 || !socket_name.empty())
2908 connection_urls.emplace_back(port, socket_name);
2909 }
2910 return connection_urls.size();
2911}
2912
2914 StreamString stream;
2915 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
2916
2917 StringExtractorGDBRemote response;
2918 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2920 if (response.IsOKResponse())
2921 return true;
2922 }
2923 return false;
2924}
2925
2927 uint64_t tid, uint64_t pid, char op) {
2929 packet.PutChar('H');
2930 packet.PutChar(op);
2931
2932 if (pid != LLDB_INVALID_PROCESS_ID)
2933 packet.Printf("p%" PRIx64 ".", pid);
2934
2935 if (tid == UINT64_MAX)
2936 packet.PutCString("-1");
2937 else
2938 packet.Printf("%" PRIx64, tid);
2939
2940 StringExtractorGDBRemote response;
2941 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2943 if (response.IsOKResponse())
2944 return {{pid, tid}};
2945
2946 /*
2947 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2948 * Hg packet.
2949 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2950 * which can
2951 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2952 */
2953 if (response.IsUnsupportedResponse() && IsConnected())
2954 return {{1, 1}};
2955 }
2956 return std::nullopt;
2957}
2958
2960 uint64_t pid) {
2961 if (m_curr_tid == tid &&
2962 (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))
2963 return true;
2964
2965 std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
2966 if (ret) {
2967 if (ret->pid != LLDB_INVALID_PROCESS_ID)
2968 m_curr_pid = ret->pid;
2969 m_curr_tid = ret->tid;
2970 }
2971 return ret.has_value();
2972}
2973
2975 uint64_t pid) {
2976 if (m_curr_tid_run == tid &&
2977 (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))
2978 return true;
2979
2980 std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
2981 if (ret) {
2982 if (ret->pid != LLDB_INVALID_PROCESS_ID)
2983 m_curr_pid_run = ret->pid;
2984 m_curr_tid_run = ret->tid;
2985 }
2986 return ret.has_value();
2987}
2988
2990 StringExtractorGDBRemote &response) {
2992 return response.IsNormalResponse();
2993 return false;
2994}
2995
2997 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2999 char packet[256];
3000 int packet_len =
3001 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
3002 assert(packet_len < (int)sizeof(packet));
3003 UNUSED_IF_ASSERT_DISABLED(packet_len);
3004 if (SendPacketAndWaitForResponse(packet, response) ==
3006 if (response.IsUnsupportedResponse())
3008 else if (response.IsNormalResponse())
3009 return true;
3010 else
3011 return false;
3012 } else {
3014 }
3015 }
3016 return false;
3017}
3018
3020 GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
3021 std::chrono::seconds timeout) {
3023 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
3024 __FUNCTION__, insert ? "add" : "remove", addr);
3025
3026 // Check if the stub is known not to support this breakpoint type
3027 if (!SupportsGDBStoppointPacket(type))
3028 return UINT8_MAX;
3029 // Construct the breakpoint packet
3030 char packet[64];
3031 const int packet_len =
3032 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
3033 insert ? 'Z' : 'z', type, addr, length);
3034 // Check we haven't overwritten the end of the packet buffer
3035 assert(packet_len + 1 < (int)sizeof(packet));
3036 UNUSED_IF_ASSERT_DISABLED(packet_len);
3037 StringExtractorGDBRemote response;
3038 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
3039 // or "" (unsupported)
3041 // Try to send the breakpoint packet, and check that it was correctly sent
3042 if (SendPacketAndWaitForResponse(packet, response, timeout) ==
3044 // Receive and OK packet when the breakpoint successfully placed
3045 if (response.IsOKResponse())
3046 return 0;
3047
3048 // Status while setting breakpoint, send back specific error
3049 if (response.IsErrorResponse())
3050 return response.GetError();
3051
3052 // Empty packet informs us that breakpoint is not supported
3053 if (response.IsUnsupportedResponse()) {
3054 // Disable this breakpoint type since it is unsupported
3055 switch (type) {
3057 m_supports_z0 = false;
3058 break;
3060 m_supports_z1 = false;
3061 break;
3062 case eWatchpointWrite:
3063 m_supports_z2 = false;
3064 break;
3065 case eWatchpointRead:
3066 m_supports_z3 = false;
3067 break;
3069 m_supports_z4 = false;
3070 break;
3071 case eStoppointInvalid:
3072 return UINT8_MAX;
3073 }
3074 }
3075 }
3076 // Signal generic failure
3077 return UINT8_MAX;
3078}
3079
3080std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
3082 bool &sequence_mutex_unavailable) {
3083 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
3084
3085 Lock lock(*this);
3086 if (lock) {
3087 sequence_mutex_unavailable = false;
3088 StringExtractorGDBRemote response;
3089
3090 PacketResult packet_result;
3091 for (packet_result =
3092 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
3093 packet_result == PacketResult::Success && response.IsNormalResponse();
3094 packet_result =
3095 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
3096 char ch = response.GetChar();
3097 if (ch == 'l')
3098 break;
3099 if (ch == 'm') {
3100 do {
3101 auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);
3102 // If we get an invalid response, break out of the loop.
3103 // If there are valid tids, they have been added to ids.
3104 // If there are no valid tids, we'll fall through to the
3105 // bare-iron target handling below.
3106 if (!pid_tid)
3107 break;
3108
3109 ids.push_back(*pid_tid);
3110 ch = response.GetChar(); // Skip the command separator
3111 } while (ch == ','); // Make sure we got a comma separator
3112 }
3113 }
3114
3115 /*
3116 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
3117 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
3118 * could
3119 * be as simple as 'S05'. There is no packet which can give us pid and/or
3120 * tid.
3121 * Assume pid=tid=1 in such cases.
3122 */
3123 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
3124 ids.size() == 0 && IsConnected()) {
3125 ids.emplace_back(1, 1);
3126 }
3127 } else {
3129 LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending "
3130 "packet 'qfThreadInfo'");
3131 sequence_mutex_unavailable = true;
3132 }
3133
3134 return ids;
3135}
3136
3138 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
3140 thread_ids.clear();
3141
3142 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
3143 if (ids.empty() || sequence_mutex_unavailable)
3144 return 0;
3145
3146 for (auto id : ids) {
3147 // skip threads that do not belong to the current process
3148 if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)
3149 continue;
3150 if (id.second != LLDB_INVALID_THREAD_ID &&
3152 thread_ids.push_back(id.second);
3153 }
3154
3155 return thread_ids.size();
3156}
3157
3159 StringExtractorGDBRemote response;
3160 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=
3162 !response.IsNormalResponse())
3163 return LLDB_INVALID_ADDRESS;
3164 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
3165}
3166
3168 llvm::StringRef command,
3169 const FileSpec &
3170 working_dir, // Pass empty FileSpec to use the current working directory
3171 int *status_ptr, // Pass NULL if you don't want the process exit status
3172 int *signo_ptr, // Pass NULL if you don't want the signal that caused the
3173 // process to exit
3174 std::string
3175 *command_output, // Pass nullptr if you don't want the command output
3176 std::string *separated_error_output, // Pass nullptr if you don't want the
3177 // command error output
3178 const Timeout<std::micro> &timeout) {
3180 stream.PutCString("qPlatform_shell:");
3181 stream.PutBytesAsRawHex8(command.data(), command.size());
3182 stream.PutChar(',');
3183 uint32_t timeout_sec = UINT32_MAX;
3184 if (timeout) {
3185 // TODO: Use chrono version of std::ceil once c++17 is available.
3186 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3187 }
3188 stream.PutHex32(timeout_sec);
3189 if (working_dir) {
3190 std::string path{working_dir.GetPath(false)};
3191 stream.PutChar(',');
3192 stream.PutStringAsRawHex8(path);
3193 }
3194 StringExtractorGDBRemote response;
3195 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3197 if (response.GetChar() != 'F')
3198 return Status::FromErrorString("malformed reply");
3199 if (response.GetChar() != ',')
3200 return Status::FromErrorString("malformed reply");
3201 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
3202 if (exitcode == UINT32_MAX)
3203 return Status::FromErrorString("unable to run remote process");
3204 else if (status_ptr)
3205 *status_ptr = exitcode;
3206 if (response.GetChar() != ',')
3207 return Status::FromErrorString("malformed reply");
3208 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
3209 if (signo_ptr)
3210 *signo_ptr = signo;
3211 if (response.GetChar() != ',')
3212 return Status::FromErrorString("malformed reply");
3213 std::string output;
3214 response.GetEscapedBinaryData(output);
3215 if (command_output)
3216 command_output->assign(output);
3217 return Status();
3218 }
3219 return Status::FromErrorString("unable to send packet");
3220}
3221
3223 uint32_t file_permissions) {
3224 std::string path{file_spec.GetPath(false)};
3226 stream.PutCString("qPlatform_mkdir:");
3227 stream.PutHex32(file_permissions);
3228 stream.PutChar(',');
3229 stream.PutStringAsRawHex8(path);
3230 llvm::StringRef packet = stream.GetString();
3231 StringExtractorGDBRemote response;
3232
3233 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
3234 return Status::FromErrorStringWithFormat("failed to send '%s' packet",
3235 packet.str().c_str());
3236
3237 if (response.GetChar() != 'F')
3238 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",
3239 packet.str().c_str());
3240
3241 return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
3242}
3243
3244Status
3246 uint32_t file_permissions) {
3247 std::string path{file_spec.GetPath(false)};
3249 stream.PutCString("qPlatform_chmod:");
3250 stream.PutHex32(file_permissions);
3251 stream.PutChar(',');
3252 stream.PutStringAsRawHex8(path);
3253 llvm::StringRef packet = stream.GetString();
3254 StringExtractorGDBRemote response;
3255
3256 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
3257 return Status::FromErrorStringWithFormat("failed to send '%s' packet",
3258 stream.GetData());
3259
3260 if (response.GetChar() != 'F')
3261 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",
3262 stream.GetData());
3263
3264 return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
3265}
3266
3267static int gdb_errno_to_system(int err) {
3268 switch (err) {
3269#define HANDLE_ERRNO(name, value) \
3270 case GDB_##name: \
3271 return name;
3272#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3273 default:
3274 return -1;
3275 }
3276}
3277
3279 uint64_t fail_result, Status &error) {
3280 response.SetFilePos(0);
3281 if (response.GetChar() != 'F')
3282 return fail_result;
3283 int32_t result = response.GetS32(-2, 16);
3284 if (result == -2)
3285 return fail_result;
3286 if (response.GetChar() == ',') {
3287 int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3288 if (result_errno != -1)
3289 error = Status(result_errno, eErrorTypePOSIX);
3290 else
3292 } else
3293 error.Clear();
3294 return result;
3295}
3298 File::OpenOptions flags, mode_t mode,
3299 Status &error) {
3300 std::string path(file_spec.GetPath(false));
3302 stream.PutCString("vFile:open:");
3303 if (path.empty())
3304 return UINT64_MAX;
3305 stream.PutStringAsRawHex8(path);
3306 stream.PutChar(',');
3307 stream.PutHex32(flags);
3308 stream.PutChar(',');
3309 stream.PutHex32(mode);
3310 StringExtractorGDBRemote response;
3311 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3313 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
3314 }
3315 return UINT64_MAX;
3316}
3317
3319 Status &error) {
3321 stream.Printf("vFile:close:%x", (int)fd);
3322 StringExtractorGDBRemote response;
3323 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3325 return ParseHostIOPacketResponse(response, -1, error) == 0;
3326 }
3327 return false;
3328}
3329
3330std::optional<GDBRemoteFStatData>
3333 stream.Printf("vFile:fstat:%" PRIx64, fd);
3334 StringExtractorGDBRemote response;
3335 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3337 if (response.GetChar() != 'F')
3338 return std::nullopt;
3339 int64_t size = response.GetS64(-1, 16);
3340 if (size > 0 && response.GetChar() == ';') {
3341 std::string buffer;
3342 if (response.GetEscapedBinaryData(buffer)) {
3344 if (buffer.size() != sizeof(out))
3345 return std::nullopt;
3346 memcpy(&out, buffer.data(), sizeof(out));
3347 return out;
3348 }
3349 }
3350 }
3351 return std::nullopt;
3352}
3353
3354std::optional<GDBRemoteFStatData>
3356 Status error;
3358 if (fd == UINT64_MAX)
3359 return std::nullopt;
3360 std::optional<GDBRemoteFStatData> st = FStat(fd);
3361 CloseFile(fd, error);
3362 return st;
3363}
3364
3365// Extension of host I/O packets to get the file size.
3367 const lldb_private::FileSpec &file_spec) {
3369 std::string path(file_spec.GetPath(false));
3371 stream.PutCString("vFile:size:");
3372 stream.PutStringAsRawHex8(path);
3373 StringExtractorGDBRemote response;
3374 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
3376 return UINT64_MAX;
3377
3378 if (!response.IsUnsupportedResponse()) {
3379 if (response.GetChar() != 'F')
3380 return UINT64_MAX;
3381 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
3382 return retcode;
3383 }
3384 m_supports_vFileSize = false;
3385 }
3386
3387 // Fallback to fstat.
3388 std::optional<GDBRemoteFStatData> st = Stat(file_spec);
3389 return st ? st->gdb_st_size : UINT64_MAX;
3390}
3391
3393 CompletionRequest &request, bool only_dir) {
3395 stream.PutCString("qPathComplete:");
3396 stream.PutHex32(only_dir ? 1 : 0);
3397 stream.PutChar(',');
3399 StringExtractorGDBRemote response;
3400 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3402 StreamString strm;
3403 char ch = response.GetChar();
3404 if (ch != 'M')
3405 return;
3406 while (response.Peek()) {
3407 strm.Clear();
3408 while ((ch = response.GetHexU8(0, false)) != '\0')
3409 strm.PutChar(ch);
3410 request.AddCompletion(strm.GetString());
3411 if (response.GetChar() != ',')
3412 break;
3413 }
3414 }
3415}
3416
3417Status
3419 uint32_t &file_permissions) {
3421 std::string path{file_spec.GetPath(false)};
3422 Status error;
3424 stream.PutCString("vFile:mode:");
3425 stream.PutStringAsRawHex8(path);
3426 StringExtractorGDBRemote response;
3427 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
3429 error = Status::FromErrorStringWithFormat("failed to send '%s' packet",
3430 stream.GetData());
3431 return error;
3432 }
3433 if (!response.IsUnsupportedResponse()) {
3434 if (response.GetChar() != 'F') {
3436 "invalid response to '%s' packet", stream.GetData());
3437 } else {
3438 const uint32_t mode = response.GetS32(-1, 16);
3439 if (static_cast<int32_t>(mode) == -1) {
3440 if (response.GetChar() == ',') {
3441 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3442 if (response_errno > 0)
3443 error = Status(response_errno, lldb::eErrorTypePOSIX);
3444 else
3445 error = Status::FromErrorString("unknown error");
3446 } else
3447 error = Status::FromErrorString("unknown error");
3448 } else {
3449 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
3450 }
3451 }
3452 return error;
3453 } else { // response.IsUnsupportedResponse()
3454 m_supports_vFileMode = false;
3455 }
3456 }
3457
3458 // Fallback to fstat.
3459 if (std::optional<GDBRemoteFStatData> st = Stat(file_spec)) {
3460 file_permissions = st->gdb_st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
3461 return Status();
3462 }
3463 return Status::FromErrorString("fstat failed");
3464}
3465
3467 uint64_t offset, void *dst,
3468 uint64_t dst_len,
3469 Status &error) {
3471 stream.Printf("vFile:pread:%x,%" PRIx64 ",%" PRIx64, (int)fd, dst_len,
3472 offset);
3473 StringExtractorGDBRemote response;
3474 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3476 if (response.GetChar() != 'F')
3477 return 0;
3478 int64_t retcode = response.GetS64(-1, 16);
3479 if (retcode == -1) {
3480 error = Status::FromErrorString("unknown error");
3481 if (response.GetChar() == ',') {
3482 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3483 if (response_errno > 0)
3484 error = Status(response_errno, lldb::eErrorTypePOSIX);
3485 }
3486 return -1;
3487 }
3488 const char next = (response.Peek() ? *response.Peek() : 0);
3489 if (next == ',')
3490 return 0;
3491 if (next == ';') {
3492 response.GetChar(); // skip the semicolon
3493 std::string buffer;
3494 if (response.GetEscapedBinaryData(buffer)) {
3495 const uint64_t data_to_write =
3496 std::min<uint64_t>(dst_len, buffer.size());
3497 if (data_to_write > 0)
3498 memcpy(dst, &buffer[0], data_to_write);
3499 return data_to_write;
3500 }
3501 }
3502 }
3503 return 0;
3504}
3505
3507 uint64_t offset,
3508 const void *src,
3509 uint64_t src_len,
3510 Status &error) {
3512 stream.Printf("vFile:pwrite:%x,%" PRIx64 ",", (int)fd, offset);
3513 stream.PutEscapedBytes(src, src_len);
3514 StringExtractorGDBRemote response;
3515 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3517 if (response.GetChar() != 'F') {
3518 error = Status::FromErrorStringWithFormat("write file failed");
3519 return 0;
3520 }
3521 int64_t bytes_written = response.GetS64(-1, 16);
3522 if (bytes_written == -1) {
3523 error = Status::FromErrorString("unknown error");
3524 if (response.GetChar() == ',') {
3525 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3526 if (response_errno > 0)
3527 error = Status(response_errno, lldb::eErrorTypePOSIX);
3528 }
3529 return -1;
3530 }
3531 return bytes_written;
3532 } else {
3533 error = Status::FromErrorString("failed to send vFile:pwrite packet");
3534 }
3535 return 0;
3536}
3537
3539 const FileSpec &dst) {
3540 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
3541 Status error;
3543 stream.PutCString("vFile:symlink:");
3544 // the unix symlink() command reverses its parameters where the dst if first,
3545 // so we follow suit here
3546 stream.PutStringAsRawHex8(dst_path);
3547 stream.PutChar(',');
3548 stream.PutStringAsRawHex8(src_path);
3549 StringExtractorGDBRemote response;
3550 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3552 if (response.GetChar() == 'F') {
3553 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
3554 if (result != 0) {
3555 error = Status::FromErrorString("unknown error");
3556 if (response.GetChar() == ',') {
3557 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3558 if (response_errno > 0)
3559 error = Status(response_errno, lldb::eErrorTypePOSIX);
3560 }
3561 }
3562 } else {
3563 // Should have returned with 'F<result>[,<errno>]'
3564 error = Status::FromErrorStringWithFormat("symlink failed");
3565 }
3566 } else {
3567 error = Status::FromErrorString("failed to send vFile:symlink packet");
3568 }
3569 return error;
3570}
3571
3573 std::string path{file_spec.GetPath(false)};
3574 Status error;
3576 stream.PutCString("vFile:unlink:");
3577 // the unix symlink() command reverses its parameters where the dst if first,
3578 // so we follow suit here
3579 stream.PutStringAsRawHex8(path);
3580 StringExtractorGDBRemote response;
3581 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3583 if (response.GetChar() == 'F') {
3584 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
3585 if (result != 0) {
3586 error = Status::FromErrorString("unknown error");
3587 if (response.GetChar() == ',') {
3588 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3589 if (response_errno > 0)
3590 error = Status(response_errno, lldb::eErrorTypePOSIX);
3591 }
3592 }
3593 } else {
3594 // Should have returned with 'F<result>[,<errno>]'
3595 error = Status::FromErrorStringWithFormat("unlink failed");
3596 }
3597 } else {
3598 error = Status::FromErrorString("failed to send vFile:unlink packet");
3599 }
3600 return error;
3601}
3602
3603// Extension of host I/O packets to get whether a file exists.
3605 const lldb_private::FileSpec &file_spec) {
3607 std::string path(file_spec.GetPath(false));
3609 stream.PutCString("vFile:exists:");
3610 stream.PutStringAsRawHex8(path);
3611 StringExtractorGDBRemote response;
3612 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
3614 return false;
3615 if (!response.IsUnsupportedResponse()) {
3616 if (response.GetChar() != 'F')
3617 return false;
3618 if (response.GetChar() != ',')
3619 return false;
3620 bool retcode = (response.GetChar() != '0');
3621 return retcode;
3622 } else
3623 m_supports_vFileExists = false;
3624 }
3625
3626 // Fallback to open.
3627 Status error;
3629 if (fd == UINT64_MAX)
3630 return false;
3631 CloseFile(fd, error);
3632 return true;
3633}
3634
3635llvm::ErrorOr<llvm::MD5::MD5Result> GDBRemoteCommunicationClient::CalculateMD5(
3636 const lldb_private::FileSpec &file_spec) {
3637 std::string path(file_spec.GetPath(false));
3639 stream.PutCString("vFile:MD5:");
3640 stream.PutStringAsRawHex8(path);
3641 StringExtractorGDBRemote response;
3642 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3644 if (response.GetChar() != 'F')
3645 return std::make_error_code(std::errc::illegal_byte_sequence);
3646 if (response.GetChar() != ',')
3647 return std::make_error_code(std::errc::illegal_byte_sequence);
3648 if (response.Peek() && *response.Peek() == 'x')
3649 return std::make_error_code(std::errc::no_such_file_or_directory);
3650
3651 // GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 concatenates low and
3652 // high hex strings. We can't use response.GetHexMaxU64 because that can't
3653 // handle the concatenated hex string. What would happen is parsing the low
3654 // would consume the whole response packet which would give incorrect
3655 // results. Instead, we get the byte string for each low and high hex
3656 // separately, and parse them.
3657 //
3658 // An alternate way to handle this is to change the server to put a
3659 // delimiter between the low/high parts, and change the client to parse the
3660 // delimiter. However, we choose not to do this so existing lldb-servers
3661 // don't have to be patched
3662
3663 // The checksum is 128 bits encoded as hex
3664 // This means low/high are halves of 64 bits each, in otherwords, 8 bytes.
3665 // Each byte takes 2 hex characters in the response.
3666 const size_t MD5_HALF_LENGTH = sizeof(uint64_t) * 2;
3667
3668 // Get low part
3669 auto part =
3670 response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);
3671 if (part.size() != MD5_HALF_LENGTH)
3672 return std::make_error_code(std::errc::illegal_byte_sequence);
3673 response.SetFilePos(response.GetFilePos() + part.size());
3674
3675 uint64_t low;
3676 if (part.getAsInteger(BASE_16, low))
3677 return std::make_error_code(std::errc::illegal_byte_sequence);
3678
3679 // Get high part
3680 part =
3681 response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);
3682 if (part.size() != MD5_HALF_LENGTH)
3683 return std::make_error_code(std::errc::illegal_byte_sequence);
3684 response.SetFilePos(response.GetFilePos() + part.size());
3685
3686 uint64_t high;
3687 if (part.getAsInteger(BASE_16, high))
3688 return std::make_error_code(std::errc::illegal_byte_sequence);
3689
3690 llvm::MD5::MD5Result result;
3691 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3692 result.data(), low);
3693 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3694 result.data() + 8, high);
3695
3696 return result;
3697 }
3698 return std::make_error_code(std::errc::operation_canceled);
3699}
3700
3702 // Some targets have issues with g/G packets and we need to avoid using them
3704 if (process) {
3706 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3707 if (arch.IsValid() &&
3708 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3709 arch.GetTriple().getOS() == llvm::Triple::IOS &&
3710 (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
3711 arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3713 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3714 if (gdb_server_version != 0) {
3715 const char *gdb_server_name = GetGDBServerProgramName();
3716 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3717 if (gdb_server_version >= 310)
3719 }
3720 }
3721 }
3722 }
3723 }
3725}
3726
3728 uint32_t reg) {
3729 StreamString payload;
3730 payload.Printf("p%x", reg);
3731 StringExtractorGDBRemote response;
3733 tid, std::move(payload), response) != PacketResult::Success ||
3734 !response.IsNormalResponse())
3735 return nullptr;
3736
3737 WritableDataBufferSP buffer_sp(
3738 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3739 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3740 return buffer_sp;
3741}
3742
3744 StreamString payload;
3745 payload.PutChar('g');
3746 StringExtractorGDBRemote response;
3748 tid, std::move(payload), response) != PacketResult::Success ||
3749 !response.IsNormalResponse())
3750 return nullptr;
3751
3752 WritableDataBufferSP buffer_sp(
3753 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3754 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3755 return buffer_sp;
3756}
3757
3759 uint32_t reg_num,
3760 llvm::ArrayRef<uint8_t> data) {
3761 StreamString payload;
3762 payload.Printf("P%x=", reg_num);
3763 payload.PutBytesAsRawHex8(data.data(), data.size(),
3766 StringExtractorGDBRemote response;
3768 tid, std::move(payload), response) == PacketResult::Success &&
3769 response.IsOKResponse();
3770}
3771
3773 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3774 StreamString payload;
3775 payload.PutChar('G');
3776 payload.PutBytesAsRawHex8(data.data(), data.size(),
3779 StringExtractorGDBRemote response;
3781 tid, std::move(payload), response) == PacketResult::Success &&
3782 response.IsOKResponse();
3783}
3784
3786 uint32_t &save_id) {
3787 save_id = 0; // Set to invalid save ID
3789 return false;
3790
3792 StreamString payload;
3793 payload.PutCString("QSaveRegisterState");
3794 StringExtractorGDBRemote response;
3796 tid, std::move(payload), response) != PacketResult::Success)
3797 return false;
3798
3799 if (response.IsUnsupportedResponse())
3801
3802 const uint32_t response_save_id = response.GetU32(0);
3803 if (response_save_id == 0)
3804 return false;
3805
3806 save_id = response_save_id;
3807 return true;
3808}
3809
3811 uint32_t save_id) {
3812 // We use the "m_supports_QSaveRegisterState" variable here because the
3813 // QSaveRegisterState and QRestoreRegisterState packets must both be
3814 // supported in order to be useful
3816 return false;
3817
3818 StreamString payload;
3819 payload.Printf("QRestoreRegisterState:%u", save_id);
3820 StringExtractorGDBRemote response;
3822 tid, std::move(payload), response) != PacketResult::Success)
3823 return false;
3824
3825 if (response.IsOKResponse())
3826 return true;
3827
3828 if (response.IsUnsupportedResponse())
3830 return false;
3831}
3832
3835 return false;
3836
3837 StreamString packet;
3838 StringExtractorGDBRemote response;
3839 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3840 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
3842 response.IsOKResponse();
3843}
3844
3845llvm::Expected<TraceSupportedResponse>
3847 Log *log = GetLog(GDBRLog::Process);
3848
3849 StreamGDBRemote escaped_packet;
3850 escaped_packet.PutCString("jLLDBTraceSupported");
3851
3852 StringExtractorGDBRemote response;
3853 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3854 timeout) ==
3856 if (response.IsErrorResponse())
3857 return response.GetStatus().ToError();
3858 if (response.IsUnsupportedResponse())
3859 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3860 "jLLDBTraceSupported is unsupported");
3861
3862 return llvm::json::parse<TraceSupportedResponse>(response.Peek(),
3863 "TraceSupportedResponse");
3864 }
3865 LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");
3866 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3867 "failed to send packet: jLLDBTraceSupported");
3868}
3869
3870llvm::Error
3872 std::chrono::seconds timeout) {
3873 Log *log = GetLog(GDBRLog::Process);
3874
3875 StreamGDBRemote escaped_packet;
3876 escaped_packet.PutCString("jLLDBTraceStop:");
3877
3878 std::string json_string;
3879 llvm::raw_string_ostream os(json_string);
3880 os << toJSON(request);
3881
3882 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3883
3884 StringExtractorGDBRemote response;
3885 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3886 timeout) ==
3888 if (response.IsErrorResponse())
3889 return response.GetStatus().ToError();
3890 if (response.IsUnsupportedResponse())
3891 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3892 "jLLDBTraceStop is unsupported");
3893 if (response.IsOKResponse())
3894 return llvm::Error::success();
3895 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3896 "Invalid jLLDBTraceStart response");
3897 }
3898 LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");
3899 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3900 "failed to send packet: jLLDBTraceStop '%s'",
3901 escaped_packet.GetData());
3902}
3903
3904llvm::Error
3905GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
3906 std::chrono::seconds timeout) {
3907 Log *log = GetLog(GDBRLog::Process);
3908
3909 StreamGDBRemote escaped_packet;
3910 escaped_packet.PutCString("jLLDBTraceStart:");
3911
3912 std::string json_string;
3913 llvm::raw_string_ostream os(json_string);
3914 os << params;
3915
3916 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3917
3918 StringExtractorGDBRemote response;
3919 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3920 timeout) ==
3922 if (response.IsErrorResponse())
3923 return response.GetStatus().ToError();
3924 if (response.IsUnsupportedResponse())
3925 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3926 "jLLDBTraceStart is unsupported");
3927 if (response.IsOKResponse())
3928 return llvm::Error::success();
3929 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3930 "Invalid jLLDBTraceStart response");
3931 }
3932 LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");
3933 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3934 "failed to send packet: jLLDBTraceStart '%s'",
3935 escaped_packet.GetData());
3936}
3937
3938llvm::Expected<std::string>
3940 std::chrono::seconds timeout) {
3941 Log *log = GetLog(GDBRLog::Process);
3942
3943 StreamGDBRemote escaped_packet;
3944 escaped_packet.PutCString("jLLDBTraceGetState:");
3945
3946 std::string json_string;
3947 llvm::raw_string_ostream os(json_string);
3948 os << toJSON(TraceGetStateRequest{type.str()});
3949
3950 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3951
3952 StringExtractorGDBRemote response;
3953 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3954 timeout) ==
3956 if (response.IsErrorResponse())
3957 return response.GetStatus().ToError();
3958 if (response.IsUnsupportedResponse())
3959 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3960 "jLLDBTraceGetState is unsupported");
3961 return std::string(response.Peek());
3962 }
3963
3964 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");
3965 return llvm::createStringError(
3966 llvm::inconvertibleErrorCode(),
3967 "failed to send packet: jLLDBTraceGetState '%s'",
3968 escaped_packet.GetData());
3969}
3970
3971llvm::Expected<std::vector<uint8_t>>
3973 const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {
3974 Log *log = GetLog(GDBRLog::Process);
3975
3976 StreamGDBRemote escaped_packet;
3977 escaped_packet.PutCString("jLLDBTraceGetBinaryData:");
3978
3979 std::string json_string;
3980 llvm::raw_string_ostream os(json_string);
3981 os << toJSON(request);
3982
3983 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3984
3985 StringExtractorGDBRemote response;
3986 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3987 timeout) ==
3989 if (response.IsErrorResponse())
3990 return response.GetStatus().ToError();
3991 std::string data;
3992 response.GetEscapedBinaryData(data);
3993 return std::vector<uint8_t>(data.begin(), data.end());
3994 }
3995 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");
3996 return llvm::createStringError(
3997 llvm::inconvertibleErrorCode(),
3998 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3999 escaped_packet.GetData());
4000}
4001
4003 StringExtractorGDBRemote response;
4004 if (SendPacketAndWaitForResponse("qOffsets", response) !=
4006 return std::nullopt;
4007 if (!response.IsNormalResponse())
4008 return std::nullopt;
4009
4010 QOffsets result;
4011 llvm::StringRef ref = response.GetStringRef();
4012 const auto &GetOffset = [&] {
4013 addr_t offset;
4014 if (ref.consumeInteger(16, offset))
4015 return false;
4016 result.offsets.push_back(offset);
4017 return true;
4018 };
4019
4020 if (ref.consume_front("Text=")) {
4021 result.segments = false;
4022 if (!GetOffset())
4023 return std::nullopt;
4024 if (!ref.consume_front(";Data=") || !GetOffset())
4025 return std::nullopt;
4026 if (ref.empty())
4027 return result;
4028 if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())
4029 return result;
4030 } else if (ref.consume_front("TextSeg=")) {
4031 result.segments = true;
4032 if (!GetOffset())
4033 return std::nullopt;
4034 if (ref.empty())
4035 return result;
4036 if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())
4037 return result;
4038 }
4039 return std::nullopt;
4040}
4041
4043 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
4044 ModuleSpec &module_spec) {
4046 return false;
4047
4048 std::string module_path = module_file_spec.GetPath(false);
4049 if (module_path.empty())
4050 return false;
4051
4052 StreamString packet;
4053 packet.PutCString("qModuleInfo:");
4054 packet.PutStringAsRawHex8(module_path);
4055 packet.PutCString(";");
4056 const auto &triple = arch_spec.GetTriple().getTriple();
4057 packet.PutStringAsRawHex8(triple);
4058
4059 StringExtractorGDBRemote response;
4060 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
4062 return false;
4063
4064 if (response.IsErrorResponse())
4065 return false;
4066
4067 if (response.IsUnsupportedResponse()) {
4068 m_supports_qModuleInfo = false;
4069 return false;
4070 }
4071
4072 llvm::StringRef name;
4073 llvm::StringRef value;
4074
4075 module_spec.Clear();
4076 module_spec.GetFileSpec() = module_file_spec;
4077
4078 while (response.GetNameColonValue(name, value)) {
4079 if (name == "uuid" || name == "md5") {
4080 StringExtractor extractor(value);
4081 std::string uuid;
4082 extractor.GetHexByteString(uuid);
4083 module_spec.GetUUID().SetFromStringRef(uuid);
4084 } else if (name == "triple") {
4085 StringExtractor extractor(value);
4086 std::string triple;
4087 extractor.GetHexByteString(triple);
4088 module_spec.GetArchitecture().SetTriple(triple.c_str());
4089 } else if (name == "file_offset") {
4090 uint64_t ival = 0;
4091 if (!value.getAsInteger(BASE_16, ival))
4092 module_spec.SetObjectOffset(ival);
4093 } else if (name == "file_size") {
4094 uint64_t ival = 0;
4095 if (!value.getAsInteger(BASE_16, ival))
4096 module_spec.SetObjectSize(ival);
4097 } else if (name == "file_path") {
4098 StringExtractor extractor(value);
4099 std::string path;
4100 extractor.GetHexByteString(path);
4101 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
4102 }
4103 }
4104
4105 return true;
4106}
4107
4108static std::optional<ModuleSpec>
4110 ModuleSpec result;
4111 if (!dict)
4112 return std::nullopt;
4113
4114 llvm::StringRef string;
4115 uint64_t integer;
4116
4117 if (!dict->GetValueForKeyAsString("uuid", string))
4118 return std::nullopt;
4119 if (!result.GetUUID().SetFromStringRef(string))
4120 return std::nullopt;
4121
4122 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
4123 return std::nullopt;
4124 result.SetObjectOffset(integer);
4125
4126 if (!dict->GetValueForKeyAsInteger("file_size", integer))
4127 return std::nullopt;
4128 result.SetObjectSize(integer);
4129
4130 if (!dict->GetValueForKeyAsString("triple", string))
4131 return std::nullopt;
4132 result.GetArchitecture().SetTriple(string);
4133
4134 if (!dict->GetValueForKeyAsString("file_path", string))
4135 return std::nullopt;
4136 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
4137
4138 return result;
4139}
4140
4141std::optional<std::vector<ModuleSpec>>
4143 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
4144 namespace json = llvm::json;
4145
4147 return std::nullopt;
4148
4149 json::Array module_array;
4150 for (const FileSpec &module_file_spec : module_file_specs) {
4151 module_array.push_back(
4152 json::Object{{"file", module_file_spec.GetPath(false)},
4153 {"triple", triple.getTriple()}});
4154 }
4155 StreamString unescaped_payload;
4156 unescaped_payload.PutCString("jModulesInfo:");
4157 unescaped_payload.AsRawOstream() << std::move(module_array);
4158
4159 StreamGDBRemote payload;
4160 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
4161 unescaped_payload.GetSize());
4162
4163 // Increase the timeout for jModulesInfo since this packet can take longer.
4164 ScopedTimeout timeout(*this, std::chrono::seconds(10));
4165
4166 StringExtractorGDBRemote response;
4167 if (SendPacketAndWaitForResponse(payload.GetString(), response) !=
4169 response.IsErrorResponse())
4170 return std::nullopt;
4171
4172 if (response.IsUnsupportedResponse()) {
4174 return std::nullopt;
4175 }
4176
4177 StructuredData::ObjectSP response_object_sp =
4179 if (!response_object_sp)
4180 return std::nullopt;
4181
4182 StructuredData::Array *response_array = response_object_sp->GetAsArray();
4183 if (!response_array)
4184 return std::nullopt;
4185
4186 std::vector<ModuleSpec> result;
4187 for (size_t i = 0; i < response_array->GetSize(); ++i) {
4188 if (std::optional<ModuleSpec> module_spec = ParseModuleSpec(
4189 response_array->GetItemAtIndex(i)->GetAsDictionary()))
4190 result.push_back(*module_spec);
4191 }
4192
4193 return result;
4194}
4195
4196// query the target remote for extended information using the qXfer packet
4197//
4198// example: object='features', annex='target.xml'
4199// return: <xml output> or error
4200llvm::Expected<std::string>
4202 llvm::StringRef annex) {
4203
4204 std::string output;
4205 llvm::raw_string_ostream output_stream(output);
4207
4208 uint64_t size = GetRemoteMaxPacketSize();
4209 if (size == 0)
4210 size = 0x1000;
4211 size = size - 1; // Leave space for the 'm' or 'l' character in the response
4212 int offset = 0;
4213 bool active = true;
4214
4215 // loop until all data has been read
4216 while (active) {
4217
4218 // send query extended feature packet
4219 std::string packet =
4220 ("qXfer:" + object + ":read:" + annex + ":" +
4221 llvm::Twine::utohexstr(offset) + "," + llvm::Twine::utohexstr(size))
4222 .str();
4223
4225 SendPacketAndWaitForResponse(packet, chunk);
4226
4228 chunk.GetStringRef().empty()) {
4229 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4230 "Error sending $qXfer packet");
4231 }
4232
4233 // check packet code
4234 switch (chunk.GetStringRef()[0]) {
4235 // last chunk
4236 case ('l'):
4237 active = false;
4238 [[fallthrough]];
4239
4240 // more chunks
4241 case ('m'):
4242 output_stream << chunk.GetStringRef().drop_front();
4243 offset += chunk.GetStringRef().size() - 1;
4244 break;
4245
4246 // unknown chunk
4247 default:
4248 return llvm::createStringError(
4249 llvm::inconvertibleErrorCode(),
4250 "Invalid continuation code from $qXfer packet");
4251 }
4252 }
4253
4254 return output;
4255}
4256
4257// Notify the target that gdb is prepared to serve symbol lookup requests.
4258// packet: "qSymbol::"
4259// reply:
4260// OK The target does not need to look up any (more) symbols.
4261// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
4262// encoded).
4263// LLDB may provide the value by sending another qSymbol
4264// packet
4265// in the form of"qSymbol:<sym_value>:<sym_name>".
4266//
4267// Three examples:
4268//
4269// lldb sends: qSymbol::
4270// lldb receives: OK
4271// Remote gdb stub does not need to know the addresses of any symbols, lldb
4272// does not
4273// need to ask again in this session.
4274//
4275// lldb sends: qSymbol::
4276// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4277// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
4278// lldb receives: OK
4279// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
4280// not know
4281// the address at this time. lldb needs to send qSymbol:: again when it has
4282// more
4283// solibs loaded.
4284//
4285// lldb sends: qSymbol::
4286// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4287// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
4288// lldb receives: OK
4289// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
4290// that it
4291// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
4292// does not
4293// need any more symbols. lldb does not need to ask again in this session.
4294
4296 lldb_private::Process *process) {
4297 // Set to true once we've resolved a symbol to an address for the remote
4298 // stub. If we get an 'OK' response after this, the remote stub doesn't need
4299 // any more symbols and we can stop asking.
4300 bool symbol_response_provided = false;
4301
4302 // Is this the initial qSymbol:: packet?
4303 bool first_qsymbol_query = true;
4304
4306 Lock lock(*this);
4307 if (lock) {
4308 StreamString packet;
4309 packet.PutCString("qSymbol::");
4310 StringExtractorGDBRemote response;
4311 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
4313 if (response.IsOKResponse()) {
4314 if (symbol_response_provided || first_qsymbol_query) {
4316 }
4317
4318 // We are done serving symbols requests
4319 return;
4320 }
4321 first_qsymbol_query = false;
4322
4323 if (response.IsUnsupportedResponse()) {
4324 // qSymbol is not supported by the current GDB server we are
4325 // connected to
4326 m_supports_qSymbol = false;
4327 return;
4328 } else {
4329 llvm::StringRef response_str(response.GetStringRef());
4330 if (response_str.starts_with("qSymbol:")) {
4331 response.SetFilePos(strlen("qSymbol:"));
4332 std::string symbol_name;
4333 if (response.GetHexByteString(symbol_name)) {
4334 if (symbol_name.empty())
4335 return;
4336
4337 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
4340 ConstString(symbol_name), eSymbolTypeAny, sc_list);
4341 for (const SymbolContext &sc : sc_list) {
4342 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
4343 break;
4344 if (sc.symbol) {
4345 switch (sc.symbol->GetType()) {
4346 case eSymbolTypeInvalid:
4353 case eSymbolTypeBlock:
4354 case eSymbolTypeLocal:
4355 case eSymbolTypeParam:
4366 if (sc.module_sp->GetArchitecture()
4367 .GetTriple()
4368 .getObjectFormat() !=
4369 llvm::Triple::ObjectFormatType::MachO) {
4370 // GDB does return symbols even when they are of unknown
4371 // type, following this behavior on non Mach-O
4372 // architectures.
4373 symbol_load_addr =
4374 sc.symbol->GetLoadAddress(&process->GetTarget());
4375 if (symbol_load_addr == LLDB_INVALID_ADDRESS) {
4376 symbol_load_addr = sc.symbol->GetRawValue();
4377 }
4378 }
4379 break;
4380
4381 case eSymbolTypeCode:
4383 case eSymbolTypeData:
4384 case eSymbolTypeRuntime:
4390 symbol_load_addr =
4391 sc.symbol->GetLoadAddress(&process->GetTarget());
4392 break;
4393 }
4394 }
4395 }
4396 // This is the normal path where our symbol lookup was successful
4397 // and we want to send a packet with the new symbol value and see
4398 // if another lookup needs to be done.
4399
4400 // Change "packet" to contain the requested symbol value and name
4401 packet.Clear();
4402 packet.PutCString("qSymbol:");
4403 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
4404 packet.Printf("%" PRIx64, symbol_load_addr);
4405 symbol_response_provided = true;
4406 } else {
4407 symbol_response_provided = false;
4408 }
4409 packet.PutCString(":");
4410 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
4411 continue; // go back to the while loop and send "packet" and wait
4412 // for another response
4413 }
4414 }
4415 }
4416 }
4417 // If we make it here, the symbol request packet response wasn't valid or
4418 // our symbol lookup failed so we must abort
4419 return;
4420
4421 } else if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets)) {
4422 LLDB_LOGF(log,
4423 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4424 __FUNCTION__);
4425 }
4426 }
4427}
4428
4432 // Query the server for the array of supported asynchronous JSON packets.
4434
4435 Log *log = GetLog(GDBRLog::Process);
4436
4437 // Poll it now.
4438 StringExtractorGDBRemote response;
4439 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==
4444 !m_supported_async_json_packets_sp->GetAsArray()) {
4445 // We were returned something other than a JSON array. This is
4446 // invalid. Clear it out.
4447 LLDB_LOGF(log,
4448 "GDBRemoteCommunicationClient::%s(): "
4449 "QSupportedAsyncJSONPackets returned invalid "
4450 "result: %s",
4451 __FUNCTION__, response.GetStringRef().data());
4453 }
4454 } else {
4455 LLDB_LOGF(log,
4456 "GDBRemoteCommunicationClient::%s(): "
4457 "QSupportedAsyncJSONPackets unsupported",
4458 __FUNCTION__);
4459 }
4460
4462 StreamString stream;
4464 LLDB_LOGF(log,
4465 "GDBRemoteCommunicationClient::%s(): supported async "
4466 "JSON packets: %s",
4467 __FUNCTION__, stream.GetData());
4468 }
4469 }
4470
4472 ? m_supported_async_json_packets_sp->GetAsArray()
4473 : nullptr;
4474}
4475
4477 llvm::ArrayRef<int32_t> signals) {
4478 // Format packet:
4479 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
4480 auto range = llvm::make_range(signals.begin(), signals.end());
4481 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
4482
4483 StringExtractorGDBRemote response;
4484 auto send_status = SendPacketAndWaitForResponse(packet, response);
4485
4487 return Status::FromErrorString("Sending QPassSignals packet failed");
4488
4489 if (response.IsOKResponse()) {
4490 return Status();
4491 } else {
4493 "Unknown error happened during sending QPassSignals packet.");
4494 }
4495}
4496
4498 llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) {
4499 Status error;
4500
4501 if (type_name.empty()) {
4502 error = Status::FromErrorString("invalid type_name argument");
4503 return error;
4504 }
4505
4506 // Build command: Configure{type_name}: serialized config data.
4507 StreamGDBRemote stream;
4508 stream.PutCString("QConfigure");
4509 stream.PutCString(type_name);
4510 stream.PutChar(':');
4511 if (config_sp) {
4512 // Gather the plain-text version of the configuration data.
4513 StreamString unescaped_stream;
4514 config_sp->Dump(unescaped_stream);
4515 unescaped_stream.Flush();
4516
4517 // Add it to the stream in escaped fashion.
4518 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
4519 unescaped_stream.GetSize());
4520 }
4521 stream.Flush();
4522
4523 // Send the packet.
4524 StringExtractorGDBRemote response;
4525 auto result = SendPacketAndWaitForResponse(stream.GetString(), response);
4526 if (result == PacketResult::Success) {
4527 // We failed if the config result comes back other than OK.
4528 if (response.GetStringRef() == "OK") {
4529 // Okay!
4530 error.Clear();
4531 } else {
4533 "configuring StructuredData feature {0} failed with error {1}",
4534 type_name, response.GetStringRef());
4535 }
4536 } else {
4537 // Can we get more data here on the failure?
4539 "configuring StructuredData feature {0} failed when sending packet: "
4540 "PacketResult={1}",
4541 type_name, (int)result);
4542 }
4543 return error;
4544}
4545
4550
4555 return true;
4556
4557 // If the remote didn't indicate native-signal support explicitly,
4558 // check whether it is an old version of lldb-server.
4559 return GetThreadSuffixSupported();
4560}
4561
4563 StringExtractorGDBRemote response;
4564 GDBRemoteCommunication::ScopedTimeout timeout(*this, seconds(3));
4565
4566 // LLDB server typically sends no response for "k", so we shouldn't try
4567 // to sync on timeout.
4568 if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout(), false) !=
4570 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4571 "failed to send k packet");
4572
4573 char packet_cmd = response.GetChar(0);
4574 if (packet_cmd == 'W' || packet_cmd == 'X')
4575 return response.GetHexU8();
4576
4577 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4578 "unexpected response to k packet: %s",
4579 response.GetStringRef().str().c_str());
4580}
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:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
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:455
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:547
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition ArchSpec.cpp:952
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.
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:56
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
MemoryRegionInfo & SetMemoryTagged(LazyBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetName(const char *name)
MemoryRegionInfo & SetIsShadowStack(LazyBool val)
lldb::offset_t GetBlocksize() const
MemoryRegionInfo & SetIsStackMemory(LazyBool val)
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:58
bool ProcessIDIsValid() const
Definition ProcessInfo.h:70
void SetArg0(llvm::StringRef arg)
lldb::pid_t GetProcessID() const
Definition ProcessInfo.h:66
void SetProcessID(lldb::pid_t pid)
Definition ProcessInfo.h:68
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:41
llvm::StringRef GetName() const
uint32_t GetUserID() const
Definition ProcessInfo.h:48
uint32_t GetGroupID() const
Definition ProcessInfo.h:50
void SetUserID(uint32_t uid)
Definition ProcessInfo.h:56
bool GroupIDIsValid() const
Definition ProcessInfo.h:54
ArchSpec & GetArchitecture()
Definition ProcessInfo.h:60
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:369
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1270
An error handling class.
Definition Status.h:118
llvm::Error takeError()
Definition Status.h:170
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 PutAsJSON(const T &obj, bool hex_ascii)
Definition GDBRemote.h:50
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:1279
const ArchSpec & GetArchitecture() const
Definition Target.h:1321
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 SetSTDIOWindowSize(uint16_t cols, uint16_t rows)
Send the dimensions of the user's stdio terminal window to the server.
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)
std::optional< LLDBSettings > GetLLDBSettings()
Return LLDB-specific settings for this GDB-remote process.
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)
llvm::Expected< std::vector< AcceleratorActions > > GetAcceleratorInitializeActions()
Send the "jAcceleratorPluginInitialize" packet and return the actions requested by each accelerator p...
bool SetCurrentThread(uint64_t tid, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
int SendStdinNotification(const char *data, size_t data_len, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0))
Sends a GDB remote protocol 'I' packet that delivers stdin data to the remote process.
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)
std::vector< AddressSpaceInfo > GetAddressSpaces()
Empty if the server does not support "jAddressSpacesInfo".
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)
bool GetWasmInstanceSupported()
Whether the WebAssembly stub can be told which module instance to read from, which it advertises with...
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)
llvm::Expected< AcceleratorBreakpointHitResponse > AcceleratorBreakpointHit(const AcceleratorBreakpointHitArgs &args)
Send the "jAcceleratorPluginBreakpointHit" packet to notify the accelerator plugin that one of its re...
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:338
llvm::json::Value toJSON(const Diagnostics::Report &report)
Render a diagnostics report as JSON, for diagnostics dump's terminal output.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition Host.h:32
@ 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:84
ByteOrder
Byte ordering definitions.
uint64_t user_id_t
Definition lldb-types.h:83
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:85
Sent by the client when a plugin-requested breakpoint is hit.
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