15ffd83dbSDimitry Andric //===-- GDBRemoteCommunicationServerCommon.cpp ----------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "GDBRemoteCommunicationServerCommon.h" 100b57cec5SDimitry Andric 11fe6060f1SDimitry Andric #include <cerrno> 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifdef __APPLE__ 140b57cec5SDimitry Andric #include <TargetConditionals.h> 150b57cec5SDimitry Andric #endif 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include <chrono> 180b57cec5SDimitry Andric #include <cstring> 19bdd1243dSDimitry Andric #include <optional> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h" 220b57cec5SDimitry Andric #include "lldb/Host/Config.h" 230b57cec5SDimitry Andric #include "lldb/Host/File.h" 240b57cec5SDimitry Andric #include "lldb/Host/FileAction.h" 250b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h" 260b57cec5SDimitry Andric #include "lldb/Host/Host.h" 270b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h" 280b57cec5SDimitry Andric #include "lldb/Host/SafeMachO.h" 290b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h" 300b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 310b57cec5SDimitry Andric #include "lldb/Target/Platform.h" 320b57cec5SDimitry Andric #include "lldb/Utility/Endian.h" 339dba64beSDimitry Andric #include "lldb/Utility/GDBRemote.h" 3481ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 350b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 360b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 370b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h" 389dba64beSDimitry Andric #include "llvm/ADT/StringSwitch.h" 399dba64beSDimitry Andric #include "llvm/Support/JSON.h" 4006c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric #include "ProcessGDBRemoteLog.h" 430b57cec5SDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h" 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric #ifdef __ANDROID__ 460b57cec5SDimitry Andric #include "lldb/Host/android/HostInfoAndroid.h" 4706c3fb27SDimitry Andric #include "lldb/Host/common/ZipFileResolver.h" 480b57cec5SDimitry Andric #endif 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric using namespace lldb; 510b57cec5SDimitry Andric using namespace lldb_private::process_gdb_remote; 529dba64beSDimitry Andric using namespace lldb_private; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric #ifdef __ANDROID__ 550b57cec5SDimitry Andric const static uint32_t g_default_packet_timeout_sec = 20; // seconds 560b57cec5SDimitry Andric #else 570b57cec5SDimitry Andric const static uint32_t g_default_packet_timeout_sec = 0; // not specified 580b57cec5SDimitry Andric #endif 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // GDBRemoteCommunicationServerCommon constructor 61bdd1243dSDimitry Andric GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon() 62bdd1243dSDimitry Andric : GDBRemoteCommunicationServer(), m_process_launch_info(), 63bdd1243dSDimitry Andric m_process_launch_error(), m_proc_infos(), m_proc_infos_index(0) { 640b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A, 650b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_A); 660b57cec5SDimitry Andric RegisterMemberFunctionHandler( 670b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QEnvironment, 680b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QEnvironment); 690b57cec5SDimitry Andric RegisterMemberFunctionHandler( 700b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded, 710b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded); 720b57cec5SDimitry Andric RegisterMemberFunctionHandler( 730b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qfProcessInfo, 740b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo); 750b57cec5SDimitry Andric RegisterMemberFunctionHandler( 760b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qGroupName, 770b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qGroupName); 780b57cec5SDimitry Andric RegisterMemberFunctionHandler( 790b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qHostInfo, 800b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qHostInfo); 810b57cec5SDimitry Andric RegisterMemberFunctionHandler( 820b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QLaunchArch, 830b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch); 840b57cec5SDimitry Andric RegisterMemberFunctionHandler( 850b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess, 860b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess); 870b57cec5SDimitry Andric RegisterMemberFunctionHandler( 880b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qEcho, 890b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qEcho); 900b57cec5SDimitry Andric RegisterMemberFunctionHandler( 910b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qModuleInfo, 920b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo); 930b57cec5SDimitry Andric RegisterMemberFunctionHandler( 940b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jModulesInfo, 950b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo); 960b57cec5SDimitry Andric RegisterMemberFunctionHandler( 970b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod, 980b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod); 990b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1000b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir, 1010b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir); 1020b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1030b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qPlatform_shell, 1040b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell); 1050b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1060b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID, 1070b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID); 1080b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1090b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError, 1100b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError); 1110b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1120b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetSTDERR, 1130b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR); 1140b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1150b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetSTDIN, 1160b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN); 1170b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1180b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT, 1190b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT); 1200b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1210b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qSpeedTest, 1220b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest); 1230b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1240b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qsProcessInfo, 1250b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo); 1260b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1270b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode, 1280b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode); 1290b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1300b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qSupported, 1310b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qSupported); 1320b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1330b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qUserName, 1340b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qUserName); 1350b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1360b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_close, 1370b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Close); 1380b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1390b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_exists, 1400b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists); 1410b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1420b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_md5, 1430b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5); 1440b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1450b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_mode, 1460b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode); 1470b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1480b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_open, 1490b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Open); 1500b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1510b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_pread, 1520b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead); 1530b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1540b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_pwrite, 1550b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite); 1560b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1570b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_size, 1580b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Size); 1590b57cec5SDimitry Andric RegisterMemberFunctionHandler( 160349cc55cSDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_fstat, 161349cc55cSDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_FStat); 162349cc55cSDimitry Andric RegisterMemberFunctionHandler( 1630b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_stat, 1640b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat); 1650b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1660b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_symlink, 1670b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink); 1680b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1690b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_unlink, 1700b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink); 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric // Destructor 174fe6060f1SDimitry Andric GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() = 175fe6060f1SDimitry Andric default; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1780b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qHostInfo( 1790b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 1800b57cec5SDimitry Andric StreamString response; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric ArchSpec host_arch(HostInfo::GetArchitecture()); 1850b57cec5SDimitry Andric const llvm::Triple &host_triple = host_arch.GetTriple(); 1860b57cec5SDimitry Andric response.PutCString("triple:"); 1870b57cec5SDimitry Andric response.PutStringAsRawHex8(host_triple.getTriple()); 1880b57cec5SDimitry Andric response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize()); 1890b57cec5SDimitry Andric 19006c3fb27SDimitry Andric llvm::StringRef distribution_id = HostInfo::GetDistributionId(); 19106c3fb27SDimitry Andric if (!distribution_id.empty()) { 1920b57cec5SDimitry Andric response.PutCString("distribution_id:"); 1930b57cec5SDimitry Andric response.PutStringAsRawHex8(distribution_id); 1940b57cec5SDimitry Andric response.PutCString(";"); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric #if defined(__APPLE__) 1980b57cec5SDimitry Andric // For parity with debugserver, we'll include the vendor key. 1990b57cec5SDimitry Andric response.PutCString("vendor:apple;"); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric // Send out MachO info. 2020b57cec5SDimitry Andric uint32_t cpu = host_arch.GetMachOCPUType(); 2030b57cec5SDimitry Andric uint32_t sub = host_arch.GetMachOCPUSubType(); 2040b57cec5SDimitry Andric if (cpu != LLDB_INVALID_CPUTYPE) 2050b57cec5SDimitry Andric response.Printf("cputype:%u;", cpu); 2060b57cec5SDimitry Andric if (sub != LLDB_INVALID_CPUTYPE) 2070b57cec5SDimitry Andric response.Printf("cpusubtype:%u;", sub); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) { 2100b57cec5SDimitry Andric // Indicate the OS type. 2110b57cec5SDimitry Andric #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 2120b57cec5SDimitry Andric response.PutCString("ostype:tvos;"); 2130b57cec5SDimitry Andric #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 2140b57cec5SDimitry Andric response.PutCString("ostype:watchos;"); 2150b57cec5SDimitry Andric #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 2160b57cec5SDimitry Andric response.PutCString("ostype:bridgeos;"); 2170b57cec5SDimitry Andric #else 2180b57cec5SDimitry Andric response.PutCString("ostype:ios;"); 2190b57cec5SDimitry Andric #endif 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric // On arm, we use "synchronous" watchpoints which means the exception is 2220b57cec5SDimitry Andric // delivered before the instruction executes. 2230b57cec5SDimitry Andric response.PutCString("watchpoint_exceptions_received:before;"); 2240b57cec5SDimitry Andric } else { 2250b57cec5SDimitry Andric response.PutCString("ostype:macosx;"); 2260b57cec5SDimitry Andric response.Printf("watchpoint_exceptions_received:after;"); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric #else 2300b57cec5SDimitry Andric if (host_arch.GetMachine() == llvm::Triple::aarch64 || 2319dba64beSDimitry Andric host_arch.GetMachine() == llvm::Triple::aarch64_32 || 2320b57cec5SDimitry Andric host_arch.GetMachine() == llvm::Triple::aarch64_be || 2330b57cec5SDimitry Andric host_arch.GetMachine() == llvm::Triple::arm || 2340b57cec5SDimitry Andric host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS()) 2350b57cec5SDimitry Andric response.Printf("watchpoint_exceptions_received:before;"); 2360b57cec5SDimitry Andric else 2370b57cec5SDimitry Andric response.Printf("watchpoint_exceptions_received:after;"); 2380b57cec5SDimitry Andric #endif 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric switch (endian::InlHostByteOrder()) { 2410b57cec5SDimitry Andric case eByteOrderBig: 2420b57cec5SDimitry Andric response.PutCString("endian:big;"); 2430b57cec5SDimitry Andric break; 2440b57cec5SDimitry Andric case eByteOrderLittle: 2450b57cec5SDimitry Andric response.PutCString("endian:little;"); 2460b57cec5SDimitry Andric break; 2470b57cec5SDimitry Andric case eByteOrderPDP: 2480b57cec5SDimitry Andric response.PutCString("endian:pdp;"); 2490b57cec5SDimitry Andric break; 2500b57cec5SDimitry Andric default: 2510b57cec5SDimitry Andric response.PutCString("endian:unknown;"); 2520b57cec5SDimitry Andric break; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric llvm::VersionTuple version = HostInfo::GetOSVersion(); 2560b57cec5SDimitry Andric if (!version.empty()) { 2570b57cec5SDimitry Andric response.Format("os_version:{0}", version.getAsString()); 2580b57cec5SDimitry Andric response.PutChar(';'); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric 2619dba64beSDimitry Andric #if defined(__APPLE__) 2629dba64beSDimitry Andric llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion(); 2639dba64beSDimitry Andric if (!maccatalyst_version.empty()) { 2649dba64beSDimitry Andric response.Format("maccatalyst_version:{0}", 2659dba64beSDimitry Andric maccatalyst_version.getAsString()); 2669dba64beSDimitry Andric response.PutChar(';'); 2679dba64beSDimitry Andric } 2689dba64beSDimitry Andric #endif 2699dba64beSDimitry Andric 270bdd1243dSDimitry Andric if (std::optional<std::string> s = HostInfo::GetOSBuildString()) { 2710b57cec5SDimitry Andric response.PutCString("os_build:"); 272349cc55cSDimitry Andric response.PutStringAsRawHex8(*s); 2730b57cec5SDimitry Andric response.PutChar(';'); 2740b57cec5SDimitry Andric } 275bdd1243dSDimitry Andric if (std::optional<std::string> s = HostInfo::GetOSKernelDescription()) { 2760b57cec5SDimitry Andric response.PutCString("os_kernel:"); 277349cc55cSDimitry Andric response.PutStringAsRawHex8(*s); 2780b57cec5SDimitry Andric response.PutChar(';'); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 281349cc55cSDimitry Andric std::string s; 2820b57cec5SDimitry Andric #if defined(__APPLE__) 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 2850b57cec5SDimitry Andric // For iOS devices, we are connected through a USB Mux so we never pretend to 2860b57cec5SDimitry Andric // actually have a hostname as far as the remote lldb that is connecting to 2870b57cec5SDimitry Andric // this lldb-platform is concerned 2880b57cec5SDimitry Andric response.PutCString("hostname:"); 2890b57cec5SDimitry Andric response.PutStringAsRawHex8("127.0.0.1"); 2900b57cec5SDimitry Andric response.PutChar(';'); 2910b57cec5SDimitry Andric #else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 2920b57cec5SDimitry Andric if (HostInfo::GetHostname(s)) { 2930b57cec5SDimitry Andric response.PutCString("hostname:"); 2940b57cec5SDimitry Andric response.PutStringAsRawHex8(s); 2950b57cec5SDimitry Andric response.PutChar(';'); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric #endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric #else // #if defined(__APPLE__) 3000b57cec5SDimitry Andric if (HostInfo::GetHostname(s)) { 3010b57cec5SDimitry Andric response.PutCString("hostname:"); 3020b57cec5SDimitry Andric response.PutStringAsRawHex8(s); 3030b57cec5SDimitry Andric response.PutChar(';'); 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric #endif // #if defined(__APPLE__) 306bdd1243dSDimitry Andric // coverity[unsigned_compare] 3070b57cec5SDimitry Andric if (g_default_packet_timeout_sec > 0) 3080b57cec5SDimitry Andric response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec); 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 3140b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID( 3150b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 3160b57cec5SDimitry Andric // Packet format: "qProcessInfoPID:%i" where %i is the pid 3170b57cec5SDimitry Andric packet.SetFilePos(::strlen("qProcessInfoPID:")); 3180b57cec5SDimitry Andric lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID); 3190b57cec5SDimitry Andric if (pid != LLDB_INVALID_PROCESS_ID) { 3200b57cec5SDimitry Andric ProcessInstanceInfo proc_info; 3210b57cec5SDimitry Andric if (Host::GetProcessInfo(pid, proc_info)) { 3220b57cec5SDimitry Andric StreamString response; 3230b57cec5SDimitry Andric CreateProcessInfoResponse(proc_info, response); 3240b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric return SendErrorResponse(1); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 3310b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( 3320b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 3330b57cec5SDimitry Andric m_proc_infos_index = 0; 3345ffd83dbSDimitry Andric m_proc_infos.clear(); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric ProcessInstanceInfoMatch match_info; 3370b57cec5SDimitry Andric packet.SetFilePos(::strlen("qfProcessInfo")); 3380b57cec5SDimitry Andric if (packet.GetChar() == ':') { 3390b57cec5SDimitry Andric llvm::StringRef key; 3400b57cec5SDimitry Andric llvm::StringRef value; 3410b57cec5SDimitry Andric while (packet.GetNameColonValue(key, value)) { 3420b57cec5SDimitry Andric bool success = true; 343*0fca6ea1SDimitry Andric if (key == "name") { 3440b57cec5SDimitry Andric StringExtractor extractor(value); 3450b57cec5SDimitry Andric std::string file; 3460b57cec5SDimitry Andric extractor.GetHexByteString(file); 3470b57cec5SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile( 3480b57cec5SDimitry Andric file, FileSpec::Style::native); 349*0fca6ea1SDimitry Andric } else if (key == "name_match") { 3500b57cec5SDimitry Andric NameMatch name_match = llvm::StringSwitch<NameMatch>(value) 3510b57cec5SDimitry Andric .Case("equals", NameMatch::Equals) 3520b57cec5SDimitry Andric .Case("starts_with", NameMatch::StartsWith) 3530b57cec5SDimitry Andric .Case("ends_with", NameMatch::EndsWith) 3540b57cec5SDimitry Andric .Case("contains", NameMatch::Contains) 3550b57cec5SDimitry Andric .Case("regex", NameMatch::RegularExpression) 3560b57cec5SDimitry Andric .Default(NameMatch::Ignore); 3570b57cec5SDimitry Andric match_info.SetNameMatchType(name_match); 3580b57cec5SDimitry Andric if (name_match == NameMatch::Ignore) 3590b57cec5SDimitry Andric return SendErrorResponse(2); 360*0fca6ea1SDimitry Andric } else if (key == "pid") { 3610b57cec5SDimitry Andric lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 3620b57cec5SDimitry Andric if (value.getAsInteger(0, pid)) 3630b57cec5SDimitry Andric return SendErrorResponse(2); 3640b57cec5SDimitry Andric match_info.GetProcessInfo().SetProcessID(pid); 365*0fca6ea1SDimitry Andric } else if (key == "parent_pid") { 3660b57cec5SDimitry Andric lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 3670b57cec5SDimitry Andric if (value.getAsInteger(0, pid)) 3680b57cec5SDimitry Andric return SendErrorResponse(2); 3690b57cec5SDimitry Andric match_info.GetProcessInfo().SetParentProcessID(pid); 370*0fca6ea1SDimitry Andric } else if (key == "uid") { 3710b57cec5SDimitry Andric uint32_t uid = UINT32_MAX; 3720b57cec5SDimitry Andric if (value.getAsInteger(0, uid)) 3730b57cec5SDimitry Andric return SendErrorResponse(2); 3740b57cec5SDimitry Andric match_info.GetProcessInfo().SetUserID(uid); 375*0fca6ea1SDimitry Andric } else if (key == "gid") { 3760b57cec5SDimitry Andric uint32_t gid = UINT32_MAX; 3770b57cec5SDimitry Andric if (value.getAsInteger(0, gid)) 3780b57cec5SDimitry Andric return SendErrorResponse(2); 3790b57cec5SDimitry Andric match_info.GetProcessInfo().SetGroupID(gid); 380*0fca6ea1SDimitry Andric } else if (key == "euid") { 3810b57cec5SDimitry Andric uint32_t uid = UINT32_MAX; 3820b57cec5SDimitry Andric if (value.getAsInteger(0, uid)) 3830b57cec5SDimitry Andric return SendErrorResponse(2); 3840b57cec5SDimitry Andric match_info.GetProcessInfo().SetEffectiveUserID(uid); 385*0fca6ea1SDimitry Andric } else if (key == "egid") { 3860b57cec5SDimitry Andric uint32_t gid = UINT32_MAX; 3870b57cec5SDimitry Andric if (value.getAsInteger(0, gid)) 3880b57cec5SDimitry Andric return SendErrorResponse(2); 3890b57cec5SDimitry Andric match_info.GetProcessInfo().SetEffectiveGroupID(gid); 390*0fca6ea1SDimitry Andric } else if (key == "all_users") { 3910b57cec5SDimitry Andric match_info.SetMatchAllUsers( 3920b57cec5SDimitry Andric OptionArgParser::ToBoolean(value, false, &success)); 393*0fca6ea1SDimitry Andric } else if (key == "triple") { 3940b57cec5SDimitry Andric match_info.GetProcessInfo().GetArchitecture() = 3950b57cec5SDimitry Andric HostInfo::GetAugmentedArchSpec(value); 3960b57cec5SDimitry Andric } else { 3970b57cec5SDimitry Andric success = false; 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric if (!success) 4010b57cec5SDimitry Andric return SendErrorResponse(2); 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric if (Host::FindProcesses(match_info, m_proc_infos)) { 4060b57cec5SDimitry Andric // We found something, return the first item by calling the get subsequent 4070b57cec5SDimitry Andric // process info packet handler... 4080b57cec5SDimitry Andric return Handle_qsProcessInfo(packet); 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric return SendErrorResponse(3); 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4140b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo( 4150b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 4165ffd83dbSDimitry Andric if (m_proc_infos_index < m_proc_infos.size()) { 4170b57cec5SDimitry Andric StreamString response; 4185ffd83dbSDimitry Andric CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response); 4190b57cec5SDimitry Andric ++m_proc_infos_index; 4200b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric return SendErrorResponse(4); 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4260b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qUserName( 4270b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 428480093f4SDimitry Andric #if LLDB_ENABLE_POSIX 42981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 4309dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric // Packet format: "qUserName:%i" where %i is the uid 4330b57cec5SDimitry Andric packet.SetFilePos(::strlen("qUserName:")); 4340b57cec5SDimitry Andric uint32_t uid = packet.GetU32(UINT32_MAX); 4350b57cec5SDimitry Andric if (uid != UINT32_MAX) { 436bdd1243dSDimitry Andric if (std::optional<llvm::StringRef> name = 4370b57cec5SDimitry Andric HostInfo::GetUserIDResolver().GetUserName(uid)) { 4380b57cec5SDimitry Andric StreamString response; 4390b57cec5SDimitry Andric response.PutStringAsRawHex8(*name); 4400b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4410b57cec5SDimitry Andric } 4420b57cec5SDimitry Andric } 4439dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__); 4440b57cec5SDimitry Andric #endif 4450b57cec5SDimitry Andric return SendErrorResponse(5); 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4490b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qGroupName( 4500b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 451480093f4SDimitry Andric #if LLDB_ENABLE_POSIX 4520b57cec5SDimitry Andric // Packet format: "qGroupName:%i" where %i is the gid 4530b57cec5SDimitry Andric packet.SetFilePos(::strlen("qGroupName:")); 4540b57cec5SDimitry Andric uint32_t gid = packet.GetU32(UINT32_MAX); 4550b57cec5SDimitry Andric if (gid != UINT32_MAX) { 456bdd1243dSDimitry Andric if (std::optional<llvm::StringRef> name = 4570b57cec5SDimitry Andric HostInfo::GetUserIDResolver().GetGroupName(gid)) { 4580b57cec5SDimitry Andric StreamString response; 4590b57cec5SDimitry Andric response.PutStringAsRawHex8(*name); 4600b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric #endif 4640b57cec5SDimitry Andric return SendErrorResponse(6); 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4680b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qSpeedTest( 4690b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 4700b57cec5SDimitry Andric packet.SetFilePos(::strlen("qSpeedTest:")); 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric llvm::StringRef key; 4730b57cec5SDimitry Andric llvm::StringRef value; 4740b57cec5SDimitry Andric bool success = packet.GetNameColonValue(key, value); 475*0fca6ea1SDimitry Andric if (success && key == "response_size") { 4760b57cec5SDimitry Andric uint32_t response_size = 0; 4770b57cec5SDimitry Andric if (!value.getAsInteger(0, response_size)) { 4780b57cec5SDimitry Andric if (response_size == 0) 4790b57cec5SDimitry Andric return SendOKResponse(); 4800b57cec5SDimitry Andric StreamString response; 4810b57cec5SDimitry Andric uint32_t bytes_left = response_size; 4820b57cec5SDimitry Andric response.PutCString("data:"); 4830b57cec5SDimitry Andric while (bytes_left > 0) { 4840b57cec5SDimitry Andric if (bytes_left >= 26) { 4850b57cec5SDimitry Andric response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 4860b57cec5SDimitry Andric bytes_left -= 26; 4870b57cec5SDimitry Andric } else { 4880b57cec5SDimitry Andric response.Printf("%*.*s;", bytes_left, bytes_left, 4890b57cec5SDimitry Andric "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 4900b57cec5SDimitry Andric bytes_left = 0; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric return SendErrorResponse(7); 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 5000b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Open( 5010b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 5020b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:open:")); 5030b57cec5SDimitry Andric std::string path; 5040b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(path, ','); 5050b57cec5SDimitry Andric if (!path.empty()) { 5060b57cec5SDimitry Andric if (packet.GetChar() == ',') { 5079dba64beSDimitry Andric auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0)); 5080b57cec5SDimitry Andric if (packet.GetChar() == ',') { 5090b57cec5SDimitry Andric mode_t mode = packet.GetHexMaxU32(false, 0600); 5100b57cec5SDimitry Andric FileSpec path_spec(path); 5110b57cec5SDimitry Andric FileSystem::Instance().Resolve(path_spec); 5120b57cec5SDimitry Andric // Do not close fd. 5139dba64beSDimitry Andric auto file = FileSystem::Instance().Open(path_spec, flags, mode, false); 5149dba64beSDimitry Andric 515349cc55cSDimitry Andric StreamString response; 516349cc55cSDimitry Andric response.PutChar('F'); 517349cc55cSDimitry Andric 5189dba64beSDimitry Andric int descriptor = File::kInvalidDescriptor; 5199dba64beSDimitry Andric if (file) { 5209dba64beSDimitry Andric descriptor = file.get()->GetDescriptor(); 521349cc55cSDimitry Andric response.Printf("%x", descriptor); 5229dba64beSDimitry Andric } else { 523349cc55cSDimitry Andric response.PutCString("-1"); 5249dba64beSDimitry Andric std::error_code code = errorToErrorCode(file.takeError()); 5259dba64beSDimitry Andric if (code.category() == std::system_category()) { 526349cc55cSDimitry Andric response.Printf(",%x", code.value()); 5279dba64beSDimitry Andric } 5289dba64beSDimitry Andric } 5299dba64beSDimitry Andric 5300b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric } 5340b57cec5SDimitry Andric return SendErrorResponse(18); 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 537349cc55cSDimitry Andric static GDBErrno system_errno_to_gdb(int err) { 538349cc55cSDimitry Andric switch (err) { 539349cc55cSDimitry Andric #define HANDLE_ERRNO(name, value) \ 540349cc55cSDimitry Andric case name: \ 541349cc55cSDimitry Andric return GDB_##name; 542349cc55cSDimitry Andric #include "Plugins/Process/gdb-remote/GDBRemoteErrno.def" 543349cc55cSDimitry Andric default: 544349cc55cSDimitry Andric return GDB_EUNKNOWN; 545349cc55cSDimitry Andric } 546349cc55cSDimitry Andric } 547349cc55cSDimitry Andric 5480b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 5490b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Close( 5500b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 5510b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:close:")); 552349cc55cSDimitry Andric int fd = packet.GetS32(-1, 16); 5530b57cec5SDimitry Andric int err = -1; 5540b57cec5SDimitry Andric int save_errno = 0; 5550b57cec5SDimitry Andric if (fd >= 0) { 5569dba64beSDimitry Andric NativeFile file(fd, File::OpenOptions(0), true); 5570b57cec5SDimitry Andric Status error = file.Close(); 5580b57cec5SDimitry Andric err = 0; 5590b57cec5SDimitry Andric save_errno = error.GetError(); 5600b57cec5SDimitry Andric } else { 5610b57cec5SDimitry Andric save_errno = EINVAL; 5620b57cec5SDimitry Andric } 5630b57cec5SDimitry Andric StreamString response; 5640b57cec5SDimitry Andric response.PutChar('F'); 565349cc55cSDimitry Andric response.Printf("%x", err); 5660b57cec5SDimitry Andric if (save_errno) 567349cc55cSDimitry Andric response.Printf(",%x", system_errno_to_gdb(save_errno)); 5680b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5690b57cec5SDimitry Andric } 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 5720b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_pRead( 5730b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 5740b57cec5SDimitry Andric StreamGDBRemote response; 5750b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:pread:")); 576349cc55cSDimitry Andric int fd = packet.GetS32(-1, 16); 5770b57cec5SDimitry Andric if (packet.GetChar() == ',') { 578349cc55cSDimitry Andric size_t count = packet.GetHexMaxU64(false, SIZE_MAX); 5790b57cec5SDimitry Andric if (packet.GetChar() == ',') { 580349cc55cSDimitry Andric off_t offset = packet.GetHexMaxU32(false, UINT32_MAX); 5819dba64beSDimitry Andric if (count == SIZE_MAX) { 582349cc55cSDimitry Andric response.Printf("F-1:%x", EINVAL); 5830b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric std::string buffer(count, 0); 587349cc55cSDimitry Andric NativeFile file(fd, File::eOpenOptionReadOnly, false); 5880b57cec5SDimitry Andric Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset); 5890b57cec5SDimitry Andric const int save_errno = error.GetError(); 5900b57cec5SDimitry Andric response.PutChar('F'); 591349cc55cSDimitry Andric if (error.Success()) { 592349cc55cSDimitry Andric response.Printf("%zx", count); 5930b57cec5SDimitry Andric response.PutChar(';'); 594349cc55cSDimitry Andric response.PutEscapedBytes(&buffer[0], count); 595349cc55cSDimitry Andric } else { 596349cc55cSDimitry Andric response.PutCString("-1"); 597349cc55cSDimitry Andric if (save_errno) 598349cc55cSDimitry Andric response.Printf(",%x", system_errno_to_gdb(save_errno)); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric return SendErrorResponse(21); 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6070b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite( 6080b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6090b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:pwrite:")); 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric StreamGDBRemote response; 6120b57cec5SDimitry Andric response.PutChar('F'); 6130b57cec5SDimitry Andric 614349cc55cSDimitry Andric int fd = packet.GetS32(-1, 16); 6150b57cec5SDimitry Andric if (packet.GetChar() == ',') { 616349cc55cSDimitry Andric off_t offset = packet.GetHexMaxU32(false, UINT32_MAX); 6170b57cec5SDimitry Andric if (packet.GetChar() == ',') { 6180b57cec5SDimitry Andric std::string buffer; 6190b57cec5SDimitry Andric if (packet.GetEscapedBinaryData(buffer)) { 620349cc55cSDimitry Andric NativeFile file(fd, File::eOpenOptionWriteOnly, false); 6210b57cec5SDimitry Andric size_t count = buffer.size(); 6220b57cec5SDimitry Andric Status error = 6230b57cec5SDimitry Andric file.Write(static_cast<const void *>(&buffer[0]), count, offset); 6240b57cec5SDimitry Andric const int save_errno = error.GetError(); 625349cc55cSDimitry Andric if (error.Success()) 626349cc55cSDimitry Andric response.Printf("%zx", count); 627349cc55cSDimitry Andric else { 628349cc55cSDimitry Andric response.PutCString("-1"); 6290b57cec5SDimitry Andric if (save_errno) 630349cc55cSDimitry Andric response.Printf(",%x", system_errno_to_gdb(save_errno)); 631349cc55cSDimitry Andric } 6320b57cec5SDimitry Andric } else { 633349cc55cSDimitry Andric response.Printf("-1,%x", EINVAL); 6340b57cec5SDimitry Andric } 6350b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric return SendErrorResponse(27); 6390b57cec5SDimitry Andric } 6400b57cec5SDimitry Andric 6410b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6420b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Size( 6430b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6440b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:size:")); 6450b57cec5SDimitry Andric std::string path; 6460b57cec5SDimitry Andric packet.GetHexByteString(path); 6470b57cec5SDimitry Andric if (!path.empty()) { 6480b57cec5SDimitry Andric uint64_t Size; 6490b57cec5SDimitry Andric if (llvm::sys::fs::file_size(path, Size)) 6500b57cec5SDimitry Andric return SendErrorResponse(5); 6510b57cec5SDimitry Andric StreamString response; 6520b57cec5SDimitry Andric response.PutChar('F'); 6530b57cec5SDimitry Andric response.PutHex64(Size); 6540b57cec5SDimitry Andric if (Size == UINT64_MAX) { 6550b57cec5SDimitry Andric response.PutChar(','); 6560b57cec5SDimitry Andric response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode() 6570b57cec5SDimitry Andric } 6580b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric return SendErrorResponse(22); 6610b57cec5SDimitry Andric } 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6640b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( 6650b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6660b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:mode:")); 6670b57cec5SDimitry Andric std::string path; 6680b57cec5SDimitry Andric packet.GetHexByteString(path); 6690b57cec5SDimitry Andric if (!path.empty()) { 6700b57cec5SDimitry Andric FileSpec file_spec(path); 6710b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec); 6720b57cec5SDimitry Andric std::error_code ec; 6730b57cec5SDimitry Andric const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); 6740b57cec5SDimitry Andric StreamString response; 675349cc55cSDimitry Andric if (mode != llvm::sys::fs::perms_not_known) 676349cc55cSDimitry Andric response.Printf("F%x", mode); 677349cc55cSDimitry Andric else 678349cc55cSDimitry Andric response.Printf("F-1,%x", (int)Status(ec).GetError()); 6790b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric return SendErrorResponse(23); 6820b57cec5SDimitry Andric } 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6850b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Exists( 6860b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6870b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:exists:")); 6880b57cec5SDimitry Andric std::string path; 6890b57cec5SDimitry Andric packet.GetHexByteString(path); 6900b57cec5SDimitry Andric if (!path.empty()) { 6910b57cec5SDimitry Andric bool retcode = llvm::sys::fs::exists(path); 6920b57cec5SDimitry Andric StreamString response; 6930b57cec5SDimitry Andric response.PutChar('F'); 6940b57cec5SDimitry Andric response.PutChar(','); 6950b57cec5SDimitry Andric if (retcode) 6960b57cec5SDimitry Andric response.PutChar('1'); 6970b57cec5SDimitry Andric else 6980b57cec5SDimitry Andric response.PutChar('0'); 6990b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric return SendErrorResponse(24); 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7050b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( 7060b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7070b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:symlink:")); 7080b57cec5SDimitry Andric std::string dst, src; 7090b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(dst, ','); 7100b57cec5SDimitry Andric packet.GetChar(); // Skip ',' char 7110b57cec5SDimitry Andric packet.GetHexByteString(src); 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric FileSpec src_spec(src); 7140b57cec5SDimitry Andric FileSystem::Instance().Resolve(src_spec); 7150b57cec5SDimitry Andric Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric StreamString response; 718349cc55cSDimitry Andric response.Printf("F%x,%x", error.GetError(), error.GetError()); 7190b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7230b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_unlink( 7240b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7250b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:unlink:")); 7260b57cec5SDimitry Andric std::string path; 7270b57cec5SDimitry Andric packet.GetHexByteString(path); 7280b57cec5SDimitry Andric Status error(llvm::sys::fs::remove(path)); 7290b57cec5SDimitry Andric StreamString response; 730349cc55cSDimitry Andric response.Printf("F%x,%x", error.GetError(), error.GetError()); 7310b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7350b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( 7360b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7370b57cec5SDimitry Andric packet.SetFilePos(::strlen("qPlatform_shell:")); 7380b57cec5SDimitry Andric std::string path; 7390b57cec5SDimitry Andric std::string working_dir; 7400b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(path, ','); 7410b57cec5SDimitry Andric if (!path.empty()) { 7420b57cec5SDimitry Andric if (packet.GetChar() == ',') { 7430b57cec5SDimitry Andric // FIXME: add timeout to qPlatform_shell packet 7440b57cec5SDimitry Andric // uint32_t timeout = packet.GetHexMaxU32(false, 32); 7450b57cec5SDimitry Andric if (packet.GetChar() == ',') 7460b57cec5SDimitry Andric packet.GetHexByteString(working_dir); 7470b57cec5SDimitry Andric int status, signo; 7480b57cec5SDimitry Andric std::string output; 7490b57cec5SDimitry Andric FileSpec working_spec(working_dir); 7500b57cec5SDimitry Andric FileSystem::Instance().Resolve(working_spec); 7510b57cec5SDimitry Andric Status err = 7520b57cec5SDimitry Andric Host::RunShellCommand(path.c_str(), working_spec, &status, &signo, 7530b57cec5SDimitry Andric &output, std::chrono::seconds(10)); 7540b57cec5SDimitry Andric StreamGDBRemote response; 7550b57cec5SDimitry Andric if (err.Fail()) { 7560b57cec5SDimitry Andric response.PutCString("F,"); 7570b57cec5SDimitry Andric response.PutHex32(UINT32_MAX); 7580b57cec5SDimitry Andric } else { 7590b57cec5SDimitry Andric response.PutCString("F,"); 7600b57cec5SDimitry Andric response.PutHex32(status); 7610b57cec5SDimitry Andric response.PutChar(','); 7620b57cec5SDimitry Andric response.PutHex32(signo); 7630b57cec5SDimitry Andric response.PutChar(','); 7640b57cec5SDimitry Andric response.PutEscapedBytes(output.c_str(), output.size()); 7650b57cec5SDimitry Andric } 7660b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7670b57cec5SDimitry Andric } 7680b57cec5SDimitry Andric } 7690b57cec5SDimitry Andric return SendErrorResponse(24); 7700b57cec5SDimitry Andric } 7710b57cec5SDimitry Andric 772349cc55cSDimitry Andric template <typename T, typename U> 773349cc55cSDimitry Andric static void fill_clamp(T &dest, U src, typename T::value_type fallback) { 774349cc55cSDimitry Andric static_assert(std::is_unsigned<typename T::value_type>::value, 775349cc55cSDimitry Andric "Destination type must be unsigned."); 776bdd1243dSDimitry Andric using UU = std::make_unsigned_t<U>; 777349cc55cSDimitry Andric constexpr auto T_max = std::numeric_limits<typename T::value_type>::max(); 778349cc55cSDimitry Andric dest = src >= 0 && static_cast<UU>(src) <= T_max ? src : fallback; 779349cc55cSDimitry Andric } 780349cc55cSDimitry Andric 781349cc55cSDimitry Andric GDBRemoteCommunication::PacketResult 782349cc55cSDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_FStat( 783349cc55cSDimitry Andric StringExtractorGDBRemote &packet) { 784349cc55cSDimitry Andric StreamGDBRemote response; 785349cc55cSDimitry Andric packet.SetFilePos(::strlen("vFile:fstat:")); 786349cc55cSDimitry Andric int fd = packet.GetS32(-1, 16); 787349cc55cSDimitry Andric 788349cc55cSDimitry Andric struct stat file_stats; 789349cc55cSDimitry Andric if (::fstat(fd, &file_stats) == -1) { 790349cc55cSDimitry Andric const int save_errno = errno; 791349cc55cSDimitry Andric response.Printf("F-1,%x", system_errno_to_gdb(save_errno)); 792349cc55cSDimitry Andric return SendPacketNoLock(response.GetString()); 793349cc55cSDimitry Andric } 794349cc55cSDimitry Andric 795349cc55cSDimitry Andric GDBRemoteFStatData data; 796349cc55cSDimitry Andric fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0); 797349cc55cSDimitry Andric fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0); 798349cc55cSDimitry Andric data.gdb_st_mode = file_stats.st_mode; 799349cc55cSDimitry Andric fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX); 800349cc55cSDimitry Andric fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0); 801349cc55cSDimitry Andric fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0); 802349cc55cSDimitry Andric fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0); 803349cc55cSDimitry Andric data.gdb_st_size = file_stats.st_size; 804349cc55cSDimitry Andric #if !defined(_WIN32) 805349cc55cSDimitry Andric data.gdb_st_blksize = file_stats.st_blksize; 806349cc55cSDimitry Andric data.gdb_st_blocks = file_stats.st_blocks; 807349cc55cSDimitry Andric #else 808349cc55cSDimitry Andric data.gdb_st_blksize = 0; 809349cc55cSDimitry Andric data.gdb_st_blocks = 0; 810349cc55cSDimitry Andric #endif 811349cc55cSDimitry Andric fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0); 812349cc55cSDimitry Andric fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0); 813349cc55cSDimitry Andric fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0); 814349cc55cSDimitry Andric 815349cc55cSDimitry Andric response.Printf("F%zx;", sizeof(data)); 816349cc55cSDimitry Andric response.PutEscapedBytes(&data, sizeof(data)); 817349cc55cSDimitry Andric return SendPacketNoLock(response.GetString()); 818349cc55cSDimitry Andric } 819349cc55cSDimitry Andric 8200b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8210b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Stat( 8220b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8230b57cec5SDimitry Andric return SendUnimplementedResponse( 8240b57cec5SDimitry Andric "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented"); 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8280b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_MD5( 8290b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8300b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:MD5:")); 8310b57cec5SDimitry Andric std::string path; 8320b57cec5SDimitry Andric packet.GetHexByteString(path); 8330b57cec5SDimitry Andric if (!path.empty()) { 8340b57cec5SDimitry Andric StreamGDBRemote response; 8350b57cec5SDimitry Andric auto Result = llvm::sys::fs::md5_contents(path); 8360b57cec5SDimitry Andric if (!Result) { 8370b57cec5SDimitry Andric response.PutCString("F,"); 8380b57cec5SDimitry Andric response.PutCString("x"); 8390b57cec5SDimitry Andric } else { 8400b57cec5SDimitry Andric response.PutCString("F,"); 8410b57cec5SDimitry Andric response.PutHex64(Result->low()); 8420b57cec5SDimitry Andric response.PutHex64(Result->high()); 8430b57cec5SDimitry Andric } 8440b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 8450b57cec5SDimitry Andric } 8460b57cec5SDimitry Andric return SendErrorResponse(25); 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8500b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir( 8510b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8520b57cec5SDimitry Andric packet.SetFilePos(::strlen("qPlatform_mkdir:")); 8530b57cec5SDimitry Andric mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 8540b57cec5SDimitry Andric if (packet.GetChar() == ',') { 8550b57cec5SDimitry Andric std::string path; 8560b57cec5SDimitry Andric packet.GetHexByteString(path); 8570b57cec5SDimitry Andric Status error(llvm::sys::fs::create_directory(path, mode)); 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric StreamGDBRemote response; 860349cc55cSDimitry Andric response.Printf("F%x", error.GetError()); 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 8630b57cec5SDimitry Andric } 8640b57cec5SDimitry Andric return SendErrorResponse(20); 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8680b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod( 8690b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8700b57cec5SDimitry Andric packet.SetFilePos(::strlen("qPlatform_chmod:")); 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric auto perms = 8730b57cec5SDimitry Andric static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX)); 8740b57cec5SDimitry Andric if (packet.GetChar() == ',') { 8750b57cec5SDimitry Andric std::string path; 8760b57cec5SDimitry Andric packet.GetHexByteString(path); 8770b57cec5SDimitry Andric Status error(llvm::sys::fs::setPermissions(path, perms)); 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric StreamGDBRemote response; 880349cc55cSDimitry Andric response.Printf("F%x", error.GetError()); 8810b57cec5SDimitry Andric 8820b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric return SendErrorResponse(19); 8850b57cec5SDimitry Andric } 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8880b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qSupported( 8890b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 890fe6060f1SDimitry Andric // Parse client-indicated features. 891fe6060f1SDimitry Andric llvm::SmallVector<llvm::StringRef, 4> client_features; 892fe6060f1SDimitry Andric packet.GetStringRef().split(client_features, ';'); 893fe6060f1SDimitry Andric return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";")); 8940b57cec5SDimitry Andric } 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8970b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError( 8980b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8990b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetDetachOnError:")); 9000b57cec5SDimitry Andric if (packet.GetU32(0)) 9010b57cec5SDimitry Andric m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError); 9020b57cec5SDimitry Andric else 9030b57cec5SDimitry Andric m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError); 9040b57cec5SDimitry Andric return SendOKResponse(); 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9080b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode( 9090b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9100b57cec5SDimitry Andric // Send response first before changing m_send_acks to we ack this packet 9110b57cec5SDimitry Andric PacketResult packet_result = SendOKResponse(); 9120b57cec5SDimitry Andric m_send_acks = false; 9130b57cec5SDimitry Andric return packet_result; 9140b57cec5SDimitry Andric } 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9170b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN( 9180b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9190b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetSTDIN:")); 9200b57cec5SDimitry Andric FileAction file_action; 9210b57cec5SDimitry Andric std::string path; 9220b57cec5SDimitry Andric packet.GetHexByteString(path); 9230b57cec5SDimitry Andric const bool read = true; 9240b57cec5SDimitry Andric const bool write = false; 9250b57cec5SDimitry Andric if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) { 9260b57cec5SDimitry Andric m_process_launch_info.AppendFileAction(file_action); 9270b57cec5SDimitry Andric return SendOKResponse(); 9280b57cec5SDimitry Andric } 9290b57cec5SDimitry Andric return SendErrorResponse(15); 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric 9320b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9330b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT( 9340b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9350b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetSTDOUT:")); 9360b57cec5SDimitry Andric FileAction file_action; 9370b57cec5SDimitry Andric std::string path; 9380b57cec5SDimitry Andric packet.GetHexByteString(path); 9390b57cec5SDimitry Andric const bool read = false; 9400b57cec5SDimitry Andric const bool write = true; 9410b57cec5SDimitry Andric if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) { 9420b57cec5SDimitry Andric m_process_launch_info.AppendFileAction(file_action); 9430b57cec5SDimitry Andric return SendOKResponse(); 9440b57cec5SDimitry Andric } 9450b57cec5SDimitry Andric return SendErrorResponse(16); 9460b57cec5SDimitry Andric } 9470b57cec5SDimitry Andric 9480b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9490b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR( 9500b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9510b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetSTDERR:")); 9520b57cec5SDimitry Andric FileAction file_action; 9530b57cec5SDimitry Andric std::string path; 9540b57cec5SDimitry Andric packet.GetHexByteString(path); 9550b57cec5SDimitry Andric const bool read = false; 9560b57cec5SDimitry Andric const bool write = true; 9570b57cec5SDimitry Andric if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) { 9580b57cec5SDimitry Andric m_process_launch_info.AppendFileAction(file_action); 9590b57cec5SDimitry Andric return SendOKResponse(); 9600b57cec5SDimitry Andric } 9610b57cec5SDimitry Andric return SendErrorResponse(17); 9620b57cec5SDimitry Andric } 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9650b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess( 9660b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9670b57cec5SDimitry Andric if (m_process_launch_error.Success()) 9680b57cec5SDimitry Andric return SendOKResponse(); 9690b57cec5SDimitry Andric StreamString response; 9700b57cec5SDimitry Andric response.PutChar('E'); 9710b57cec5SDimitry Andric response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 9720b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 9730b57cec5SDimitry Andric } 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9760b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QEnvironment( 9770b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9780b57cec5SDimitry Andric packet.SetFilePos(::strlen("QEnvironment:")); 9790b57cec5SDimitry Andric const uint32_t bytes_left = packet.GetBytesLeft(); 9800b57cec5SDimitry Andric if (bytes_left > 0) { 9810b57cec5SDimitry Andric m_process_launch_info.GetEnvironment().insert(packet.Peek()); 9820b57cec5SDimitry Andric return SendOKResponse(); 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric return SendErrorResponse(12); 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9880b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded( 9890b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9900b57cec5SDimitry Andric packet.SetFilePos(::strlen("QEnvironmentHexEncoded:")); 9910b57cec5SDimitry Andric const uint32_t bytes_left = packet.GetBytesLeft(); 9920b57cec5SDimitry Andric if (bytes_left > 0) { 9930b57cec5SDimitry Andric std::string str; 9940b57cec5SDimitry Andric packet.GetHexByteString(str); 9950b57cec5SDimitry Andric m_process_launch_info.GetEnvironment().insert(str); 9960b57cec5SDimitry Andric return SendOKResponse(); 9970b57cec5SDimitry Andric } 9980b57cec5SDimitry Andric return SendErrorResponse(12); 9990b57cec5SDimitry Andric } 10000b57cec5SDimitry Andric 10010b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 10020b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QLaunchArch( 10030b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 10040b57cec5SDimitry Andric packet.SetFilePos(::strlen("QLaunchArch:")); 10050b57cec5SDimitry Andric const uint32_t bytes_left = packet.GetBytesLeft(); 10060b57cec5SDimitry Andric if (bytes_left > 0) { 10070b57cec5SDimitry Andric const char *arch_triple = packet.Peek(); 10080b57cec5SDimitry Andric m_process_launch_info.SetArchitecture( 10090b57cec5SDimitry Andric HostInfo::GetAugmentedArchSpec(arch_triple)); 10100b57cec5SDimitry Andric return SendOKResponse(); 10110b57cec5SDimitry Andric } 10120b57cec5SDimitry Andric return SendErrorResponse(13); 10130b57cec5SDimitry Andric } 10140b57cec5SDimitry Andric 10150b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 10160b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { 10170b57cec5SDimitry Andric // The 'A' packet is the most over designed packet ever here with redundant 10180b57cec5SDimitry Andric // argument indexes, redundant argument lengths and needed hex encoded 10190b57cec5SDimitry Andric // argument string values. Really all that is needed is a comma separated hex 10200b57cec5SDimitry Andric // encoded argument value list, but we will stay true to the documented 10210b57cec5SDimitry Andric // version of the 'A' packet here... 10220b57cec5SDimitry Andric 102381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 10240b57cec5SDimitry Andric int actual_arg_index = 0; 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric packet.SetFilePos(1); // Skip the 'A' 10270b57cec5SDimitry Andric bool success = true; 10280b57cec5SDimitry Andric while (success && packet.GetBytesLeft() > 0) { 10290b57cec5SDimitry Andric // Decode the decimal argument string length. This length is the number of 10300b57cec5SDimitry Andric // hex nibbles in the argument string value. 10310b57cec5SDimitry Andric const uint32_t arg_len = packet.GetU32(UINT32_MAX); 10320b57cec5SDimitry Andric if (arg_len == UINT32_MAX) 10330b57cec5SDimitry Andric success = false; 10340b57cec5SDimitry Andric else { 10350b57cec5SDimitry Andric // Make sure the argument hex string length is followed by a comma 10360b57cec5SDimitry Andric if (packet.GetChar() != ',') 10370b57cec5SDimitry Andric success = false; 10380b57cec5SDimitry Andric else { 10390b57cec5SDimitry Andric // Decode the argument index. We ignore this really because who would 10400b57cec5SDimitry Andric // really send down the arguments in a random order??? 10410b57cec5SDimitry Andric const uint32_t arg_idx = packet.GetU32(UINT32_MAX); 10420b57cec5SDimitry Andric if (arg_idx == UINT32_MAX) 10430b57cec5SDimitry Andric success = false; 10440b57cec5SDimitry Andric else { 10450b57cec5SDimitry Andric // Make sure the argument index is followed by a comma 10460b57cec5SDimitry Andric if (packet.GetChar() != ',') 10470b57cec5SDimitry Andric success = false; 10480b57cec5SDimitry Andric else { 10490b57cec5SDimitry Andric // Decode the argument string value from hex bytes back into a UTF8 10500b57cec5SDimitry Andric // string and make sure the length matches the one supplied in the 10510b57cec5SDimitry Andric // packet 10520b57cec5SDimitry Andric std::string arg; 10530b57cec5SDimitry Andric if (packet.GetHexByteStringFixedLength(arg, arg_len) != 10540b57cec5SDimitry Andric (arg_len / 2)) 10550b57cec5SDimitry Andric success = false; 10560b57cec5SDimitry Andric else { 10570b57cec5SDimitry Andric // If there are any bytes left 10580b57cec5SDimitry Andric if (packet.GetBytesLeft()) { 10590b57cec5SDimitry Andric if (packet.GetChar() != ',') 10600b57cec5SDimitry Andric success = false; 10610b57cec5SDimitry Andric } 10620b57cec5SDimitry Andric 10630b57cec5SDimitry Andric if (success) { 10640b57cec5SDimitry Andric if (arg_idx == 0) 10650b57cec5SDimitry Andric m_process_launch_info.GetExecutableFile().SetFile( 10660b57cec5SDimitry Andric arg, FileSpec::Style::native); 10670b57cec5SDimitry Andric m_process_launch_info.GetArguments().AppendArgument(arg); 10689dba64beSDimitry Andric LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"", 10690b57cec5SDimitry Andric __FUNCTION__, actual_arg_index, arg.c_str()); 10700b57cec5SDimitry Andric ++actual_arg_index; 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric } 10740b57cec5SDimitry Andric } 10750b57cec5SDimitry Andric } 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric } 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric if (success) { 10800b57cec5SDimitry Andric m_process_launch_error = LaunchProcess(); 10810b57cec5SDimitry Andric if (m_process_launch_error.Success()) 10820b57cec5SDimitry Andric return SendOKResponse(); 10830b57cec5SDimitry Andric LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error); 10840b57cec5SDimitry Andric } 10850b57cec5SDimitry Andric return SendErrorResponse(8); 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 10890b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qEcho( 10900b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 10910b57cec5SDimitry Andric // Just echo back the exact same packet for qEcho... 10920b57cec5SDimitry Andric return SendPacketNoLock(packet.GetStringRef()); 10930b57cec5SDimitry Andric } 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 10960b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( 10970b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 10980b57cec5SDimitry Andric packet.SetFilePos(::strlen("qModuleInfo:")); 10990b57cec5SDimitry Andric 11000b57cec5SDimitry Andric std::string module_path; 11010b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(module_path, ';'); 11020b57cec5SDimitry Andric if (module_path.empty()) 11030b57cec5SDimitry Andric return SendErrorResponse(1); 11040b57cec5SDimitry Andric 11050b57cec5SDimitry Andric if (packet.GetChar() != ';') 11060b57cec5SDimitry Andric return SendErrorResponse(2); 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric std::string triple; 11090b57cec5SDimitry Andric packet.GetHexByteString(triple); 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple); 11120b57cec5SDimitry Andric if (!matched_module_spec.GetFileSpec()) 11130b57cec5SDimitry Andric return SendErrorResponse(3); 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric const auto file_offset = matched_module_spec.GetObjectOffset(); 11160b57cec5SDimitry Andric const auto file_size = matched_module_spec.GetObjectSize(); 11170b57cec5SDimitry Andric const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric StreamGDBRemote response; 11200b57cec5SDimitry Andric 11210b57cec5SDimitry Andric if (uuid_str.empty()) { 11220b57cec5SDimitry Andric auto Result = llvm::sys::fs::md5_contents( 11230b57cec5SDimitry Andric matched_module_spec.GetFileSpec().GetPath()); 11240b57cec5SDimitry Andric if (!Result) 11250b57cec5SDimitry Andric return SendErrorResponse(5); 11260b57cec5SDimitry Andric response.PutCString("md5:"); 11270b57cec5SDimitry Andric response.PutStringAsRawHex8(Result->digest()); 11280b57cec5SDimitry Andric } else { 11290b57cec5SDimitry Andric response.PutCString("uuid:"); 11300b57cec5SDimitry Andric response.PutStringAsRawHex8(uuid_str); 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric response.PutChar(';'); 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric const auto &module_arch = matched_module_spec.GetArchitecture(); 11350b57cec5SDimitry Andric response.PutCString("triple:"); 11360b57cec5SDimitry Andric response.PutStringAsRawHex8(module_arch.GetTriple().getTriple()); 11370b57cec5SDimitry Andric response.PutChar(';'); 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andric response.PutCString("file_path:"); 1140bdd1243dSDimitry Andric response.PutStringAsRawHex8( 1141bdd1243dSDimitry Andric matched_module_spec.GetFileSpec().GetPath().c_str()); 11420b57cec5SDimitry Andric response.PutChar(';'); 11430b57cec5SDimitry Andric response.PutCString("file_offset:"); 11440b57cec5SDimitry Andric response.PutHex64(file_offset); 11450b57cec5SDimitry Andric response.PutChar(';'); 11460b57cec5SDimitry Andric response.PutCString("file_size:"); 11470b57cec5SDimitry Andric response.PutHex64(file_size); 11480b57cec5SDimitry Andric response.PutChar(';'); 11490b57cec5SDimitry Andric 11500b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 11510b57cec5SDimitry Andric } 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 11540b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_jModulesInfo( 11550b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 11569dba64beSDimitry Andric namespace json = llvm::json; 11579dba64beSDimitry Andric 11580b57cec5SDimitry Andric packet.SetFilePos(::strlen("jModulesInfo:")); 11590b57cec5SDimitry Andric 11600b57cec5SDimitry Andric StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek()); 11610b57cec5SDimitry Andric if (!object_sp) 11620b57cec5SDimitry Andric return SendErrorResponse(1); 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric StructuredData::Array *packet_array = object_sp->GetAsArray(); 11650b57cec5SDimitry Andric if (!packet_array) 11660b57cec5SDimitry Andric return SendErrorResponse(2); 11670b57cec5SDimitry Andric 11689dba64beSDimitry Andric json::Array response_array; 11690b57cec5SDimitry Andric for (size_t i = 0; i < packet_array->GetSize(); ++i) { 11700b57cec5SDimitry Andric StructuredData::Dictionary *query = 11710b57cec5SDimitry Andric packet_array->GetItemAtIndex(i)->GetAsDictionary(); 11720b57cec5SDimitry Andric if (!query) 11730b57cec5SDimitry Andric continue; 11740b57cec5SDimitry Andric llvm::StringRef file, triple; 11750b57cec5SDimitry Andric if (!query->GetValueForKeyAsString("file", file) || 11760b57cec5SDimitry Andric !query->GetValueForKeyAsString("triple", triple)) 11770b57cec5SDimitry Andric continue; 11780b57cec5SDimitry Andric 11790b57cec5SDimitry Andric ModuleSpec matched_module_spec = GetModuleInfo(file, triple); 11800b57cec5SDimitry Andric if (!matched_module_spec.GetFileSpec()) 11810b57cec5SDimitry Andric continue; 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric const auto file_offset = matched_module_spec.GetObjectOffset(); 11840b57cec5SDimitry Andric const auto file_size = matched_module_spec.GetObjectSize(); 11850b57cec5SDimitry Andric const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); 11860b57cec5SDimitry Andric if (uuid_str.empty()) 11870b57cec5SDimitry Andric continue; 11889dba64beSDimitry Andric const auto triple_str = 11899dba64beSDimitry Andric matched_module_spec.GetArchitecture().GetTriple().getTriple(); 11909dba64beSDimitry Andric const auto file_path = matched_module_spec.GetFileSpec().GetPath(); 11910b57cec5SDimitry Andric 11929dba64beSDimitry Andric json::Object response{{"uuid", uuid_str}, 11939dba64beSDimitry Andric {"triple", triple_str}, 11949dba64beSDimitry Andric {"file_path", file_path}, 11959dba64beSDimitry Andric {"file_offset", static_cast<int64_t>(file_offset)}, 11969dba64beSDimitry Andric {"file_size", static_cast<int64_t>(file_size)}}; 11979dba64beSDimitry Andric response_array.push_back(std::move(response)); 11980b57cec5SDimitry Andric } 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric StreamString response; 12019dba64beSDimitry Andric response.AsRawOstream() << std::move(response_array); 12020b57cec5SDimitry Andric StreamGDBRemote escaped_response; 12030b57cec5SDimitry Andric escaped_response.PutEscapedBytes(response.GetString().data(), 12040b57cec5SDimitry Andric response.GetSize()); 12050b57cec5SDimitry Andric return SendPacketNoLock(escaped_response.GetString()); 12060b57cec5SDimitry Andric } 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse( 12090b57cec5SDimitry Andric const ProcessInstanceInfo &proc_info, StreamString &response) { 12100b57cec5SDimitry Andric response.Printf( 12110b57cec5SDimitry Andric "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", 12120b57cec5SDimitry Andric proc_info.GetProcessID(), proc_info.GetParentProcessID(), 12130b57cec5SDimitry Andric proc_info.GetUserID(), proc_info.GetGroupID(), 12140b57cec5SDimitry Andric proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID()); 12150b57cec5SDimitry Andric response.PutCString("name:"); 1216bdd1243dSDimitry Andric response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str()); 12179dba64beSDimitry Andric 12189dba64beSDimitry Andric response.PutChar(';'); 12199dba64beSDimitry Andric response.PutCString("args:"); 12209dba64beSDimitry Andric response.PutStringAsRawHex8(proc_info.GetArg0()); 12219dba64beSDimitry Andric for (auto &arg : proc_info.GetArguments()) { 12229dba64beSDimitry Andric response.PutChar('-'); 12239dba64beSDimitry Andric response.PutStringAsRawHex8(arg.ref()); 12249dba64beSDimitry Andric } 12259dba64beSDimitry Andric 12260b57cec5SDimitry Andric response.PutChar(';'); 12270b57cec5SDimitry Andric const ArchSpec &proc_arch = proc_info.GetArchitecture(); 12280b57cec5SDimitry Andric if (proc_arch.IsValid()) { 12290b57cec5SDimitry Andric const llvm::Triple &proc_triple = proc_arch.GetTriple(); 12300b57cec5SDimitry Andric response.PutCString("triple:"); 12310b57cec5SDimitry Andric response.PutStringAsRawHex8(proc_triple.getTriple()); 12320b57cec5SDimitry Andric response.PutChar(';'); 12330b57cec5SDimitry Andric } 12340b57cec5SDimitry Andric } 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric void GDBRemoteCommunicationServerCommon:: 12370b57cec5SDimitry Andric CreateProcessInfoResponse_DebugServerStyle( 12380b57cec5SDimitry Andric const ProcessInstanceInfo &proc_info, StreamString &response) { 12390b57cec5SDimitry Andric response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64 12400b57cec5SDimitry Andric ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;", 12410b57cec5SDimitry Andric proc_info.GetProcessID(), proc_info.GetParentProcessID(), 12420b57cec5SDimitry Andric proc_info.GetUserID(), proc_info.GetGroupID(), 12430b57cec5SDimitry Andric proc_info.GetEffectiveUserID(), 12440b57cec5SDimitry Andric proc_info.GetEffectiveGroupID()); 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andric const ArchSpec &proc_arch = proc_info.GetArchitecture(); 12470b57cec5SDimitry Andric if (proc_arch.IsValid()) { 12480b57cec5SDimitry Andric const llvm::Triple &proc_triple = proc_arch.GetTriple(); 12490b57cec5SDimitry Andric #if defined(__APPLE__) 12500b57cec5SDimitry Andric // We'll send cputype/cpusubtype. 12510b57cec5SDimitry Andric const uint32_t cpu_type = proc_arch.GetMachOCPUType(); 12520b57cec5SDimitry Andric if (cpu_type != 0) 12530b57cec5SDimitry Andric response.Printf("cputype:%" PRIx32 ";", cpu_type); 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andric const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType(); 12560b57cec5SDimitry Andric if (cpu_subtype != 0) 12570b57cec5SDimitry Andric response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype); 12580b57cec5SDimitry Andric 12595ffd83dbSDimitry Andric const std::string vendor = proc_triple.getVendorName().str(); 12600b57cec5SDimitry Andric if (!vendor.empty()) 12610b57cec5SDimitry Andric response.Printf("vendor:%s;", vendor.c_str()); 12620b57cec5SDimitry Andric #else 12630b57cec5SDimitry Andric // We'll send the triple. 12640b57cec5SDimitry Andric response.PutCString("triple:"); 12650b57cec5SDimitry Andric response.PutStringAsRawHex8(proc_triple.getTriple()); 12660b57cec5SDimitry Andric response.PutChar(';'); 12670b57cec5SDimitry Andric #endif 12685ffd83dbSDimitry Andric std::string ostype = std::string(proc_triple.getOSName()); 12690b57cec5SDimitry Andric // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64. 12700b57cec5SDimitry Andric if (proc_triple.getVendor() == llvm::Triple::Apple) { 12710b57cec5SDimitry Andric switch (proc_triple.getArch()) { 12720b57cec5SDimitry Andric case llvm::Triple::arm: 12730b57cec5SDimitry Andric case llvm::Triple::thumb: 12740b57cec5SDimitry Andric case llvm::Triple::aarch64: 12759dba64beSDimitry Andric case llvm::Triple::aarch64_32: 12760b57cec5SDimitry Andric ostype = "ios"; 12770b57cec5SDimitry Andric break; 12780b57cec5SDimitry Andric default: 12790b57cec5SDimitry Andric // No change. 12800b57cec5SDimitry Andric break; 12810b57cec5SDimitry Andric } 12820b57cec5SDimitry Andric } 12830b57cec5SDimitry Andric response.Printf("ostype:%s;", ostype.c_str()); 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric switch (proc_arch.GetByteOrder()) { 12860b57cec5SDimitry Andric case lldb::eByteOrderLittle: 12870b57cec5SDimitry Andric response.PutCString("endian:little;"); 12880b57cec5SDimitry Andric break; 12890b57cec5SDimitry Andric case lldb::eByteOrderBig: 12900b57cec5SDimitry Andric response.PutCString("endian:big;"); 12910b57cec5SDimitry Andric break; 12920b57cec5SDimitry Andric case lldb::eByteOrderPDP: 12930b57cec5SDimitry Andric response.PutCString("endian:pdp;"); 12940b57cec5SDimitry Andric break; 12950b57cec5SDimitry Andric default: 12960b57cec5SDimitry Andric // Nothing. 12970b57cec5SDimitry Andric break; 12980b57cec5SDimitry Andric } 12990b57cec5SDimitry Andric // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer 13000b57cec5SDimitry Andric // size is 4 and for N64 it is 8 13010b57cec5SDimitry Andric std::string abi = proc_arch.GetTargetABI(); 13020b57cec5SDimitry Andric if (!abi.empty()) 13030b57cec5SDimitry Andric response.Printf("elf_abi:%s;", abi.c_str()); 13040b57cec5SDimitry Andric response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize()); 13050b57cec5SDimitry Andric } 13060b57cec5SDimitry Andric } 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( 13090b57cec5SDimitry Andric const std::string &module_path, const ArchSpec &arch) { 13100b57cec5SDimitry Andric #ifdef __ANDROID__ 13110b57cec5SDimitry Andric return HostInfoAndroid::ResolveLibraryPath(module_path, arch); 13120b57cec5SDimitry Andric #else 13130b57cec5SDimitry Andric FileSpec file_spec(module_path); 13140b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec); 13150b57cec5SDimitry Andric return file_spec; 13160b57cec5SDimitry Andric #endif 13170b57cec5SDimitry Andric } 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric ModuleSpec 13200b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, 13210b57cec5SDimitry Andric llvm::StringRef triple) { 13220b57cec5SDimitry Andric ArchSpec arch(triple); 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andric FileSpec req_module_path_spec(module_path); 13250b57cec5SDimitry Andric FileSystem::Instance().Resolve(req_module_path_spec); 13260b57cec5SDimitry Andric 13270b57cec5SDimitry Andric const FileSpec module_path_spec = 13280b57cec5SDimitry Andric FindModuleFile(req_module_path_spec.GetPath(), arch); 132906c3fb27SDimitry Andric 133006c3fb27SDimitry Andric lldb::offset_t file_offset = 0; 133106c3fb27SDimitry Andric lldb::offset_t file_size = 0; 133206c3fb27SDimitry Andric #ifdef __ANDROID__ 133306c3fb27SDimitry Andric // In Android API level 23 and above, dynamic loader is able to load .so file 133406c3fb27SDimitry Andric // directly from zip file. In that case, module_path will be 133506c3fb27SDimitry Andric // "zip_path!/so_path". Resolve the zip file path, .so file offset and size. 133606c3fb27SDimitry Andric ZipFileResolver::FileKind file_kind = ZipFileResolver::eFileKindInvalid; 133706c3fb27SDimitry Andric std::string file_path; 133806c3fb27SDimitry Andric if (!ZipFileResolver::ResolveSharedLibraryPath( 133906c3fb27SDimitry Andric module_path_spec, file_kind, file_path, file_offset, file_size)) { 134006c3fb27SDimitry Andric return ModuleSpec(); 134106c3fb27SDimitry Andric } 134206c3fb27SDimitry Andric lldbassert(file_kind != ZipFileResolver::eFileKindInvalid); 134306c3fb27SDimitry Andric // For zip .so file, this file_path will contain only the actual zip file 134406c3fb27SDimitry Andric // path for the object file processing. Otherwise it is the same as 134506c3fb27SDimitry Andric // module_path. 134606c3fb27SDimitry Andric const FileSpec actual_module_path_spec(file_path); 134706c3fb27SDimitry Andric #else 134806c3fb27SDimitry Andric // It is just module_path_spec reference for other platforms. 134906c3fb27SDimitry Andric const FileSpec &actual_module_path_spec = module_path_spec; 135006c3fb27SDimitry Andric #endif 135106c3fb27SDimitry Andric 135206c3fb27SDimitry Andric const ModuleSpec module_spec(actual_module_path_spec, arch); 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric ModuleSpecList module_specs; 135506c3fb27SDimitry Andric if (!ObjectFile::GetModuleSpecifications(actual_module_path_spec, file_offset, 135606c3fb27SDimitry Andric file_size, module_specs)) 13570b57cec5SDimitry Andric return ModuleSpec(); 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric ModuleSpec matched_module_spec; 13600b57cec5SDimitry Andric if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) 13610b57cec5SDimitry Andric return ModuleSpec(); 13620b57cec5SDimitry Andric 136306c3fb27SDimitry Andric #ifdef __ANDROID__ 136406c3fb27SDimitry Andric if (file_kind == ZipFileResolver::eFileKindZip) { 136506c3fb27SDimitry Andric // For zip .so file, matched_module_spec contains only the actual zip file 136606c3fb27SDimitry Andric // path for the object file processing. Overwrite the matched_module_spec 136706c3fb27SDimitry Andric // file spec with the original module_path_spec to pass "zip_path!/so_path" 136806c3fb27SDimitry Andric // through to PlatformAndroid::DownloadModuleSlice. 136906c3fb27SDimitry Andric *matched_module_spec.GetFileSpecPtr() = module_path_spec; 137006c3fb27SDimitry Andric } 137106c3fb27SDimitry Andric #endif 137206c3fb27SDimitry Andric 13730b57cec5SDimitry Andric return matched_module_spec; 13740b57cec5SDimitry Andric } 1375fe6060f1SDimitry Andric 1376fe6060f1SDimitry Andric std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures( 1377fe6060f1SDimitry Andric const llvm::ArrayRef<llvm::StringRef> client_features) { 1378fe6060f1SDimitry Andric // 128KBytes is a reasonable max packet size--debugger can always use less. 1379fe6060f1SDimitry Andric constexpr uint32_t max_packet_size = 128 * 1024; 1380fe6060f1SDimitry Andric 1381fe6060f1SDimitry Andric // Features common to platform server and llgs. 1382fe6060f1SDimitry Andric return { 1383fe6060f1SDimitry Andric llvm::formatv("PacketSize={0}", max_packet_size), 1384fe6060f1SDimitry Andric "QStartNoAckMode+", 1385fe6060f1SDimitry Andric "qEcho+", 1386349cc55cSDimitry Andric "native-signals+", 1387fe6060f1SDimitry Andric }; 1388fe6060f1SDimitry Andric } 1389