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