1dda28197Spatrick //===-- GDBRemoteCommunicationServerCommon.cpp ----------------------------===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9061da546Spatrick #include "GDBRemoteCommunicationServerCommon.h" 10061da546Spatrick 11*a0747c9fSpatrick #include <cerrno> 12061da546Spatrick 13061da546Spatrick #ifdef __APPLE__ 14061da546Spatrick #include <TargetConditionals.h> 15061da546Spatrick #endif 16061da546Spatrick 17061da546Spatrick #include <chrono> 18061da546Spatrick #include <cstring> 19061da546Spatrick 20061da546Spatrick #include "lldb/Core/ModuleSpec.h" 21061da546Spatrick #include "lldb/Host/Config.h" 22061da546Spatrick #include "lldb/Host/File.h" 23061da546Spatrick #include "lldb/Host/FileAction.h" 24061da546Spatrick #include "lldb/Host/FileSystem.h" 25061da546Spatrick #include "lldb/Host/Host.h" 26061da546Spatrick #include "lldb/Host/HostInfo.h" 27061da546Spatrick #include "lldb/Host/SafeMachO.h" 28061da546Spatrick #include "lldb/Interpreter/OptionArgParser.h" 29061da546Spatrick #include "lldb/Symbol/ObjectFile.h" 30061da546Spatrick #include "lldb/Target/Platform.h" 31061da546Spatrick #include "lldb/Utility/Endian.h" 32061da546Spatrick #include "lldb/Utility/GDBRemote.h" 33061da546Spatrick #include "lldb/Utility/Log.h" 34061da546Spatrick #include "lldb/Utility/StreamString.h" 35061da546Spatrick #include "lldb/Utility/StructuredData.h" 36061da546Spatrick #include "llvm/ADT/StringSwitch.h" 37061da546Spatrick #include "llvm/ADT/Triple.h" 38061da546Spatrick #include "llvm/Support/JSON.h" 39061da546Spatrick 40061da546Spatrick #include "ProcessGDBRemoteLog.h" 41061da546Spatrick #include "lldb/Utility/StringExtractorGDBRemote.h" 42061da546Spatrick 43061da546Spatrick #ifdef __ANDROID__ 44061da546Spatrick #include "lldb/Host/android/HostInfoAndroid.h" 45061da546Spatrick #endif 46061da546Spatrick 47061da546Spatrick 48061da546Spatrick using namespace lldb; 49061da546Spatrick using namespace lldb_private::process_gdb_remote; 50061da546Spatrick using namespace lldb_private; 51061da546Spatrick 52061da546Spatrick #ifdef __ANDROID__ 53061da546Spatrick const static uint32_t g_default_packet_timeout_sec = 20; // seconds 54061da546Spatrick #else 55061da546Spatrick const static uint32_t g_default_packet_timeout_sec = 0; // not specified 56061da546Spatrick #endif 57061da546Spatrick 58061da546Spatrick // GDBRemoteCommunicationServerCommon constructor 59061da546Spatrick GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( 60061da546Spatrick const char *comm_name, const char *listener_name) 61061da546Spatrick : GDBRemoteCommunicationServer(comm_name, listener_name), 62061da546Spatrick m_process_launch_info(), m_process_launch_error(), m_proc_infos(), 63*a0747c9fSpatrick m_proc_infos_index(0) { 64061da546Spatrick RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A, 65061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_A); 66061da546Spatrick RegisterMemberFunctionHandler( 67061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QEnvironment, 68061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QEnvironment); 69061da546Spatrick RegisterMemberFunctionHandler( 70061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded, 71061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded); 72061da546Spatrick RegisterMemberFunctionHandler( 73061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qfProcessInfo, 74061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo); 75061da546Spatrick RegisterMemberFunctionHandler( 76061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qGroupName, 77061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qGroupName); 78061da546Spatrick RegisterMemberFunctionHandler( 79061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qHostInfo, 80061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qHostInfo); 81061da546Spatrick RegisterMemberFunctionHandler( 82061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QLaunchArch, 83061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch); 84061da546Spatrick RegisterMemberFunctionHandler( 85061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess, 86061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess); 87061da546Spatrick RegisterMemberFunctionHandler( 88061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qEcho, 89061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qEcho); 90061da546Spatrick RegisterMemberFunctionHandler( 91061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qModuleInfo, 92061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo); 93061da546Spatrick RegisterMemberFunctionHandler( 94061da546Spatrick StringExtractorGDBRemote::eServerPacketType_jModulesInfo, 95061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo); 96061da546Spatrick RegisterMemberFunctionHandler( 97061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod, 98061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod); 99061da546Spatrick RegisterMemberFunctionHandler( 100061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir, 101061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir); 102061da546Spatrick RegisterMemberFunctionHandler( 103061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qPlatform_shell, 104061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell); 105061da546Spatrick RegisterMemberFunctionHandler( 106061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID, 107061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID); 108061da546Spatrick RegisterMemberFunctionHandler( 109061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError, 110061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError); 111061da546Spatrick RegisterMemberFunctionHandler( 112061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QSetSTDERR, 113061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR); 114061da546Spatrick RegisterMemberFunctionHandler( 115061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QSetSTDIN, 116061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN); 117061da546Spatrick RegisterMemberFunctionHandler( 118061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT, 119061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT); 120061da546Spatrick RegisterMemberFunctionHandler( 121061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qSpeedTest, 122061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest); 123061da546Spatrick RegisterMemberFunctionHandler( 124061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qsProcessInfo, 125061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo); 126061da546Spatrick RegisterMemberFunctionHandler( 127061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode, 128061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode); 129061da546Spatrick RegisterMemberFunctionHandler( 130061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qSupported, 131061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qSupported); 132061da546Spatrick RegisterMemberFunctionHandler( 133061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qUserName, 134061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_qUserName); 135061da546Spatrick RegisterMemberFunctionHandler( 136061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_close, 137061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_Close); 138061da546Spatrick RegisterMemberFunctionHandler( 139061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_exists, 140061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists); 141061da546Spatrick RegisterMemberFunctionHandler( 142061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_md5, 143061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5); 144061da546Spatrick RegisterMemberFunctionHandler( 145061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_mode, 146061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode); 147061da546Spatrick RegisterMemberFunctionHandler( 148061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_open, 149061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_Open); 150061da546Spatrick RegisterMemberFunctionHandler( 151061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_pread, 152061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead); 153061da546Spatrick RegisterMemberFunctionHandler( 154061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_pwrite, 155061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite); 156061da546Spatrick RegisterMemberFunctionHandler( 157061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_size, 158061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_Size); 159061da546Spatrick RegisterMemberFunctionHandler( 160061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_stat, 161061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat); 162061da546Spatrick RegisterMemberFunctionHandler( 163061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_symlink, 164061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink); 165061da546Spatrick RegisterMemberFunctionHandler( 166061da546Spatrick StringExtractorGDBRemote::eServerPacketType_vFile_unlink, 167061da546Spatrick &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink); 168061da546Spatrick } 169061da546Spatrick 170061da546Spatrick // Destructor 171*a0747c9fSpatrick GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() = 172*a0747c9fSpatrick default; 173061da546Spatrick 174061da546Spatrick GDBRemoteCommunication::PacketResult 175061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qHostInfo( 176061da546Spatrick StringExtractorGDBRemote &packet) { 177061da546Spatrick StreamString response; 178061da546Spatrick 179061da546Spatrick // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 180061da546Spatrick 181061da546Spatrick ArchSpec host_arch(HostInfo::GetArchitecture()); 182061da546Spatrick const llvm::Triple &host_triple = host_arch.GetTriple(); 183061da546Spatrick response.PutCString("triple:"); 184061da546Spatrick response.PutStringAsRawHex8(host_triple.getTriple()); 185061da546Spatrick response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize()); 186061da546Spatrick 187061da546Spatrick const char *distribution_id = host_arch.GetDistributionId().AsCString(); 188061da546Spatrick if (distribution_id) { 189061da546Spatrick response.PutCString("distribution_id:"); 190061da546Spatrick response.PutStringAsRawHex8(distribution_id); 191061da546Spatrick response.PutCString(";"); 192061da546Spatrick } 193061da546Spatrick 194061da546Spatrick #if defined(__APPLE__) 195061da546Spatrick // For parity with debugserver, we'll include the vendor key. 196061da546Spatrick response.PutCString("vendor:apple;"); 197061da546Spatrick 198061da546Spatrick // Send out MachO info. 199061da546Spatrick uint32_t cpu = host_arch.GetMachOCPUType(); 200061da546Spatrick uint32_t sub = host_arch.GetMachOCPUSubType(); 201061da546Spatrick if (cpu != LLDB_INVALID_CPUTYPE) 202061da546Spatrick response.Printf("cputype:%u;", cpu); 203061da546Spatrick if (sub != LLDB_INVALID_CPUTYPE) 204061da546Spatrick response.Printf("cpusubtype:%u;", sub); 205061da546Spatrick 206061da546Spatrick if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) { 207061da546Spatrick // Indicate the OS type. 208061da546Spatrick #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 209061da546Spatrick response.PutCString("ostype:tvos;"); 210061da546Spatrick #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 211061da546Spatrick response.PutCString("ostype:watchos;"); 212061da546Spatrick #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 213061da546Spatrick response.PutCString("ostype:bridgeos;"); 214061da546Spatrick #else 215061da546Spatrick response.PutCString("ostype:ios;"); 216061da546Spatrick #endif 217061da546Spatrick 218061da546Spatrick // On arm, we use "synchronous" watchpoints which means the exception is 219061da546Spatrick // delivered before the instruction executes. 220061da546Spatrick response.PutCString("watchpoint_exceptions_received:before;"); 221061da546Spatrick } else { 222061da546Spatrick response.PutCString("ostype:macosx;"); 223061da546Spatrick response.Printf("watchpoint_exceptions_received:after;"); 224061da546Spatrick } 225061da546Spatrick 226061da546Spatrick #else 227061da546Spatrick if (host_arch.GetMachine() == llvm::Triple::aarch64 || 228061da546Spatrick host_arch.GetMachine() == llvm::Triple::aarch64_32 || 229061da546Spatrick host_arch.GetMachine() == llvm::Triple::aarch64_be || 230061da546Spatrick host_arch.GetMachine() == llvm::Triple::arm || 231061da546Spatrick host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS()) 232061da546Spatrick response.Printf("watchpoint_exceptions_received:before;"); 233061da546Spatrick else 234061da546Spatrick response.Printf("watchpoint_exceptions_received:after;"); 235061da546Spatrick #endif 236061da546Spatrick 237061da546Spatrick switch (endian::InlHostByteOrder()) { 238061da546Spatrick case eByteOrderBig: 239061da546Spatrick response.PutCString("endian:big;"); 240061da546Spatrick break; 241061da546Spatrick case eByteOrderLittle: 242061da546Spatrick response.PutCString("endian:little;"); 243061da546Spatrick break; 244061da546Spatrick case eByteOrderPDP: 245061da546Spatrick response.PutCString("endian:pdp;"); 246061da546Spatrick break; 247061da546Spatrick default: 248061da546Spatrick response.PutCString("endian:unknown;"); 249061da546Spatrick break; 250061da546Spatrick } 251061da546Spatrick 252061da546Spatrick llvm::VersionTuple version = HostInfo::GetOSVersion(); 253061da546Spatrick if (!version.empty()) { 254061da546Spatrick response.Format("os_version:{0}", version.getAsString()); 255061da546Spatrick response.PutChar(';'); 256061da546Spatrick } 257061da546Spatrick 258061da546Spatrick #if defined(__APPLE__) 259061da546Spatrick llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion(); 260061da546Spatrick if (!maccatalyst_version.empty()) { 261061da546Spatrick response.Format("maccatalyst_version:{0}", 262061da546Spatrick maccatalyst_version.getAsString()); 263061da546Spatrick response.PutChar(';'); 264061da546Spatrick } 265061da546Spatrick #endif 266061da546Spatrick 267061da546Spatrick std::string s; 268061da546Spatrick if (HostInfo::GetOSBuildString(s)) { 269061da546Spatrick response.PutCString("os_build:"); 270061da546Spatrick response.PutStringAsRawHex8(s); 271061da546Spatrick response.PutChar(';'); 272061da546Spatrick } 273061da546Spatrick if (HostInfo::GetOSKernelDescription(s)) { 274061da546Spatrick response.PutCString("os_kernel:"); 275061da546Spatrick response.PutStringAsRawHex8(s); 276061da546Spatrick response.PutChar(';'); 277061da546Spatrick } 278061da546Spatrick 279061da546Spatrick #if defined(__APPLE__) 280061da546Spatrick 281061da546Spatrick #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 282061da546Spatrick // For iOS devices, we are connected through a USB Mux so we never pretend to 283061da546Spatrick // actually have a hostname as far as the remote lldb that is connecting to 284061da546Spatrick // this lldb-platform is concerned 285061da546Spatrick response.PutCString("hostname:"); 286061da546Spatrick response.PutStringAsRawHex8("127.0.0.1"); 287061da546Spatrick response.PutChar(';'); 288061da546Spatrick #else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 289061da546Spatrick if (HostInfo::GetHostname(s)) { 290061da546Spatrick response.PutCString("hostname:"); 291061da546Spatrick response.PutStringAsRawHex8(s); 292061da546Spatrick response.PutChar(';'); 293061da546Spatrick } 294061da546Spatrick #endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 295061da546Spatrick 296061da546Spatrick #else // #if defined(__APPLE__) 297061da546Spatrick if (HostInfo::GetHostname(s)) { 298061da546Spatrick response.PutCString("hostname:"); 299061da546Spatrick response.PutStringAsRawHex8(s); 300061da546Spatrick response.PutChar(';'); 301061da546Spatrick } 302061da546Spatrick #endif // #if defined(__APPLE__) 303061da546Spatrick 304061da546Spatrick if (g_default_packet_timeout_sec > 0) 305061da546Spatrick response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec); 306061da546Spatrick 307061da546Spatrick return SendPacketNoLock(response.GetString()); 308061da546Spatrick } 309061da546Spatrick 310061da546Spatrick GDBRemoteCommunication::PacketResult 311061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID( 312061da546Spatrick StringExtractorGDBRemote &packet) { 313061da546Spatrick // Packet format: "qProcessInfoPID:%i" where %i is the pid 314061da546Spatrick packet.SetFilePos(::strlen("qProcessInfoPID:")); 315061da546Spatrick lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID); 316061da546Spatrick if (pid != LLDB_INVALID_PROCESS_ID) { 317061da546Spatrick ProcessInstanceInfo proc_info; 318061da546Spatrick if (Host::GetProcessInfo(pid, proc_info)) { 319061da546Spatrick StreamString response; 320061da546Spatrick CreateProcessInfoResponse(proc_info, response); 321061da546Spatrick return SendPacketNoLock(response.GetString()); 322061da546Spatrick } 323061da546Spatrick } 324061da546Spatrick return SendErrorResponse(1); 325061da546Spatrick } 326061da546Spatrick 327061da546Spatrick GDBRemoteCommunication::PacketResult 328061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( 329061da546Spatrick StringExtractorGDBRemote &packet) { 330061da546Spatrick m_proc_infos_index = 0; 331dda28197Spatrick m_proc_infos.clear(); 332061da546Spatrick 333061da546Spatrick ProcessInstanceInfoMatch match_info; 334061da546Spatrick packet.SetFilePos(::strlen("qfProcessInfo")); 335061da546Spatrick if (packet.GetChar() == ':') { 336061da546Spatrick llvm::StringRef key; 337061da546Spatrick llvm::StringRef value; 338061da546Spatrick while (packet.GetNameColonValue(key, value)) { 339061da546Spatrick bool success = true; 340061da546Spatrick if (key.equals("name")) { 341061da546Spatrick StringExtractor extractor(value); 342061da546Spatrick std::string file; 343061da546Spatrick extractor.GetHexByteString(file); 344061da546Spatrick match_info.GetProcessInfo().GetExecutableFile().SetFile( 345061da546Spatrick file, FileSpec::Style::native); 346061da546Spatrick } else if (key.equals("name_match")) { 347061da546Spatrick NameMatch name_match = llvm::StringSwitch<NameMatch>(value) 348061da546Spatrick .Case("equals", NameMatch::Equals) 349061da546Spatrick .Case("starts_with", NameMatch::StartsWith) 350061da546Spatrick .Case("ends_with", NameMatch::EndsWith) 351061da546Spatrick .Case("contains", NameMatch::Contains) 352061da546Spatrick .Case("regex", NameMatch::RegularExpression) 353061da546Spatrick .Default(NameMatch::Ignore); 354061da546Spatrick match_info.SetNameMatchType(name_match); 355061da546Spatrick if (name_match == NameMatch::Ignore) 356061da546Spatrick return SendErrorResponse(2); 357061da546Spatrick } else if (key.equals("pid")) { 358061da546Spatrick lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 359061da546Spatrick if (value.getAsInteger(0, pid)) 360061da546Spatrick return SendErrorResponse(2); 361061da546Spatrick match_info.GetProcessInfo().SetProcessID(pid); 362061da546Spatrick } else if (key.equals("parent_pid")) { 363061da546Spatrick lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 364061da546Spatrick if (value.getAsInteger(0, pid)) 365061da546Spatrick return SendErrorResponse(2); 366061da546Spatrick match_info.GetProcessInfo().SetParentProcessID(pid); 367061da546Spatrick } else if (key.equals("uid")) { 368061da546Spatrick uint32_t uid = UINT32_MAX; 369061da546Spatrick if (value.getAsInteger(0, uid)) 370061da546Spatrick return SendErrorResponse(2); 371061da546Spatrick match_info.GetProcessInfo().SetUserID(uid); 372061da546Spatrick } else if (key.equals("gid")) { 373061da546Spatrick uint32_t gid = UINT32_MAX; 374061da546Spatrick if (value.getAsInteger(0, gid)) 375061da546Spatrick return SendErrorResponse(2); 376061da546Spatrick match_info.GetProcessInfo().SetGroupID(gid); 377061da546Spatrick } else if (key.equals("euid")) { 378061da546Spatrick uint32_t uid = UINT32_MAX; 379061da546Spatrick if (value.getAsInteger(0, uid)) 380061da546Spatrick return SendErrorResponse(2); 381061da546Spatrick match_info.GetProcessInfo().SetEffectiveUserID(uid); 382061da546Spatrick } else if (key.equals("egid")) { 383061da546Spatrick uint32_t gid = UINT32_MAX; 384061da546Spatrick if (value.getAsInteger(0, gid)) 385061da546Spatrick return SendErrorResponse(2); 386061da546Spatrick match_info.GetProcessInfo().SetEffectiveGroupID(gid); 387061da546Spatrick } else if (key.equals("all_users")) { 388061da546Spatrick match_info.SetMatchAllUsers( 389061da546Spatrick OptionArgParser::ToBoolean(value, false, &success)); 390061da546Spatrick } else if (key.equals("triple")) { 391061da546Spatrick match_info.GetProcessInfo().GetArchitecture() = 392061da546Spatrick HostInfo::GetAugmentedArchSpec(value); 393061da546Spatrick } else { 394061da546Spatrick success = false; 395061da546Spatrick } 396061da546Spatrick 397061da546Spatrick if (!success) 398061da546Spatrick return SendErrorResponse(2); 399061da546Spatrick } 400061da546Spatrick } 401061da546Spatrick 402061da546Spatrick if (Host::FindProcesses(match_info, m_proc_infos)) { 403061da546Spatrick // We found something, return the first item by calling the get subsequent 404061da546Spatrick // process info packet handler... 405061da546Spatrick return Handle_qsProcessInfo(packet); 406061da546Spatrick } 407061da546Spatrick return SendErrorResponse(3); 408061da546Spatrick } 409061da546Spatrick 410061da546Spatrick GDBRemoteCommunication::PacketResult 411061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo( 412061da546Spatrick StringExtractorGDBRemote &packet) { 413dda28197Spatrick if (m_proc_infos_index < m_proc_infos.size()) { 414061da546Spatrick StreamString response; 415dda28197Spatrick CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response); 416061da546Spatrick ++m_proc_infos_index; 417061da546Spatrick return SendPacketNoLock(response.GetString()); 418061da546Spatrick } 419061da546Spatrick return SendErrorResponse(4); 420061da546Spatrick } 421061da546Spatrick 422061da546Spatrick GDBRemoteCommunication::PacketResult 423061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qUserName( 424061da546Spatrick StringExtractorGDBRemote &packet) { 425061da546Spatrick #if LLDB_ENABLE_POSIX 426061da546Spatrick Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); 427061da546Spatrick LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); 428061da546Spatrick 429061da546Spatrick // Packet format: "qUserName:%i" where %i is the uid 430061da546Spatrick packet.SetFilePos(::strlen("qUserName:")); 431061da546Spatrick uint32_t uid = packet.GetU32(UINT32_MAX); 432061da546Spatrick if (uid != UINT32_MAX) { 433061da546Spatrick if (llvm::Optional<llvm::StringRef> name = 434061da546Spatrick HostInfo::GetUserIDResolver().GetUserName(uid)) { 435061da546Spatrick StreamString response; 436061da546Spatrick response.PutStringAsRawHex8(*name); 437061da546Spatrick return SendPacketNoLock(response.GetString()); 438061da546Spatrick } 439061da546Spatrick } 440061da546Spatrick LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__); 441061da546Spatrick #endif 442061da546Spatrick return SendErrorResponse(5); 443061da546Spatrick } 444061da546Spatrick 445061da546Spatrick GDBRemoteCommunication::PacketResult 446061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qGroupName( 447061da546Spatrick StringExtractorGDBRemote &packet) { 448061da546Spatrick #if LLDB_ENABLE_POSIX 449061da546Spatrick // Packet format: "qGroupName:%i" where %i is the gid 450061da546Spatrick packet.SetFilePos(::strlen("qGroupName:")); 451061da546Spatrick uint32_t gid = packet.GetU32(UINT32_MAX); 452061da546Spatrick if (gid != UINT32_MAX) { 453061da546Spatrick if (llvm::Optional<llvm::StringRef> name = 454061da546Spatrick HostInfo::GetUserIDResolver().GetGroupName(gid)) { 455061da546Spatrick StreamString response; 456061da546Spatrick response.PutStringAsRawHex8(*name); 457061da546Spatrick return SendPacketNoLock(response.GetString()); 458061da546Spatrick } 459061da546Spatrick } 460061da546Spatrick #endif 461061da546Spatrick return SendErrorResponse(6); 462061da546Spatrick } 463061da546Spatrick 464061da546Spatrick GDBRemoteCommunication::PacketResult 465061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qSpeedTest( 466061da546Spatrick StringExtractorGDBRemote &packet) { 467061da546Spatrick packet.SetFilePos(::strlen("qSpeedTest:")); 468061da546Spatrick 469061da546Spatrick llvm::StringRef key; 470061da546Spatrick llvm::StringRef value; 471061da546Spatrick bool success = packet.GetNameColonValue(key, value); 472061da546Spatrick if (success && key.equals("response_size")) { 473061da546Spatrick uint32_t response_size = 0; 474061da546Spatrick if (!value.getAsInteger(0, response_size)) { 475061da546Spatrick if (response_size == 0) 476061da546Spatrick return SendOKResponse(); 477061da546Spatrick StreamString response; 478061da546Spatrick uint32_t bytes_left = response_size; 479061da546Spatrick response.PutCString("data:"); 480061da546Spatrick while (bytes_left > 0) { 481061da546Spatrick if (bytes_left >= 26) { 482061da546Spatrick response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 483061da546Spatrick bytes_left -= 26; 484061da546Spatrick } else { 485061da546Spatrick response.Printf("%*.*s;", bytes_left, bytes_left, 486061da546Spatrick "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 487061da546Spatrick bytes_left = 0; 488061da546Spatrick } 489061da546Spatrick } 490061da546Spatrick return SendPacketNoLock(response.GetString()); 491061da546Spatrick } 492061da546Spatrick } 493061da546Spatrick return SendErrorResponse(7); 494061da546Spatrick } 495061da546Spatrick 496061da546Spatrick GDBRemoteCommunication::PacketResult 497061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_Open( 498061da546Spatrick StringExtractorGDBRemote &packet) { 499061da546Spatrick packet.SetFilePos(::strlen("vFile:open:")); 500061da546Spatrick std::string path; 501061da546Spatrick packet.GetHexByteStringTerminatedBy(path, ','); 502061da546Spatrick if (!path.empty()) { 503061da546Spatrick if (packet.GetChar() == ',') { 504061da546Spatrick // FIXME 505061da546Spatrick // The flag values for OpenOptions do not match the values used by GDB 506061da546Spatrick // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags 507061da546Spatrick // * rdar://problem/46788934 508061da546Spatrick auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0)); 509061da546Spatrick if (packet.GetChar() == ',') { 510061da546Spatrick mode_t mode = packet.GetHexMaxU32(false, 0600); 511061da546Spatrick FileSpec path_spec(path); 512061da546Spatrick FileSystem::Instance().Resolve(path_spec); 513061da546Spatrick // Do not close fd. 514061da546Spatrick auto file = FileSystem::Instance().Open(path_spec, flags, mode, false); 515061da546Spatrick 516061da546Spatrick int save_errno = 0; 517061da546Spatrick int descriptor = File::kInvalidDescriptor; 518061da546Spatrick if (file) { 519061da546Spatrick descriptor = file.get()->GetDescriptor(); 520061da546Spatrick } else { 521061da546Spatrick std::error_code code = errorToErrorCode(file.takeError()); 522061da546Spatrick if (code.category() == std::system_category()) { 523061da546Spatrick save_errno = code.value(); 524061da546Spatrick } 525061da546Spatrick } 526061da546Spatrick 527061da546Spatrick StreamString response; 528061da546Spatrick response.PutChar('F'); 529061da546Spatrick response.Printf("%i", descriptor); 530061da546Spatrick if (save_errno) 531061da546Spatrick response.Printf(",%i", save_errno); 532061da546Spatrick return SendPacketNoLock(response.GetString()); 533061da546Spatrick } 534061da546Spatrick } 535061da546Spatrick } 536061da546Spatrick return SendErrorResponse(18); 537061da546Spatrick } 538061da546Spatrick 539061da546Spatrick GDBRemoteCommunication::PacketResult 540061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_Close( 541061da546Spatrick StringExtractorGDBRemote &packet) { 542061da546Spatrick packet.SetFilePos(::strlen("vFile:close:")); 543061da546Spatrick int fd = packet.GetS32(-1); 544061da546Spatrick int err = -1; 545061da546Spatrick int save_errno = 0; 546061da546Spatrick if (fd >= 0) { 547061da546Spatrick NativeFile file(fd, File::OpenOptions(0), true); 548061da546Spatrick Status error = file.Close(); 549061da546Spatrick err = 0; 550061da546Spatrick save_errno = error.GetError(); 551061da546Spatrick } else { 552061da546Spatrick save_errno = EINVAL; 553061da546Spatrick } 554061da546Spatrick StreamString response; 555061da546Spatrick response.PutChar('F'); 556061da546Spatrick response.Printf("%i", err); 557061da546Spatrick if (save_errno) 558061da546Spatrick response.Printf(",%i", save_errno); 559061da546Spatrick return SendPacketNoLock(response.GetString()); 560061da546Spatrick } 561061da546Spatrick 562061da546Spatrick GDBRemoteCommunication::PacketResult 563061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_pRead( 564061da546Spatrick StringExtractorGDBRemote &packet) { 565061da546Spatrick StreamGDBRemote response; 566061da546Spatrick packet.SetFilePos(::strlen("vFile:pread:")); 567061da546Spatrick int fd = packet.GetS32(-1); 568061da546Spatrick if (packet.GetChar() == ',') { 569061da546Spatrick size_t count = packet.GetU64(SIZE_MAX); 570061da546Spatrick if (packet.GetChar() == ',') { 571061da546Spatrick off_t offset = packet.GetU64(UINT32_MAX); 572061da546Spatrick if (count == SIZE_MAX) { 573061da546Spatrick response.Printf("F-1:%i", EINVAL); 574061da546Spatrick return SendPacketNoLock(response.GetString()); 575061da546Spatrick } 576061da546Spatrick 577061da546Spatrick std::string buffer(count, 0); 578061da546Spatrick NativeFile file(fd, File::eOpenOptionRead, false); 579061da546Spatrick Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset); 580061da546Spatrick const ssize_t bytes_read = error.Success() ? count : -1; 581061da546Spatrick const int save_errno = error.GetError(); 582061da546Spatrick response.PutChar('F'); 583061da546Spatrick response.Printf("%zi", bytes_read); 584061da546Spatrick if (save_errno) 585061da546Spatrick response.Printf(",%i", save_errno); 586061da546Spatrick else { 587061da546Spatrick response.PutChar(';'); 588061da546Spatrick response.PutEscapedBytes(&buffer[0], bytes_read); 589061da546Spatrick } 590061da546Spatrick return SendPacketNoLock(response.GetString()); 591061da546Spatrick } 592061da546Spatrick } 593061da546Spatrick return SendErrorResponse(21); 594061da546Spatrick } 595061da546Spatrick 596061da546Spatrick GDBRemoteCommunication::PacketResult 597061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite( 598061da546Spatrick StringExtractorGDBRemote &packet) { 599061da546Spatrick packet.SetFilePos(::strlen("vFile:pwrite:")); 600061da546Spatrick 601061da546Spatrick StreamGDBRemote response; 602061da546Spatrick response.PutChar('F'); 603061da546Spatrick 604061da546Spatrick int fd = packet.GetU32(UINT32_MAX); 605061da546Spatrick if (packet.GetChar() == ',') { 606061da546Spatrick off_t offset = packet.GetU64(UINT32_MAX); 607061da546Spatrick if (packet.GetChar() == ',') { 608061da546Spatrick std::string buffer; 609061da546Spatrick if (packet.GetEscapedBinaryData(buffer)) { 610061da546Spatrick NativeFile file(fd, File::eOpenOptionWrite, false); 611061da546Spatrick size_t count = buffer.size(); 612061da546Spatrick Status error = 613061da546Spatrick file.Write(static_cast<const void *>(&buffer[0]), count, offset); 614061da546Spatrick const ssize_t bytes_written = error.Success() ? count : -1; 615061da546Spatrick const int save_errno = error.GetError(); 616061da546Spatrick response.Printf("%zi", bytes_written); 617061da546Spatrick if (save_errno) 618061da546Spatrick response.Printf(",%i", save_errno); 619061da546Spatrick } else { 620061da546Spatrick response.Printf("-1,%i", EINVAL); 621061da546Spatrick } 622061da546Spatrick return SendPacketNoLock(response.GetString()); 623061da546Spatrick } 624061da546Spatrick } 625061da546Spatrick return SendErrorResponse(27); 626061da546Spatrick } 627061da546Spatrick 628061da546Spatrick GDBRemoteCommunication::PacketResult 629061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_Size( 630061da546Spatrick StringExtractorGDBRemote &packet) { 631061da546Spatrick packet.SetFilePos(::strlen("vFile:size:")); 632061da546Spatrick std::string path; 633061da546Spatrick packet.GetHexByteString(path); 634061da546Spatrick if (!path.empty()) { 635061da546Spatrick uint64_t Size; 636061da546Spatrick if (llvm::sys::fs::file_size(path, Size)) 637061da546Spatrick return SendErrorResponse(5); 638061da546Spatrick StreamString response; 639061da546Spatrick response.PutChar('F'); 640061da546Spatrick response.PutHex64(Size); 641061da546Spatrick if (Size == UINT64_MAX) { 642061da546Spatrick response.PutChar(','); 643061da546Spatrick response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode() 644061da546Spatrick } 645061da546Spatrick return SendPacketNoLock(response.GetString()); 646061da546Spatrick } 647061da546Spatrick return SendErrorResponse(22); 648061da546Spatrick } 649061da546Spatrick 650061da546Spatrick GDBRemoteCommunication::PacketResult 651061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( 652061da546Spatrick StringExtractorGDBRemote &packet) { 653061da546Spatrick packet.SetFilePos(::strlen("vFile:mode:")); 654061da546Spatrick std::string path; 655061da546Spatrick packet.GetHexByteString(path); 656061da546Spatrick if (!path.empty()) { 657061da546Spatrick FileSpec file_spec(path); 658061da546Spatrick FileSystem::Instance().Resolve(file_spec); 659061da546Spatrick std::error_code ec; 660061da546Spatrick const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); 661061da546Spatrick StreamString response; 662061da546Spatrick response.Printf("F%u", mode); 663061da546Spatrick if (mode == 0 || ec) 664061da546Spatrick response.Printf(",%i", (int)Status(ec).GetError()); 665061da546Spatrick return SendPacketNoLock(response.GetString()); 666061da546Spatrick } 667061da546Spatrick return SendErrorResponse(23); 668061da546Spatrick } 669061da546Spatrick 670061da546Spatrick GDBRemoteCommunication::PacketResult 671061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_Exists( 672061da546Spatrick StringExtractorGDBRemote &packet) { 673061da546Spatrick packet.SetFilePos(::strlen("vFile:exists:")); 674061da546Spatrick std::string path; 675061da546Spatrick packet.GetHexByteString(path); 676061da546Spatrick if (!path.empty()) { 677061da546Spatrick bool retcode = llvm::sys::fs::exists(path); 678061da546Spatrick StreamString response; 679061da546Spatrick response.PutChar('F'); 680061da546Spatrick response.PutChar(','); 681061da546Spatrick if (retcode) 682061da546Spatrick response.PutChar('1'); 683061da546Spatrick else 684061da546Spatrick response.PutChar('0'); 685061da546Spatrick return SendPacketNoLock(response.GetString()); 686061da546Spatrick } 687061da546Spatrick return SendErrorResponse(24); 688061da546Spatrick } 689061da546Spatrick 690061da546Spatrick GDBRemoteCommunication::PacketResult 691061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( 692061da546Spatrick StringExtractorGDBRemote &packet) { 693061da546Spatrick packet.SetFilePos(::strlen("vFile:symlink:")); 694061da546Spatrick std::string dst, src; 695061da546Spatrick packet.GetHexByteStringTerminatedBy(dst, ','); 696061da546Spatrick packet.GetChar(); // Skip ',' char 697061da546Spatrick packet.GetHexByteString(src); 698061da546Spatrick 699061da546Spatrick FileSpec src_spec(src); 700061da546Spatrick FileSystem::Instance().Resolve(src_spec); 701061da546Spatrick Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); 702061da546Spatrick 703061da546Spatrick StreamString response; 704061da546Spatrick response.Printf("F%u,%u", error.GetError(), error.GetError()); 705061da546Spatrick return SendPacketNoLock(response.GetString()); 706061da546Spatrick } 707061da546Spatrick 708061da546Spatrick GDBRemoteCommunication::PacketResult 709061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_unlink( 710061da546Spatrick StringExtractorGDBRemote &packet) { 711061da546Spatrick packet.SetFilePos(::strlen("vFile:unlink:")); 712061da546Spatrick std::string path; 713061da546Spatrick packet.GetHexByteString(path); 714061da546Spatrick Status error(llvm::sys::fs::remove(path)); 715061da546Spatrick StreamString response; 716061da546Spatrick response.Printf("F%u,%u", error.GetError(), error.GetError()); 717061da546Spatrick return SendPacketNoLock(response.GetString()); 718061da546Spatrick } 719061da546Spatrick 720061da546Spatrick GDBRemoteCommunication::PacketResult 721061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( 722061da546Spatrick StringExtractorGDBRemote &packet) { 723061da546Spatrick packet.SetFilePos(::strlen("qPlatform_shell:")); 724061da546Spatrick std::string path; 725061da546Spatrick std::string working_dir; 726061da546Spatrick packet.GetHexByteStringTerminatedBy(path, ','); 727061da546Spatrick if (!path.empty()) { 728061da546Spatrick if (packet.GetChar() == ',') { 729061da546Spatrick // FIXME: add timeout to qPlatform_shell packet 730061da546Spatrick // uint32_t timeout = packet.GetHexMaxU32(false, 32); 731061da546Spatrick if (packet.GetChar() == ',') 732061da546Spatrick packet.GetHexByteString(working_dir); 733061da546Spatrick int status, signo; 734061da546Spatrick std::string output; 735061da546Spatrick FileSpec working_spec(working_dir); 736061da546Spatrick FileSystem::Instance().Resolve(working_spec); 737061da546Spatrick Status err = 738061da546Spatrick Host::RunShellCommand(path.c_str(), working_spec, &status, &signo, 739061da546Spatrick &output, std::chrono::seconds(10)); 740061da546Spatrick StreamGDBRemote response; 741061da546Spatrick if (err.Fail()) { 742061da546Spatrick response.PutCString("F,"); 743061da546Spatrick response.PutHex32(UINT32_MAX); 744061da546Spatrick } else { 745061da546Spatrick response.PutCString("F,"); 746061da546Spatrick response.PutHex32(status); 747061da546Spatrick response.PutChar(','); 748061da546Spatrick response.PutHex32(signo); 749061da546Spatrick response.PutChar(','); 750061da546Spatrick response.PutEscapedBytes(output.c_str(), output.size()); 751061da546Spatrick } 752061da546Spatrick return SendPacketNoLock(response.GetString()); 753061da546Spatrick } 754061da546Spatrick } 755061da546Spatrick return SendErrorResponse(24); 756061da546Spatrick } 757061da546Spatrick 758061da546Spatrick GDBRemoteCommunication::PacketResult 759061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_Stat( 760061da546Spatrick StringExtractorGDBRemote &packet) { 761061da546Spatrick return SendUnimplementedResponse( 762061da546Spatrick "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented"); 763061da546Spatrick } 764061da546Spatrick 765061da546Spatrick GDBRemoteCommunication::PacketResult 766061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_vFile_MD5( 767061da546Spatrick StringExtractorGDBRemote &packet) { 768061da546Spatrick packet.SetFilePos(::strlen("vFile:MD5:")); 769061da546Spatrick std::string path; 770061da546Spatrick packet.GetHexByteString(path); 771061da546Spatrick if (!path.empty()) { 772061da546Spatrick StreamGDBRemote response; 773061da546Spatrick auto Result = llvm::sys::fs::md5_contents(path); 774061da546Spatrick if (!Result) { 775061da546Spatrick response.PutCString("F,"); 776061da546Spatrick response.PutCString("x"); 777061da546Spatrick } else { 778061da546Spatrick response.PutCString("F,"); 779061da546Spatrick response.PutHex64(Result->low()); 780061da546Spatrick response.PutHex64(Result->high()); 781061da546Spatrick } 782061da546Spatrick return SendPacketNoLock(response.GetString()); 783061da546Spatrick } 784061da546Spatrick return SendErrorResponse(25); 785061da546Spatrick } 786061da546Spatrick 787061da546Spatrick GDBRemoteCommunication::PacketResult 788061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir( 789061da546Spatrick StringExtractorGDBRemote &packet) { 790061da546Spatrick packet.SetFilePos(::strlen("qPlatform_mkdir:")); 791061da546Spatrick mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 792061da546Spatrick if (packet.GetChar() == ',') { 793061da546Spatrick std::string path; 794061da546Spatrick packet.GetHexByteString(path); 795061da546Spatrick Status error(llvm::sys::fs::create_directory(path, mode)); 796061da546Spatrick 797061da546Spatrick StreamGDBRemote response; 798061da546Spatrick response.Printf("F%u", error.GetError()); 799061da546Spatrick 800061da546Spatrick return SendPacketNoLock(response.GetString()); 801061da546Spatrick } 802061da546Spatrick return SendErrorResponse(20); 803061da546Spatrick } 804061da546Spatrick 805061da546Spatrick GDBRemoteCommunication::PacketResult 806061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod( 807061da546Spatrick StringExtractorGDBRemote &packet) { 808061da546Spatrick packet.SetFilePos(::strlen("qPlatform_chmod:")); 809061da546Spatrick 810061da546Spatrick auto perms = 811061da546Spatrick static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX)); 812061da546Spatrick if (packet.GetChar() == ',') { 813061da546Spatrick std::string path; 814061da546Spatrick packet.GetHexByteString(path); 815061da546Spatrick Status error(llvm::sys::fs::setPermissions(path, perms)); 816061da546Spatrick 817061da546Spatrick StreamGDBRemote response; 818061da546Spatrick response.Printf("F%u", error.GetError()); 819061da546Spatrick 820061da546Spatrick return SendPacketNoLock(response.GetString()); 821061da546Spatrick } 822061da546Spatrick return SendErrorResponse(19); 823061da546Spatrick } 824061da546Spatrick 825061da546Spatrick GDBRemoteCommunication::PacketResult 826061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qSupported( 827061da546Spatrick StringExtractorGDBRemote &packet) { 828*a0747c9fSpatrick // Parse client-indicated features. 829*a0747c9fSpatrick llvm::SmallVector<llvm::StringRef, 4> client_features; 830*a0747c9fSpatrick packet.GetStringRef().split(client_features, ';'); 831*a0747c9fSpatrick return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";")); 832061da546Spatrick } 833061da546Spatrick 834061da546Spatrick GDBRemoteCommunication::PacketResult 835061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError( 836061da546Spatrick StringExtractorGDBRemote &packet) { 837061da546Spatrick packet.SetFilePos(::strlen("QSetDetachOnError:")); 838061da546Spatrick if (packet.GetU32(0)) 839061da546Spatrick m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError); 840061da546Spatrick else 841061da546Spatrick m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError); 842061da546Spatrick return SendOKResponse(); 843061da546Spatrick } 844061da546Spatrick 845061da546Spatrick GDBRemoteCommunication::PacketResult 846061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode( 847061da546Spatrick StringExtractorGDBRemote &packet) { 848061da546Spatrick // Send response first before changing m_send_acks to we ack this packet 849061da546Spatrick PacketResult packet_result = SendOKResponse(); 850061da546Spatrick m_send_acks = false; 851061da546Spatrick return packet_result; 852061da546Spatrick } 853061da546Spatrick 854061da546Spatrick GDBRemoteCommunication::PacketResult 855061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN( 856061da546Spatrick StringExtractorGDBRemote &packet) { 857061da546Spatrick packet.SetFilePos(::strlen("QSetSTDIN:")); 858061da546Spatrick FileAction file_action; 859061da546Spatrick std::string path; 860061da546Spatrick packet.GetHexByteString(path); 861061da546Spatrick const bool read = true; 862061da546Spatrick const bool write = false; 863061da546Spatrick if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) { 864061da546Spatrick m_process_launch_info.AppendFileAction(file_action); 865061da546Spatrick return SendOKResponse(); 866061da546Spatrick } 867061da546Spatrick return SendErrorResponse(15); 868061da546Spatrick } 869061da546Spatrick 870061da546Spatrick GDBRemoteCommunication::PacketResult 871061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT( 872061da546Spatrick StringExtractorGDBRemote &packet) { 873061da546Spatrick packet.SetFilePos(::strlen("QSetSTDOUT:")); 874061da546Spatrick FileAction file_action; 875061da546Spatrick std::string path; 876061da546Spatrick packet.GetHexByteString(path); 877061da546Spatrick const bool read = false; 878061da546Spatrick const bool write = true; 879061da546Spatrick if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) { 880061da546Spatrick m_process_launch_info.AppendFileAction(file_action); 881061da546Spatrick return SendOKResponse(); 882061da546Spatrick } 883061da546Spatrick return SendErrorResponse(16); 884061da546Spatrick } 885061da546Spatrick 886061da546Spatrick GDBRemoteCommunication::PacketResult 887061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR( 888061da546Spatrick StringExtractorGDBRemote &packet) { 889061da546Spatrick packet.SetFilePos(::strlen("QSetSTDERR:")); 890061da546Spatrick FileAction file_action; 891061da546Spatrick std::string path; 892061da546Spatrick packet.GetHexByteString(path); 893061da546Spatrick const bool read = false; 894061da546Spatrick const bool write = true; 895061da546Spatrick if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) { 896061da546Spatrick m_process_launch_info.AppendFileAction(file_action); 897061da546Spatrick return SendOKResponse(); 898061da546Spatrick } 899061da546Spatrick return SendErrorResponse(17); 900061da546Spatrick } 901061da546Spatrick 902061da546Spatrick GDBRemoteCommunication::PacketResult 903061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess( 904061da546Spatrick StringExtractorGDBRemote &packet) { 905061da546Spatrick if (m_process_launch_error.Success()) 906061da546Spatrick return SendOKResponse(); 907061da546Spatrick StreamString response; 908061da546Spatrick response.PutChar('E'); 909061da546Spatrick response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 910061da546Spatrick return SendPacketNoLock(response.GetString()); 911061da546Spatrick } 912061da546Spatrick 913061da546Spatrick GDBRemoteCommunication::PacketResult 914061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QEnvironment( 915061da546Spatrick StringExtractorGDBRemote &packet) { 916061da546Spatrick packet.SetFilePos(::strlen("QEnvironment:")); 917061da546Spatrick const uint32_t bytes_left = packet.GetBytesLeft(); 918061da546Spatrick if (bytes_left > 0) { 919061da546Spatrick m_process_launch_info.GetEnvironment().insert(packet.Peek()); 920061da546Spatrick return SendOKResponse(); 921061da546Spatrick } 922061da546Spatrick return SendErrorResponse(12); 923061da546Spatrick } 924061da546Spatrick 925061da546Spatrick GDBRemoteCommunication::PacketResult 926061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded( 927061da546Spatrick StringExtractorGDBRemote &packet) { 928061da546Spatrick packet.SetFilePos(::strlen("QEnvironmentHexEncoded:")); 929061da546Spatrick const uint32_t bytes_left = packet.GetBytesLeft(); 930061da546Spatrick if (bytes_left > 0) { 931061da546Spatrick std::string str; 932061da546Spatrick packet.GetHexByteString(str); 933061da546Spatrick m_process_launch_info.GetEnvironment().insert(str); 934061da546Spatrick return SendOKResponse(); 935061da546Spatrick } 936061da546Spatrick return SendErrorResponse(12); 937061da546Spatrick } 938061da546Spatrick 939061da546Spatrick GDBRemoteCommunication::PacketResult 940061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_QLaunchArch( 941061da546Spatrick StringExtractorGDBRemote &packet) { 942061da546Spatrick packet.SetFilePos(::strlen("QLaunchArch:")); 943061da546Spatrick const uint32_t bytes_left = packet.GetBytesLeft(); 944061da546Spatrick if (bytes_left > 0) { 945061da546Spatrick const char *arch_triple = packet.Peek(); 946061da546Spatrick m_process_launch_info.SetArchitecture( 947061da546Spatrick HostInfo::GetAugmentedArchSpec(arch_triple)); 948061da546Spatrick return SendOKResponse(); 949061da546Spatrick } 950061da546Spatrick return SendErrorResponse(13); 951061da546Spatrick } 952061da546Spatrick 953061da546Spatrick GDBRemoteCommunication::PacketResult 954061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { 955061da546Spatrick // The 'A' packet is the most over designed packet ever here with redundant 956061da546Spatrick // argument indexes, redundant argument lengths and needed hex encoded 957061da546Spatrick // argument string values. Really all that is needed is a comma separated hex 958061da546Spatrick // encoded argument value list, but we will stay true to the documented 959061da546Spatrick // version of the 'A' packet here... 960061da546Spatrick 961061da546Spatrick Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); 962061da546Spatrick int actual_arg_index = 0; 963061da546Spatrick 964061da546Spatrick packet.SetFilePos(1); // Skip the 'A' 965061da546Spatrick bool success = true; 966061da546Spatrick while (success && packet.GetBytesLeft() > 0) { 967061da546Spatrick // Decode the decimal argument string length. This length is the number of 968061da546Spatrick // hex nibbles in the argument string value. 969061da546Spatrick const uint32_t arg_len = packet.GetU32(UINT32_MAX); 970061da546Spatrick if (arg_len == UINT32_MAX) 971061da546Spatrick success = false; 972061da546Spatrick else { 973061da546Spatrick // Make sure the argument hex string length is followed by a comma 974061da546Spatrick if (packet.GetChar() != ',') 975061da546Spatrick success = false; 976061da546Spatrick else { 977061da546Spatrick // Decode the argument index. We ignore this really because who would 978061da546Spatrick // really send down the arguments in a random order??? 979061da546Spatrick const uint32_t arg_idx = packet.GetU32(UINT32_MAX); 980061da546Spatrick if (arg_idx == UINT32_MAX) 981061da546Spatrick success = false; 982061da546Spatrick else { 983061da546Spatrick // Make sure the argument index is followed by a comma 984061da546Spatrick if (packet.GetChar() != ',') 985061da546Spatrick success = false; 986061da546Spatrick else { 987061da546Spatrick // Decode the argument string value from hex bytes back into a UTF8 988061da546Spatrick // string and make sure the length matches the one supplied in the 989061da546Spatrick // packet 990061da546Spatrick std::string arg; 991061da546Spatrick if (packet.GetHexByteStringFixedLength(arg, arg_len) != 992061da546Spatrick (arg_len / 2)) 993061da546Spatrick success = false; 994061da546Spatrick else { 995061da546Spatrick // If there are any bytes left 996061da546Spatrick if (packet.GetBytesLeft()) { 997061da546Spatrick if (packet.GetChar() != ',') 998061da546Spatrick success = false; 999061da546Spatrick } 1000061da546Spatrick 1001061da546Spatrick if (success) { 1002061da546Spatrick if (arg_idx == 0) 1003061da546Spatrick m_process_launch_info.GetExecutableFile().SetFile( 1004061da546Spatrick arg, FileSpec::Style::native); 1005061da546Spatrick m_process_launch_info.GetArguments().AppendArgument(arg); 1006061da546Spatrick LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"", 1007061da546Spatrick __FUNCTION__, actual_arg_index, arg.c_str()); 1008061da546Spatrick ++actual_arg_index; 1009061da546Spatrick } 1010061da546Spatrick } 1011061da546Spatrick } 1012061da546Spatrick } 1013061da546Spatrick } 1014061da546Spatrick } 1015061da546Spatrick } 1016061da546Spatrick 1017061da546Spatrick if (success) { 1018061da546Spatrick m_process_launch_error = LaunchProcess(); 1019061da546Spatrick if (m_process_launch_error.Success()) 1020061da546Spatrick return SendOKResponse(); 1021061da546Spatrick LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error); 1022061da546Spatrick } 1023061da546Spatrick return SendErrorResponse(8); 1024061da546Spatrick } 1025061da546Spatrick 1026061da546Spatrick GDBRemoteCommunication::PacketResult 1027061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qEcho( 1028061da546Spatrick StringExtractorGDBRemote &packet) { 1029061da546Spatrick // Just echo back the exact same packet for qEcho... 1030061da546Spatrick return SendPacketNoLock(packet.GetStringRef()); 1031061da546Spatrick } 1032061da546Spatrick 1033061da546Spatrick GDBRemoteCommunication::PacketResult 1034061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( 1035061da546Spatrick StringExtractorGDBRemote &packet) { 1036061da546Spatrick packet.SetFilePos(::strlen("qModuleInfo:")); 1037061da546Spatrick 1038061da546Spatrick std::string module_path; 1039061da546Spatrick packet.GetHexByteStringTerminatedBy(module_path, ';'); 1040061da546Spatrick if (module_path.empty()) 1041061da546Spatrick return SendErrorResponse(1); 1042061da546Spatrick 1043061da546Spatrick if (packet.GetChar() != ';') 1044061da546Spatrick return SendErrorResponse(2); 1045061da546Spatrick 1046061da546Spatrick std::string triple; 1047061da546Spatrick packet.GetHexByteString(triple); 1048061da546Spatrick 1049061da546Spatrick ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple); 1050061da546Spatrick if (!matched_module_spec.GetFileSpec()) 1051061da546Spatrick return SendErrorResponse(3); 1052061da546Spatrick 1053061da546Spatrick const auto file_offset = matched_module_spec.GetObjectOffset(); 1054061da546Spatrick const auto file_size = matched_module_spec.GetObjectSize(); 1055061da546Spatrick const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); 1056061da546Spatrick 1057061da546Spatrick StreamGDBRemote response; 1058061da546Spatrick 1059061da546Spatrick if (uuid_str.empty()) { 1060061da546Spatrick auto Result = llvm::sys::fs::md5_contents( 1061061da546Spatrick matched_module_spec.GetFileSpec().GetPath()); 1062061da546Spatrick if (!Result) 1063061da546Spatrick return SendErrorResponse(5); 1064061da546Spatrick response.PutCString("md5:"); 1065061da546Spatrick response.PutStringAsRawHex8(Result->digest()); 1066061da546Spatrick } else { 1067061da546Spatrick response.PutCString("uuid:"); 1068061da546Spatrick response.PutStringAsRawHex8(uuid_str); 1069061da546Spatrick } 1070061da546Spatrick response.PutChar(';'); 1071061da546Spatrick 1072061da546Spatrick const auto &module_arch = matched_module_spec.GetArchitecture(); 1073061da546Spatrick response.PutCString("triple:"); 1074061da546Spatrick response.PutStringAsRawHex8(module_arch.GetTriple().getTriple()); 1075061da546Spatrick response.PutChar(';'); 1076061da546Spatrick 1077061da546Spatrick response.PutCString("file_path:"); 1078061da546Spatrick response.PutStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString()); 1079061da546Spatrick response.PutChar(';'); 1080061da546Spatrick response.PutCString("file_offset:"); 1081061da546Spatrick response.PutHex64(file_offset); 1082061da546Spatrick response.PutChar(';'); 1083061da546Spatrick response.PutCString("file_size:"); 1084061da546Spatrick response.PutHex64(file_size); 1085061da546Spatrick response.PutChar(';'); 1086061da546Spatrick 1087061da546Spatrick return SendPacketNoLock(response.GetString()); 1088061da546Spatrick } 1089061da546Spatrick 1090061da546Spatrick GDBRemoteCommunication::PacketResult 1091061da546Spatrick GDBRemoteCommunicationServerCommon::Handle_jModulesInfo( 1092061da546Spatrick StringExtractorGDBRemote &packet) { 1093061da546Spatrick namespace json = llvm::json; 1094061da546Spatrick 1095061da546Spatrick packet.SetFilePos(::strlen("jModulesInfo:")); 1096061da546Spatrick 1097061da546Spatrick StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek()); 1098061da546Spatrick if (!object_sp) 1099061da546Spatrick return SendErrorResponse(1); 1100061da546Spatrick 1101061da546Spatrick StructuredData::Array *packet_array = object_sp->GetAsArray(); 1102061da546Spatrick if (!packet_array) 1103061da546Spatrick return SendErrorResponse(2); 1104061da546Spatrick 1105061da546Spatrick json::Array response_array; 1106061da546Spatrick for (size_t i = 0; i < packet_array->GetSize(); ++i) { 1107061da546Spatrick StructuredData::Dictionary *query = 1108061da546Spatrick packet_array->GetItemAtIndex(i)->GetAsDictionary(); 1109061da546Spatrick if (!query) 1110061da546Spatrick continue; 1111061da546Spatrick llvm::StringRef file, triple; 1112061da546Spatrick if (!query->GetValueForKeyAsString("file", file) || 1113061da546Spatrick !query->GetValueForKeyAsString("triple", triple)) 1114061da546Spatrick continue; 1115061da546Spatrick 1116061da546Spatrick ModuleSpec matched_module_spec = GetModuleInfo(file, triple); 1117061da546Spatrick if (!matched_module_spec.GetFileSpec()) 1118061da546Spatrick continue; 1119061da546Spatrick 1120061da546Spatrick const auto file_offset = matched_module_spec.GetObjectOffset(); 1121061da546Spatrick const auto file_size = matched_module_spec.GetObjectSize(); 1122061da546Spatrick const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); 1123061da546Spatrick if (uuid_str.empty()) 1124061da546Spatrick continue; 1125061da546Spatrick const auto triple_str = 1126061da546Spatrick matched_module_spec.GetArchitecture().GetTriple().getTriple(); 1127061da546Spatrick const auto file_path = matched_module_spec.GetFileSpec().GetPath(); 1128061da546Spatrick 1129061da546Spatrick json::Object response{{"uuid", uuid_str}, 1130061da546Spatrick {"triple", triple_str}, 1131061da546Spatrick {"file_path", file_path}, 1132061da546Spatrick {"file_offset", static_cast<int64_t>(file_offset)}, 1133061da546Spatrick {"file_size", static_cast<int64_t>(file_size)}}; 1134061da546Spatrick response_array.push_back(std::move(response)); 1135061da546Spatrick } 1136061da546Spatrick 1137061da546Spatrick StreamString response; 1138061da546Spatrick response.AsRawOstream() << std::move(response_array); 1139061da546Spatrick StreamGDBRemote escaped_response; 1140061da546Spatrick escaped_response.PutEscapedBytes(response.GetString().data(), 1141061da546Spatrick response.GetSize()); 1142061da546Spatrick return SendPacketNoLock(escaped_response.GetString()); 1143061da546Spatrick } 1144061da546Spatrick 1145061da546Spatrick void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse( 1146061da546Spatrick const ProcessInstanceInfo &proc_info, StreamString &response) { 1147061da546Spatrick response.Printf( 1148061da546Spatrick "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", 1149061da546Spatrick proc_info.GetProcessID(), proc_info.GetParentProcessID(), 1150061da546Spatrick proc_info.GetUserID(), proc_info.GetGroupID(), 1151061da546Spatrick proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID()); 1152061da546Spatrick response.PutCString("name:"); 1153061da546Spatrick response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString()); 1154061da546Spatrick 1155061da546Spatrick response.PutChar(';'); 1156061da546Spatrick response.PutCString("args:"); 1157061da546Spatrick response.PutStringAsRawHex8(proc_info.GetArg0()); 1158061da546Spatrick for (auto &arg : proc_info.GetArguments()) { 1159061da546Spatrick response.PutChar('-'); 1160061da546Spatrick response.PutStringAsRawHex8(arg.ref()); 1161061da546Spatrick } 1162061da546Spatrick 1163061da546Spatrick response.PutChar(';'); 1164061da546Spatrick const ArchSpec &proc_arch = proc_info.GetArchitecture(); 1165061da546Spatrick if (proc_arch.IsValid()) { 1166061da546Spatrick const llvm::Triple &proc_triple = proc_arch.GetTriple(); 1167061da546Spatrick response.PutCString("triple:"); 1168061da546Spatrick response.PutStringAsRawHex8(proc_triple.getTriple()); 1169061da546Spatrick response.PutChar(';'); 1170061da546Spatrick } 1171061da546Spatrick } 1172061da546Spatrick 1173061da546Spatrick void GDBRemoteCommunicationServerCommon:: 1174061da546Spatrick CreateProcessInfoResponse_DebugServerStyle( 1175061da546Spatrick const ProcessInstanceInfo &proc_info, StreamString &response) { 1176061da546Spatrick response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64 1177061da546Spatrick ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;", 1178061da546Spatrick proc_info.GetProcessID(), proc_info.GetParentProcessID(), 1179061da546Spatrick proc_info.GetUserID(), proc_info.GetGroupID(), 1180061da546Spatrick proc_info.GetEffectiveUserID(), 1181061da546Spatrick proc_info.GetEffectiveGroupID()); 1182061da546Spatrick 1183061da546Spatrick const ArchSpec &proc_arch = proc_info.GetArchitecture(); 1184061da546Spatrick if (proc_arch.IsValid()) { 1185061da546Spatrick const llvm::Triple &proc_triple = proc_arch.GetTriple(); 1186061da546Spatrick #if defined(__APPLE__) 1187061da546Spatrick // We'll send cputype/cpusubtype. 1188061da546Spatrick const uint32_t cpu_type = proc_arch.GetMachOCPUType(); 1189061da546Spatrick if (cpu_type != 0) 1190061da546Spatrick response.Printf("cputype:%" PRIx32 ";", cpu_type); 1191061da546Spatrick 1192061da546Spatrick const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType(); 1193061da546Spatrick if (cpu_subtype != 0) 1194061da546Spatrick response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype); 1195061da546Spatrick 1196dda28197Spatrick const std::string vendor = proc_triple.getVendorName().str(); 1197061da546Spatrick if (!vendor.empty()) 1198061da546Spatrick response.Printf("vendor:%s;", vendor.c_str()); 1199061da546Spatrick #else 1200061da546Spatrick // We'll send the triple. 1201061da546Spatrick response.PutCString("triple:"); 1202061da546Spatrick response.PutStringAsRawHex8(proc_triple.getTriple()); 1203061da546Spatrick response.PutChar(';'); 1204061da546Spatrick #endif 1205dda28197Spatrick std::string ostype = std::string(proc_triple.getOSName()); 1206061da546Spatrick // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64. 1207061da546Spatrick if (proc_triple.getVendor() == llvm::Triple::Apple) { 1208061da546Spatrick switch (proc_triple.getArch()) { 1209061da546Spatrick case llvm::Triple::arm: 1210061da546Spatrick case llvm::Triple::thumb: 1211061da546Spatrick case llvm::Triple::aarch64: 1212061da546Spatrick case llvm::Triple::aarch64_32: 1213061da546Spatrick ostype = "ios"; 1214061da546Spatrick break; 1215061da546Spatrick default: 1216061da546Spatrick // No change. 1217061da546Spatrick break; 1218061da546Spatrick } 1219061da546Spatrick } 1220061da546Spatrick response.Printf("ostype:%s;", ostype.c_str()); 1221061da546Spatrick 1222061da546Spatrick switch (proc_arch.GetByteOrder()) { 1223061da546Spatrick case lldb::eByteOrderLittle: 1224061da546Spatrick response.PutCString("endian:little;"); 1225061da546Spatrick break; 1226061da546Spatrick case lldb::eByteOrderBig: 1227061da546Spatrick response.PutCString("endian:big;"); 1228061da546Spatrick break; 1229061da546Spatrick case lldb::eByteOrderPDP: 1230061da546Spatrick response.PutCString("endian:pdp;"); 1231061da546Spatrick break; 1232061da546Spatrick default: 1233061da546Spatrick // Nothing. 1234061da546Spatrick break; 1235061da546Spatrick } 1236061da546Spatrick // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer 1237061da546Spatrick // size is 4 and for N64 it is 8 1238061da546Spatrick std::string abi = proc_arch.GetTargetABI(); 1239061da546Spatrick if (!abi.empty()) 1240061da546Spatrick response.Printf("elf_abi:%s;", abi.c_str()); 1241061da546Spatrick response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize()); 1242061da546Spatrick } 1243061da546Spatrick } 1244061da546Spatrick 1245061da546Spatrick FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( 1246061da546Spatrick const std::string &module_path, const ArchSpec &arch) { 1247061da546Spatrick #ifdef __ANDROID__ 1248061da546Spatrick return HostInfoAndroid::ResolveLibraryPath(module_path, arch); 1249061da546Spatrick #else 1250061da546Spatrick FileSpec file_spec(module_path); 1251061da546Spatrick FileSystem::Instance().Resolve(file_spec); 1252061da546Spatrick return file_spec; 1253061da546Spatrick #endif 1254061da546Spatrick } 1255061da546Spatrick 1256061da546Spatrick ModuleSpec 1257061da546Spatrick GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, 1258061da546Spatrick llvm::StringRef triple) { 1259061da546Spatrick ArchSpec arch(triple); 1260061da546Spatrick 1261061da546Spatrick FileSpec req_module_path_spec(module_path); 1262061da546Spatrick FileSystem::Instance().Resolve(req_module_path_spec); 1263061da546Spatrick 1264061da546Spatrick const FileSpec module_path_spec = 1265061da546Spatrick FindModuleFile(req_module_path_spec.GetPath(), arch); 1266061da546Spatrick const ModuleSpec module_spec(module_path_spec, arch); 1267061da546Spatrick 1268061da546Spatrick ModuleSpecList module_specs; 1269061da546Spatrick if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, 1270061da546Spatrick module_specs)) 1271061da546Spatrick return ModuleSpec(); 1272061da546Spatrick 1273061da546Spatrick ModuleSpec matched_module_spec; 1274061da546Spatrick if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) 1275061da546Spatrick return ModuleSpec(); 1276061da546Spatrick 1277061da546Spatrick return matched_module_spec; 1278061da546Spatrick } 1279*a0747c9fSpatrick 1280*a0747c9fSpatrick std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures( 1281*a0747c9fSpatrick const llvm::ArrayRef<llvm::StringRef> client_features) { 1282*a0747c9fSpatrick // 128KBytes is a reasonable max packet size--debugger can always use less. 1283*a0747c9fSpatrick constexpr uint32_t max_packet_size = 128 * 1024; 1284*a0747c9fSpatrick 1285*a0747c9fSpatrick // Features common to platform server and llgs. 1286*a0747c9fSpatrick return { 1287*a0747c9fSpatrick llvm::formatv("PacketSize={0}", max_packet_size), 1288*a0747c9fSpatrick "QStartNoAckMode+", 1289*a0747c9fSpatrick "qEcho+", 1290*a0747c9fSpatrick }; 1291*a0747c9fSpatrick } 1292