Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
39642 views
//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "GDBRemoteCommunicationClient.h"910#include <cmath>11#include <sys/stat.h>1213#include <numeric>14#include <optional>15#include <sstream>1617#include "lldb/Core/ModuleSpec.h"18#include "lldb/Host/HostInfo.h"19#include "lldb/Host/SafeMachO.h"20#include "lldb/Host/XML.h"21#include "lldb/Symbol/Symbol.h"22#include "lldb/Target/MemoryRegionInfo.h"23#include "lldb/Target/Target.h"24#include "lldb/Target/UnixSignals.h"25#include "lldb/Utility/Args.h"26#include "lldb/Utility/DataBufferHeap.h"27#include "lldb/Utility/LLDBAssert.h"28#include "lldb/Utility/LLDBLog.h"29#include "lldb/Utility/Log.h"30#include "lldb/Utility/State.h"31#include "lldb/Utility/StreamString.h"3233#include "ProcessGDBRemote.h"34#include "ProcessGDBRemoteLog.h"35#include "lldb/Host/Config.h"36#include "lldb/Utility/StringExtractorGDBRemote.h"3738#include "llvm/ADT/STLExtras.h"39#include "llvm/ADT/StringSwitch.h"40#include "llvm/Support/JSON.h"4142#if defined(HAVE_LIBCOMPRESSION)43#include <compression.h>44#endif4546using namespace lldb;47using namespace lldb_private::process_gdb_remote;48using namespace lldb_private;49using namespace std::chrono;5051llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,52const QOffsets &offsets) {53return os << llvm::formatv(54"QOffsets({0}, [{1:@[x]}])", offsets.segments,55llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));56}5758// GDBRemoteCommunicationClient constructor59GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()60: GDBRemoteClientBase("gdb-remote.client"),6162m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),63m_supports_qUserName(true), m_supports_qGroupName(true),64m_supports_qThreadStopInfo(true), m_supports_z0(true),65m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),66m_supports_z4(true), m_supports_QEnvironment(true),67m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),68m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),69m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),70m_supports_vFileSize(true), m_supports_vFileMode(true),71m_supports_vFileExists(true), m_supports_vRun(true),7273m_host_arch(), m_host_distribution_id(), m_process_arch(), m_os_build(),74m_os_kernel(), m_hostname(), m_gdb_server_name(),75m_default_packet_timeout(0), m_qSupported_response(),76m_supported_async_json_packets_sp(), m_qXfer_memory_map() {}7778// Destructor79GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {80if (IsConnected())81Disconnect();82}8384bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {85ResetDiscoverableSettings(false);8687// Start the read thread after we send the handshake ack since if we fail to88// send the handshake ack, there is no reason to continue...89std::chrono::steady_clock::time_point start_of_handshake =90std::chrono::steady_clock::now();91if (SendAck()) {92// The return value from QueryNoAckModeSupported() is true if the packet93// was sent and _any_ response (including UNIMPLEMENTED) was received), or94// false if no response was received. This quickly tells us if we have a95// live connection to a remote GDB server...96if (QueryNoAckModeSupported()) {97return true;98} else {99std::chrono::steady_clock::time_point end_of_handshake =100std::chrono::steady_clock::now();101auto handshake_timeout =102std::chrono::duration<double>(end_of_handshake - start_of_handshake)103.count();104if (error_ptr) {105if (!IsConnected())106error_ptr->SetErrorString("Connection shut down by remote side "107"while waiting for reply to initial "108"handshake packet");109else110error_ptr->SetErrorStringWithFormat(111"failed to get reply to handshake packet within timeout of "112"%.1f seconds",113handshake_timeout);114}115}116} else {117if (error_ptr)118error_ptr->SetErrorString("failed to send the handshake ack");119}120return false;121}122123bool GDBRemoteCommunicationClient::GetEchoSupported() {124if (m_supports_qEcho == eLazyBoolCalculate) {125GetRemoteQSupported();126}127return m_supports_qEcho == eLazyBoolYes;128}129130bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {131if (m_supports_QPassSignals == eLazyBoolCalculate) {132GetRemoteQSupported();133}134return m_supports_QPassSignals == eLazyBoolYes;135}136137bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {138if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {139GetRemoteQSupported();140}141return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;142}143144bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {145if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {146GetRemoteQSupported();147}148return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;149}150151bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {152if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {153GetRemoteQSupported();154}155return m_supports_qXfer_libraries_read == eLazyBoolYes;156}157158bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {159if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {160GetRemoteQSupported();161}162return m_supports_qXfer_auxv_read == eLazyBoolYes;163}164165bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {166if (m_supports_qXfer_features_read == eLazyBoolCalculate) {167GetRemoteQSupported();168}169return m_supports_qXfer_features_read == eLazyBoolYes;170}171172bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {173if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {174GetRemoteQSupported();175}176return m_supports_qXfer_memory_map_read == eLazyBoolYes;177}178179bool GDBRemoteCommunicationClient::GetQXferSigInfoReadSupported() {180if (m_supports_qXfer_siginfo_read == eLazyBoolCalculate) {181GetRemoteQSupported();182}183return m_supports_qXfer_siginfo_read == eLazyBoolYes;184}185186bool GDBRemoteCommunicationClient::GetMultiprocessSupported() {187if (m_supports_memory_tagging == eLazyBoolCalculate)188GetRemoteQSupported();189return m_supports_multiprocess == eLazyBoolYes;190}191192uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {193if (m_max_packet_size == 0) {194GetRemoteQSupported();195}196return m_max_packet_size;197}198199bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {200if (m_supports_not_sending_acks == eLazyBoolCalculate) {201m_send_acks = true;202m_supports_not_sending_acks = eLazyBoolNo;203204// This is the first real packet that we'll send in a debug session and it205// may take a little longer than normal to receive a reply. Wait at least206// 6 seconds for a reply to this packet.207208ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));209210StringExtractorGDBRemote response;211if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==212PacketResult::Success) {213if (response.IsOKResponse()) {214m_send_acks = false;215m_supports_not_sending_acks = eLazyBoolYes;216}217return true;218}219}220return false;221}222223void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {224if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {225m_supports_threads_in_stop_reply = eLazyBoolNo;226227StringExtractorGDBRemote response;228if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) ==229PacketResult::Success) {230if (response.IsOKResponse())231m_supports_threads_in_stop_reply = eLazyBoolYes;232}233}234}235236bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {237if (m_attach_or_wait_reply == eLazyBoolCalculate) {238m_attach_or_wait_reply = eLazyBoolNo;239240StringExtractorGDBRemote response;241if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) ==242PacketResult::Success) {243if (response.IsOKResponse())244m_attach_or_wait_reply = eLazyBoolYes;245}246}247return m_attach_or_wait_reply == eLazyBoolYes;248}249250bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {251if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {252m_prepare_for_reg_writing_reply = eLazyBoolNo;253254StringExtractorGDBRemote response;255if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) ==256PacketResult::Success) {257if (response.IsOKResponse())258m_prepare_for_reg_writing_reply = eLazyBoolYes;259}260}261return m_prepare_for_reg_writing_reply == eLazyBoolYes;262}263264void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {265if (!did_exec) {266// Hard reset everything, this is when we first connect to a GDB server267m_supports_not_sending_acks = eLazyBoolCalculate;268m_supports_thread_suffix = eLazyBoolCalculate;269m_supports_threads_in_stop_reply = eLazyBoolCalculate;270m_supports_vCont_c = eLazyBoolCalculate;271m_supports_vCont_C = eLazyBoolCalculate;272m_supports_vCont_s = eLazyBoolCalculate;273m_supports_vCont_S = eLazyBoolCalculate;274m_supports_p = eLazyBoolCalculate;275m_supports_x = eLazyBoolCalculate;276m_supports_QSaveRegisterState = eLazyBoolCalculate;277m_qHostInfo_is_valid = eLazyBoolCalculate;278m_curr_pid_is_valid = eLazyBoolCalculate;279m_qGDBServerVersion_is_valid = eLazyBoolCalculate;280m_supports_alloc_dealloc_memory = eLazyBoolCalculate;281m_supports_memory_region_info = eLazyBoolCalculate;282m_prepare_for_reg_writing_reply = eLazyBoolCalculate;283m_attach_or_wait_reply = eLazyBoolCalculate;284m_avoid_g_packets = eLazyBoolCalculate;285m_supports_multiprocess = eLazyBoolCalculate;286m_supports_qSaveCore = eLazyBoolCalculate;287m_supports_qXfer_auxv_read = eLazyBoolCalculate;288m_supports_qXfer_libraries_read = eLazyBoolCalculate;289m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;290m_supports_qXfer_features_read = eLazyBoolCalculate;291m_supports_qXfer_memory_map_read = eLazyBoolCalculate;292m_supports_qXfer_siginfo_read = eLazyBoolCalculate;293m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;294m_uses_native_signals = eLazyBoolCalculate;295m_supports_qProcessInfoPID = true;296m_supports_qfProcessInfo = true;297m_supports_qUserName = true;298m_supports_qGroupName = true;299m_supports_qThreadStopInfo = true;300m_supports_z0 = true;301m_supports_z1 = true;302m_supports_z2 = true;303m_supports_z3 = true;304m_supports_z4 = true;305m_supports_QEnvironment = true;306m_supports_QEnvironmentHexEncoded = true;307m_supports_qSymbol = true;308m_qSymbol_requests_done = false;309m_supports_qModuleInfo = true;310m_host_arch.Clear();311m_host_distribution_id.clear();312m_os_version = llvm::VersionTuple();313m_os_build.clear();314m_os_kernel.clear();315m_hostname.clear();316m_gdb_server_name.clear();317m_gdb_server_version = UINT32_MAX;318m_default_packet_timeout = seconds(0);319m_target_vm_page_size = 0;320m_max_packet_size = 0;321m_qSupported_response.clear();322m_supported_async_json_packets_is_valid = false;323m_supported_async_json_packets_sp.reset();324m_supports_jModulesInfo = true;325}326327// These flags should be reset when we first connect to a GDB server and when328// our inferior process execs329m_qProcessInfo_is_valid = eLazyBoolCalculate;330m_process_arch.Clear();331}332333void GDBRemoteCommunicationClient::GetRemoteQSupported() {334// Clear out any capabilities we expect to see in the qSupported response335m_supports_qXfer_auxv_read = eLazyBoolNo;336m_supports_qXfer_libraries_read = eLazyBoolNo;337m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;338m_supports_augmented_libraries_svr4_read = eLazyBoolNo;339m_supports_qXfer_features_read = eLazyBoolNo;340m_supports_qXfer_memory_map_read = eLazyBoolNo;341m_supports_qXfer_siginfo_read = eLazyBoolNo;342m_supports_multiprocess = eLazyBoolNo;343m_supports_qEcho = eLazyBoolNo;344m_supports_QPassSignals = eLazyBoolNo;345m_supports_memory_tagging = eLazyBoolNo;346m_supports_qSaveCore = eLazyBoolNo;347m_uses_native_signals = eLazyBoolNo;348349m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if350// not, we assume no limit351352// build the qSupported packet353std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",354"multiprocess+", "fork-events+",355"vfork-events+"};356StreamString packet;357packet.PutCString("qSupported");358for (uint32_t i = 0; i < features.size(); ++i) {359packet.PutCString(i == 0 ? ":" : ";");360packet.PutCString(features[i]);361}362363StringExtractorGDBRemote response;364if (SendPacketAndWaitForResponse(packet.GetString(), response) ==365PacketResult::Success) {366// Hang on to the qSupported packet, so that platforms can do custom367// configuration of the transport before attaching/launching the process.368m_qSupported_response = response.GetStringRef().str();369370for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) {371if (x == "qXfer:auxv:read+")372m_supports_qXfer_auxv_read = eLazyBoolYes;373else if (x == "qXfer:libraries-svr4:read+")374m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;375else if (x == "augmented-libraries-svr4-read") {376m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied377m_supports_augmented_libraries_svr4_read = eLazyBoolYes;378} else if (x == "qXfer:libraries:read+")379m_supports_qXfer_libraries_read = eLazyBoolYes;380else if (x == "qXfer:features:read+")381m_supports_qXfer_features_read = eLazyBoolYes;382else if (x == "qXfer:memory-map:read+")383m_supports_qXfer_memory_map_read = eLazyBoolYes;384else if (x == "qXfer:siginfo:read+")385m_supports_qXfer_siginfo_read = eLazyBoolYes;386else if (x == "qEcho")387m_supports_qEcho = eLazyBoolYes;388else if (x == "QPassSignals+")389m_supports_QPassSignals = eLazyBoolYes;390else if (x == "multiprocess+")391m_supports_multiprocess = eLazyBoolYes;392else if (x == "memory-tagging+")393m_supports_memory_tagging = eLazyBoolYes;394else if (x == "qSaveCore+")395m_supports_qSaveCore = eLazyBoolYes;396else if (x == "native-signals+")397m_uses_native_signals = eLazyBoolYes;398// Look for a list of compressions in the features list e.g.399// qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-400// deflate,lzma401else if (x.consume_front("SupportedCompressions=")) {402llvm::SmallVector<llvm::StringRef, 4> compressions;403x.split(compressions, ',');404if (!compressions.empty())405MaybeEnableCompression(compressions);406} else if (x.consume_front("SupportedWatchpointTypes=")) {407llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;408x.split(watchpoint_types, ',');409m_watchpoint_types = eWatchpointHardwareFeatureUnknown;410for (auto wp_type : watchpoint_types) {411if (wp_type == "x86_64")412m_watchpoint_types |= eWatchpointHardwareX86;413if (wp_type == "aarch64-mask")414m_watchpoint_types |= eWatchpointHardwareArmMASK;415if (wp_type == "aarch64-bas")416m_watchpoint_types |= eWatchpointHardwareArmBAS;417}418} else if (x.consume_front("PacketSize=")) {419StringExtractorGDBRemote packet_response(x);420m_max_packet_size =421packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);422if (m_max_packet_size == 0) {423m_max_packet_size = UINT64_MAX; // Must have been a garbled response424Log *log(GetLog(GDBRLog::Process));425LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");426}427}428}429}430}431432bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {433if (m_supports_thread_suffix == eLazyBoolCalculate) {434StringExtractorGDBRemote response;435m_supports_thread_suffix = eLazyBoolNo;436if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) ==437PacketResult::Success) {438if (response.IsOKResponse())439m_supports_thread_suffix = eLazyBoolYes;440}441}442return m_supports_thread_suffix;443}444bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {445if (m_supports_vCont_c == eLazyBoolCalculate) {446StringExtractorGDBRemote response;447m_supports_vCont_any = eLazyBoolNo;448m_supports_vCont_all = eLazyBoolNo;449m_supports_vCont_c = eLazyBoolNo;450m_supports_vCont_C = eLazyBoolNo;451m_supports_vCont_s = eLazyBoolNo;452m_supports_vCont_S = eLazyBoolNo;453if (SendPacketAndWaitForResponse("vCont?", response) ==454PacketResult::Success) {455const char *response_cstr = response.GetStringRef().data();456if (::strstr(response_cstr, ";c"))457m_supports_vCont_c = eLazyBoolYes;458459if (::strstr(response_cstr, ";C"))460m_supports_vCont_C = eLazyBoolYes;461462if (::strstr(response_cstr, ";s"))463m_supports_vCont_s = eLazyBoolYes;464465if (::strstr(response_cstr, ";S"))466m_supports_vCont_S = eLazyBoolYes;467468if (m_supports_vCont_c == eLazyBoolYes &&469m_supports_vCont_C == eLazyBoolYes &&470m_supports_vCont_s == eLazyBoolYes &&471m_supports_vCont_S == eLazyBoolYes) {472m_supports_vCont_all = eLazyBoolYes;473}474475if (m_supports_vCont_c == eLazyBoolYes ||476m_supports_vCont_C == eLazyBoolYes ||477m_supports_vCont_s == eLazyBoolYes ||478m_supports_vCont_S == eLazyBoolYes) {479m_supports_vCont_any = eLazyBoolYes;480}481}482}483484switch (flavor) {485case 'a':486return m_supports_vCont_any;487case 'A':488return m_supports_vCont_all;489case 'c':490return m_supports_vCont_c;491case 'C':492return m_supports_vCont_C;493case 's':494return m_supports_vCont_s;495case 'S':496return m_supports_vCont_S;497default:498break;499}500return false;501}502503GDBRemoteCommunication::PacketResult504GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(505lldb::tid_t tid, StreamString &&payload,506StringExtractorGDBRemote &response) {507Lock lock(*this);508if (!lock) {509if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets))510LLDB_LOGF(log,511"GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "512"for %s packet.",513__FUNCTION__, payload.GetData());514return PacketResult::ErrorNoSequenceLock;515}516517if (GetThreadSuffixSupported())518payload.Printf(";thread:%4.4" PRIx64 ";", tid);519else {520if (!SetCurrentThread(tid))521return PacketResult::ErrorSendFailed;522}523524return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);525}526527// Check if the target supports 'p' packet. It sends out a 'p' packet and528// checks the response. A normal packet will tell us that support is available.529//530// Takes a valid thread ID because p needs to apply to a thread.531bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {532if (m_supports_p == eLazyBoolCalculate)533m_supports_p = GetThreadPacketSupported(tid, "p0");534return m_supports_p;535}536537LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(538lldb::tid_t tid, llvm::StringRef packetStr) {539StreamString payload;540payload.PutCString(packetStr);541StringExtractorGDBRemote response;542if (SendThreadSpecificPacketAndWaitForResponse(543tid, std::move(payload), response) == PacketResult::Success &&544response.IsNormalResponse()) {545return eLazyBoolYes;546}547return eLazyBoolNo;548}549550bool GDBRemoteCommunicationClient::GetSaveCoreSupported() const {551return m_supports_qSaveCore == eLazyBoolYes;552}553554StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {555// Get information on all threads at one using the "jThreadsInfo" packet556StructuredData::ObjectSP object_sp;557558if (m_supports_jThreadsInfo) {559StringExtractorGDBRemote response;560response.SetResponseValidatorToJSON();561if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==562PacketResult::Success) {563if (response.IsUnsupportedResponse()) {564m_supports_jThreadsInfo = false;565} else if (!response.Empty()) {566object_sp = StructuredData::ParseJSON(response.GetStringRef());567}568}569}570return object_sp;571}572573bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {574if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {575StringExtractorGDBRemote response;576m_supports_jThreadExtendedInfo = eLazyBoolNo;577if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) ==578PacketResult::Success) {579if (response.IsOKResponse()) {580m_supports_jThreadExtendedInfo = eLazyBoolYes;581}582}583}584return m_supports_jThreadExtendedInfo;585}586587void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {588if (m_supports_error_string_reply == eLazyBoolCalculate) {589StringExtractorGDBRemote response;590// We try to enable error strings in remote packets but if we fail, we just591// work in the older way.592m_supports_error_string_reply = eLazyBoolNo;593if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==594PacketResult::Success) {595if (response.IsOKResponse()) {596m_supports_error_string_reply = eLazyBoolYes;597}598}599}600}601602bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {603if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {604StringExtractorGDBRemote response;605m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;606if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",607response) == PacketResult::Success) {608if (response.IsOKResponse()) {609m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;610}611}612}613return m_supports_jLoadedDynamicLibrariesInfos;614}615616bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {617if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {618StringExtractorGDBRemote response;619m_supports_jGetSharedCacheInfo = eLazyBoolNo;620if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) ==621PacketResult::Success) {622if (response.IsOKResponse()) {623m_supports_jGetSharedCacheInfo = eLazyBoolYes;624}625}626}627return m_supports_jGetSharedCacheInfo;628}629630bool GDBRemoteCommunicationClient::GetDynamicLoaderProcessStateSupported() {631if (m_supports_jGetDyldProcessState == eLazyBoolCalculate) {632StringExtractorGDBRemote response;633m_supports_jGetDyldProcessState = eLazyBoolNo;634if (SendPacketAndWaitForResponse("jGetDyldProcessState", response) ==635PacketResult::Success) {636if (!response.IsUnsupportedResponse())637m_supports_jGetDyldProcessState = eLazyBoolYes;638}639}640return m_supports_jGetDyldProcessState;641}642643bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {644if (m_supports_memory_tagging == eLazyBoolCalculate) {645GetRemoteQSupported();646}647return m_supports_memory_tagging == eLazyBoolYes;648}649650DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,651size_t len,652int32_t type) {653StreamString packet;654packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);655StringExtractorGDBRemote response;656657Log *log = GetLog(GDBRLog::Memory);658659if (SendPacketAndWaitForResponse(packet.GetString(), response) !=660PacketResult::Success ||661!response.IsNormalResponse()) {662LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",663__FUNCTION__);664return nullptr;665}666667// We are expecting668// m<hex encoded bytes>669670if (response.GetChar() != 'm') {671LLDB_LOGF(log,672"GDBRemoteCommunicationClient::%s: qMemTags response did not "673"begin with \"m\"",674__FUNCTION__);675return nullptr;676}677678size_t expected_bytes = response.GetBytesLeft() / 2;679WritableDataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));680size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());681// Check both because in some situations chars are consumed even682// if the decoding fails.683if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {684LLDB_LOGF(685log,686"GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",687__FUNCTION__);688return nullptr;689}690691return buffer_sp;692}693694Status GDBRemoteCommunicationClient::WriteMemoryTags(695lldb::addr_t addr, size_t len, int32_t type,696const std::vector<uint8_t> &tags) {697// Format QMemTags:address,length:type:tags698StreamString packet;699packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);700packet.PutBytesAsRawHex8(tags.data(), tags.size());701702Status status;703StringExtractorGDBRemote response;704if (SendPacketAndWaitForResponse(packet.GetString(), response) !=705PacketResult::Success ||706!response.IsOKResponse()) {707status.SetErrorString("QMemTags packet failed");708}709return status;710}711712bool GDBRemoteCommunicationClient::GetxPacketSupported() {713if (m_supports_x == eLazyBoolCalculate) {714StringExtractorGDBRemote response;715m_supports_x = eLazyBoolNo;716char packet[256];717snprintf(packet, sizeof(packet), "x0,0");718if (SendPacketAndWaitForResponse(packet, response) ==719PacketResult::Success) {720if (response.IsOKResponse())721m_supports_x = eLazyBoolYes;722}723}724return m_supports_x;725}726727lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {728if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)729return m_curr_pid;730731// First try to retrieve the pid via the qProcessInfo request.732GetCurrentProcessInfo(allow_lazy);733if (m_curr_pid_is_valid == eLazyBoolYes) {734// We really got it.735return m_curr_pid;736} else {737// If we don't get a response for qProcessInfo, check if $qC gives us a738// result. $qC only returns a real process id on older debugserver and739// lldb-platform stubs. The gdb remote protocol documents $qC as returning740// the thread id, which newer debugserver and lldb-gdbserver stubs return741// correctly.742StringExtractorGDBRemote response;743if (SendPacketAndWaitForResponse("qC", response) == PacketResult::Success) {744if (response.GetChar() == 'Q') {745if (response.GetChar() == 'C') {746m_curr_pid_run = m_curr_pid =747response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);748if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {749m_curr_pid_is_valid = eLazyBoolYes;750return m_curr_pid;751}752}753}754}755756// If we don't get a response for $qC, check if $qfThreadID gives us a757// result.758if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {759bool sequence_mutex_unavailable;760auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);761if (!ids.empty() && !sequence_mutex_unavailable) {762// If server returned an explicit PID, use that.763m_curr_pid_run = m_curr_pid = ids.front().first;764// Otherwise, use the TID of the first thread (Linux hack).765if (m_curr_pid == LLDB_INVALID_PROCESS_ID)766m_curr_pid_run = m_curr_pid = ids.front().second;767m_curr_pid_is_valid = eLazyBoolYes;768return m_curr_pid;769}770}771}772773return LLDB_INVALID_PROCESS_ID;774}775776llvm::Error GDBRemoteCommunicationClient::LaunchProcess(const Args &args) {777if (!args.GetArgumentAtIndex(0))778return llvm::createStringError(llvm::inconvertibleErrorCode(),779"Nothing to launch");780// try vRun first781if (m_supports_vRun) {782StreamString packet;783packet.PutCString("vRun");784for (const Args::ArgEntry &arg : args) {785packet.PutChar(';');786packet.PutStringAsRawHex8(arg.ref());787}788789StringExtractorGDBRemote response;790if (SendPacketAndWaitForResponse(packet.GetString(), response) !=791PacketResult::Success)792return llvm::createStringError(llvm::inconvertibleErrorCode(),793"Sending vRun packet failed");794795if (response.IsErrorResponse())796return response.GetStatus().ToError();797798// vRun replies with a stop reason packet799// FIXME: right now we just discard the packet and LLDB queries800// for stop reason again801if (!response.IsUnsupportedResponse())802return llvm::Error::success();803804m_supports_vRun = false;805}806807// fallback to A808StreamString packet;809packet.PutChar('A');810llvm::ListSeparator LS(",");811for (const auto &arg : llvm::enumerate(args)) {812packet << LS;813packet.Format("{0},{1},", arg.value().ref().size() * 2, arg.index());814packet.PutStringAsRawHex8(arg.value().ref());815}816817StringExtractorGDBRemote response;818if (SendPacketAndWaitForResponse(packet.GetString(), response) !=819PacketResult::Success) {820return llvm::createStringError(llvm::inconvertibleErrorCode(),821"Sending A packet failed");822}823if (!response.IsOKResponse())824return response.GetStatus().ToError();825826if (SendPacketAndWaitForResponse("qLaunchSuccess", response) !=827PacketResult::Success) {828return llvm::createStringError(llvm::inconvertibleErrorCode(),829"Sending qLaunchSuccess packet failed");830}831if (response.IsOKResponse())832return llvm::Error::success();833if (response.GetChar() == 'E') {834return llvm::createStringError(llvm::inconvertibleErrorCode(),835response.GetStringRef().substr(1));836}837return llvm::createStringError(llvm::inconvertibleErrorCode(),838"unknown error occurred launching process");839}840841int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {842llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;843for (const auto &kv : env)844vec.emplace_back(kv.first(), kv.second);845llvm::sort(vec, llvm::less_first());846for (const auto &[k, v] : vec) {847int r = SendEnvironmentPacket((k + "=" + v).str().c_str());848if (r != 0)849return r;850}851return 0;852}853854int GDBRemoteCommunicationClient::SendEnvironmentPacket(855char const *name_equal_value) {856if (name_equal_value && name_equal_value[0]) {857bool send_hex_encoding = false;858for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;859++p) {860if (llvm::isPrint(*p)) {861switch (*p) {862case '$':863case '#':864case '*':865case '}':866send_hex_encoding = true;867break;868default:869break;870}871} else {872// We have non printable characters, lets hex encode this...873send_hex_encoding = true;874}875}876877StringExtractorGDBRemote response;878// Prefer sending unencoded, if possible and the server supports it.879if (!send_hex_encoding && m_supports_QEnvironment) {880StreamString packet;881packet.Printf("QEnvironment:%s", name_equal_value);882if (SendPacketAndWaitForResponse(packet.GetString(), response) !=883PacketResult::Success)884return -1;885886if (response.IsOKResponse())887return 0;888if (response.IsUnsupportedResponse())889m_supports_QEnvironment = false;890else {891uint8_t error = response.GetError();892if (error)893return error;894return -1;895}896}897898if (m_supports_QEnvironmentHexEncoded) {899StreamString packet;900packet.PutCString("QEnvironmentHexEncoded:");901packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));902if (SendPacketAndWaitForResponse(packet.GetString(), response) !=903PacketResult::Success)904return -1;905906if (response.IsOKResponse())907return 0;908if (response.IsUnsupportedResponse())909m_supports_QEnvironmentHexEncoded = false;910else {911uint8_t error = response.GetError();912if (error)913return error;914return -1;915}916}917}918return -1;919}920921int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {922if (arch && arch[0]) {923StreamString packet;924packet.Printf("QLaunchArch:%s", arch);925StringExtractorGDBRemote response;926if (SendPacketAndWaitForResponse(packet.GetString(), response) ==927PacketResult::Success) {928if (response.IsOKResponse())929return 0;930uint8_t error = response.GetError();931if (error)932return error;933}934}935return -1;936}937938int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(939char const *data, bool *was_supported) {940if (data && *data != '\0') {941StreamString packet;942packet.Printf("QSetProcessEvent:%s", data);943StringExtractorGDBRemote response;944if (SendPacketAndWaitForResponse(packet.GetString(), response) ==945PacketResult::Success) {946if (response.IsOKResponse()) {947if (was_supported)948*was_supported = true;949return 0;950} else if (response.IsUnsupportedResponse()) {951if (was_supported)952*was_supported = false;953return -1;954} else {955uint8_t error = response.GetError();956if (was_supported)957*was_supported = true;958if (error)959return error;960}961}962}963return -1;964}965966llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {967GetHostInfo();968return m_os_version;969}970971llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {972GetHostInfo();973return m_maccatalyst_version;974}975976std::optional<std::string> GDBRemoteCommunicationClient::GetOSBuildString() {977if (GetHostInfo()) {978if (!m_os_build.empty())979return m_os_build;980}981return std::nullopt;982}983984std::optional<std::string>985GDBRemoteCommunicationClient::GetOSKernelDescription() {986if (GetHostInfo()) {987if (!m_os_kernel.empty())988return m_os_kernel;989}990return std::nullopt;991}992993bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {994if (GetHostInfo()) {995if (!m_hostname.empty()) {996s = m_hostname;997return true;998}999}1000s.clear();1001return false;1002}10031004ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {1005if (GetHostInfo())1006return m_host_arch;1007return ArchSpec();1008}10091010const lldb_private::ArchSpec &1011GDBRemoteCommunicationClient::GetProcessArchitecture() {1012if (m_qProcessInfo_is_valid == eLazyBoolCalculate)1013GetCurrentProcessInfo();1014return m_process_arch;1015}10161017bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(1018UUID &uuid, addr_t &value, bool &value_is_offset) {1019if (m_qProcessInfo_is_valid == eLazyBoolCalculate)1020GetCurrentProcessInfo();10211022// Return true if we have a UUID or an address/offset of the1023// main standalone / firmware binary being used.1024if (!m_process_standalone_uuid.IsValid() &&1025m_process_standalone_value == LLDB_INVALID_ADDRESS)1026return false;10271028uuid = m_process_standalone_uuid;1029value = m_process_standalone_value;1030value_is_offset = m_process_standalone_value_is_offset;1031return true;1032}10331034std::vector<addr_t>1035GDBRemoteCommunicationClient::GetProcessStandaloneBinaries() {1036if (m_qProcessInfo_is_valid == eLazyBoolCalculate)1037GetCurrentProcessInfo();1038return m_binary_addresses;1039}10401041bool GDBRemoteCommunicationClient::GetGDBServerVersion() {1042if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {1043m_gdb_server_name.clear();1044m_gdb_server_version = 0;1045m_qGDBServerVersion_is_valid = eLazyBoolNo;10461047StringExtractorGDBRemote response;1048if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==1049PacketResult::Success) {1050if (response.IsNormalResponse()) {1051llvm::StringRef name, value;1052bool success = false;1053while (response.GetNameColonValue(name, value)) {1054if (name == "name") {1055success = true;1056m_gdb_server_name = std::string(value);1057} else if (name == "version") {1058llvm::StringRef major, minor;1059std::tie(major, minor) = value.split('.');1060if (!major.getAsInteger(0, m_gdb_server_version))1061success = true;1062}1063}1064if (success)1065m_qGDBServerVersion_is_valid = eLazyBoolYes;1066}1067}1068}1069return m_qGDBServerVersion_is_valid == eLazyBoolYes;1070}10711072void GDBRemoteCommunicationClient::MaybeEnableCompression(1073llvm::ArrayRef<llvm::StringRef> supported_compressions) {1074CompressionType avail_type = CompressionType::None;1075llvm::StringRef avail_name;10761077#if defined(HAVE_LIBCOMPRESSION)1078if (avail_type == CompressionType::None) {1079for (auto compression : supported_compressions) {1080if (compression == "lzfse") {1081avail_type = CompressionType::LZFSE;1082avail_name = compression;1083break;1084}1085}1086}1087#endif10881089#if defined(HAVE_LIBCOMPRESSION)1090if (avail_type == CompressionType::None) {1091for (auto compression : supported_compressions) {1092if (compression == "zlib-deflate") {1093avail_type = CompressionType::ZlibDeflate;1094avail_name = compression;1095break;1096}1097}1098}1099#endif11001101#if LLVM_ENABLE_ZLIB1102if (avail_type == CompressionType::None) {1103for (auto compression : supported_compressions) {1104if (compression == "zlib-deflate") {1105avail_type = CompressionType::ZlibDeflate;1106avail_name = compression;1107break;1108}1109}1110}1111#endif11121113#if defined(HAVE_LIBCOMPRESSION)1114if (avail_type == CompressionType::None) {1115for (auto compression : supported_compressions) {1116if (compression == "lz4") {1117avail_type = CompressionType::LZ4;1118avail_name = compression;1119break;1120}1121}1122}1123#endif11241125#if defined(HAVE_LIBCOMPRESSION)1126if (avail_type == CompressionType::None) {1127for (auto compression : supported_compressions) {1128if (compression == "lzma") {1129avail_type = CompressionType::LZMA;1130avail_name = compression;1131break;1132}1133}1134}1135#endif11361137if (avail_type != CompressionType::None) {1138StringExtractorGDBRemote response;1139std::string packet = "QEnableCompression:type:" + avail_name.str() + ";";1140if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)1141return;11421143if (response.IsOKResponse()) {1144m_compression_type = avail_type;1145}1146}1147}11481149const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {1150if (GetGDBServerVersion()) {1151if (!m_gdb_server_name.empty())1152return m_gdb_server_name.c_str();1153}1154return nullptr;1155}11561157uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {1158if (GetGDBServerVersion())1159return m_gdb_server_version;1160return 0;1161}11621163bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {1164StringExtractorGDBRemote response;1165if (SendPacketAndWaitForResponse("qC", response) != PacketResult::Success)1166return false;11671168if (!response.IsNormalResponse())1169return false;11701171if (response.GetChar() == 'Q' && response.GetChar() == 'C') {1172auto pid_tid = response.GetPidTid(0);1173if (!pid_tid)1174return false;11751176lldb::pid_t pid = pid_tid->first;1177// invalid1178if (pid == StringExtractorGDBRemote::AllProcesses)1179return false;11801181// if we get pid as well, update m_curr_pid1182if (pid != 0) {1183m_curr_pid_run = m_curr_pid = pid;1184m_curr_pid_is_valid = eLazyBoolYes;1185}1186tid = pid_tid->second;1187}11881189return true;1190}11911192static void ParseOSType(llvm::StringRef value, std::string &os_name,1193std::string &environment) {1194if (value == "iossimulator" || value == "tvossimulator" ||1195value == "watchossimulator" || value == "xrossimulator" ||1196value == "visionossimulator") {1197environment = "simulator";1198os_name = value.drop_back(environment.size()).str();1199} else if (value == "maccatalyst") {1200os_name = "ios";1201environment = "macabi";1202} else {1203os_name = value.str();1204}1205}12061207bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {1208Log *log = GetLog(GDBRLog::Process);12091210if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {1211// host info computation can require DNS traffic and shelling out to external processes.1212// Increase the timeout to account for that.1213ScopedTimeout timeout(*this, seconds(10));1214m_qHostInfo_is_valid = eLazyBoolNo;1215StringExtractorGDBRemote response;1216if (SendPacketAndWaitForResponse("qHostInfo", response) ==1217PacketResult::Success) {1218if (response.IsNormalResponse()) {1219llvm::StringRef name;1220llvm::StringRef value;1221uint32_t cpu = LLDB_INVALID_CPUTYPE;1222uint32_t sub = 0;1223std::string arch_name;1224std::string os_name;1225std::string environment;1226std::string vendor_name;1227std::string triple;1228uint32_t pointer_byte_size = 0;1229ByteOrder byte_order = eByteOrderInvalid;1230uint32_t num_keys_decoded = 0;1231while (response.GetNameColonValue(name, value)) {1232if (name == "cputype") {1233// exception type in big endian hex1234if (!value.getAsInteger(0, cpu))1235++num_keys_decoded;1236} else if (name == "cpusubtype") {1237// exception count in big endian hex1238if (!value.getAsInteger(0, sub))1239++num_keys_decoded;1240} else if (name == "arch") {1241arch_name = std::string(value);1242++num_keys_decoded;1243} else if (name == "triple") {1244StringExtractor extractor(value);1245extractor.GetHexByteString(triple);1246++num_keys_decoded;1247} else if (name == "distribution_id") {1248StringExtractor extractor(value);1249extractor.GetHexByteString(m_host_distribution_id);1250++num_keys_decoded;1251} else if (name == "os_build") {1252StringExtractor extractor(value);1253extractor.GetHexByteString(m_os_build);1254++num_keys_decoded;1255} else if (name == "hostname") {1256StringExtractor extractor(value);1257extractor.GetHexByteString(m_hostname);1258++num_keys_decoded;1259} else if (name == "os_kernel") {1260StringExtractor extractor(value);1261extractor.GetHexByteString(m_os_kernel);1262++num_keys_decoded;1263} else if (name == "ostype") {1264ParseOSType(value, os_name, environment);1265++num_keys_decoded;1266} else if (name == "vendor") {1267vendor_name = std::string(value);1268++num_keys_decoded;1269} else if (name == "endian") {1270byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)1271.Case("little", eByteOrderLittle)1272.Case("big", eByteOrderBig)1273.Case("pdp", eByteOrderPDP)1274.Default(eByteOrderInvalid);1275if (byte_order != eByteOrderInvalid)1276++num_keys_decoded;1277} else if (name == "ptrsize") {1278if (!value.getAsInteger(0, pointer_byte_size))1279++num_keys_decoded;1280} else if (name == "addressing_bits") {1281if (!value.getAsInteger(0, m_low_mem_addressing_bits)) {1282++num_keys_decoded;1283}1284} else if (name == "high_mem_addressing_bits") {1285if (!value.getAsInteger(0, m_high_mem_addressing_bits))1286++num_keys_decoded;1287} else if (name == "low_mem_addressing_bits") {1288if (!value.getAsInteger(0, m_low_mem_addressing_bits))1289++num_keys_decoded;1290} else if (name == "os_version" ||1291name == "version") // Older debugserver binaries used1292// the "version" key instead of1293// "os_version"...1294{1295if (!m_os_version.tryParse(value))1296++num_keys_decoded;1297} else if (name == "maccatalyst_version") {1298if (!m_maccatalyst_version.tryParse(value))1299++num_keys_decoded;1300} else if (name == "watchpoint_exceptions_received") {1301m_watchpoints_trigger_after_instruction =1302llvm::StringSwitch<LazyBool>(value)1303.Case("before", eLazyBoolNo)1304.Case("after", eLazyBoolYes)1305.Default(eLazyBoolCalculate);1306if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)1307++num_keys_decoded;1308} else if (name == "default_packet_timeout") {1309uint32_t timeout_seconds;1310if (!value.getAsInteger(0, timeout_seconds)) {1311m_default_packet_timeout = seconds(timeout_seconds);1312SetPacketTimeout(m_default_packet_timeout);1313++num_keys_decoded;1314}1315} else if (name == "vm-page-size") {1316int page_size;1317if (!value.getAsInteger(0, page_size)) {1318m_target_vm_page_size = page_size;1319++num_keys_decoded;1320}1321}1322}13231324if (num_keys_decoded > 0)1325m_qHostInfo_is_valid = eLazyBoolYes;13261327if (triple.empty()) {1328if (arch_name.empty()) {1329if (cpu != LLDB_INVALID_CPUTYPE) {1330m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);1331if (pointer_byte_size) {1332assert(pointer_byte_size == m_host_arch.GetAddressByteSize());1333}1334if (byte_order != eByteOrderInvalid) {1335assert(byte_order == m_host_arch.GetByteOrder());1336}13371338if (!vendor_name.empty())1339m_host_arch.GetTriple().setVendorName(1340llvm::StringRef(vendor_name));1341if (!os_name.empty())1342m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));1343if (!environment.empty())1344m_host_arch.GetTriple().setEnvironmentName(environment);1345}1346} else {1347std::string triple;1348triple += arch_name;1349if (!vendor_name.empty() || !os_name.empty()) {1350triple += '-';1351if (vendor_name.empty())1352triple += "unknown";1353else1354triple += vendor_name;1355triple += '-';1356if (os_name.empty())1357triple += "unknown";1358else1359triple += os_name;1360}1361m_host_arch.SetTriple(triple.c_str());13621363llvm::Triple &host_triple = m_host_arch.GetTriple();1364if (host_triple.getVendor() == llvm::Triple::Apple &&1365host_triple.getOS() == llvm::Triple::Darwin) {1366switch (m_host_arch.GetMachine()) {1367case llvm::Triple::aarch64:1368case llvm::Triple::aarch64_32:1369case llvm::Triple::arm:1370case llvm::Triple::thumb:1371host_triple.setOS(llvm::Triple::IOS);1372break;1373default:1374host_triple.setOS(llvm::Triple::MacOSX);1375break;1376}1377}1378if (pointer_byte_size) {1379assert(pointer_byte_size == m_host_arch.GetAddressByteSize());1380}1381if (byte_order != eByteOrderInvalid) {1382assert(byte_order == m_host_arch.GetByteOrder());1383}1384}1385} else {1386m_host_arch.SetTriple(triple.c_str());1387if (pointer_byte_size) {1388assert(pointer_byte_size == m_host_arch.GetAddressByteSize());1389}1390if (byte_order != eByteOrderInvalid) {1391assert(byte_order == m_host_arch.GetByteOrder());1392}13931394LLDB_LOGF(log,1395"GDBRemoteCommunicationClient::%s parsed host "1396"architecture as %s, triple as %s from triple text %s",1397__FUNCTION__,1398m_host_arch.GetArchitectureName()1399? m_host_arch.GetArchitectureName()1400: "<null-arch-name>",1401m_host_arch.GetTriple().getTriple().c_str(),1402triple.c_str());1403}1404}1405}1406}1407return m_qHostInfo_is_valid == eLazyBoolYes;1408}14091410int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,1411size_t data_len) {1412StreamString packet;1413packet.PutCString("I");1414packet.PutBytesAsRawHex8(data, data_len);1415StringExtractorGDBRemote response;1416if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1417PacketResult::Success) {1418return 0;1419}1420return response.GetError();1421}14221423const lldb_private::ArchSpec &1424GDBRemoteCommunicationClient::GetHostArchitecture() {1425if (m_qHostInfo_is_valid == eLazyBoolCalculate)1426GetHostInfo();1427return m_host_arch;1428}14291430AddressableBits GDBRemoteCommunicationClient::GetAddressableBits() {1431AddressableBits addressable_bits;1432if (m_qHostInfo_is_valid == eLazyBoolCalculate)1433GetHostInfo();14341435if (m_low_mem_addressing_bits == m_high_mem_addressing_bits)1436addressable_bits.SetAddressableBits(m_low_mem_addressing_bits);1437else1438addressable_bits.SetAddressableBits(m_low_mem_addressing_bits,1439m_high_mem_addressing_bits);1440return addressable_bits;1441}14421443seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {1444if (m_qHostInfo_is_valid == eLazyBoolCalculate)1445GetHostInfo();1446return m_default_packet_timeout;1447}14481449addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,1450uint32_t permissions) {1451if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {1452m_supports_alloc_dealloc_memory = eLazyBoolYes;1453char packet[64];1454const int packet_len = ::snprintf(1455packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,1456permissions & lldb::ePermissionsReadable ? "r" : "",1457permissions & lldb::ePermissionsWritable ? "w" : "",1458permissions & lldb::ePermissionsExecutable ? "x" : "");1459assert(packet_len < (int)sizeof(packet));1460UNUSED_IF_ASSERT_DISABLED(packet_len);1461StringExtractorGDBRemote response;1462if (SendPacketAndWaitForResponse(packet, response) ==1463PacketResult::Success) {1464if (response.IsUnsupportedResponse())1465m_supports_alloc_dealloc_memory = eLazyBoolNo;1466else if (!response.IsErrorResponse())1467return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);1468} else {1469m_supports_alloc_dealloc_memory = eLazyBoolNo;1470}1471}1472return LLDB_INVALID_ADDRESS;1473}14741475bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {1476if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {1477m_supports_alloc_dealloc_memory = eLazyBoolYes;1478char packet[64];1479const int packet_len =1480::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);1481assert(packet_len < (int)sizeof(packet));1482UNUSED_IF_ASSERT_DISABLED(packet_len);1483StringExtractorGDBRemote response;1484if (SendPacketAndWaitForResponse(packet, response) ==1485PacketResult::Success) {1486if (response.IsUnsupportedResponse())1487m_supports_alloc_dealloc_memory = eLazyBoolNo;1488else if (response.IsOKResponse())1489return true;1490} else {1491m_supports_alloc_dealloc_memory = eLazyBoolNo;1492}1493}1494return false;1495}14961497Status GDBRemoteCommunicationClient::Detach(bool keep_stopped,1498lldb::pid_t pid) {1499Status error;1500lldb_private::StreamString packet;15011502packet.PutChar('D');1503if (keep_stopped) {1504if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {1505char packet[64];1506const int packet_len =1507::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");1508assert(packet_len < (int)sizeof(packet));1509UNUSED_IF_ASSERT_DISABLED(packet_len);1510StringExtractorGDBRemote response;1511if (SendPacketAndWaitForResponse(packet, response) ==1512PacketResult::Success &&1513response.IsOKResponse()) {1514m_supports_detach_stay_stopped = eLazyBoolYes;1515} else {1516m_supports_detach_stay_stopped = eLazyBoolNo;1517}1518}15191520if (m_supports_detach_stay_stopped == eLazyBoolNo) {1521error.SetErrorString("Stays stopped not supported by this target.");1522return error;1523} else {1524packet.PutChar('1');1525}1526}15271528if (GetMultiprocessSupported()) {1529// Some servers (e.g. qemu) require specifying the PID even if only a single1530// process is running.1531if (pid == LLDB_INVALID_PROCESS_ID)1532pid = GetCurrentProcessID();1533packet.PutChar(';');1534packet.PutHex64(pid);1535} else if (pid != LLDB_INVALID_PROCESS_ID) {1536error.SetErrorString("Multiprocess extension not supported by the server.");1537return error;1538}15391540StringExtractorGDBRemote response;1541PacketResult packet_result =1542SendPacketAndWaitForResponse(packet.GetString(), response);1543if (packet_result != PacketResult::Success)1544error.SetErrorString("Sending isconnect packet failed.");1545return error;1546}15471548Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(1549lldb::addr_t addr, lldb_private::MemoryRegionInfo ®ion_info) {1550Status error;1551region_info.Clear();15521553if (m_supports_memory_region_info != eLazyBoolNo) {1554m_supports_memory_region_info = eLazyBoolYes;1555char packet[64];1556const int packet_len = ::snprintf(1557packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);1558assert(packet_len < (int)sizeof(packet));1559UNUSED_IF_ASSERT_DISABLED(packet_len);1560StringExtractorGDBRemote response;1561if (SendPacketAndWaitForResponse(packet, response) ==1562PacketResult::Success &&1563response.GetResponseType() == StringExtractorGDBRemote::eResponse) {1564llvm::StringRef name;1565llvm::StringRef value;1566addr_t addr_value = LLDB_INVALID_ADDRESS;1567bool success = true;1568bool saw_permissions = false;1569while (success && response.GetNameColonValue(name, value)) {1570if (name == "start") {1571if (!value.getAsInteger(16, addr_value))1572region_info.GetRange().SetRangeBase(addr_value);1573} else if (name == "size") {1574if (!value.getAsInteger(16, addr_value)) {1575region_info.GetRange().SetByteSize(addr_value);1576if (region_info.GetRange().GetRangeEnd() <1577region_info.GetRange().GetRangeBase()) {1578// Range size overflowed, truncate it.1579region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);1580}1581}1582} else if (name == "permissions" && region_info.GetRange().IsValid()) {1583saw_permissions = true;1584if (region_info.GetRange().Contains(addr)) {1585if (value.contains('r'))1586region_info.SetReadable(MemoryRegionInfo::eYes);1587else1588region_info.SetReadable(MemoryRegionInfo::eNo);15891590if (value.contains('w'))1591region_info.SetWritable(MemoryRegionInfo::eYes);1592else1593region_info.SetWritable(MemoryRegionInfo::eNo);15941595if (value.contains('x'))1596region_info.SetExecutable(MemoryRegionInfo::eYes);1597else1598region_info.SetExecutable(MemoryRegionInfo::eNo);15991600region_info.SetMapped(MemoryRegionInfo::eYes);1601} else {1602// The reported region does not contain this address -- we're1603// looking at an unmapped page1604region_info.SetReadable(MemoryRegionInfo::eNo);1605region_info.SetWritable(MemoryRegionInfo::eNo);1606region_info.SetExecutable(MemoryRegionInfo::eNo);1607region_info.SetMapped(MemoryRegionInfo::eNo);1608}1609} else if (name == "name") {1610StringExtractorGDBRemote name_extractor(value);1611std::string name;1612name_extractor.GetHexByteString(name);1613region_info.SetName(name.c_str());1614} else if (name == "flags") {1615region_info.SetMemoryTagged(MemoryRegionInfo::eNo);16161617llvm::StringRef flags = value;1618llvm::StringRef flag;1619while (flags.size()) {1620flags = flags.ltrim();1621std::tie(flag, flags) = flags.split(' ');1622// To account for trailing whitespace1623if (flag.size()) {1624if (flag == "mt") {1625region_info.SetMemoryTagged(MemoryRegionInfo::eYes);1626break;1627}1628}1629}1630} else if (name == "type") {1631std::string comma_sep_str = value.str();1632size_t comma_pos;1633while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) {1634comma_sep_str[comma_pos] = '\0';1635if (comma_sep_str == "stack") {1636region_info.SetIsStackMemory(MemoryRegionInfo::eYes);1637}1638}1639// handle final (or only) type of "stack"1640if (comma_sep_str == "stack") {1641region_info.SetIsStackMemory(MemoryRegionInfo::eYes);1642}1643} else if (name == "error") {1644StringExtractorGDBRemote error_extractor(value);1645std::string error_string;1646// Now convert the HEX bytes into a string value1647error_extractor.GetHexByteString(error_string);1648error.SetErrorString(error_string.c_str());1649} else if (name == "dirty-pages") {1650std::vector<addr_t> dirty_page_list;1651for (llvm::StringRef x : llvm::split(value, ',')) {1652addr_t page;1653x.consume_front("0x");1654if (llvm::to_integer(x, page, 16))1655dirty_page_list.push_back(page);1656}1657region_info.SetDirtyPageList(dirty_page_list);1658}1659}16601661if (m_target_vm_page_size != 0)1662region_info.SetPageSize(m_target_vm_page_size);16631664if (region_info.GetRange().IsValid()) {1665// We got a valid address range back but no permissions -- which means1666// this is an unmapped page1667if (!saw_permissions) {1668region_info.SetReadable(MemoryRegionInfo::eNo);1669region_info.SetWritable(MemoryRegionInfo::eNo);1670region_info.SetExecutable(MemoryRegionInfo::eNo);1671region_info.SetMapped(MemoryRegionInfo::eNo);1672}1673} else {1674// We got an invalid address range back1675error.SetErrorString("Server returned invalid range");1676}1677} else {1678m_supports_memory_region_info = eLazyBoolNo;1679}1680}16811682if (m_supports_memory_region_info == eLazyBoolNo) {1683error.SetErrorString("qMemoryRegionInfo is not supported");1684}16851686// Try qXfer:memory-map:read to get region information not included in1687// qMemoryRegionInfo1688MemoryRegionInfo qXfer_region_info;1689Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);16901691if (error.Fail()) {1692// If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use1693// the qXfer result as a fallback1694if (qXfer_error.Success()) {1695region_info = qXfer_region_info;1696error.Clear();1697} else {1698region_info.Clear();1699}1700} else if (qXfer_error.Success()) {1701// If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if1702// both regions are the same range, update the result to include the flash-1703// memory information that is specific to the qXfer result.1704if (region_info.GetRange() == qXfer_region_info.GetRange()) {1705region_info.SetFlash(qXfer_region_info.GetFlash());1706region_info.SetBlocksize(qXfer_region_info.GetBlocksize());1707}1708}1709return error;1710}17111712Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(1713lldb::addr_t addr, MemoryRegionInfo ®ion) {1714Status error = LoadQXferMemoryMap();1715if (!error.Success())1716return error;1717for (const auto &map_region : m_qXfer_memory_map) {1718if (map_region.GetRange().Contains(addr)) {1719region = map_region;1720return error;1721}1722}1723error.SetErrorString("Region not found");1724return error;1725}17261727Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {17281729Status error;17301731if (m_qXfer_memory_map_loaded)1732// Already loaded, return success1733return error;17341735if (!XMLDocument::XMLEnabled()) {1736error.SetErrorString("XML is not supported");1737return error;1738}17391740if (!GetQXferMemoryMapReadSupported()) {1741error.SetErrorString("Memory map is not supported");1742return error;1743}17441745llvm::Expected<std::string> xml = ReadExtFeature("memory-map", "");1746if (!xml)1747return Status(xml.takeError());17481749XMLDocument xml_document;17501751if (!xml_document.ParseMemory(xml->c_str(), xml->size())) {1752error.SetErrorString("Failed to parse memory map xml");1753return error;1754}17551756XMLNode map_node = xml_document.GetRootElement("memory-map");1757if (!map_node) {1758error.SetErrorString("Invalid root node in memory map xml");1759return error;1760}17611762m_qXfer_memory_map.clear();17631764map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {1765if (!memory_node.IsElement())1766return true;1767if (memory_node.GetName() != "memory")1768return true;1769auto type = memory_node.GetAttributeValue("type", "");1770uint64_t start;1771uint64_t length;1772if (!memory_node.GetAttributeValueAsUnsigned("start", start))1773return true;1774if (!memory_node.GetAttributeValueAsUnsigned("length", length))1775return true;1776MemoryRegionInfo region;1777region.GetRange().SetRangeBase(start);1778region.GetRange().SetByteSize(length);1779if (type == "rom") {1780region.SetReadable(MemoryRegionInfo::eYes);1781this->m_qXfer_memory_map.push_back(region);1782} else if (type == "ram") {1783region.SetReadable(MemoryRegionInfo::eYes);1784region.SetWritable(MemoryRegionInfo::eYes);1785this->m_qXfer_memory_map.push_back(region);1786} else if (type == "flash") {1787region.SetFlash(MemoryRegionInfo::eYes);1788memory_node.ForEachChildElement(1789[®ion](const XMLNode &prop_node) -> bool {1790if (!prop_node.IsElement())1791return true;1792if (prop_node.GetName() != "property")1793return true;1794auto propname = prop_node.GetAttributeValue("name", "");1795if (propname == "blocksize") {1796uint64_t blocksize;1797if (prop_node.GetElementTextAsUnsigned(blocksize))1798region.SetBlocksize(blocksize);1799}1800return true;1801});1802this->m_qXfer_memory_map.push_back(region);1803}1804return true;1805});18061807m_qXfer_memory_map_loaded = true;18081809return error;1810}18111812std::optional<uint32_t> GDBRemoteCommunicationClient::GetWatchpointSlotCount() {1813if (m_supports_watchpoint_support_info == eLazyBoolYes) {1814return m_num_supported_hardware_watchpoints;1815}18161817std::optional<uint32_t> num;1818if (m_supports_watchpoint_support_info != eLazyBoolNo) {1819StringExtractorGDBRemote response;1820if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==1821PacketResult::Success) {1822m_supports_watchpoint_support_info = eLazyBoolYes;1823llvm::StringRef name;1824llvm::StringRef value;1825while (response.GetNameColonValue(name, value)) {1826if (name == "num") {1827value.getAsInteger(0, m_num_supported_hardware_watchpoints);1828num = m_num_supported_hardware_watchpoints;1829}1830}1831if (!num) {1832m_supports_watchpoint_support_info = eLazyBoolNo;1833}1834} else {1835m_supports_watchpoint_support_info = eLazyBoolNo;1836}1837}18381839return num;1840}18411842WatchpointHardwareFeature1843GDBRemoteCommunicationClient::GetSupportedWatchpointTypes() {1844return m_watchpoint_types;1845}18461847std::optional<bool> GDBRemoteCommunicationClient::GetWatchpointReportedAfter() {1848if (m_qHostInfo_is_valid == eLazyBoolCalculate)1849GetHostInfo();18501851// Process determines this by target CPU, but allow for the1852// remote stub to override it via the qHostInfo1853// watchpoint_exceptions_received key, if it is present.1854if (m_qHostInfo_is_valid == eLazyBoolYes) {1855if (m_watchpoints_trigger_after_instruction == eLazyBoolNo)1856return false;1857if (m_watchpoints_trigger_after_instruction == eLazyBoolYes)1858return true;1859}18601861return std::nullopt;1862}18631864int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {1865if (file_spec) {1866std::string path{file_spec.GetPath(false)};1867StreamString packet;1868packet.PutCString("QSetSTDIN:");1869packet.PutStringAsRawHex8(path);18701871StringExtractorGDBRemote response;1872if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1873PacketResult::Success) {1874if (response.IsOKResponse())1875return 0;1876uint8_t error = response.GetError();1877if (error)1878return error;1879}1880}1881return -1;1882}18831884int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {1885if (file_spec) {1886std::string path{file_spec.GetPath(false)};1887StreamString packet;1888packet.PutCString("QSetSTDOUT:");1889packet.PutStringAsRawHex8(path);18901891StringExtractorGDBRemote response;1892if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1893PacketResult::Success) {1894if (response.IsOKResponse())1895return 0;1896uint8_t error = response.GetError();1897if (error)1898return error;1899}1900}1901return -1;1902}19031904int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {1905if (file_spec) {1906std::string path{file_spec.GetPath(false)};1907StreamString packet;1908packet.PutCString("QSetSTDERR:");1909packet.PutStringAsRawHex8(path);19101911StringExtractorGDBRemote response;1912if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1913PacketResult::Success) {1914if (response.IsOKResponse())1915return 0;1916uint8_t error = response.GetError();1917if (error)1918return error;1919}1920}1921return -1;1922}19231924bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {1925StringExtractorGDBRemote response;1926if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==1927PacketResult::Success) {1928if (response.IsUnsupportedResponse())1929return false;1930if (response.IsErrorResponse())1931return false;1932std::string cwd;1933response.GetHexByteString(cwd);1934working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());1935return !cwd.empty();1936}1937return false;1938}19391940int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {1941if (working_dir) {1942std::string path{working_dir.GetPath(false)};1943StreamString packet;1944packet.PutCString("QSetWorkingDir:");1945packet.PutStringAsRawHex8(path);19461947StringExtractorGDBRemote response;1948if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1949PacketResult::Success) {1950if (response.IsOKResponse())1951return 0;1952uint8_t error = response.GetError();1953if (error)1954return error;1955}1956}1957return -1;1958}19591960int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {1961char packet[32];1962const int packet_len =1963::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);1964assert(packet_len < (int)sizeof(packet));1965UNUSED_IF_ASSERT_DISABLED(packet_len);1966StringExtractorGDBRemote response;1967if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {1968if (response.IsOKResponse())1969return 0;1970uint8_t error = response.GetError();1971if (error)1972return error;1973}1974return -1;1975}19761977int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {1978char packet[32];1979const int packet_len = ::snprintf(packet, sizeof(packet),1980"QSetDetachOnError:%i", enable ? 1 : 0);1981assert(packet_len < (int)sizeof(packet));1982UNUSED_IF_ASSERT_DISABLED(packet_len);1983StringExtractorGDBRemote response;1984if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {1985if (response.IsOKResponse())1986return 0;1987uint8_t error = response.GetError();1988if (error)1989return error;1990}1991return -1;1992}19931994bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(1995StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {1996if (response.IsNormalResponse()) {1997llvm::StringRef name;1998llvm::StringRef value;1999StringExtractor extractor;20002001uint32_t cpu = LLDB_INVALID_CPUTYPE;2002uint32_t sub = 0;2003std::string vendor;2004std::string os_type;20052006while (response.GetNameColonValue(name, value)) {2007if (name == "pid") {2008lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;2009value.getAsInteger(0, pid);2010process_info.SetProcessID(pid);2011} else if (name == "ppid") {2012lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;2013value.getAsInteger(0, pid);2014process_info.SetParentProcessID(pid);2015} else if (name == "uid") {2016uint32_t uid = UINT32_MAX;2017value.getAsInteger(0, uid);2018process_info.SetUserID(uid);2019} else if (name == "euid") {2020uint32_t uid = UINT32_MAX;2021value.getAsInteger(0, uid);2022process_info.SetEffectiveUserID(uid);2023} else if (name == "gid") {2024uint32_t gid = UINT32_MAX;2025value.getAsInteger(0, gid);2026process_info.SetGroupID(gid);2027} else if (name == "egid") {2028uint32_t gid = UINT32_MAX;2029value.getAsInteger(0, gid);2030process_info.SetEffectiveGroupID(gid);2031} else if (name == "triple") {2032StringExtractor extractor(value);2033std::string triple;2034extractor.GetHexByteString(triple);2035process_info.GetArchitecture().SetTriple(triple.c_str());2036} else if (name == "name") {2037StringExtractor extractor(value);2038// The process name from ASCII hex bytes since we can't control the2039// characters in a process name2040std::string name;2041extractor.GetHexByteString(name);2042process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);2043} else if (name == "args") {2044llvm::StringRef encoded_args(value), hex_arg;20452046bool is_arg0 = true;2047while (!encoded_args.empty()) {2048std::tie(hex_arg, encoded_args) = encoded_args.split('-');2049std::string arg;2050StringExtractor extractor(hex_arg);2051if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {2052// In case of wrong encoding, we discard all the arguments2053process_info.GetArguments().Clear();2054process_info.SetArg0("");2055break;2056}2057if (is_arg0)2058process_info.SetArg0(arg);2059else2060process_info.GetArguments().AppendArgument(arg);2061is_arg0 = false;2062}2063} else if (name == "cputype") {2064value.getAsInteger(0, cpu);2065} else if (name == "cpusubtype") {2066value.getAsInteger(0, sub);2067} else if (name == "vendor") {2068vendor = std::string(value);2069} else if (name == "ostype") {2070os_type = std::string(value);2071}2072}20732074if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {2075if (vendor == "apple") {2076process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,2077sub);2078process_info.GetArchitecture().GetTriple().setVendorName(2079llvm::StringRef(vendor));2080process_info.GetArchitecture().GetTriple().setOSName(2081llvm::StringRef(os_type));2082}2083}20842085if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)2086return true;2087}2088return false;2089}20902091bool GDBRemoteCommunicationClient::GetProcessInfo(2092lldb::pid_t pid, ProcessInstanceInfo &process_info) {2093process_info.Clear();20942095if (m_supports_qProcessInfoPID) {2096char packet[32];2097const int packet_len =2098::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);2099assert(packet_len < (int)sizeof(packet));2100UNUSED_IF_ASSERT_DISABLED(packet_len);2101StringExtractorGDBRemote response;2102if (SendPacketAndWaitForResponse(packet, response) ==2103PacketResult::Success) {2104return DecodeProcessInfoResponse(response, process_info);2105} else {2106m_supports_qProcessInfoPID = false;2107return false;2108}2109}2110return false;2111}21122113bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {2114Log *log(GetLog(GDBRLog::Process | GDBRLog::Packets));21152116if (allow_lazy) {2117if (m_qProcessInfo_is_valid == eLazyBoolYes)2118return true;2119if (m_qProcessInfo_is_valid == eLazyBoolNo)2120return false;2121}21222123GetHostInfo();21242125StringExtractorGDBRemote response;2126if (SendPacketAndWaitForResponse("qProcessInfo", response) ==2127PacketResult::Success) {2128if (response.IsNormalResponse()) {2129llvm::StringRef name;2130llvm::StringRef value;2131uint32_t cpu = LLDB_INVALID_CPUTYPE;2132uint32_t sub = 0;2133std::string arch_name;2134std::string os_name;2135std::string environment;2136std::string vendor_name;2137std::string triple;2138std::string elf_abi;2139uint32_t pointer_byte_size = 0;2140StringExtractor extractor;2141ByteOrder byte_order = eByteOrderInvalid;2142uint32_t num_keys_decoded = 0;2143lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;2144while (response.GetNameColonValue(name, value)) {2145if (name == "cputype") {2146if (!value.getAsInteger(16, cpu))2147++num_keys_decoded;2148} else if (name == "cpusubtype") {2149if (!value.getAsInteger(16, sub)) {2150++num_keys_decoded;2151// Workaround for pre-2024 Apple debugserver, which always2152// returns arm64e on arm64e-capable hardware regardless of2153// what the process is. This can be deleted at some point2154// in the future.2155if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&2156sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {2157if (GetGDBServerVersion())2158if (m_gdb_server_version >= 1000 &&2159m_gdb_server_version <= 1504)2160sub = 0;2161}2162}2163} else if (name == "triple") {2164StringExtractor extractor(value);2165extractor.GetHexByteString(triple);2166++num_keys_decoded;2167} else if (name == "ostype") {2168ParseOSType(value, os_name, environment);2169++num_keys_decoded;2170} else if (name == "vendor") {2171vendor_name = std::string(value);2172++num_keys_decoded;2173} else if (name == "endian") {2174byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)2175.Case("little", eByteOrderLittle)2176.Case("big", eByteOrderBig)2177.Case("pdp", eByteOrderPDP)2178.Default(eByteOrderInvalid);2179if (byte_order != eByteOrderInvalid)2180++num_keys_decoded;2181} else if (name == "ptrsize") {2182if (!value.getAsInteger(16, pointer_byte_size))2183++num_keys_decoded;2184} else if (name == "pid") {2185if (!value.getAsInteger(16, pid))2186++num_keys_decoded;2187} else if (name == "elf_abi") {2188elf_abi = std::string(value);2189++num_keys_decoded;2190} else if (name == "main-binary-uuid") {2191m_process_standalone_uuid.SetFromStringRef(value);2192++num_keys_decoded;2193} else if (name == "main-binary-slide") {2194StringExtractor extractor(value);2195m_process_standalone_value =2196extractor.GetU64(LLDB_INVALID_ADDRESS, 16);2197if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {2198m_process_standalone_value_is_offset = true;2199++num_keys_decoded;2200}2201} else if (name == "main-binary-address") {2202StringExtractor extractor(value);2203m_process_standalone_value =2204extractor.GetU64(LLDB_INVALID_ADDRESS, 16);2205if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {2206m_process_standalone_value_is_offset = false;2207++num_keys_decoded;2208}2209} else if (name == "binary-addresses") {2210m_binary_addresses.clear();2211++num_keys_decoded;2212for (llvm::StringRef x : llvm::split(value, ',')) {2213addr_t vmaddr;2214x.consume_front("0x");2215if (llvm::to_integer(x, vmaddr, 16))2216m_binary_addresses.push_back(vmaddr);2217}2218}2219}2220if (num_keys_decoded > 0)2221m_qProcessInfo_is_valid = eLazyBoolYes;2222if (pid != LLDB_INVALID_PROCESS_ID) {2223m_curr_pid_is_valid = eLazyBoolYes;2224m_curr_pid_run = m_curr_pid = pid;2225}22262227// Set the ArchSpec from the triple if we have it.2228if (!triple.empty()) {2229m_process_arch.SetTriple(triple.c_str());2230m_process_arch.SetFlags(elf_abi);2231if (pointer_byte_size) {2232assert(pointer_byte_size == m_process_arch.GetAddressByteSize());2233}2234} else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&2235!vendor_name.empty()) {2236llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);2237if (!environment.empty())2238triple.setEnvironmentName(environment);22392240assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);2241assert(triple.getObjectFormat() != llvm::Triple::Wasm);2242assert(triple.getObjectFormat() != llvm::Triple::XCOFF);2243switch (triple.getObjectFormat()) {2244case llvm::Triple::MachO:2245m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);2246break;2247case llvm::Triple::ELF:2248m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);2249break;2250case llvm::Triple::COFF:2251m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);2252break;2253case llvm::Triple::GOFF:2254case llvm::Triple::SPIRV:2255case llvm::Triple::Wasm:2256case llvm::Triple::XCOFF:2257case llvm::Triple::DXContainer:2258LLDB_LOGF(log, "error: not supported target architecture");2259return false;2260case llvm::Triple::UnknownObjectFormat:2261LLDB_LOGF(log, "error: failed to determine target architecture");2262return false;2263}22642265if (pointer_byte_size) {2266assert(pointer_byte_size == m_process_arch.GetAddressByteSize());2267}2268if (byte_order != eByteOrderInvalid) {2269assert(byte_order == m_process_arch.GetByteOrder());2270}2271m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));2272m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));2273m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));2274}2275return true;2276}2277} else {2278m_qProcessInfo_is_valid = eLazyBoolNo;2279}22802281return false;2282}22832284uint32_t GDBRemoteCommunicationClient::FindProcesses(2285const ProcessInstanceInfoMatch &match_info,2286ProcessInstanceInfoList &process_infos) {2287process_infos.clear();22882289if (m_supports_qfProcessInfo) {2290StreamString packet;2291packet.PutCString("qfProcessInfo");2292if (!match_info.MatchAllProcesses()) {2293packet.PutChar(':');2294const char *name = match_info.GetProcessInfo().GetName();2295bool has_name_match = false;2296if (name && name[0]) {2297has_name_match = true;2298NameMatch name_match_type = match_info.GetNameMatchType();2299switch (name_match_type) {2300case NameMatch::Ignore:2301has_name_match = false;2302break;23032304case NameMatch::Equals:2305packet.PutCString("name_match:equals;");2306break;23072308case NameMatch::Contains:2309packet.PutCString("name_match:contains;");2310break;23112312case NameMatch::StartsWith:2313packet.PutCString("name_match:starts_with;");2314break;23152316case NameMatch::EndsWith:2317packet.PutCString("name_match:ends_with;");2318break;23192320case NameMatch::RegularExpression:2321packet.PutCString("name_match:regex;");2322break;2323}2324if (has_name_match) {2325packet.PutCString("name:");2326packet.PutBytesAsRawHex8(name, ::strlen(name));2327packet.PutChar(';');2328}2329}23302331if (match_info.GetProcessInfo().ProcessIDIsValid())2332packet.Printf("pid:%" PRIu64 ";",2333match_info.GetProcessInfo().GetProcessID());2334if (match_info.GetProcessInfo().ParentProcessIDIsValid())2335packet.Printf("parent_pid:%" PRIu64 ";",2336match_info.GetProcessInfo().GetParentProcessID());2337if (match_info.GetProcessInfo().UserIDIsValid())2338packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());2339if (match_info.GetProcessInfo().GroupIDIsValid())2340packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());2341if (match_info.GetProcessInfo().EffectiveUserIDIsValid())2342packet.Printf("euid:%u;",2343match_info.GetProcessInfo().GetEffectiveUserID());2344if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())2345packet.Printf("egid:%u;",2346match_info.GetProcessInfo().GetEffectiveGroupID());2347packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);2348if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {2349const ArchSpec &match_arch =2350match_info.GetProcessInfo().GetArchitecture();2351const llvm::Triple &triple = match_arch.GetTriple();2352packet.PutCString("triple:");2353packet.PutCString(triple.getTriple());2354packet.PutChar(';');2355}2356}2357StringExtractorGDBRemote response;2358// Increase timeout as the first qfProcessInfo packet takes a long time on2359// Android. The value of 1min was arrived at empirically.2360ScopedTimeout timeout(*this, minutes(1));2361if (SendPacketAndWaitForResponse(packet.GetString(), response) ==2362PacketResult::Success) {2363do {2364ProcessInstanceInfo process_info;2365if (!DecodeProcessInfoResponse(response, process_info))2366break;2367process_infos.push_back(process_info);2368response = StringExtractorGDBRemote();2369} while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==2370PacketResult::Success);2371} else {2372m_supports_qfProcessInfo = false;2373return 0;2374}2375}2376return process_infos.size();2377}23782379bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,2380std::string &name) {2381if (m_supports_qUserName) {2382char packet[32];2383const int packet_len =2384::snprintf(packet, sizeof(packet), "qUserName:%i", uid);2385assert(packet_len < (int)sizeof(packet));2386UNUSED_IF_ASSERT_DISABLED(packet_len);2387StringExtractorGDBRemote response;2388if (SendPacketAndWaitForResponse(packet, response) ==2389PacketResult::Success) {2390if (response.IsNormalResponse()) {2391// Make sure we parsed the right number of characters. The response is2392// the hex encoded user name and should make up the entire packet. If2393// there are any non-hex ASCII bytes, the length won't match below..2394if (response.GetHexByteString(name) * 2 ==2395response.GetStringRef().size())2396return true;2397}2398} else {2399m_supports_qUserName = false;2400return false;2401}2402}2403return false;2404}24052406bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,2407std::string &name) {2408if (m_supports_qGroupName) {2409char packet[32];2410const int packet_len =2411::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);2412assert(packet_len < (int)sizeof(packet));2413UNUSED_IF_ASSERT_DISABLED(packet_len);2414StringExtractorGDBRemote response;2415if (SendPacketAndWaitForResponse(packet, response) ==2416PacketResult::Success) {2417if (response.IsNormalResponse()) {2418// Make sure we parsed the right number of characters. The response is2419// the hex encoded group name and should make up the entire packet. If2420// there are any non-hex ASCII bytes, the length won't match below..2421if (response.GetHexByteString(name) * 2 ==2422response.GetStringRef().size())2423return true;2424}2425} else {2426m_supports_qGroupName = false;2427return false;2428}2429}2430return false;2431}24322433static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,2434uint32_t recv_size) {2435packet.Clear();2436packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);2437uint32_t bytes_left = send_size;2438while (bytes_left > 0) {2439if (bytes_left >= 26) {2440packet.PutCString("abcdefghijklmnopqrstuvwxyz");2441bytes_left -= 26;2442} else {2443packet.Printf("%*.*s;", bytes_left, bytes_left,2444"abcdefghijklmnopqrstuvwxyz");2445bytes_left = 0;2446}2447}2448}24492450duration<float>2451calculate_standard_deviation(const std::vector<duration<float>> &v) {2452if (v.size() == 0)2453return duration<float>::zero();2454using Dur = duration<float>;2455Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());2456Dur mean = sum / v.size();2457float accum = 0;2458for (auto d : v) {2459float delta = (d - mean).count();2460accum += delta * delta;2461};24622463return Dur(sqrtf(accum / (v.size() - 1)));2464}24652466void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,2467uint32_t max_send,2468uint32_t max_recv,2469uint64_t recv_amount,2470bool json, Stream &strm) {24712472if (SendSpeedTestPacket(0, 0)) {2473StreamString packet;2474if (json)2475strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "2476"\"results\" : [",2477num_packets);2478else2479strm.Printf("Testing sending %u packets of various sizes:\n",2480num_packets);2481strm.Flush();24822483uint32_t result_idx = 0;2484uint32_t send_size;2485std::vector<duration<float>> packet_times;24862487for (send_size = 0; send_size <= max_send;2488send_size ? send_size *= 2 : send_size = 4) {2489for (uint32_t recv_size = 0; recv_size <= max_recv;2490recv_size ? recv_size *= 2 : recv_size = 4) {2491MakeSpeedTestPacket(packet, send_size, recv_size);24922493packet_times.clear();2494// Test how long it takes to send 'num_packets' packets2495const auto start_time = steady_clock::now();2496for (uint32_t i = 0; i < num_packets; ++i) {2497const auto packet_start_time = steady_clock::now();2498StringExtractorGDBRemote response;2499SendPacketAndWaitForResponse(packet.GetString(), response);2500const auto packet_end_time = steady_clock::now();2501packet_times.push_back(packet_end_time - packet_start_time);2502}2503const auto end_time = steady_clock::now();2504const auto total_time = end_time - start_time;25052506float packets_per_second =2507((float)num_packets) / duration<float>(total_time).count();2508auto average_per_packet = num_packets > 0 ? total_time / num_packets2509: duration<float>::zero();2510const duration<float> standard_deviation =2511calculate_standard_deviation(packet_times);2512if (json) {2513strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "2514"{2,6}, \"total_time_nsec\" : {3,12:ns-}, "2515"\"standard_deviation_nsec\" : {4,9:ns-f0}}",2516result_idx > 0 ? "," : "", send_size, recv_size,2517total_time, standard_deviation);2518++result_idx;2519} else {2520strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "2521"{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "2522"standard deviation of {5,10:ms+f6}\n",2523send_size, recv_size, duration<float>(total_time),2524packets_per_second, duration<float>(average_per_packet),2525standard_deviation);2526}2527strm.Flush();2528}2529}25302531const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);2532if (json)2533strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "2534": %" PRIu64 ",\n \"results\" : [",2535recv_amount);2536else2537strm.Printf("Testing receiving %2.1fMB of data using varying receive "2538"packet sizes:\n",2539k_recv_amount_mb);2540strm.Flush();2541send_size = 0;2542result_idx = 0;2543for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {2544MakeSpeedTestPacket(packet, send_size, recv_size);25452546// If we have a receive size, test how long it takes to receive 4MB of2547// data2548if (recv_size > 0) {2549const auto start_time = steady_clock::now();2550uint32_t bytes_read = 0;2551uint32_t packet_count = 0;2552while (bytes_read < recv_amount) {2553StringExtractorGDBRemote response;2554SendPacketAndWaitForResponse(packet.GetString(), response);2555bytes_read += recv_size;2556++packet_count;2557}2558const auto end_time = steady_clock::now();2559const auto total_time = end_time - start_time;2560float mb_second = ((float)recv_amount) /2561duration<float>(total_time).count() /2562(1024.0 * 1024.0);2563float packets_per_second =2564((float)packet_count) / duration<float>(total_time).count();2565const auto average_per_packet = packet_count > 02566? total_time / packet_count2567: duration<float>::zero();25682569if (json) {2570strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "2571"{2,6}, \"total_time_nsec\" : {3,12:ns-}}",2572result_idx > 0 ? "," : "", send_size, recv_size,2573total_time);2574++result_idx;2575} else {2576strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "2577"to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "2578"{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",2579send_size, recv_size, packet_count, k_recv_amount_mb,2580duration<float>(total_time), mb_second,2581packets_per_second, duration<float>(average_per_packet));2582}2583strm.Flush();2584}2585}2586if (json)2587strm.Printf("\n ]\n }\n}\n");2588else2589strm.EOL();2590}2591}25922593bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,2594uint32_t recv_size) {2595StreamString packet;2596packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);2597uint32_t bytes_left = send_size;2598while (bytes_left > 0) {2599if (bytes_left >= 26) {2600packet.PutCString("abcdefghijklmnopqrstuvwxyz");2601bytes_left -= 26;2602} else {2603packet.Printf("%*.*s;", bytes_left, bytes_left,2604"abcdefghijklmnopqrstuvwxyz");2605bytes_left = 0;2606}2607}26082609StringExtractorGDBRemote response;2610return SendPacketAndWaitForResponse(packet.GetString(), response) ==2611PacketResult::Success;2612}26132614bool GDBRemoteCommunicationClient::LaunchGDBServer(2615const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,2616std::string &socket_name) {2617pid = LLDB_INVALID_PROCESS_ID;2618port = 0;2619socket_name.clear();26202621StringExtractorGDBRemote response;2622StreamString stream;2623stream.PutCString("qLaunchGDBServer;");2624std::string hostname;2625if (remote_accept_hostname && remote_accept_hostname[0])2626hostname = remote_accept_hostname;2627else {2628if (HostInfo::GetHostname(hostname)) {2629// Make the GDB server we launch only accept connections from this host2630stream.Printf("host:%s;", hostname.c_str());2631} else {2632// Make the GDB server we launch accept connections from any host since2633// we can't figure out the hostname2634stream.Printf("host:*;");2635}2636}2637// give the process a few seconds to startup2638ScopedTimeout timeout(*this, seconds(10));26392640if (SendPacketAndWaitForResponse(stream.GetString(), response) ==2641PacketResult::Success) {2642if (response.IsErrorResponse())2643return false;26442645llvm::StringRef name;2646llvm::StringRef value;2647while (response.GetNameColonValue(name, value)) {2648if (name == "port")2649value.getAsInteger(0, port);2650else if (name == "pid")2651value.getAsInteger(0, pid);2652else if (name.compare("socket_name") == 0) {2653StringExtractor extractor(value);2654extractor.GetHexByteString(socket_name);2655}2656}2657return true;2658}2659return false;2660}26612662size_t GDBRemoteCommunicationClient::QueryGDBServer(2663std::vector<std::pair<uint16_t, std::string>> &connection_urls) {2664connection_urls.clear();26652666StringExtractorGDBRemote response;2667if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=2668PacketResult::Success)2669return 0;26702671StructuredData::ObjectSP data =2672StructuredData::ParseJSON(response.GetStringRef());2673if (!data)2674return 0;26752676StructuredData::Array *array = data->GetAsArray();2677if (!array)2678return 0;26792680for (size_t i = 0, count = array->GetSize(); i < count; ++i) {2681std::optional<StructuredData::Dictionary *> maybe_element =2682array->GetItemAtIndexAsDictionary(i);2683if (!maybe_element)2684continue;26852686StructuredData::Dictionary *element = *maybe_element;2687uint16_t port = 0;2688if (StructuredData::ObjectSP port_osp =2689element->GetValueForKey(llvm::StringRef("port")))2690port = port_osp->GetUnsignedIntegerValue(0);26912692std::string socket_name;2693if (StructuredData::ObjectSP socket_name_osp =2694element->GetValueForKey(llvm::StringRef("socket_name")))2695socket_name = std::string(socket_name_osp->GetStringValue());26962697if (port != 0 || !socket_name.empty())2698connection_urls.emplace_back(port, socket_name);2699}2700return connection_urls.size();2701}27022703bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {2704StreamString stream;2705stream.Printf("qKillSpawnedProcess:%" PRId64, pid);27062707StringExtractorGDBRemote response;2708if (SendPacketAndWaitForResponse(stream.GetString(), response) ==2709PacketResult::Success) {2710if (response.IsOKResponse())2711return true;2712}2713return false;2714}27152716std::optional<PidTid> GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(2717uint64_t tid, uint64_t pid, char op) {2718lldb_private::StreamString packet;2719packet.PutChar('H');2720packet.PutChar(op);27212722if (pid != LLDB_INVALID_PROCESS_ID)2723packet.Printf("p%" PRIx64 ".", pid);27242725if (tid == UINT64_MAX)2726packet.PutCString("-1");2727else2728packet.Printf("%" PRIx64, tid);27292730StringExtractorGDBRemote response;2731if (SendPacketAndWaitForResponse(packet.GetString(), response) ==2732PacketResult::Success) {2733if (response.IsOKResponse())2734return {{pid, tid}};27352736/*2737* Connected bare-iron target (like YAMON gdb-stub) may not have support for2738* Hg packet.2739* The reply from '?' packet could be as simple as 'S05'. There is no packet2740* which can2741* give us pid and/or tid. Assume pid=tid=1 in such cases.2742*/2743if (response.IsUnsupportedResponse() && IsConnected())2744return {{1, 1}};2745}2746return std::nullopt;2747}27482749bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,2750uint64_t pid) {2751if (m_curr_tid == tid &&2752(m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))2753return true;27542755std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');2756if (ret) {2757if (ret->pid != LLDB_INVALID_PROCESS_ID)2758m_curr_pid = ret->pid;2759m_curr_tid = ret->tid;2760}2761return ret.has_value();2762}27632764bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,2765uint64_t pid) {2766if (m_curr_tid_run == tid &&2767(m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))2768return true;27692770std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');2771if (ret) {2772if (ret->pid != LLDB_INVALID_PROCESS_ID)2773m_curr_pid_run = ret->pid;2774m_curr_tid_run = ret->tid;2775}2776return ret.has_value();2777}27782779bool GDBRemoteCommunicationClient::GetStopReply(2780StringExtractorGDBRemote &response) {2781if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success)2782return response.IsNormalResponse();2783return false;2784}27852786bool GDBRemoteCommunicationClient::GetThreadStopInfo(2787lldb::tid_t tid, StringExtractorGDBRemote &response) {2788if (m_supports_qThreadStopInfo) {2789char packet[256];2790int packet_len =2791::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);2792assert(packet_len < (int)sizeof(packet));2793UNUSED_IF_ASSERT_DISABLED(packet_len);2794if (SendPacketAndWaitForResponse(packet, response) ==2795PacketResult::Success) {2796if (response.IsUnsupportedResponse())2797m_supports_qThreadStopInfo = false;2798else if (response.IsNormalResponse())2799return true;2800else2801return false;2802} else {2803m_supports_qThreadStopInfo = false;2804}2805}2806return false;2807}28082809uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(2810GDBStoppointType type, bool insert, addr_t addr, uint32_t length,2811std::chrono::seconds timeout) {2812Log *log = GetLog(LLDBLog::Breakpoints);2813LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,2814__FUNCTION__, insert ? "add" : "remove", addr);28152816// Check if the stub is known not to support this breakpoint type2817if (!SupportsGDBStoppointPacket(type))2818return UINT8_MAX;2819// Construct the breakpoint packet2820char packet[64];2821const int packet_len =2822::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",2823insert ? 'Z' : 'z', type, addr, length);2824// Check we haven't overwritten the end of the packet buffer2825assert(packet_len + 1 < (int)sizeof(packet));2826UNUSED_IF_ASSERT_DISABLED(packet_len);2827StringExtractorGDBRemote response;2828// Make sure the response is either "OK", "EXX" where XX are two hex digits,2829// or "" (unsupported)2830response.SetResponseValidatorToOKErrorNotSupported();2831// Try to send the breakpoint packet, and check that it was correctly sent2832if (SendPacketAndWaitForResponse(packet, response, timeout) ==2833PacketResult::Success) {2834// Receive and OK packet when the breakpoint successfully placed2835if (response.IsOKResponse())2836return 0;28372838// Status while setting breakpoint, send back specific error2839if (response.IsErrorResponse())2840return response.GetError();28412842// Empty packet informs us that breakpoint is not supported2843if (response.IsUnsupportedResponse()) {2844// Disable this breakpoint type since it is unsupported2845switch (type) {2846case eBreakpointSoftware:2847m_supports_z0 = false;2848break;2849case eBreakpointHardware:2850m_supports_z1 = false;2851break;2852case eWatchpointWrite:2853m_supports_z2 = false;2854break;2855case eWatchpointRead:2856m_supports_z3 = false;2857break;2858case eWatchpointReadWrite:2859m_supports_z4 = false;2860break;2861case eStoppointInvalid:2862return UINT8_MAX;2863}2864}2865}2866// Signal generic failure2867return UINT8_MAX;2868}28692870std::vector<std::pair<lldb::pid_t, lldb::tid_t>>2871GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(2872bool &sequence_mutex_unavailable) {2873std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;28742875Lock lock(*this);2876if (lock) {2877sequence_mutex_unavailable = false;2878StringExtractorGDBRemote response;28792880PacketResult packet_result;2881for (packet_result =2882SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);2883packet_result == PacketResult::Success && response.IsNormalResponse();2884packet_result =2885SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {2886char ch = response.GetChar();2887if (ch == 'l')2888break;2889if (ch == 'm') {2890do {2891auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);2892// If we get an invalid response, break out of the loop.2893// If there are valid tids, they have been added to ids.2894// If there are no valid tids, we'll fall through to the2895// bare-iron target handling below.2896if (!pid_tid)2897break;28982899ids.push_back(*pid_tid);2900ch = response.GetChar(); // Skip the command separator2901} while (ch == ','); // Make sure we got a comma separator2902}2903}29042905/*2906* Connected bare-iron target (like YAMON gdb-stub) may not have support for2907* qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet2908* could2909* be as simple as 'S05'. There is no packet which can give us pid and/or2910* tid.2911* Assume pid=tid=1 in such cases.2912*/2913if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&2914ids.size() == 0 && IsConnected()) {2915ids.emplace_back(1, 1);2916}2917} else {2918Log *log(GetLog(GDBRLog::Process | GDBRLog::Packets));2919LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending "2920"packet 'qfThreadInfo'");2921sequence_mutex_unavailable = true;2922}29232924return ids;2925}29262927size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(2928std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {2929lldb::pid_t pid = GetCurrentProcessID();2930thread_ids.clear();29312932auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);2933if (ids.empty() || sequence_mutex_unavailable)2934return 0;29352936for (auto id : ids) {2937// skip threads that do not belong to the current process2938if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)2939continue;2940if (id.second != LLDB_INVALID_THREAD_ID &&2941id.second != StringExtractorGDBRemote::AllThreads)2942thread_ids.push_back(id.second);2943}29442945return thread_ids.size();2946}29472948lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {2949StringExtractorGDBRemote response;2950if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=2951PacketResult::Success ||2952!response.IsNormalResponse())2953return LLDB_INVALID_ADDRESS;2954return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);2955}29562957lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(2958llvm::StringRef command,2959const FileSpec &2960working_dir, // Pass empty FileSpec to use the current working directory2961int *status_ptr, // Pass NULL if you don't want the process exit status2962int *signo_ptr, // Pass NULL if you don't want the signal that caused the2963// process to exit2964std::string2965*command_output, // Pass NULL if you don't want the command output2966const Timeout<std::micro> &timeout) {2967lldb_private::StreamString stream;2968stream.PutCString("qPlatform_shell:");2969stream.PutBytesAsRawHex8(command.data(), command.size());2970stream.PutChar(',');2971uint32_t timeout_sec = UINT32_MAX;2972if (timeout) {2973// TODO: Use chrono version of std::ceil once c++17 is available.2974timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());2975}2976stream.PutHex32(timeout_sec);2977if (working_dir) {2978std::string path{working_dir.GetPath(false)};2979stream.PutChar(',');2980stream.PutStringAsRawHex8(path);2981}2982StringExtractorGDBRemote response;2983if (SendPacketAndWaitForResponse(stream.GetString(), response) ==2984PacketResult::Success) {2985if (response.GetChar() != 'F')2986return Status("malformed reply");2987if (response.GetChar() != ',')2988return Status("malformed reply");2989uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);2990if (exitcode == UINT32_MAX)2991return Status("unable to run remote process");2992else if (status_ptr)2993*status_ptr = exitcode;2994if (response.GetChar() != ',')2995return Status("malformed reply");2996uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);2997if (signo_ptr)2998*signo_ptr = signo;2999if (response.GetChar() != ',')3000return Status("malformed reply");3001std::string output;3002response.GetEscapedBinaryData(output);3003if (command_output)3004command_output->assign(output);3005return Status();3006}3007return Status("unable to send packet");3008}30093010Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,3011uint32_t file_permissions) {3012std::string path{file_spec.GetPath(false)};3013lldb_private::StreamString stream;3014stream.PutCString("qPlatform_mkdir:");3015stream.PutHex32(file_permissions);3016stream.PutChar(',');3017stream.PutStringAsRawHex8(path);3018llvm::StringRef packet = stream.GetString();3019StringExtractorGDBRemote response;30203021if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)3022return Status("failed to send '%s' packet", packet.str().c_str());30233024if (response.GetChar() != 'F')3025return Status("invalid response to '%s' packet", packet.str().c_str());30263027return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);3028}30293030Status3031GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,3032uint32_t file_permissions) {3033std::string path{file_spec.GetPath(false)};3034lldb_private::StreamString stream;3035stream.PutCString("qPlatform_chmod:");3036stream.PutHex32(file_permissions);3037stream.PutChar(',');3038stream.PutStringAsRawHex8(path);3039llvm::StringRef packet = stream.GetString();3040StringExtractorGDBRemote response;30413042if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)3043return Status("failed to send '%s' packet", stream.GetData());30443045if (response.GetChar() != 'F')3046return Status("invalid response to '%s' packet", stream.GetData());30473048return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);3049}30503051static int gdb_errno_to_system(int err) {3052switch (err) {3053#define HANDLE_ERRNO(name, value) \3054case GDB_##name: \3055return name;3056#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"3057default:3058return -1;3059}3060}30613062static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,3063uint64_t fail_result, Status &error) {3064response.SetFilePos(0);3065if (response.GetChar() != 'F')3066return fail_result;3067int32_t result = response.GetS32(-2, 16);3068if (result == -2)3069return fail_result;3070if (response.GetChar() == ',') {3071int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));3072if (result_errno != -1)3073error.SetError(result_errno, eErrorTypePOSIX);3074else3075error.SetError(-1, eErrorTypeGeneric);3076} else3077error.Clear();3078return result;3079}3080lldb::user_id_t3081GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,3082File::OpenOptions flags, mode_t mode,3083Status &error) {3084std::string path(file_spec.GetPath(false));3085lldb_private::StreamString stream;3086stream.PutCString("vFile:open:");3087if (path.empty())3088return UINT64_MAX;3089stream.PutStringAsRawHex8(path);3090stream.PutChar(',');3091stream.PutHex32(flags);3092stream.PutChar(',');3093stream.PutHex32(mode);3094StringExtractorGDBRemote response;3095if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3096PacketResult::Success) {3097return ParseHostIOPacketResponse(response, UINT64_MAX, error);3098}3099return UINT64_MAX;3100}31013102bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,3103Status &error) {3104lldb_private::StreamString stream;3105stream.Printf("vFile:close:%x", (int)fd);3106StringExtractorGDBRemote response;3107if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3108PacketResult::Success) {3109return ParseHostIOPacketResponse(response, -1, error) == 0;3110}3111return false;3112}31133114std::optional<GDBRemoteFStatData>3115GDBRemoteCommunicationClient::FStat(lldb::user_id_t fd) {3116lldb_private::StreamString stream;3117stream.Printf("vFile:fstat:%" PRIx64, fd);3118StringExtractorGDBRemote response;3119if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3120PacketResult::Success) {3121if (response.GetChar() != 'F')3122return std::nullopt;3123int64_t size = response.GetS64(-1, 16);3124if (size > 0 && response.GetChar() == ';') {3125std::string buffer;3126if (response.GetEscapedBinaryData(buffer)) {3127GDBRemoteFStatData out;3128if (buffer.size() != sizeof(out))3129return std::nullopt;3130memcpy(&out, buffer.data(), sizeof(out));3131return out;3132}3133}3134}3135return std::nullopt;3136}31373138std::optional<GDBRemoteFStatData>3139GDBRemoteCommunicationClient::Stat(const lldb_private::FileSpec &file_spec) {3140Status error;3141lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error);3142if (fd == UINT64_MAX)3143return std::nullopt;3144std::optional<GDBRemoteFStatData> st = FStat(fd);3145CloseFile(fd, error);3146return st;3147}31483149// Extension of host I/O packets to get the file size.3150lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(3151const lldb_private::FileSpec &file_spec) {3152if (m_supports_vFileSize) {3153std::string path(file_spec.GetPath(false));3154lldb_private::StreamString stream;3155stream.PutCString("vFile:size:");3156stream.PutStringAsRawHex8(path);3157StringExtractorGDBRemote response;3158if (SendPacketAndWaitForResponse(stream.GetString(), response) !=3159PacketResult::Success)3160return UINT64_MAX;31613162if (!response.IsUnsupportedResponse()) {3163if (response.GetChar() != 'F')3164return UINT64_MAX;3165uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);3166return retcode;3167}3168m_supports_vFileSize = false;3169}31703171// Fallback to fstat.3172std::optional<GDBRemoteFStatData> st = Stat(file_spec);3173return st ? st->gdb_st_size : UINT64_MAX;3174}31753176void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(3177CompletionRequest &request, bool only_dir) {3178lldb_private::StreamString stream;3179stream.PutCString("qPathComplete:");3180stream.PutHex32(only_dir ? 1 : 0);3181stream.PutChar(',');3182stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix());3183StringExtractorGDBRemote response;3184if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3185PacketResult::Success) {3186StreamString strm;3187char ch = response.GetChar();3188if (ch != 'M')3189return;3190while (response.Peek()) {3191strm.Clear();3192while ((ch = response.GetHexU8(0, false)) != '\0')3193strm.PutChar(ch);3194request.AddCompletion(strm.GetString());3195if (response.GetChar() != ',')3196break;3197}3198}3199}32003201Status3202GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,3203uint32_t &file_permissions) {3204if (m_supports_vFileMode) {3205std::string path{file_spec.GetPath(false)};3206Status error;3207lldb_private::StreamString stream;3208stream.PutCString("vFile:mode:");3209stream.PutStringAsRawHex8(path);3210StringExtractorGDBRemote response;3211if (SendPacketAndWaitForResponse(stream.GetString(), response) !=3212PacketResult::Success) {3213error.SetErrorStringWithFormat("failed to send '%s' packet",3214stream.GetData());3215return error;3216}3217if (!response.IsUnsupportedResponse()) {3218if (response.GetChar() != 'F') {3219error.SetErrorStringWithFormat("invalid response to '%s' packet",3220stream.GetData());3221} else {3222const uint32_t mode = response.GetS32(-1, 16);3223if (static_cast<int32_t>(mode) == -1) {3224if (response.GetChar() == ',') {3225int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3226if (response_errno > 0)3227error.SetError(response_errno, lldb::eErrorTypePOSIX);3228else3229error.SetErrorToGenericError();3230} else3231error.SetErrorToGenericError();3232} else {3233file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);3234}3235}3236return error;3237} else { // response.IsUnsupportedResponse()3238m_supports_vFileMode = false;3239}3240}32413242// Fallback to fstat.3243if (std::optional<GDBRemoteFStatData> st = Stat(file_spec)) {3244file_permissions = st->gdb_st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);3245return Status();3246}3247return Status("fstat failed");3248}32493250uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,3251uint64_t offset, void *dst,3252uint64_t dst_len,3253Status &error) {3254lldb_private::StreamString stream;3255stream.Printf("vFile:pread:%x,%" PRIx64 ",%" PRIx64, (int)fd, dst_len,3256offset);3257StringExtractorGDBRemote response;3258if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3259PacketResult::Success) {3260if (response.GetChar() != 'F')3261return 0;3262int64_t retcode = response.GetS64(-1, 16);3263if (retcode == -1) {3264error.SetErrorToGenericError();3265if (response.GetChar() == ',') {3266int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3267if (response_errno > 0)3268error.SetError(response_errno, lldb::eErrorTypePOSIX);3269}3270return -1;3271}3272const char next = (response.Peek() ? *response.Peek() : 0);3273if (next == ',')3274return 0;3275if (next == ';') {3276response.GetChar(); // skip the semicolon3277std::string buffer;3278if (response.GetEscapedBinaryData(buffer)) {3279const uint64_t data_to_write =3280std::min<uint64_t>(dst_len, buffer.size());3281if (data_to_write > 0)3282memcpy(dst, &buffer[0], data_to_write);3283return data_to_write;3284}3285}3286}3287return 0;3288}32893290uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,3291uint64_t offset,3292const void *src,3293uint64_t src_len,3294Status &error) {3295lldb_private::StreamGDBRemote stream;3296stream.Printf("vFile:pwrite:%x,%" PRIx64 ",", (int)fd, offset);3297stream.PutEscapedBytes(src, src_len);3298StringExtractorGDBRemote response;3299if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3300PacketResult::Success) {3301if (response.GetChar() != 'F') {3302error.SetErrorStringWithFormat("write file failed");3303return 0;3304}3305int64_t bytes_written = response.GetS64(-1, 16);3306if (bytes_written == -1) {3307error.SetErrorToGenericError();3308if (response.GetChar() == ',') {3309int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3310if (response_errno > 0)3311error.SetError(response_errno, lldb::eErrorTypePOSIX);3312}3313return -1;3314}3315return bytes_written;3316} else {3317error.SetErrorString("failed to send vFile:pwrite packet");3318}3319return 0;3320}33213322Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,3323const FileSpec &dst) {3324std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};3325Status error;3326lldb_private::StreamGDBRemote stream;3327stream.PutCString("vFile:symlink:");3328// the unix symlink() command reverses its parameters where the dst if first,3329// so we follow suit here3330stream.PutStringAsRawHex8(dst_path);3331stream.PutChar(',');3332stream.PutStringAsRawHex8(src_path);3333StringExtractorGDBRemote response;3334if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3335PacketResult::Success) {3336if (response.GetChar() == 'F') {3337uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);3338if (result != 0) {3339error.SetErrorToGenericError();3340if (response.GetChar() == ',') {3341int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3342if (response_errno > 0)3343error.SetError(response_errno, lldb::eErrorTypePOSIX);3344}3345}3346} else {3347// Should have returned with 'F<result>[,<errno>]'3348error.SetErrorStringWithFormat("symlink failed");3349}3350} else {3351error.SetErrorString("failed to send vFile:symlink packet");3352}3353return error;3354}33553356Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {3357std::string path{file_spec.GetPath(false)};3358Status error;3359lldb_private::StreamGDBRemote stream;3360stream.PutCString("vFile:unlink:");3361// the unix symlink() command reverses its parameters where the dst if first,3362// so we follow suit here3363stream.PutStringAsRawHex8(path);3364StringExtractorGDBRemote response;3365if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3366PacketResult::Success) {3367if (response.GetChar() == 'F') {3368uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);3369if (result != 0) {3370error.SetErrorToGenericError();3371if (response.GetChar() == ',') {3372int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3373if (response_errno > 0)3374error.SetError(response_errno, lldb::eErrorTypePOSIX);3375}3376}3377} else {3378// Should have returned with 'F<result>[,<errno>]'3379error.SetErrorStringWithFormat("unlink failed");3380}3381} else {3382error.SetErrorString("failed to send vFile:unlink packet");3383}3384return error;3385}33863387// Extension of host I/O packets to get whether a file exists.3388bool GDBRemoteCommunicationClient::GetFileExists(3389const lldb_private::FileSpec &file_spec) {3390if (m_supports_vFileExists) {3391std::string path(file_spec.GetPath(false));3392lldb_private::StreamString stream;3393stream.PutCString("vFile:exists:");3394stream.PutStringAsRawHex8(path);3395StringExtractorGDBRemote response;3396if (SendPacketAndWaitForResponse(stream.GetString(), response) !=3397PacketResult::Success)3398return false;3399if (!response.IsUnsupportedResponse()) {3400if (response.GetChar() != 'F')3401return false;3402if (response.GetChar() != ',')3403return false;3404bool retcode = (response.GetChar() != '0');3405return retcode;3406} else3407m_supports_vFileExists = false;3408}34093410// Fallback to open.3411Status error;3412lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error);3413if (fd == UINT64_MAX)3414return false;3415CloseFile(fd, error);3416return true;3417}34183419llvm::ErrorOr<llvm::MD5::MD5Result> GDBRemoteCommunicationClient::CalculateMD5(3420const lldb_private::FileSpec &file_spec) {3421std::string path(file_spec.GetPath(false));3422lldb_private::StreamString stream;3423stream.PutCString("vFile:MD5:");3424stream.PutStringAsRawHex8(path);3425StringExtractorGDBRemote response;3426if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3427PacketResult::Success) {3428if (response.GetChar() != 'F')3429return std::make_error_code(std::errc::illegal_byte_sequence);3430if (response.GetChar() != ',')3431return std::make_error_code(std::errc::illegal_byte_sequence);3432if (response.Peek() && *response.Peek() == 'x')3433return std::make_error_code(std::errc::no_such_file_or_directory);34343435// GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 concatenates low and3436// high hex strings. We can't use response.GetHexMaxU64 because that can't3437// handle the concatenated hex string. What would happen is parsing the low3438// would consume the whole response packet which would give incorrect3439// results. Instead, we get the byte string for each low and high hex3440// separately, and parse them.3441//3442// An alternate way to handle this is to change the server to put a3443// delimiter between the low/high parts, and change the client to parse the3444// delimiter. However, we choose not to do this so existing lldb-servers3445// don't have to be patched34463447// The checksum is 128 bits encoded as hex3448// This means low/high are halves of 64 bits each, in otherwords, 8 bytes.3449// Each byte takes 2 hex characters in the response.3450const size_t MD5_HALF_LENGTH = sizeof(uint64_t) * 2;34513452// Get low part3453auto part =3454response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);3455if (part.size() != MD5_HALF_LENGTH)3456return std::make_error_code(std::errc::illegal_byte_sequence);3457response.SetFilePos(response.GetFilePos() + part.size());34583459uint64_t low;3460if (part.getAsInteger(/*radix=*/16, low))3461return std::make_error_code(std::errc::illegal_byte_sequence);34623463// Get high part3464part =3465response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);3466if (part.size() != MD5_HALF_LENGTH)3467return std::make_error_code(std::errc::illegal_byte_sequence);3468response.SetFilePos(response.GetFilePos() + part.size());34693470uint64_t high;3471if (part.getAsInteger(/*radix=*/16, high))3472return std::make_error_code(std::errc::illegal_byte_sequence);34733474llvm::MD5::MD5Result result;3475llvm::support::endian::write<uint64_t, llvm::endianness::little>(3476result.data(), low);3477llvm::support::endian::write<uint64_t, llvm::endianness::little>(3478result.data() + 8, high);34793480return result;3481}3482return std::make_error_code(std::errc::operation_canceled);3483}34843485bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {3486// Some targets have issues with g/G packets and we need to avoid using them3487if (m_avoid_g_packets == eLazyBoolCalculate) {3488if (process) {3489m_avoid_g_packets = eLazyBoolNo;3490const ArchSpec &arch = process->GetTarget().GetArchitecture();3491if (arch.IsValid() &&3492arch.GetTriple().getVendor() == llvm::Triple::Apple &&3493arch.GetTriple().getOS() == llvm::Triple::IOS &&3494(arch.GetTriple().getArch() == llvm::Triple::aarch64 ||3495arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {3496m_avoid_g_packets = eLazyBoolYes;3497uint32_t gdb_server_version = GetGDBServerProgramVersion();3498if (gdb_server_version != 0) {3499const char *gdb_server_name = GetGDBServerProgramName();3500if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {3501if (gdb_server_version >= 310)3502m_avoid_g_packets = eLazyBoolNo;3503}3504}3505}3506}3507}3508return m_avoid_g_packets == eLazyBoolYes;3509}35103511DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,3512uint32_t reg) {3513StreamString payload;3514payload.Printf("p%x", reg);3515StringExtractorGDBRemote response;3516if (SendThreadSpecificPacketAndWaitForResponse(3517tid, std::move(payload), response) != PacketResult::Success ||3518!response.IsNormalResponse())3519return nullptr;35203521WritableDataBufferSP buffer_sp(3522new DataBufferHeap(response.GetStringRef().size() / 2, 0));3523response.GetHexBytes(buffer_sp->GetData(), '\xcc');3524return buffer_sp;3525}35263527DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {3528StreamString payload;3529payload.PutChar('g');3530StringExtractorGDBRemote response;3531if (SendThreadSpecificPacketAndWaitForResponse(3532tid, std::move(payload), response) != PacketResult::Success ||3533!response.IsNormalResponse())3534return nullptr;35353536WritableDataBufferSP buffer_sp(3537new DataBufferHeap(response.GetStringRef().size() / 2, 0));3538response.GetHexBytes(buffer_sp->GetData(), '\xcc');3539return buffer_sp;3540}35413542bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,3543uint32_t reg_num,3544llvm::ArrayRef<uint8_t> data) {3545StreamString payload;3546payload.Printf("P%x=", reg_num);3547payload.PutBytesAsRawHex8(data.data(), data.size(),3548endian::InlHostByteOrder(),3549endian::InlHostByteOrder());3550StringExtractorGDBRemote response;3551return SendThreadSpecificPacketAndWaitForResponse(3552tid, std::move(payload), response) == PacketResult::Success &&3553response.IsOKResponse();3554}35553556bool GDBRemoteCommunicationClient::WriteAllRegisters(3557lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {3558StreamString payload;3559payload.PutChar('G');3560payload.PutBytesAsRawHex8(data.data(), data.size(),3561endian::InlHostByteOrder(),3562endian::InlHostByteOrder());3563StringExtractorGDBRemote response;3564return SendThreadSpecificPacketAndWaitForResponse(3565tid, std::move(payload), response) == PacketResult::Success &&3566response.IsOKResponse();3567}35683569bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,3570uint32_t &save_id) {3571save_id = 0; // Set to invalid save ID3572if (m_supports_QSaveRegisterState == eLazyBoolNo)3573return false;35743575m_supports_QSaveRegisterState = eLazyBoolYes;3576StreamString payload;3577payload.PutCString("QSaveRegisterState");3578StringExtractorGDBRemote response;3579if (SendThreadSpecificPacketAndWaitForResponse(3580tid, std::move(payload), response) != PacketResult::Success)3581return false;35823583if (response.IsUnsupportedResponse())3584m_supports_QSaveRegisterState = eLazyBoolNo;35853586const uint32_t response_save_id = response.GetU32(0);3587if (response_save_id == 0)3588return false;35893590save_id = response_save_id;3591return true;3592}35933594bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,3595uint32_t save_id) {3596// We use the "m_supports_QSaveRegisterState" variable here because the3597// QSaveRegisterState and QRestoreRegisterState packets must both be3598// supported in order to be useful3599if (m_supports_QSaveRegisterState == eLazyBoolNo)3600return false;36013602StreamString payload;3603payload.Printf("QRestoreRegisterState:%u", save_id);3604StringExtractorGDBRemote response;3605if (SendThreadSpecificPacketAndWaitForResponse(3606tid, std::move(payload), response) != PacketResult::Success)3607return false;36083609if (response.IsOKResponse())3610return true;36113612if (response.IsUnsupportedResponse())3613m_supports_QSaveRegisterState = eLazyBoolNo;3614return false;3615}36163617bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {3618if (!GetSyncThreadStateSupported())3619return false;36203621StreamString packet;3622StringExtractorGDBRemote response;3623packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);3624return SendPacketAndWaitForResponse(packet.GetString(), response) ==3625GDBRemoteCommunication::PacketResult::Success &&3626response.IsOKResponse();3627}36283629llvm::Expected<TraceSupportedResponse>3630GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) {3631Log *log = GetLog(GDBRLog::Process);36323633StreamGDBRemote escaped_packet;3634escaped_packet.PutCString("jLLDBTraceSupported");36353636StringExtractorGDBRemote response;3637if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3638timeout) ==3639GDBRemoteCommunication::PacketResult::Success) {3640if (response.IsErrorResponse())3641return response.GetStatus().ToError();3642if (response.IsUnsupportedResponse())3643return llvm::createStringError(llvm::inconvertibleErrorCode(),3644"jLLDBTraceSupported is unsupported");36453646return llvm::json::parse<TraceSupportedResponse>(response.Peek(),3647"TraceSupportedResponse");3648}3649LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");3650return llvm::createStringError(llvm::inconvertibleErrorCode(),3651"failed to send packet: jLLDBTraceSupported");3652}36533654llvm::Error3655GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request,3656std::chrono::seconds timeout) {3657Log *log = GetLog(GDBRLog::Process);36583659StreamGDBRemote escaped_packet;3660escaped_packet.PutCString("jLLDBTraceStop:");36613662std::string json_string;3663llvm::raw_string_ostream os(json_string);3664os << toJSON(request);3665os.flush();36663667escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());36683669StringExtractorGDBRemote response;3670if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3671timeout) ==3672GDBRemoteCommunication::PacketResult::Success) {3673if (response.IsErrorResponse())3674return response.GetStatus().ToError();3675if (response.IsUnsupportedResponse())3676return llvm::createStringError(llvm::inconvertibleErrorCode(),3677"jLLDBTraceStop is unsupported");3678if (response.IsOKResponse())3679return llvm::Error::success();3680return llvm::createStringError(llvm::inconvertibleErrorCode(),3681"Invalid jLLDBTraceStart response");3682}3683LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");3684return llvm::createStringError(llvm::inconvertibleErrorCode(),3685"failed to send packet: jLLDBTraceStop '%s'",3686escaped_packet.GetData());3687}36883689llvm::Error3690GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value ¶ms,3691std::chrono::seconds timeout) {3692Log *log = GetLog(GDBRLog::Process);36933694StreamGDBRemote escaped_packet;3695escaped_packet.PutCString("jLLDBTraceStart:");36963697std::string json_string;3698llvm::raw_string_ostream os(json_string);3699os << params;3700os.flush();37013702escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());37033704StringExtractorGDBRemote response;3705if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3706timeout) ==3707GDBRemoteCommunication::PacketResult::Success) {3708if (response.IsErrorResponse())3709return response.GetStatus().ToError();3710if (response.IsUnsupportedResponse())3711return llvm::createStringError(llvm::inconvertibleErrorCode(),3712"jLLDBTraceStart is unsupported");3713if (response.IsOKResponse())3714return llvm::Error::success();3715return llvm::createStringError(llvm::inconvertibleErrorCode(),3716"Invalid jLLDBTraceStart response");3717}3718LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");3719return llvm::createStringError(llvm::inconvertibleErrorCode(),3720"failed to send packet: jLLDBTraceStart '%s'",3721escaped_packet.GetData());3722}37233724llvm::Expected<std::string>3725GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type,3726std::chrono::seconds timeout) {3727Log *log = GetLog(GDBRLog::Process);37283729StreamGDBRemote escaped_packet;3730escaped_packet.PutCString("jLLDBTraceGetState:");37313732std::string json_string;3733llvm::raw_string_ostream os(json_string);3734os << toJSON(TraceGetStateRequest{type.str()});3735os.flush();37363737escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());37383739StringExtractorGDBRemote response;3740if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3741timeout) ==3742GDBRemoteCommunication::PacketResult::Success) {3743if (response.IsErrorResponse())3744return response.GetStatus().ToError();3745if (response.IsUnsupportedResponse())3746return llvm::createStringError(llvm::inconvertibleErrorCode(),3747"jLLDBTraceGetState is unsupported");3748return std::string(response.Peek());3749}37503751LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");3752return llvm::createStringError(3753llvm::inconvertibleErrorCode(),3754"failed to send packet: jLLDBTraceGetState '%s'",3755escaped_packet.GetData());3756}37573758llvm::Expected<std::vector<uint8_t>>3759GDBRemoteCommunicationClient::SendTraceGetBinaryData(3760const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {3761Log *log = GetLog(GDBRLog::Process);37623763StreamGDBRemote escaped_packet;3764escaped_packet.PutCString("jLLDBTraceGetBinaryData:");37653766std::string json_string;3767llvm::raw_string_ostream os(json_string);3768os << toJSON(request);3769os.flush();37703771escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());37723773StringExtractorGDBRemote response;3774if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3775timeout) ==3776GDBRemoteCommunication::PacketResult::Success) {3777if (response.IsErrorResponse())3778return response.GetStatus().ToError();3779std::string data;3780response.GetEscapedBinaryData(data);3781return std::vector<uint8_t>(data.begin(), data.end());3782}3783LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");3784return llvm::createStringError(3785llvm::inconvertibleErrorCode(),3786"failed to send packet: jLLDBTraceGetBinaryData '%s'",3787escaped_packet.GetData());3788}37893790std::optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {3791StringExtractorGDBRemote response;3792if (SendPacketAndWaitForResponse("qOffsets", response) !=3793PacketResult::Success)3794return std::nullopt;3795if (!response.IsNormalResponse())3796return std::nullopt;37973798QOffsets result;3799llvm::StringRef ref = response.GetStringRef();3800const auto &GetOffset = [&] {3801addr_t offset;3802if (ref.consumeInteger(16, offset))3803return false;3804result.offsets.push_back(offset);3805return true;3806};38073808if (ref.consume_front("Text=")) {3809result.segments = false;3810if (!GetOffset())3811return std::nullopt;3812if (!ref.consume_front(";Data=") || !GetOffset())3813return std::nullopt;3814if (ref.empty())3815return result;3816if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())3817return result;3818} else if (ref.consume_front("TextSeg=")) {3819result.segments = true;3820if (!GetOffset())3821return std::nullopt;3822if (ref.empty())3823return result;3824if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())3825return result;3826}3827return std::nullopt;3828}38293830bool GDBRemoteCommunicationClient::GetModuleInfo(3831const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,3832ModuleSpec &module_spec) {3833if (!m_supports_qModuleInfo)3834return false;38353836std::string module_path = module_file_spec.GetPath(false);3837if (module_path.empty())3838return false;38393840StreamString packet;3841packet.PutCString("qModuleInfo:");3842packet.PutStringAsRawHex8(module_path);3843packet.PutCString(";");3844const auto &triple = arch_spec.GetTriple().getTriple();3845packet.PutStringAsRawHex8(triple);38463847StringExtractorGDBRemote response;3848if (SendPacketAndWaitForResponse(packet.GetString(), response) !=3849PacketResult::Success)3850return false;38513852if (response.IsErrorResponse())3853return false;38543855if (response.IsUnsupportedResponse()) {3856m_supports_qModuleInfo = false;3857return false;3858}38593860llvm::StringRef name;3861llvm::StringRef value;38623863module_spec.Clear();3864module_spec.GetFileSpec() = module_file_spec;38653866while (response.GetNameColonValue(name, value)) {3867if (name == "uuid" || name == "md5") {3868StringExtractor extractor(value);3869std::string uuid;3870extractor.GetHexByteString(uuid);3871module_spec.GetUUID().SetFromStringRef(uuid);3872} else if (name == "triple") {3873StringExtractor extractor(value);3874std::string triple;3875extractor.GetHexByteString(triple);3876module_spec.GetArchitecture().SetTriple(triple.c_str());3877} else if (name == "file_offset") {3878uint64_t ival = 0;3879if (!value.getAsInteger(16, ival))3880module_spec.SetObjectOffset(ival);3881} else if (name == "file_size") {3882uint64_t ival = 0;3883if (!value.getAsInteger(16, ival))3884module_spec.SetObjectSize(ival);3885} else if (name == "file_path") {3886StringExtractor extractor(value);3887std::string path;3888extractor.GetHexByteString(path);3889module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());3890}3891}38923893return true;3894}38953896static std::optional<ModuleSpec>3897ParseModuleSpec(StructuredData::Dictionary *dict) {3898ModuleSpec result;3899if (!dict)3900return std::nullopt;39013902llvm::StringRef string;3903uint64_t integer;39043905if (!dict->GetValueForKeyAsString("uuid", string))3906return std::nullopt;3907if (!result.GetUUID().SetFromStringRef(string))3908return std::nullopt;39093910if (!dict->GetValueForKeyAsInteger("file_offset", integer))3911return std::nullopt;3912result.SetObjectOffset(integer);39133914if (!dict->GetValueForKeyAsInteger("file_size", integer))3915return std::nullopt;3916result.SetObjectSize(integer);39173918if (!dict->GetValueForKeyAsString("triple", string))3919return std::nullopt;3920result.GetArchitecture().SetTriple(string);39213922if (!dict->GetValueForKeyAsString("file_path", string))3923return std::nullopt;3924result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());39253926return result;3927}39283929std::optional<std::vector<ModuleSpec>>3930GDBRemoteCommunicationClient::GetModulesInfo(3931llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {3932namespace json = llvm::json;39333934if (!m_supports_jModulesInfo)3935return std::nullopt;39363937json::Array module_array;3938for (const FileSpec &module_file_spec : module_file_specs) {3939module_array.push_back(3940json::Object{{"file", module_file_spec.GetPath(false)},3941{"triple", triple.getTriple()}});3942}3943StreamString unescaped_payload;3944unescaped_payload.PutCString("jModulesInfo:");3945unescaped_payload.AsRawOstream() << std::move(module_array);39463947StreamGDBRemote payload;3948payload.PutEscapedBytes(unescaped_payload.GetString().data(),3949unescaped_payload.GetSize());39503951// Increase the timeout for jModulesInfo since this packet can take longer.3952ScopedTimeout timeout(*this, std::chrono::seconds(10));39533954StringExtractorGDBRemote response;3955if (SendPacketAndWaitForResponse(payload.GetString(), response) !=3956PacketResult::Success ||3957response.IsErrorResponse())3958return std::nullopt;39593960if (response.IsUnsupportedResponse()) {3961m_supports_jModulesInfo = false;3962return std::nullopt;3963}39643965StructuredData::ObjectSP response_object_sp =3966StructuredData::ParseJSON(response.GetStringRef());3967if (!response_object_sp)3968return std::nullopt;39693970StructuredData::Array *response_array = response_object_sp->GetAsArray();3971if (!response_array)3972return std::nullopt;39733974std::vector<ModuleSpec> result;3975for (size_t i = 0; i < response_array->GetSize(); ++i) {3976if (std::optional<ModuleSpec> module_spec = ParseModuleSpec(3977response_array->GetItemAtIndex(i)->GetAsDictionary()))3978result.push_back(*module_spec);3979}39803981return result;3982}39833984// query the target remote for extended information using the qXfer packet3985//3986// example: object='features', annex='target.xml'3987// return: <xml output> or error3988llvm::Expected<std::string>3989GDBRemoteCommunicationClient::ReadExtFeature(llvm::StringRef object,3990llvm::StringRef annex) {39913992std::string output;3993llvm::raw_string_ostream output_stream(output);3994StringExtractorGDBRemote chunk;39953996uint64_t size = GetRemoteMaxPacketSize();3997if (size == 0)3998size = 0x1000;3999size = size - 1; // Leave space for the 'm' or 'l' character in the response4000int offset = 0;4001bool active = true;40024003// loop until all data has been read4004while (active) {40054006// send query extended feature packet4007std::string packet =4008("qXfer:" + object + ":read:" + annex + ":" +4009llvm::Twine::utohexstr(offset) + "," + llvm::Twine::utohexstr(size))4010.str();40114012GDBRemoteCommunication::PacketResult res =4013SendPacketAndWaitForResponse(packet, chunk);40144015if (res != GDBRemoteCommunication::PacketResult::Success ||4016chunk.GetStringRef().empty()) {4017return llvm::createStringError(llvm::inconvertibleErrorCode(),4018"Error sending $qXfer packet");4019}40204021// check packet code4022switch (chunk.GetStringRef()[0]) {4023// last chunk4024case ('l'):4025active = false;4026[[fallthrough]];40274028// more chunks4029case ('m'):4030output_stream << chunk.GetStringRef().drop_front();4031offset += chunk.GetStringRef().size() - 1;4032break;40334034// unknown chunk4035default:4036return llvm::createStringError(4037llvm::inconvertibleErrorCode(),4038"Invalid continuation code from $qXfer packet");4039}4040}40414042return output_stream.str();4043}40444045// Notify the target that gdb is prepared to serve symbol lookup requests.4046// packet: "qSymbol::"4047// reply:4048// OK The target does not need to look up any (more) symbols.4049// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex4050// encoded).4051// LLDB may provide the value by sending another qSymbol4052// packet4053// in the form of"qSymbol:<sym_value>:<sym_name>".4054//4055// Three examples:4056//4057// lldb sends: qSymbol::4058// lldb receives: OK4059// Remote gdb stub does not need to know the addresses of any symbols, lldb4060// does not4061// need to ask again in this session.4062//4063// lldb sends: qSymbol::4064// lldb receives: qSymbol:64697370617463685f71756575655f6f6666736574734065// lldb sends: qSymbol::64697370617463685f71756575655f6f6666736574734066// lldb receives: OK4067// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does4068// not know4069// the address at this time. lldb needs to send qSymbol:: again when it has4070// more4071// solibs loaded.4072//4073// lldb sends: qSymbol::4074// lldb receives: qSymbol:64697370617463685f71756575655f6f6666736574734075// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f6666736574734076// lldb receives: OK4077// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says4078// that it4079// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it4080// does not4081// need any more symbols. lldb does not need to ask again in this session.40824083void GDBRemoteCommunicationClient::ServeSymbolLookups(4084lldb_private::Process *process) {4085// Set to true once we've resolved a symbol to an address for the remote4086// stub. If we get an 'OK' response after this, the remote stub doesn't need4087// any more symbols and we can stop asking.4088bool symbol_response_provided = false;40894090// Is this the initial qSymbol:: packet?4091bool first_qsymbol_query = true;40924093if (m_supports_qSymbol && !m_qSymbol_requests_done) {4094Lock lock(*this);4095if (lock) {4096StreamString packet;4097packet.PutCString("qSymbol::");4098StringExtractorGDBRemote response;4099while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==4100PacketResult::Success) {4101if (response.IsOKResponse()) {4102if (symbol_response_provided || first_qsymbol_query) {4103m_qSymbol_requests_done = true;4104}41054106// We are done serving symbols requests4107return;4108}4109first_qsymbol_query = false;41104111if (response.IsUnsupportedResponse()) {4112// qSymbol is not supported by the current GDB server we are4113// connected to4114m_supports_qSymbol = false;4115return;4116} else {4117llvm::StringRef response_str(response.GetStringRef());4118if (response_str.starts_with("qSymbol:")) {4119response.SetFilePos(strlen("qSymbol:"));4120std::string symbol_name;4121if (response.GetHexByteString(symbol_name)) {4122if (symbol_name.empty())4123return;41244125addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;4126lldb_private::SymbolContextList sc_list;4127process->GetTarget().GetImages().FindSymbolsWithNameAndType(4128ConstString(symbol_name), eSymbolTypeAny, sc_list);4129for (const SymbolContext &sc : sc_list) {4130if (symbol_load_addr != LLDB_INVALID_ADDRESS)4131break;4132if (sc.symbol) {4133switch (sc.symbol->GetType()) {4134case eSymbolTypeInvalid:4135case eSymbolTypeAbsolute:4136case eSymbolTypeUndefined:4137case eSymbolTypeSourceFile:4138case eSymbolTypeHeaderFile:4139case eSymbolTypeObjectFile:4140case eSymbolTypeCommonBlock:4141case eSymbolTypeBlock:4142case eSymbolTypeLocal:4143case eSymbolTypeParam:4144case eSymbolTypeVariable:4145case eSymbolTypeVariableType:4146case eSymbolTypeLineEntry:4147case eSymbolTypeLineHeader:4148case eSymbolTypeScopeBegin:4149case eSymbolTypeScopeEnd:4150case eSymbolTypeAdditional:4151case eSymbolTypeCompiler:4152case eSymbolTypeInstrumentation:4153case eSymbolTypeTrampoline:4154break;41554156case eSymbolTypeCode:4157case eSymbolTypeResolver:4158case eSymbolTypeData:4159case eSymbolTypeRuntime:4160case eSymbolTypeException:4161case eSymbolTypeObjCClass:4162case eSymbolTypeObjCMetaClass:4163case eSymbolTypeObjCIVar:4164case eSymbolTypeReExported:4165symbol_load_addr =4166sc.symbol->GetLoadAddress(&process->GetTarget());4167break;4168}4169}4170}4171// This is the normal path where our symbol lookup was successful4172// and we want to send a packet with the new symbol value and see4173// if another lookup needs to be done.41744175// Change "packet" to contain the requested symbol value and name4176packet.Clear();4177packet.PutCString("qSymbol:");4178if (symbol_load_addr != LLDB_INVALID_ADDRESS) {4179packet.Printf("%" PRIx64, symbol_load_addr);4180symbol_response_provided = true;4181} else {4182symbol_response_provided = false;4183}4184packet.PutCString(":");4185packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());4186continue; // go back to the while loop and send "packet" and wait4187// for another response4188}4189}4190}4191}4192// If we make it here, the symbol request packet response wasn't valid or4193// our symbol lookup failed so we must abort4194return;41954196} else if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets)) {4197LLDB_LOGF(log,4198"GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",4199__FUNCTION__);4200}4201}4202}42034204StructuredData::Array *4205GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {4206if (!m_supported_async_json_packets_is_valid) {4207// Query the server for the array of supported asynchronous JSON packets.4208m_supported_async_json_packets_is_valid = true;42094210Log *log = GetLog(GDBRLog::Process);42114212// Poll it now.4213StringExtractorGDBRemote response;4214if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==4215PacketResult::Success) {4216m_supported_async_json_packets_sp =4217StructuredData::ParseJSON(response.GetStringRef());4218if (m_supported_async_json_packets_sp &&4219!m_supported_async_json_packets_sp->GetAsArray()) {4220// We were returned something other than a JSON array. This is4221// invalid. Clear it out.4222LLDB_LOGF(log,4223"GDBRemoteCommunicationClient::%s(): "4224"QSupportedAsyncJSONPackets returned invalid "4225"result: %s",4226__FUNCTION__, response.GetStringRef().data());4227m_supported_async_json_packets_sp.reset();4228}4229} else {4230LLDB_LOGF(log,4231"GDBRemoteCommunicationClient::%s(): "4232"QSupportedAsyncJSONPackets unsupported",4233__FUNCTION__);4234}42354236if (log && m_supported_async_json_packets_sp) {4237StreamString stream;4238m_supported_async_json_packets_sp->Dump(stream);4239LLDB_LOGF(log,4240"GDBRemoteCommunicationClient::%s(): supported async "4241"JSON packets: %s",4242__FUNCTION__, stream.GetData());4243}4244}42454246return m_supported_async_json_packets_sp4247? m_supported_async_json_packets_sp->GetAsArray()4248: nullptr;4249}42504251Status GDBRemoteCommunicationClient::SendSignalsToIgnore(4252llvm::ArrayRef<int32_t> signals) {4253// Format packet:4254// QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>4255auto range = llvm::make_range(signals.begin(), signals.end());4256std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();42574258StringExtractorGDBRemote response;4259auto send_status = SendPacketAndWaitForResponse(packet, response);42604261if (send_status != GDBRemoteCommunication::PacketResult::Success)4262return Status("Sending QPassSignals packet failed");42634264if (response.IsOKResponse()) {4265return Status();4266} else {4267return Status("Unknown error happened during sending QPassSignals packet.");4268}4269}42704271Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(4272llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) {4273Status error;42744275if (type_name.empty()) {4276error.SetErrorString("invalid type_name argument");4277return error;4278}42794280// Build command: Configure{type_name}: serialized config data.4281StreamGDBRemote stream;4282stream.PutCString("QConfigure");4283stream.PutCString(type_name);4284stream.PutChar(':');4285if (config_sp) {4286// Gather the plain-text version of the configuration data.4287StreamString unescaped_stream;4288config_sp->Dump(unescaped_stream);4289unescaped_stream.Flush();42904291// Add it to the stream in escaped fashion.4292stream.PutEscapedBytes(unescaped_stream.GetString().data(),4293unescaped_stream.GetSize());4294}4295stream.Flush();42964297// Send the packet.4298StringExtractorGDBRemote response;4299auto result = SendPacketAndWaitForResponse(stream.GetString(), response);4300if (result == PacketResult::Success) {4301// We failed if the config result comes back other than OK.4302if (response.GetStringRef() == "OK") {4303// Okay!4304error.Clear();4305} else {4306error.SetErrorStringWithFormatv(4307"configuring StructuredData feature {0} failed with error {1}",4308type_name, response.GetStringRef());4309}4310} else {4311// Can we get more data here on the failure?4312error.SetErrorStringWithFormatv(4313"configuring StructuredData feature {0} failed when sending packet: "4314"PacketResult={1}",4315type_name, (int)result);4316}4317return error;4318}43194320void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {4321GDBRemoteClientBase::OnRunPacketSent(first);4322m_curr_tid = LLDB_INVALID_THREAD_ID;4323}43244325bool GDBRemoteCommunicationClient::UsesNativeSignals() {4326if (m_uses_native_signals == eLazyBoolCalculate)4327GetRemoteQSupported();4328if (m_uses_native_signals == eLazyBoolYes)4329return true;43304331// If the remote didn't indicate native-signal support explicitly,4332// check whether it is an old version of lldb-server.4333return GetThreadSuffixSupported();4334}43354336llvm::Expected<int> GDBRemoteCommunicationClient::KillProcess(lldb::pid_t pid) {4337StringExtractorGDBRemote response;4338GDBRemoteCommunication::ScopedTimeout(*this, seconds(3));43394340if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout()) !=4341PacketResult::Success)4342return llvm::createStringError(llvm::inconvertibleErrorCode(),4343"failed to send k packet");43444345char packet_cmd = response.GetChar(0);4346if (packet_cmd == 'W' || packet_cmd == 'X')4347return response.GetHexU8();43484349return llvm::createStringError(llvm::inconvertibleErrorCode(),4350"unexpected response to k packet: %s",4351response.GetStringRef().str().c_str());4352}435343544355