10b57cec5SDimitry Andric //===-- GDBRemoteCommunicationServerCommon.cpp ------------------*- C++ -*-===// 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 110b57cec5SDimitry Andric #include <errno.h> 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifdef __APPLE__ 140b57cec5SDimitry Andric #include <TargetConditionals.h> 150b57cec5SDimitry Andric #endif 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include <chrono> 180b57cec5SDimitry Andric #include <cstring> 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h" 210b57cec5SDimitry Andric #include "lldb/Host/Config.h" 220b57cec5SDimitry Andric #include "lldb/Host/File.h" 230b57cec5SDimitry Andric #include "lldb/Host/FileAction.h" 240b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h" 250b57cec5SDimitry Andric #include "lldb/Host/Host.h" 260b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h" 270b57cec5SDimitry Andric #include "lldb/Host/SafeMachO.h" 280b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h" 290b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 300b57cec5SDimitry Andric #include "lldb/Target/Platform.h" 310b57cec5SDimitry Andric #include "lldb/Utility/Endian.h" 32*9dba64beSDimitry Andric #include "lldb/Utility/GDBRemote.h" 330b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 340b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 350b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h" 36*9dba64beSDimitry Andric #include "llvm/ADT/StringSwitch.h" 370b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 38*9dba64beSDimitry Andric #include "llvm/Support/JSON.h" 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric #include "ProcessGDBRemoteLog.h" 410b57cec5SDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h" 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric #ifdef __ANDROID__ 440b57cec5SDimitry Andric #include "lldb/Host/android/HostInfoAndroid.h" 450b57cec5SDimitry Andric #endif 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric using namespace lldb; 490b57cec5SDimitry Andric using namespace lldb_private::process_gdb_remote; 50*9dba64beSDimitry Andric using namespace lldb_private; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric #ifdef __ANDROID__ 530b57cec5SDimitry Andric const static uint32_t g_default_packet_timeout_sec = 20; // seconds 540b57cec5SDimitry Andric #else 550b57cec5SDimitry Andric const static uint32_t g_default_packet_timeout_sec = 0; // not specified 560b57cec5SDimitry Andric #endif 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric // GDBRemoteCommunicationServerCommon constructor 590b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( 600b57cec5SDimitry Andric const char *comm_name, const char *listener_name) 610b57cec5SDimitry Andric : GDBRemoteCommunicationServer(comm_name, listener_name), 620b57cec5SDimitry Andric m_process_launch_info(), m_process_launch_error(), m_proc_infos(), 630b57cec5SDimitry Andric m_proc_infos_index(0), m_thread_suffix_supported(false), 640b57cec5SDimitry Andric m_list_threads_in_stop_reply(false) { 650b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A, 660b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_A); 670b57cec5SDimitry Andric RegisterMemberFunctionHandler( 680b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QEnvironment, 690b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QEnvironment); 700b57cec5SDimitry Andric RegisterMemberFunctionHandler( 710b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded, 720b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded); 730b57cec5SDimitry Andric RegisterMemberFunctionHandler( 740b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qfProcessInfo, 750b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo); 760b57cec5SDimitry Andric RegisterMemberFunctionHandler( 770b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qGroupName, 780b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qGroupName); 790b57cec5SDimitry Andric RegisterMemberFunctionHandler( 800b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qHostInfo, 810b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qHostInfo); 820b57cec5SDimitry Andric RegisterMemberFunctionHandler( 830b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QLaunchArch, 840b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch); 850b57cec5SDimitry Andric RegisterMemberFunctionHandler( 860b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess, 870b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess); 880b57cec5SDimitry Andric RegisterMemberFunctionHandler( 890b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply, 900b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply); 910b57cec5SDimitry Andric RegisterMemberFunctionHandler( 920b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qEcho, 930b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qEcho); 940b57cec5SDimitry Andric RegisterMemberFunctionHandler( 950b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qModuleInfo, 960b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo); 970b57cec5SDimitry Andric RegisterMemberFunctionHandler( 980b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jModulesInfo, 990b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo); 1000b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1010b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod, 1020b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod); 1030b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1040b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir, 1050b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir); 1060b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1070b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qPlatform_shell, 1080b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell); 1090b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1100b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID, 1110b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID); 1120b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1130b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError, 1140b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError); 1150b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1160b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetSTDERR, 1170b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR); 1180b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1190b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetSTDIN, 1200b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN); 1210b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1220b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT, 1230b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT); 1240b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1250b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qSpeedTest, 1260b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest); 1270b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1280b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qsProcessInfo, 1290b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo); 1300b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1310b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode, 1320b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode); 1330b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1340b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qSupported, 1350b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qSupported); 1360b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1370b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported, 1380b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported); 1390b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1400b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qUserName, 1410b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_qUserName); 1420b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1430b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_close, 1440b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Close); 1450b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1460b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_exists, 1470b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists); 1480b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1490b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_md5, 1500b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5); 1510b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1520b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_mode, 1530b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode); 1540b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1550b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_open, 1560b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Open); 1570b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1580b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_pread, 1590b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead); 1600b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1610b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_pwrite, 1620b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite); 1630b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1640b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_size, 1650b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Size); 1660b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1670b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_stat, 1680b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat); 1690b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1700b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_symlink, 1710b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink); 1720b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1730b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vFile_unlink, 1740b57cec5SDimitry Andric &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink); 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric // Destructor 1780b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {} 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1810b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qHostInfo( 1820b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 1830b57cec5SDimitry Andric StreamString response; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric ArchSpec host_arch(HostInfo::GetArchitecture()); 1880b57cec5SDimitry Andric const llvm::Triple &host_triple = host_arch.GetTriple(); 1890b57cec5SDimitry Andric response.PutCString("triple:"); 1900b57cec5SDimitry Andric response.PutStringAsRawHex8(host_triple.getTriple()); 1910b57cec5SDimitry Andric response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize()); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric const char *distribution_id = host_arch.GetDistributionId().AsCString(); 1940b57cec5SDimitry Andric if (distribution_id) { 1950b57cec5SDimitry Andric response.PutCString("distribution_id:"); 1960b57cec5SDimitry Andric response.PutStringAsRawHex8(distribution_id); 1970b57cec5SDimitry Andric response.PutCString(";"); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric #if defined(__APPLE__) 2010b57cec5SDimitry Andric // For parity with debugserver, we'll include the vendor key. 2020b57cec5SDimitry Andric response.PutCString("vendor:apple;"); 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric // Send out MachO info. 2050b57cec5SDimitry Andric uint32_t cpu = host_arch.GetMachOCPUType(); 2060b57cec5SDimitry Andric uint32_t sub = host_arch.GetMachOCPUSubType(); 2070b57cec5SDimitry Andric if (cpu != LLDB_INVALID_CPUTYPE) 2080b57cec5SDimitry Andric response.Printf("cputype:%u;", cpu); 2090b57cec5SDimitry Andric if (sub != LLDB_INVALID_CPUTYPE) 2100b57cec5SDimitry Andric response.Printf("cpusubtype:%u;", sub); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) { 2130b57cec5SDimitry Andric // Indicate the OS type. 2140b57cec5SDimitry Andric #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 2150b57cec5SDimitry Andric response.PutCString("ostype:tvos;"); 2160b57cec5SDimitry Andric #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 2170b57cec5SDimitry Andric response.PutCString("ostype:watchos;"); 2180b57cec5SDimitry Andric #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 2190b57cec5SDimitry Andric response.PutCString("ostype:bridgeos;"); 2200b57cec5SDimitry Andric #else 2210b57cec5SDimitry Andric response.PutCString("ostype:ios;"); 2220b57cec5SDimitry Andric #endif 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric // On arm, we use "synchronous" watchpoints which means the exception is 2250b57cec5SDimitry Andric // delivered before the instruction executes. 2260b57cec5SDimitry Andric response.PutCString("watchpoint_exceptions_received:before;"); 2270b57cec5SDimitry Andric } else { 2280b57cec5SDimitry Andric response.PutCString("ostype:macosx;"); 2290b57cec5SDimitry Andric response.Printf("watchpoint_exceptions_received:after;"); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric #else 2330b57cec5SDimitry Andric if (host_arch.GetMachine() == llvm::Triple::aarch64 || 234*9dba64beSDimitry Andric host_arch.GetMachine() == llvm::Triple::aarch64_32 || 2350b57cec5SDimitry Andric host_arch.GetMachine() == llvm::Triple::aarch64_be || 2360b57cec5SDimitry Andric host_arch.GetMachine() == llvm::Triple::arm || 2370b57cec5SDimitry Andric host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS()) 2380b57cec5SDimitry Andric response.Printf("watchpoint_exceptions_received:before;"); 2390b57cec5SDimitry Andric else 2400b57cec5SDimitry Andric response.Printf("watchpoint_exceptions_received:after;"); 2410b57cec5SDimitry Andric #endif 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric switch (endian::InlHostByteOrder()) { 2440b57cec5SDimitry Andric case eByteOrderBig: 2450b57cec5SDimitry Andric response.PutCString("endian:big;"); 2460b57cec5SDimitry Andric break; 2470b57cec5SDimitry Andric case eByteOrderLittle: 2480b57cec5SDimitry Andric response.PutCString("endian:little;"); 2490b57cec5SDimitry Andric break; 2500b57cec5SDimitry Andric case eByteOrderPDP: 2510b57cec5SDimitry Andric response.PutCString("endian:pdp;"); 2520b57cec5SDimitry Andric break; 2530b57cec5SDimitry Andric default: 2540b57cec5SDimitry Andric response.PutCString("endian:unknown;"); 2550b57cec5SDimitry Andric break; 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric llvm::VersionTuple version = HostInfo::GetOSVersion(); 2590b57cec5SDimitry Andric if (!version.empty()) { 2600b57cec5SDimitry Andric response.Format("os_version:{0}", version.getAsString()); 2610b57cec5SDimitry Andric response.PutChar(';'); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 264*9dba64beSDimitry Andric #if defined(__APPLE__) 265*9dba64beSDimitry Andric llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion(); 266*9dba64beSDimitry Andric if (!maccatalyst_version.empty()) { 267*9dba64beSDimitry Andric response.Format("maccatalyst_version:{0}", 268*9dba64beSDimitry Andric maccatalyst_version.getAsString()); 269*9dba64beSDimitry Andric response.PutChar(';'); 270*9dba64beSDimitry Andric } 271*9dba64beSDimitry Andric #endif 272*9dba64beSDimitry Andric 2730b57cec5SDimitry Andric std::string s; 2740b57cec5SDimitry Andric if (HostInfo::GetOSBuildString(s)) { 2750b57cec5SDimitry Andric response.PutCString("os_build:"); 2760b57cec5SDimitry Andric response.PutStringAsRawHex8(s); 2770b57cec5SDimitry Andric response.PutChar(';'); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric if (HostInfo::GetOSKernelDescription(s)) { 2800b57cec5SDimitry Andric response.PutCString("os_kernel:"); 2810b57cec5SDimitry Andric response.PutStringAsRawHex8(s); 2820b57cec5SDimitry Andric response.PutChar(';'); 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric #if defined(__APPLE__) 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 2880b57cec5SDimitry Andric // For iOS devices, we are connected through a USB Mux so we never pretend to 2890b57cec5SDimitry Andric // actually have a hostname as far as the remote lldb that is connecting to 2900b57cec5SDimitry Andric // this lldb-platform is concerned 2910b57cec5SDimitry Andric response.PutCString("hostname:"); 2920b57cec5SDimitry Andric response.PutStringAsRawHex8("127.0.0.1"); 2930b57cec5SDimitry Andric response.PutChar(';'); 2940b57cec5SDimitry Andric #else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 2950b57cec5SDimitry Andric if (HostInfo::GetHostname(s)) { 2960b57cec5SDimitry Andric response.PutCString("hostname:"); 2970b57cec5SDimitry Andric response.PutStringAsRawHex8(s); 2980b57cec5SDimitry Andric response.PutChar(';'); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric #endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric #else // #if defined(__APPLE__) 3030b57cec5SDimitry Andric if (HostInfo::GetHostname(s)) { 3040b57cec5SDimitry Andric response.PutCString("hostname:"); 3050b57cec5SDimitry Andric response.PutStringAsRawHex8(s); 3060b57cec5SDimitry Andric response.PutChar(';'); 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric #endif // #if defined(__APPLE__) 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric if (g_default_packet_timeout_sec > 0) 3110b57cec5SDimitry Andric response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec); 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 3170b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID( 3180b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 3190b57cec5SDimitry Andric // Packet format: "qProcessInfoPID:%i" where %i is the pid 3200b57cec5SDimitry Andric packet.SetFilePos(::strlen("qProcessInfoPID:")); 3210b57cec5SDimitry Andric lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID); 3220b57cec5SDimitry Andric if (pid != LLDB_INVALID_PROCESS_ID) { 3230b57cec5SDimitry Andric ProcessInstanceInfo proc_info; 3240b57cec5SDimitry Andric if (Host::GetProcessInfo(pid, proc_info)) { 3250b57cec5SDimitry Andric StreamString response; 3260b57cec5SDimitry Andric CreateProcessInfoResponse(proc_info, response); 3270b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric return SendErrorResponse(1); 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 3340b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( 3350b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 3360b57cec5SDimitry Andric m_proc_infos_index = 0; 3370b57cec5SDimitry Andric m_proc_infos.Clear(); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric ProcessInstanceInfoMatch match_info; 3400b57cec5SDimitry Andric packet.SetFilePos(::strlen("qfProcessInfo")); 3410b57cec5SDimitry Andric if (packet.GetChar() == ':') { 3420b57cec5SDimitry Andric llvm::StringRef key; 3430b57cec5SDimitry Andric llvm::StringRef value; 3440b57cec5SDimitry Andric while (packet.GetNameColonValue(key, value)) { 3450b57cec5SDimitry Andric bool success = true; 3460b57cec5SDimitry Andric if (key.equals("name")) { 3470b57cec5SDimitry Andric StringExtractor extractor(value); 3480b57cec5SDimitry Andric std::string file; 3490b57cec5SDimitry Andric extractor.GetHexByteString(file); 3500b57cec5SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile( 3510b57cec5SDimitry Andric file, FileSpec::Style::native); 3520b57cec5SDimitry Andric } else if (key.equals("name_match")) { 3530b57cec5SDimitry Andric NameMatch name_match = llvm::StringSwitch<NameMatch>(value) 3540b57cec5SDimitry Andric .Case("equals", NameMatch::Equals) 3550b57cec5SDimitry Andric .Case("starts_with", NameMatch::StartsWith) 3560b57cec5SDimitry Andric .Case("ends_with", NameMatch::EndsWith) 3570b57cec5SDimitry Andric .Case("contains", NameMatch::Contains) 3580b57cec5SDimitry Andric .Case("regex", NameMatch::RegularExpression) 3590b57cec5SDimitry Andric .Default(NameMatch::Ignore); 3600b57cec5SDimitry Andric match_info.SetNameMatchType(name_match); 3610b57cec5SDimitry Andric if (name_match == NameMatch::Ignore) 3620b57cec5SDimitry Andric return SendErrorResponse(2); 3630b57cec5SDimitry Andric } else if (key.equals("pid")) { 3640b57cec5SDimitry Andric lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 3650b57cec5SDimitry Andric if (value.getAsInteger(0, pid)) 3660b57cec5SDimitry Andric return SendErrorResponse(2); 3670b57cec5SDimitry Andric match_info.GetProcessInfo().SetProcessID(pid); 3680b57cec5SDimitry Andric } else if (key.equals("parent_pid")) { 3690b57cec5SDimitry Andric lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 3700b57cec5SDimitry Andric if (value.getAsInteger(0, pid)) 3710b57cec5SDimitry Andric return SendErrorResponse(2); 3720b57cec5SDimitry Andric match_info.GetProcessInfo().SetParentProcessID(pid); 3730b57cec5SDimitry Andric } else if (key.equals("uid")) { 3740b57cec5SDimitry Andric uint32_t uid = UINT32_MAX; 3750b57cec5SDimitry Andric if (value.getAsInteger(0, uid)) 3760b57cec5SDimitry Andric return SendErrorResponse(2); 3770b57cec5SDimitry Andric match_info.GetProcessInfo().SetUserID(uid); 3780b57cec5SDimitry Andric } else if (key.equals("gid")) { 3790b57cec5SDimitry Andric uint32_t gid = UINT32_MAX; 3800b57cec5SDimitry Andric if (value.getAsInteger(0, gid)) 3810b57cec5SDimitry Andric return SendErrorResponse(2); 3820b57cec5SDimitry Andric match_info.GetProcessInfo().SetGroupID(gid); 3830b57cec5SDimitry Andric } else if (key.equals("euid")) { 3840b57cec5SDimitry Andric uint32_t uid = UINT32_MAX; 3850b57cec5SDimitry Andric if (value.getAsInteger(0, uid)) 3860b57cec5SDimitry Andric return SendErrorResponse(2); 3870b57cec5SDimitry Andric match_info.GetProcessInfo().SetEffectiveUserID(uid); 3880b57cec5SDimitry Andric } else if (key.equals("egid")) { 3890b57cec5SDimitry Andric uint32_t gid = UINT32_MAX; 3900b57cec5SDimitry Andric if (value.getAsInteger(0, gid)) 3910b57cec5SDimitry Andric return SendErrorResponse(2); 3920b57cec5SDimitry Andric match_info.GetProcessInfo().SetEffectiveGroupID(gid); 3930b57cec5SDimitry Andric } else if (key.equals("all_users")) { 3940b57cec5SDimitry Andric match_info.SetMatchAllUsers( 3950b57cec5SDimitry Andric OptionArgParser::ToBoolean(value, false, &success)); 3960b57cec5SDimitry Andric } else if (key.equals("triple")) { 3970b57cec5SDimitry Andric match_info.GetProcessInfo().GetArchitecture() = 3980b57cec5SDimitry Andric HostInfo::GetAugmentedArchSpec(value); 3990b57cec5SDimitry Andric } else { 4000b57cec5SDimitry Andric success = false; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric if (!success) 4040b57cec5SDimitry Andric return SendErrorResponse(2); 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric if (Host::FindProcesses(match_info, m_proc_infos)) { 4090b57cec5SDimitry Andric // We found something, return the first item by calling the get subsequent 4100b57cec5SDimitry Andric // process info packet handler... 4110b57cec5SDimitry Andric return Handle_qsProcessInfo(packet); 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric return SendErrorResponse(3); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4170b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo( 4180b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 4190b57cec5SDimitry Andric if (m_proc_infos_index < m_proc_infos.GetSize()) { 4200b57cec5SDimitry Andric StreamString response; 4210b57cec5SDimitry Andric CreateProcessInfoResponse( 4220b57cec5SDimitry Andric m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); 4230b57cec5SDimitry Andric ++m_proc_infos_index; 4240b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric return SendErrorResponse(4); 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4300b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qUserName( 4310b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 4320b57cec5SDimitry Andric #if !defined(LLDB_DISABLE_POSIX) 4330b57cec5SDimitry Andric Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); 434*9dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric // Packet format: "qUserName:%i" where %i is the uid 4370b57cec5SDimitry Andric packet.SetFilePos(::strlen("qUserName:")); 4380b57cec5SDimitry Andric uint32_t uid = packet.GetU32(UINT32_MAX); 4390b57cec5SDimitry Andric if (uid != UINT32_MAX) { 4400b57cec5SDimitry Andric if (llvm::Optional<llvm::StringRef> name = 4410b57cec5SDimitry Andric HostInfo::GetUserIDResolver().GetUserName(uid)) { 4420b57cec5SDimitry Andric StreamString response; 4430b57cec5SDimitry Andric response.PutStringAsRawHex8(*name); 4440b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric } 447*9dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__); 4480b57cec5SDimitry Andric #endif 4490b57cec5SDimitry Andric return SendErrorResponse(5); 4500b57cec5SDimitry Andric } 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4530b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qGroupName( 4540b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 4550b57cec5SDimitry Andric #if !defined(LLDB_DISABLE_POSIX) 4560b57cec5SDimitry Andric // Packet format: "qGroupName:%i" where %i is the gid 4570b57cec5SDimitry Andric packet.SetFilePos(::strlen("qGroupName:")); 4580b57cec5SDimitry Andric uint32_t gid = packet.GetU32(UINT32_MAX); 4590b57cec5SDimitry Andric if (gid != UINT32_MAX) { 4600b57cec5SDimitry Andric if (llvm::Optional<llvm::StringRef> name = 4610b57cec5SDimitry Andric HostInfo::GetUserIDResolver().GetGroupName(gid)) { 4620b57cec5SDimitry Andric StreamString response; 4630b57cec5SDimitry Andric response.PutStringAsRawHex8(*name); 4640b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric #endif 4680b57cec5SDimitry Andric return SendErrorResponse(6); 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4720b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qSpeedTest( 4730b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 4740b57cec5SDimitry Andric packet.SetFilePos(::strlen("qSpeedTest:")); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric llvm::StringRef key; 4770b57cec5SDimitry Andric llvm::StringRef value; 4780b57cec5SDimitry Andric bool success = packet.GetNameColonValue(key, value); 4790b57cec5SDimitry Andric if (success && key.equals("response_size")) { 4800b57cec5SDimitry Andric uint32_t response_size = 0; 4810b57cec5SDimitry Andric if (!value.getAsInteger(0, response_size)) { 4820b57cec5SDimitry Andric if (response_size == 0) 4830b57cec5SDimitry Andric return SendOKResponse(); 4840b57cec5SDimitry Andric StreamString response; 4850b57cec5SDimitry Andric uint32_t bytes_left = response_size; 4860b57cec5SDimitry Andric response.PutCString("data:"); 4870b57cec5SDimitry Andric while (bytes_left > 0) { 4880b57cec5SDimitry Andric if (bytes_left >= 26) { 4890b57cec5SDimitry Andric response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 4900b57cec5SDimitry Andric bytes_left -= 26; 4910b57cec5SDimitry Andric } else { 4920b57cec5SDimitry Andric response.Printf("%*.*s;", bytes_left, bytes_left, 4930b57cec5SDimitry Andric "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 4940b57cec5SDimitry Andric bytes_left = 0; 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric return SendErrorResponse(7); 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 5040b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Open( 5050b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 5060b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:open:")); 5070b57cec5SDimitry Andric std::string path; 5080b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(path, ','); 5090b57cec5SDimitry Andric if (!path.empty()) { 5100b57cec5SDimitry Andric if (packet.GetChar() == ',') { 511*9dba64beSDimitry Andric // FIXME 512*9dba64beSDimitry Andric // The flag values for OpenOptions do not match the values used by GDB 513*9dba64beSDimitry Andric // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags 514*9dba64beSDimitry Andric // * rdar://problem/46788934 515*9dba64beSDimitry Andric auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0)); 5160b57cec5SDimitry Andric if (packet.GetChar() == ',') { 5170b57cec5SDimitry Andric mode_t mode = packet.GetHexMaxU32(false, 0600); 5180b57cec5SDimitry Andric FileSpec path_spec(path); 5190b57cec5SDimitry Andric FileSystem::Instance().Resolve(path_spec); 5200b57cec5SDimitry Andric // Do not close fd. 521*9dba64beSDimitry Andric auto file = FileSystem::Instance().Open(path_spec, flags, mode, false); 522*9dba64beSDimitry Andric 523*9dba64beSDimitry Andric int save_errno = 0; 524*9dba64beSDimitry Andric int descriptor = File::kInvalidDescriptor; 525*9dba64beSDimitry Andric if (file) { 526*9dba64beSDimitry Andric descriptor = file.get()->GetDescriptor(); 527*9dba64beSDimitry Andric } else { 528*9dba64beSDimitry Andric std::error_code code = errorToErrorCode(file.takeError()); 529*9dba64beSDimitry Andric if (code.category() == std::system_category()) { 530*9dba64beSDimitry Andric save_errno = code.value(); 531*9dba64beSDimitry Andric } 532*9dba64beSDimitry Andric } 533*9dba64beSDimitry Andric 5340b57cec5SDimitry Andric StreamString response; 5350b57cec5SDimitry Andric response.PutChar('F'); 536*9dba64beSDimitry Andric response.Printf("%i", descriptor); 5370b57cec5SDimitry Andric if (save_errno) 5380b57cec5SDimitry Andric response.Printf(",%i", save_errno); 5390b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric return SendErrorResponse(18); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 5470b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Close( 5480b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 5490b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:close:")); 5500b57cec5SDimitry Andric int fd = packet.GetS32(-1); 5510b57cec5SDimitry Andric int err = -1; 5520b57cec5SDimitry Andric int save_errno = 0; 5530b57cec5SDimitry Andric if (fd >= 0) { 554*9dba64beSDimitry Andric NativeFile file(fd, File::OpenOptions(0), true); 5550b57cec5SDimitry Andric Status error = file.Close(); 5560b57cec5SDimitry Andric err = 0; 5570b57cec5SDimitry Andric save_errno = error.GetError(); 5580b57cec5SDimitry Andric } else { 5590b57cec5SDimitry Andric save_errno = EINVAL; 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric StreamString response; 5620b57cec5SDimitry Andric response.PutChar('F'); 5630b57cec5SDimitry Andric response.Printf("%i", err); 5640b57cec5SDimitry Andric if (save_errno) 5650b57cec5SDimitry Andric response.Printf(",%i", save_errno); 5660b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 5700b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_pRead( 5710b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 5720b57cec5SDimitry Andric StreamGDBRemote response; 5730b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:pread:")); 5740b57cec5SDimitry Andric int fd = packet.GetS32(-1); 5750b57cec5SDimitry Andric if (packet.GetChar() == ',') { 576*9dba64beSDimitry Andric size_t count = packet.GetU64(SIZE_MAX); 5770b57cec5SDimitry Andric if (packet.GetChar() == ',') { 5780b57cec5SDimitry Andric off_t offset = packet.GetU64(UINT32_MAX); 579*9dba64beSDimitry Andric if (count == SIZE_MAX) { 5800b57cec5SDimitry Andric response.Printf("F-1:%i", EINVAL); 5810b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric std::string buffer(count, 0); 585*9dba64beSDimitry Andric NativeFile file(fd, File::eOpenOptionRead, false); 5860b57cec5SDimitry Andric Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset); 5870b57cec5SDimitry Andric const ssize_t bytes_read = error.Success() ? count : -1; 5880b57cec5SDimitry Andric const int save_errno = error.GetError(); 5890b57cec5SDimitry Andric response.PutChar('F'); 5900b57cec5SDimitry Andric response.Printf("%zi", bytes_read); 5910b57cec5SDimitry Andric if (save_errno) 5920b57cec5SDimitry Andric response.Printf(",%i", save_errno); 5930b57cec5SDimitry Andric else { 5940b57cec5SDimitry Andric response.PutChar(';'); 5950b57cec5SDimitry Andric response.PutEscapedBytes(&buffer[0], bytes_read); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric return SendErrorResponse(21); 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6040b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite( 6050b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6060b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:pwrite:")); 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric StreamGDBRemote response; 6090b57cec5SDimitry Andric response.PutChar('F'); 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric int fd = packet.GetU32(UINT32_MAX); 6120b57cec5SDimitry Andric if (packet.GetChar() == ',') { 6130b57cec5SDimitry Andric off_t offset = packet.GetU64(UINT32_MAX); 6140b57cec5SDimitry Andric if (packet.GetChar() == ',') { 6150b57cec5SDimitry Andric std::string buffer; 6160b57cec5SDimitry Andric if (packet.GetEscapedBinaryData(buffer)) { 617*9dba64beSDimitry Andric NativeFile file(fd, File::eOpenOptionWrite, false); 6180b57cec5SDimitry Andric size_t count = buffer.size(); 6190b57cec5SDimitry Andric Status error = 6200b57cec5SDimitry Andric file.Write(static_cast<const void *>(&buffer[0]), count, offset); 6210b57cec5SDimitry Andric const ssize_t bytes_written = error.Success() ? count : -1; 6220b57cec5SDimitry Andric const int save_errno = error.GetError(); 6230b57cec5SDimitry Andric response.Printf("%zi", bytes_written); 6240b57cec5SDimitry Andric if (save_errno) 6250b57cec5SDimitry Andric response.Printf(",%i", save_errno); 6260b57cec5SDimitry Andric } else { 6270b57cec5SDimitry Andric response.Printf("-1,%i", EINVAL); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6300b57cec5SDimitry Andric } 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric return SendErrorResponse(27); 6330b57cec5SDimitry Andric } 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6360b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Size( 6370b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6380b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:size:")); 6390b57cec5SDimitry Andric std::string path; 6400b57cec5SDimitry Andric packet.GetHexByteString(path); 6410b57cec5SDimitry Andric if (!path.empty()) { 6420b57cec5SDimitry Andric uint64_t Size; 6430b57cec5SDimitry Andric if (llvm::sys::fs::file_size(path, Size)) 6440b57cec5SDimitry Andric return SendErrorResponse(5); 6450b57cec5SDimitry Andric StreamString response; 6460b57cec5SDimitry Andric response.PutChar('F'); 6470b57cec5SDimitry Andric response.PutHex64(Size); 6480b57cec5SDimitry Andric if (Size == UINT64_MAX) { 6490b57cec5SDimitry Andric response.PutChar(','); 6500b57cec5SDimitry Andric response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode() 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric return SendErrorResponse(22); 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6580b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( 6590b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6600b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:mode:")); 6610b57cec5SDimitry Andric std::string path; 6620b57cec5SDimitry Andric packet.GetHexByteString(path); 6630b57cec5SDimitry Andric if (!path.empty()) { 6640b57cec5SDimitry Andric FileSpec file_spec(path); 6650b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec); 6660b57cec5SDimitry Andric std::error_code ec; 6670b57cec5SDimitry Andric const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); 6680b57cec5SDimitry Andric StreamString response; 6690b57cec5SDimitry Andric response.Printf("F%u", mode); 6700b57cec5SDimitry Andric if (mode == 0 || ec) 6710b57cec5SDimitry Andric response.Printf(",%i", (int)Status(ec).GetError()); 6720b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric return SendErrorResponse(23); 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6780b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Exists( 6790b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 6800b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:exists:")); 6810b57cec5SDimitry Andric std::string path; 6820b57cec5SDimitry Andric packet.GetHexByteString(path); 6830b57cec5SDimitry Andric if (!path.empty()) { 6840b57cec5SDimitry Andric bool retcode = llvm::sys::fs::exists(path); 6850b57cec5SDimitry Andric StreamString response; 6860b57cec5SDimitry Andric response.PutChar('F'); 6870b57cec5SDimitry Andric response.PutChar(','); 6880b57cec5SDimitry Andric if (retcode) 6890b57cec5SDimitry Andric response.PutChar('1'); 6900b57cec5SDimitry Andric else 6910b57cec5SDimitry Andric response.PutChar('0'); 6920b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 6930b57cec5SDimitry Andric } 6940b57cec5SDimitry Andric return SendErrorResponse(24); 6950b57cec5SDimitry Andric } 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 6980b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( 6990b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7000b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:symlink:")); 7010b57cec5SDimitry Andric std::string dst, src; 7020b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(dst, ','); 7030b57cec5SDimitry Andric packet.GetChar(); // Skip ',' char 7040b57cec5SDimitry Andric packet.GetHexByteString(src); 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric FileSpec src_spec(src); 7070b57cec5SDimitry Andric FileSystem::Instance().Resolve(src_spec); 7080b57cec5SDimitry Andric Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric StreamString response; 7110b57cec5SDimitry Andric response.Printf("F%u,%u", error.GetError(), error.GetError()); 7120b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7160b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_unlink( 7170b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7180b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:unlink:")); 7190b57cec5SDimitry Andric std::string path; 7200b57cec5SDimitry Andric packet.GetHexByteString(path); 7210b57cec5SDimitry Andric Status error(llvm::sys::fs::remove(path)); 7220b57cec5SDimitry Andric StreamString response; 7230b57cec5SDimitry Andric response.Printf("F%u,%u", error.GetError(), error.GetError()); 7240b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7280b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( 7290b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7300b57cec5SDimitry Andric packet.SetFilePos(::strlen("qPlatform_shell:")); 7310b57cec5SDimitry Andric std::string path; 7320b57cec5SDimitry Andric std::string working_dir; 7330b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(path, ','); 7340b57cec5SDimitry Andric if (!path.empty()) { 7350b57cec5SDimitry Andric if (packet.GetChar() == ',') { 7360b57cec5SDimitry Andric // FIXME: add timeout to qPlatform_shell packet 7370b57cec5SDimitry Andric // uint32_t timeout = packet.GetHexMaxU32(false, 32); 7380b57cec5SDimitry Andric if (packet.GetChar() == ',') 7390b57cec5SDimitry Andric packet.GetHexByteString(working_dir); 7400b57cec5SDimitry Andric int status, signo; 7410b57cec5SDimitry Andric std::string output; 7420b57cec5SDimitry Andric FileSpec working_spec(working_dir); 7430b57cec5SDimitry Andric FileSystem::Instance().Resolve(working_spec); 7440b57cec5SDimitry Andric Status err = 7450b57cec5SDimitry Andric Host::RunShellCommand(path.c_str(), working_spec, &status, &signo, 7460b57cec5SDimitry Andric &output, std::chrono::seconds(10)); 7470b57cec5SDimitry Andric StreamGDBRemote response; 7480b57cec5SDimitry Andric if (err.Fail()) { 7490b57cec5SDimitry Andric response.PutCString("F,"); 7500b57cec5SDimitry Andric response.PutHex32(UINT32_MAX); 7510b57cec5SDimitry Andric } else { 7520b57cec5SDimitry Andric response.PutCString("F,"); 7530b57cec5SDimitry Andric response.PutHex32(status); 7540b57cec5SDimitry Andric response.PutChar(','); 7550b57cec5SDimitry Andric response.PutHex32(signo); 7560b57cec5SDimitry Andric response.PutChar(','); 7570b57cec5SDimitry Andric response.PutEscapedBytes(output.c_str(), output.size()); 7580b57cec5SDimitry Andric } 7590b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric return SendErrorResponse(24); 7630b57cec5SDimitry Andric } 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7660b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Stat( 7670b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7680b57cec5SDimitry Andric return SendUnimplementedResponse( 7690b57cec5SDimitry Andric "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented"); 7700b57cec5SDimitry Andric } 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7730b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_MD5( 7740b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7750b57cec5SDimitry Andric packet.SetFilePos(::strlen("vFile:MD5:")); 7760b57cec5SDimitry Andric std::string path; 7770b57cec5SDimitry Andric packet.GetHexByteString(path); 7780b57cec5SDimitry Andric if (!path.empty()) { 7790b57cec5SDimitry Andric StreamGDBRemote response; 7800b57cec5SDimitry Andric auto Result = llvm::sys::fs::md5_contents(path); 7810b57cec5SDimitry Andric if (!Result) { 7820b57cec5SDimitry Andric response.PutCString("F,"); 7830b57cec5SDimitry Andric response.PutCString("x"); 7840b57cec5SDimitry Andric } else { 7850b57cec5SDimitry Andric response.PutCString("F,"); 7860b57cec5SDimitry Andric response.PutHex64(Result->low()); 7870b57cec5SDimitry Andric response.PutHex64(Result->high()); 7880b57cec5SDimitry Andric } 7890b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 7900b57cec5SDimitry Andric } 7910b57cec5SDimitry Andric return SendErrorResponse(25); 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 7950b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir( 7960b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 7970b57cec5SDimitry Andric packet.SetFilePos(::strlen("qPlatform_mkdir:")); 7980b57cec5SDimitry Andric mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 7990b57cec5SDimitry Andric if (packet.GetChar() == ',') { 8000b57cec5SDimitry Andric std::string path; 8010b57cec5SDimitry Andric packet.GetHexByteString(path); 8020b57cec5SDimitry Andric Status error(llvm::sys::fs::create_directory(path, mode)); 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andric StreamGDBRemote response; 8050b57cec5SDimitry Andric response.Printf("F%u", error.GetError()); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 8080b57cec5SDimitry Andric } 8090b57cec5SDimitry Andric return SendErrorResponse(20); 8100b57cec5SDimitry Andric } 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8130b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod( 8140b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8150b57cec5SDimitry Andric packet.SetFilePos(::strlen("qPlatform_chmod:")); 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric auto perms = 8180b57cec5SDimitry Andric static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX)); 8190b57cec5SDimitry Andric if (packet.GetChar() == ',') { 8200b57cec5SDimitry Andric std::string path; 8210b57cec5SDimitry Andric packet.GetHexByteString(path); 8220b57cec5SDimitry Andric Status error(llvm::sys::fs::setPermissions(path, perms)); 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric StreamGDBRemote response; 8250b57cec5SDimitry Andric response.Printf("F%u", error.GetError()); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 8280b57cec5SDimitry Andric } 8290b57cec5SDimitry Andric return SendErrorResponse(19); 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8330b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qSupported( 8340b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8350b57cec5SDimitry Andric StreamGDBRemote response; 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric // Features common to lldb-platform and llgs. 8380b57cec5SDimitry Andric uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet 8390b57cec5SDimitry Andric // size--debugger can always use less 8400b57cec5SDimitry Andric response.Printf("PacketSize=%x", max_packet_size); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric response.PutCString(";QStartNoAckMode+"); 8430b57cec5SDimitry Andric response.PutCString(";QThreadSuffixSupported+"); 8440b57cec5SDimitry Andric response.PutCString(";QListThreadsInStopReply+"); 8450b57cec5SDimitry Andric response.PutCString(";qEcho+"); 8460b57cec5SDimitry Andric #if defined(__linux__) || defined(__NetBSD__) 8470b57cec5SDimitry Andric response.PutCString(";QPassSignals+"); 8480b57cec5SDimitry Andric response.PutCString(";qXfer:auxv:read+"); 849*9dba64beSDimitry Andric response.PutCString(";qXfer:libraries-svr4:read+"); 8500b57cec5SDimitry Andric #endif 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 8530b57cec5SDimitry Andric } 8540b57cec5SDimitry Andric 8550b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8560b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported( 8570b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8580b57cec5SDimitry Andric m_thread_suffix_supported = true; 8590b57cec5SDimitry Andric return SendOKResponse(); 8600b57cec5SDimitry Andric } 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8630b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply( 8640b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8650b57cec5SDimitry Andric m_list_threads_in_stop_reply = true; 8660b57cec5SDimitry Andric return SendOKResponse(); 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8700b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError( 8710b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8720b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetDetachOnError:")); 8730b57cec5SDimitry Andric if (packet.GetU32(0)) 8740b57cec5SDimitry Andric m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError); 8750b57cec5SDimitry Andric else 8760b57cec5SDimitry Andric m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError); 8770b57cec5SDimitry Andric return SendOKResponse(); 8780b57cec5SDimitry Andric } 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8810b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode( 8820b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8830b57cec5SDimitry Andric // Send response first before changing m_send_acks to we ack this packet 8840b57cec5SDimitry Andric PacketResult packet_result = SendOKResponse(); 8850b57cec5SDimitry Andric m_send_acks = false; 8860b57cec5SDimitry Andric return packet_result; 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 8900b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN( 8910b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 8920b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetSTDIN:")); 8930b57cec5SDimitry Andric FileAction file_action; 8940b57cec5SDimitry Andric std::string path; 8950b57cec5SDimitry Andric packet.GetHexByteString(path); 8960b57cec5SDimitry Andric const bool read = true; 8970b57cec5SDimitry Andric const bool write = false; 8980b57cec5SDimitry Andric if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) { 8990b57cec5SDimitry Andric m_process_launch_info.AppendFileAction(file_action); 9000b57cec5SDimitry Andric return SendOKResponse(); 9010b57cec5SDimitry Andric } 9020b57cec5SDimitry Andric return SendErrorResponse(15); 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9060b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT( 9070b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9080b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetSTDOUT:")); 9090b57cec5SDimitry Andric FileAction file_action; 9100b57cec5SDimitry Andric std::string path; 9110b57cec5SDimitry Andric packet.GetHexByteString(path); 9120b57cec5SDimitry Andric const bool read = false; 9130b57cec5SDimitry Andric const bool write = true; 9140b57cec5SDimitry Andric if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) { 9150b57cec5SDimitry Andric m_process_launch_info.AppendFileAction(file_action); 9160b57cec5SDimitry Andric return SendOKResponse(); 9170b57cec5SDimitry Andric } 9180b57cec5SDimitry Andric return SendErrorResponse(16); 9190b57cec5SDimitry Andric } 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9220b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR( 9230b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9240b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetSTDERR:")); 9250b57cec5SDimitry Andric FileAction file_action; 9260b57cec5SDimitry Andric std::string path; 9270b57cec5SDimitry Andric packet.GetHexByteString(path); 9280b57cec5SDimitry Andric const bool read = false; 9290b57cec5SDimitry Andric const bool write = true; 9300b57cec5SDimitry Andric if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) { 9310b57cec5SDimitry Andric m_process_launch_info.AppendFileAction(file_action); 9320b57cec5SDimitry Andric return SendOKResponse(); 9330b57cec5SDimitry Andric } 9340b57cec5SDimitry Andric return SendErrorResponse(17); 9350b57cec5SDimitry Andric } 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9380b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess( 9390b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9400b57cec5SDimitry Andric if (m_process_launch_error.Success()) 9410b57cec5SDimitry Andric return SendOKResponse(); 9420b57cec5SDimitry Andric StreamString response; 9430b57cec5SDimitry Andric response.PutChar('E'); 9440b57cec5SDimitry Andric response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 9450b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 9460b57cec5SDimitry Andric } 9470b57cec5SDimitry Andric 9480b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9490b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QEnvironment( 9500b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9510b57cec5SDimitry Andric packet.SetFilePos(::strlen("QEnvironment:")); 9520b57cec5SDimitry Andric const uint32_t bytes_left = packet.GetBytesLeft(); 9530b57cec5SDimitry Andric if (bytes_left > 0) { 9540b57cec5SDimitry Andric m_process_launch_info.GetEnvironment().insert(packet.Peek()); 9550b57cec5SDimitry Andric return SendOKResponse(); 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric return SendErrorResponse(12); 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9610b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded( 9620b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9630b57cec5SDimitry Andric packet.SetFilePos(::strlen("QEnvironmentHexEncoded:")); 9640b57cec5SDimitry Andric const uint32_t bytes_left = packet.GetBytesLeft(); 9650b57cec5SDimitry Andric if (bytes_left > 0) { 9660b57cec5SDimitry Andric std::string str; 9670b57cec5SDimitry Andric packet.GetHexByteString(str); 9680b57cec5SDimitry Andric m_process_launch_info.GetEnvironment().insert(str); 9690b57cec5SDimitry Andric return SendOKResponse(); 9700b57cec5SDimitry Andric } 9710b57cec5SDimitry Andric return SendErrorResponse(12); 9720b57cec5SDimitry Andric } 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9750b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QLaunchArch( 9760b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 9770b57cec5SDimitry Andric packet.SetFilePos(::strlen("QLaunchArch:")); 9780b57cec5SDimitry Andric const uint32_t bytes_left = packet.GetBytesLeft(); 9790b57cec5SDimitry Andric if (bytes_left > 0) { 9800b57cec5SDimitry Andric const char *arch_triple = packet.Peek(); 9810b57cec5SDimitry Andric m_process_launch_info.SetArchitecture( 9820b57cec5SDimitry Andric HostInfo::GetAugmentedArchSpec(arch_triple)); 9830b57cec5SDimitry Andric return SendOKResponse(); 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric return SendErrorResponse(13); 9860b57cec5SDimitry Andric } 9870b57cec5SDimitry Andric 9880b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 9890b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { 9900b57cec5SDimitry Andric // The 'A' packet is the most over designed packet ever here with redundant 9910b57cec5SDimitry Andric // argument indexes, redundant argument lengths and needed hex encoded 9920b57cec5SDimitry Andric // argument string values. Really all that is needed is a comma separated hex 9930b57cec5SDimitry Andric // encoded argument value list, but we will stay true to the documented 9940b57cec5SDimitry Andric // version of the 'A' packet here... 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); 9970b57cec5SDimitry Andric int actual_arg_index = 0; 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric packet.SetFilePos(1); // Skip the 'A' 10000b57cec5SDimitry Andric bool success = true; 10010b57cec5SDimitry Andric while (success && packet.GetBytesLeft() > 0) { 10020b57cec5SDimitry Andric // Decode the decimal argument string length. This length is the number of 10030b57cec5SDimitry Andric // hex nibbles in the argument string value. 10040b57cec5SDimitry Andric const uint32_t arg_len = packet.GetU32(UINT32_MAX); 10050b57cec5SDimitry Andric if (arg_len == UINT32_MAX) 10060b57cec5SDimitry Andric success = false; 10070b57cec5SDimitry Andric else { 10080b57cec5SDimitry Andric // Make sure the argument hex string length is followed by a comma 10090b57cec5SDimitry Andric if (packet.GetChar() != ',') 10100b57cec5SDimitry Andric success = false; 10110b57cec5SDimitry Andric else { 10120b57cec5SDimitry Andric // Decode the argument index. We ignore this really because who would 10130b57cec5SDimitry Andric // really send down the arguments in a random order??? 10140b57cec5SDimitry Andric const uint32_t arg_idx = packet.GetU32(UINT32_MAX); 10150b57cec5SDimitry Andric if (arg_idx == UINT32_MAX) 10160b57cec5SDimitry Andric success = false; 10170b57cec5SDimitry Andric else { 10180b57cec5SDimitry Andric // Make sure the argument index is followed by a comma 10190b57cec5SDimitry Andric if (packet.GetChar() != ',') 10200b57cec5SDimitry Andric success = false; 10210b57cec5SDimitry Andric else { 10220b57cec5SDimitry Andric // Decode the argument string value from hex bytes back into a UTF8 10230b57cec5SDimitry Andric // string and make sure the length matches the one supplied in the 10240b57cec5SDimitry Andric // packet 10250b57cec5SDimitry Andric std::string arg; 10260b57cec5SDimitry Andric if (packet.GetHexByteStringFixedLength(arg, arg_len) != 10270b57cec5SDimitry Andric (arg_len / 2)) 10280b57cec5SDimitry Andric success = false; 10290b57cec5SDimitry Andric else { 10300b57cec5SDimitry Andric // If there are any bytes left 10310b57cec5SDimitry Andric if (packet.GetBytesLeft()) { 10320b57cec5SDimitry Andric if (packet.GetChar() != ',') 10330b57cec5SDimitry Andric success = false; 10340b57cec5SDimitry Andric } 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric if (success) { 10370b57cec5SDimitry Andric if (arg_idx == 0) 10380b57cec5SDimitry Andric m_process_launch_info.GetExecutableFile().SetFile( 10390b57cec5SDimitry Andric arg, FileSpec::Style::native); 10400b57cec5SDimitry Andric m_process_launch_info.GetArguments().AppendArgument(arg); 1041*9dba64beSDimitry Andric LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"", 10420b57cec5SDimitry Andric __FUNCTION__, actual_arg_index, arg.c_str()); 10430b57cec5SDimitry Andric ++actual_arg_index; 10440b57cec5SDimitry Andric } 10450b57cec5SDimitry Andric } 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric } 10480b57cec5SDimitry Andric } 10490b57cec5SDimitry Andric } 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric if (success) { 10530b57cec5SDimitry Andric m_process_launch_error = LaunchProcess(); 10540b57cec5SDimitry Andric if (m_process_launch_error.Success()) 10550b57cec5SDimitry Andric return SendOKResponse(); 10560b57cec5SDimitry Andric LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error); 10570b57cec5SDimitry Andric } 10580b57cec5SDimitry Andric return SendErrorResponse(8); 10590b57cec5SDimitry Andric } 10600b57cec5SDimitry Andric 10610b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 10620b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qEcho( 10630b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 10640b57cec5SDimitry Andric // Just echo back the exact same packet for qEcho... 10650b57cec5SDimitry Andric return SendPacketNoLock(packet.GetStringRef()); 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 10690b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( 10700b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 10710b57cec5SDimitry Andric packet.SetFilePos(::strlen("qModuleInfo:")); 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric std::string module_path; 10740b57cec5SDimitry Andric packet.GetHexByteStringTerminatedBy(module_path, ';'); 10750b57cec5SDimitry Andric if (module_path.empty()) 10760b57cec5SDimitry Andric return SendErrorResponse(1); 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric if (packet.GetChar() != ';') 10790b57cec5SDimitry Andric return SendErrorResponse(2); 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric std::string triple; 10820b57cec5SDimitry Andric packet.GetHexByteString(triple); 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple); 10850b57cec5SDimitry Andric if (!matched_module_spec.GetFileSpec()) 10860b57cec5SDimitry Andric return SendErrorResponse(3); 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric const auto file_offset = matched_module_spec.GetObjectOffset(); 10890b57cec5SDimitry Andric const auto file_size = matched_module_spec.GetObjectSize(); 10900b57cec5SDimitry Andric const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric StreamGDBRemote response; 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric if (uuid_str.empty()) { 10950b57cec5SDimitry Andric auto Result = llvm::sys::fs::md5_contents( 10960b57cec5SDimitry Andric matched_module_spec.GetFileSpec().GetPath()); 10970b57cec5SDimitry Andric if (!Result) 10980b57cec5SDimitry Andric return SendErrorResponse(5); 10990b57cec5SDimitry Andric response.PutCString("md5:"); 11000b57cec5SDimitry Andric response.PutStringAsRawHex8(Result->digest()); 11010b57cec5SDimitry Andric } else { 11020b57cec5SDimitry Andric response.PutCString("uuid:"); 11030b57cec5SDimitry Andric response.PutStringAsRawHex8(uuid_str); 11040b57cec5SDimitry Andric } 11050b57cec5SDimitry Andric response.PutChar(';'); 11060b57cec5SDimitry Andric 11070b57cec5SDimitry Andric const auto &module_arch = matched_module_spec.GetArchitecture(); 11080b57cec5SDimitry Andric response.PutCString("triple:"); 11090b57cec5SDimitry Andric response.PutStringAsRawHex8(module_arch.GetTriple().getTriple()); 11100b57cec5SDimitry Andric response.PutChar(';'); 11110b57cec5SDimitry Andric 11120b57cec5SDimitry Andric response.PutCString("file_path:"); 11130b57cec5SDimitry Andric response.PutStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString()); 11140b57cec5SDimitry Andric response.PutChar(';'); 11150b57cec5SDimitry Andric response.PutCString("file_offset:"); 11160b57cec5SDimitry Andric response.PutHex64(file_offset); 11170b57cec5SDimitry Andric response.PutChar(';'); 11180b57cec5SDimitry Andric response.PutCString("file_size:"); 11190b57cec5SDimitry Andric response.PutHex64(file_size); 11200b57cec5SDimitry Andric response.PutChar(';'); 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 11260b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_jModulesInfo( 11270b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 1128*9dba64beSDimitry Andric namespace json = llvm::json; 1129*9dba64beSDimitry Andric 11300b57cec5SDimitry Andric packet.SetFilePos(::strlen("jModulesInfo:")); 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andric StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek()); 11330b57cec5SDimitry Andric if (!object_sp) 11340b57cec5SDimitry Andric return SendErrorResponse(1); 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric StructuredData::Array *packet_array = object_sp->GetAsArray(); 11370b57cec5SDimitry Andric if (!packet_array) 11380b57cec5SDimitry Andric return SendErrorResponse(2); 11390b57cec5SDimitry Andric 1140*9dba64beSDimitry Andric json::Array response_array; 11410b57cec5SDimitry Andric for (size_t i = 0; i < packet_array->GetSize(); ++i) { 11420b57cec5SDimitry Andric StructuredData::Dictionary *query = 11430b57cec5SDimitry Andric packet_array->GetItemAtIndex(i)->GetAsDictionary(); 11440b57cec5SDimitry Andric if (!query) 11450b57cec5SDimitry Andric continue; 11460b57cec5SDimitry Andric llvm::StringRef file, triple; 11470b57cec5SDimitry Andric if (!query->GetValueForKeyAsString("file", file) || 11480b57cec5SDimitry Andric !query->GetValueForKeyAsString("triple", triple)) 11490b57cec5SDimitry Andric continue; 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric ModuleSpec matched_module_spec = GetModuleInfo(file, triple); 11520b57cec5SDimitry Andric if (!matched_module_spec.GetFileSpec()) 11530b57cec5SDimitry Andric continue; 11540b57cec5SDimitry Andric 11550b57cec5SDimitry Andric const auto file_offset = matched_module_spec.GetObjectOffset(); 11560b57cec5SDimitry Andric const auto file_size = matched_module_spec.GetObjectSize(); 11570b57cec5SDimitry Andric const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); 11580b57cec5SDimitry Andric if (uuid_str.empty()) 11590b57cec5SDimitry Andric continue; 1160*9dba64beSDimitry Andric const auto triple_str = 1161*9dba64beSDimitry Andric matched_module_spec.GetArchitecture().GetTriple().getTriple(); 1162*9dba64beSDimitry Andric const auto file_path = matched_module_spec.GetFileSpec().GetPath(); 11630b57cec5SDimitry Andric 1164*9dba64beSDimitry Andric json::Object response{{"uuid", uuid_str}, 1165*9dba64beSDimitry Andric {"triple", triple_str}, 1166*9dba64beSDimitry Andric {"file_path", file_path}, 1167*9dba64beSDimitry Andric {"file_offset", static_cast<int64_t>(file_offset)}, 1168*9dba64beSDimitry Andric {"file_size", static_cast<int64_t>(file_size)}}; 1169*9dba64beSDimitry Andric response_array.push_back(std::move(response)); 11700b57cec5SDimitry Andric } 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric StreamString response; 1173*9dba64beSDimitry Andric response.AsRawOstream() << std::move(response_array); 11740b57cec5SDimitry Andric StreamGDBRemote escaped_response; 11750b57cec5SDimitry Andric escaped_response.PutEscapedBytes(response.GetString().data(), 11760b57cec5SDimitry Andric response.GetSize()); 11770b57cec5SDimitry Andric return SendPacketNoLock(escaped_response.GetString()); 11780b57cec5SDimitry Andric } 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse( 11810b57cec5SDimitry Andric const ProcessInstanceInfo &proc_info, StreamString &response) { 11820b57cec5SDimitry Andric response.Printf( 11830b57cec5SDimitry Andric "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", 11840b57cec5SDimitry Andric proc_info.GetProcessID(), proc_info.GetParentProcessID(), 11850b57cec5SDimitry Andric proc_info.GetUserID(), proc_info.GetGroupID(), 11860b57cec5SDimitry Andric proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID()); 11870b57cec5SDimitry Andric response.PutCString("name:"); 11880b57cec5SDimitry Andric response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString()); 1189*9dba64beSDimitry Andric 1190*9dba64beSDimitry Andric response.PutChar(';'); 1191*9dba64beSDimitry Andric response.PutCString("args:"); 1192*9dba64beSDimitry Andric response.PutStringAsRawHex8(proc_info.GetArg0()); 1193*9dba64beSDimitry Andric for (auto &arg : proc_info.GetArguments()) { 1194*9dba64beSDimitry Andric response.PutChar('-'); 1195*9dba64beSDimitry Andric response.PutStringAsRawHex8(arg.ref()); 1196*9dba64beSDimitry Andric } 1197*9dba64beSDimitry Andric 11980b57cec5SDimitry Andric response.PutChar(';'); 11990b57cec5SDimitry Andric const ArchSpec &proc_arch = proc_info.GetArchitecture(); 12000b57cec5SDimitry Andric if (proc_arch.IsValid()) { 12010b57cec5SDimitry Andric const llvm::Triple &proc_triple = proc_arch.GetTriple(); 12020b57cec5SDimitry Andric response.PutCString("triple:"); 12030b57cec5SDimitry Andric response.PutStringAsRawHex8(proc_triple.getTriple()); 12040b57cec5SDimitry Andric response.PutChar(';'); 12050b57cec5SDimitry Andric } 12060b57cec5SDimitry Andric } 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric void GDBRemoteCommunicationServerCommon:: 12090b57cec5SDimitry Andric CreateProcessInfoResponse_DebugServerStyle( 12100b57cec5SDimitry Andric const ProcessInstanceInfo &proc_info, StreamString &response) { 12110b57cec5SDimitry Andric response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64 12120b57cec5SDimitry Andric ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;", 12130b57cec5SDimitry Andric proc_info.GetProcessID(), proc_info.GetParentProcessID(), 12140b57cec5SDimitry Andric proc_info.GetUserID(), proc_info.GetGroupID(), 12150b57cec5SDimitry Andric proc_info.GetEffectiveUserID(), 12160b57cec5SDimitry Andric proc_info.GetEffectiveGroupID()); 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric const ArchSpec &proc_arch = proc_info.GetArchitecture(); 12190b57cec5SDimitry Andric if (proc_arch.IsValid()) { 12200b57cec5SDimitry Andric const llvm::Triple &proc_triple = proc_arch.GetTriple(); 12210b57cec5SDimitry Andric #if defined(__APPLE__) 12220b57cec5SDimitry Andric // We'll send cputype/cpusubtype. 12230b57cec5SDimitry Andric const uint32_t cpu_type = proc_arch.GetMachOCPUType(); 12240b57cec5SDimitry Andric if (cpu_type != 0) 12250b57cec5SDimitry Andric response.Printf("cputype:%" PRIx32 ";", cpu_type); 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType(); 12280b57cec5SDimitry Andric if (cpu_subtype != 0) 12290b57cec5SDimitry Andric response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype); 12300b57cec5SDimitry Andric 12310b57cec5SDimitry Andric const std::string vendor = proc_triple.getVendorName(); 12320b57cec5SDimitry Andric if (!vendor.empty()) 12330b57cec5SDimitry Andric response.Printf("vendor:%s;", vendor.c_str()); 12340b57cec5SDimitry Andric #else 12350b57cec5SDimitry Andric // We'll send the triple. 12360b57cec5SDimitry Andric response.PutCString("triple:"); 12370b57cec5SDimitry Andric response.PutStringAsRawHex8(proc_triple.getTriple()); 12380b57cec5SDimitry Andric response.PutChar(';'); 12390b57cec5SDimitry Andric #endif 12400b57cec5SDimitry Andric std::string ostype = proc_triple.getOSName(); 12410b57cec5SDimitry Andric // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64. 12420b57cec5SDimitry Andric if (proc_triple.getVendor() == llvm::Triple::Apple) { 12430b57cec5SDimitry Andric switch (proc_triple.getArch()) { 12440b57cec5SDimitry Andric case llvm::Triple::arm: 12450b57cec5SDimitry Andric case llvm::Triple::thumb: 12460b57cec5SDimitry Andric case llvm::Triple::aarch64: 1247*9dba64beSDimitry Andric case llvm::Triple::aarch64_32: 12480b57cec5SDimitry Andric ostype = "ios"; 12490b57cec5SDimitry Andric break; 12500b57cec5SDimitry Andric default: 12510b57cec5SDimitry Andric // No change. 12520b57cec5SDimitry Andric break; 12530b57cec5SDimitry Andric } 12540b57cec5SDimitry Andric } 12550b57cec5SDimitry Andric response.Printf("ostype:%s;", ostype.c_str()); 12560b57cec5SDimitry Andric 12570b57cec5SDimitry Andric switch (proc_arch.GetByteOrder()) { 12580b57cec5SDimitry Andric case lldb::eByteOrderLittle: 12590b57cec5SDimitry Andric response.PutCString("endian:little;"); 12600b57cec5SDimitry Andric break; 12610b57cec5SDimitry Andric case lldb::eByteOrderBig: 12620b57cec5SDimitry Andric response.PutCString("endian:big;"); 12630b57cec5SDimitry Andric break; 12640b57cec5SDimitry Andric case lldb::eByteOrderPDP: 12650b57cec5SDimitry Andric response.PutCString("endian:pdp;"); 12660b57cec5SDimitry Andric break; 12670b57cec5SDimitry Andric default: 12680b57cec5SDimitry Andric // Nothing. 12690b57cec5SDimitry Andric break; 12700b57cec5SDimitry Andric } 12710b57cec5SDimitry Andric // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer 12720b57cec5SDimitry Andric // size is 4 and for N64 it is 8 12730b57cec5SDimitry Andric std::string abi = proc_arch.GetTargetABI(); 12740b57cec5SDimitry Andric if (!abi.empty()) 12750b57cec5SDimitry Andric response.Printf("elf_abi:%s;", abi.c_str()); 12760b57cec5SDimitry Andric response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize()); 12770b57cec5SDimitry Andric } 12780b57cec5SDimitry Andric } 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( 12810b57cec5SDimitry Andric const std::string &module_path, const ArchSpec &arch) { 12820b57cec5SDimitry Andric #ifdef __ANDROID__ 12830b57cec5SDimitry Andric return HostInfoAndroid::ResolveLibraryPath(module_path, arch); 12840b57cec5SDimitry Andric #else 12850b57cec5SDimitry Andric FileSpec file_spec(module_path); 12860b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec); 12870b57cec5SDimitry Andric return file_spec; 12880b57cec5SDimitry Andric #endif 12890b57cec5SDimitry Andric } 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric ModuleSpec 12920b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, 12930b57cec5SDimitry Andric llvm::StringRef triple) { 12940b57cec5SDimitry Andric ArchSpec arch(triple); 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric FileSpec req_module_path_spec(module_path); 12970b57cec5SDimitry Andric FileSystem::Instance().Resolve(req_module_path_spec); 12980b57cec5SDimitry Andric 12990b57cec5SDimitry Andric const FileSpec module_path_spec = 13000b57cec5SDimitry Andric FindModuleFile(req_module_path_spec.GetPath(), arch); 13010b57cec5SDimitry Andric const ModuleSpec module_spec(module_path_spec, arch); 13020b57cec5SDimitry Andric 13030b57cec5SDimitry Andric ModuleSpecList module_specs; 13040b57cec5SDimitry Andric if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, 13050b57cec5SDimitry Andric module_specs)) 13060b57cec5SDimitry Andric return ModuleSpec(); 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric ModuleSpec matched_module_spec; 13090b57cec5SDimitry Andric if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) 13100b57cec5SDimitry Andric return ModuleSpec(); 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric return matched_module_spec; 13130b57cec5SDimitry Andric } 1314