1391 lines · cpp
1//===-- GDBRemoteCommunicationServerCommon.cpp ----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "GDBRemoteCommunicationServerCommon.h"10 11#include <cerrno>12 13#ifdef __APPLE__14#include <TargetConditionals.h>15#endif16 17#include <chrono>18#include <cstring>19#include <optional>20 21#include "lldb/Core/ModuleSpec.h"22#include "lldb/Host/Config.h"23#include "lldb/Host/File.h"24#include "lldb/Host/FileAction.h"25#include "lldb/Host/FileSystem.h"26#include "lldb/Host/Host.h"27#include "lldb/Host/HostInfo.h"28#include "lldb/Host/SafeMachO.h"29#include "lldb/Interpreter/OptionArgParser.h"30#include "lldb/Symbol/ObjectFile.h"31#include "lldb/Target/Platform.h"32#include "lldb/Utility/Endian.h"33#include "lldb/Utility/GDBRemote.h"34#include "lldb/Utility/LLDBLog.h"35#include "lldb/Utility/Log.h"36#include "lldb/Utility/StreamString.h"37#include "lldb/Utility/StructuredData.h"38#include "llvm/ADT/StringSwitch.h"39#include "llvm/Support/JSON.h"40#include "llvm/TargetParser/Triple.h"41 42#include "ProcessGDBRemoteLog.h"43#include "lldb/Utility/StringExtractorGDBRemote.h"44 45#ifdef __ANDROID__46#include "lldb/Host/android/HostInfoAndroid.h"47#include "lldb/Host/common/ZipFileResolver.h"48#endif49 50using namespace lldb;51using namespace lldb_private::process_gdb_remote;52using namespace lldb_private;53 54#ifdef __ANDROID__55const static uint32_t g_default_packet_timeout_sec = 20; // seconds56#else57const static uint32_t g_default_packet_timeout_sec = 0; // not specified58#endif59 60// GDBRemoteCommunicationServerCommon constructor61GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon()62 : GDBRemoteCommunicationServer(), m_process_launch_info(),63 m_process_launch_error(), m_proc_infos(), m_proc_infos_index(0) {64 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,65 &GDBRemoteCommunicationServerCommon::Handle_A);66 RegisterMemberFunctionHandler(67 StringExtractorGDBRemote::eServerPacketType_QEnvironment,68 &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);69 RegisterMemberFunctionHandler(70 StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,71 &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);72 RegisterMemberFunctionHandler(73 StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,74 &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);75 RegisterMemberFunctionHandler(76 StringExtractorGDBRemote::eServerPacketType_qGroupName,77 &GDBRemoteCommunicationServerCommon::Handle_qGroupName);78 RegisterMemberFunctionHandler(79 StringExtractorGDBRemote::eServerPacketType_qHostInfo,80 &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);81 RegisterMemberFunctionHandler(82 StringExtractorGDBRemote::eServerPacketType_QLaunchArch,83 &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);84 RegisterMemberFunctionHandler(85 StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,86 &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);87 RegisterMemberFunctionHandler(88 StringExtractorGDBRemote::eServerPacketType_qEcho,89 &GDBRemoteCommunicationServerCommon::Handle_qEcho);90 RegisterMemberFunctionHandler(91 StringExtractorGDBRemote::eServerPacketType_qModuleInfo,92 &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);93 RegisterMemberFunctionHandler(94 StringExtractorGDBRemote::eServerPacketType_jModulesInfo,95 &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo);96 RegisterMemberFunctionHandler(97 StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,98 &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);99 RegisterMemberFunctionHandler(100 StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,101 &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);102 RegisterMemberFunctionHandler(103 StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,104 &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);105 RegisterMemberFunctionHandler(106 StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,107 &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);108 RegisterMemberFunctionHandler(109 StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,110 &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);111 RegisterMemberFunctionHandler(112 StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,113 &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);114 RegisterMemberFunctionHandler(115 StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,116 &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);117 RegisterMemberFunctionHandler(118 StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,119 &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);120 RegisterMemberFunctionHandler(121 StringExtractorGDBRemote::eServerPacketType_qSpeedTest,122 &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);123 RegisterMemberFunctionHandler(124 StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,125 &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);126 RegisterMemberFunctionHandler(127 StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,128 &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);129 RegisterMemberFunctionHandler(130 StringExtractorGDBRemote::eServerPacketType_qSupported,131 &GDBRemoteCommunicationServerCommon::Handle_qSupported);132 RegisterMemberFunctionHandler(133 StringExtractorGDBRemote::eServerPacketType_qUserName,134 &GDBRemoteCommunicationServerCommon::Handle_qUserName);135 RegisterMemberFunctionHandler(136 StringExtractorGDBRemote::eServerPacketType_vFile_close,137 &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);138 RegisterMemberFunctionHandler(139 StringExtractorGDBRemote::eServerPacketType_vFile_exists,140 &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);141 RegisterMemberFunctionHandler(142 StringExtractorGDBRemote::eServerPacketType_vFile_md5,143 &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);144 RegisterMemberFunctionHandler(145 StringExtractorGDBRemote::eServerPacketType_vFile_mode,146 &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);147 RegisterMemberFunctionHandler(148 StringExtractorGDBRemote::eServerPacketType_vFile_open,149 &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);150 RegisterMemberFunctionHandler(151 StringExtractorGDBRemote::eServerPacketType_vFile_pread,152 &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);153 RegisterMemberFunctionHandler(154 StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,155 &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);156 RegisterMemberFunctionHandler(157 StringExtractorGDBRemote::eServerPacketType_vFile_size,158 &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);159 RegisterMemberFunctionHandler(160 StringExtractorGDBRemote::eServerPacketType_vFile_fstat,161 &GDBRemoteCommunicationServerCommon::Handle_vFile_FStat);162 RegisterMemberFunctionHandler(163 StringExtractorGDBRemote::eServerPacketType_vFile_stat,164 &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);165 RegisterMemberFunctionHandler(166 StringExtractorGDBRemote::eServerPacketType_vFile_symlink,167 &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);168 RegisterMemberFunctionHandler(169 StringExtractorGDBRemote::eServerPacketType_vFile_unlink,170 &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);171}172 173// Destructor174GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() =175 default;176 177GDBRemoteCommunication::PacketResult178GDBRemoteCommunicationServerCommon::Handle_qHostInfo(179 StringExtractorGDBRemote &packet) {180 StreamString response;181 182 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00183 184 ArchSpec host_arch(HostInfo::GetArchitecture());185 const llvm::Triple &host_triple = host_arch.GetTriple();186 response.PutCString("triple:");187 response.PutStringAsRawHex8(host_triple.getTriple());188 response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());189 190 llvm::StringRef distribution_id = HostInfo::GetDistributionId();191 if (!distribution_id.empty()) {192 response.PutCString("distribution_id:");193 response.PutStringAsRawHex8(distribution_id);194 response.PutCString(";");195 }196 197#if defined(__APPLE__)198 // For parity with debugserver, we'll include the vendor key.199 response.PutCString("vendor:apple;");200 201 // Send out MachO info.202 uint32_t cpu = host_arch.GetMachOCPUType();203 uint32_t sub = host_arch.GetMachOCPUSubType();204 if (cpu != LLDB_INVALID_CPUTYPE)205 response.Printf("cputype:%u;", cpu);206 if (sub != LLDB_INVALID_CPUTYPE)207 response.Printf("cpusubtype:%u;", sub);208 209 if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) {210// Indicate the OS type.211#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1212 response.PutCString("ostype:tvos;");213#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1214 response.PutCString("ostype:watchos;");215#elif defined(TARGET_OS_XR) && TARGET_OS_XR == 1216 response.PutCString("ostype:xros;");217#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1218 response.PutCString("ostype:bridgeos;");219#else220 response.PutCString("ostype:ios;");221#endif222 223 // On arm, we use "synchronous" watchpoints which means the exception is224 // delivered before the instruction executes.225 response.PutCString("watchpoint_exceptions_received:before;");226 } else {227 response.PutCString("ostype:macosx;");228 response.Printf("watchpoint_exceptions_received:after;");229 }230 231#else232 if (host_arch.GetMachine() == llvm::Triple::aarch64 ||233 host_arch.GetMachine() == llvm::Triple::aarch64_32 ||234 host_arch.GetMachine() == llvm::Triple::aarch64_be ||235 host_arch.GetMachine() == llvm::Triple::arm ||236 host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS() ||237 host_arch.GetTriple().isLoongArch())238 response.Printf("watchpoint_exceptions_received:before;");239 else240 response.Printf("watchpoint_exceptions_received:after;");241#endif242 243 switch (endian::InlHostByteOrder()) {244 case eByteOrderBig:245 response.PutCString("endian:big;");246 break;247 case eByteOrderLittle:248 response.PutCString("endian:little;");249 break;250 case eByteOrderPDP:251 response.PutCString("endian:pdp;");252 break;253 default:254 response.PutCString("endian:unknown;");255 break;256 }257 258 llvm::VersionTuple version = HostInfo::GetOSVersion();259 if (!version.empty()) {260 response.Format("os_version:{0}", version.getAsString());261 response.PutChar(';');262 }263 264#if defined(__APPLE__)265 llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();266 if (!maccatalyst_version.empty()) {267 response.Format("maccatalyst_version:{0}",268 maccatalyst_version.getAsString());269 response.PutChar(';');270 }271#endif272 273 if (std::optional<std::string> s = HostInfo::GetOSBuildString()) {274 response.PutCString("os_build:");275 response.PutStringAsRawHex8(*s);276 response.PutChar(';');277 }278 if (std::optional<std::string> s = HostInfo::GetOSKernelDescription()) {279 response.PutCString("os_kernel:");280 response.PutStringAsRawHex8(*s);281 response.PutChar(';');282 }283 284 std::string s;285#if defined(__APPLE__)286 287#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)288 // For iOS devices, we are connected through a USB Mux so we never pretend to289 // actually have a hostname as far as the remote lldb that is connecting to290 // this lldb-platform is concerned291 response.PutCString("hostname:");292 response.PutStringAsRawHex8("127.0.0.1");293 response.PutChar(';');294#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)295 if (HostInfo::GetHostname(s)) {296 response.PutCString("hostname:");297 response.PutStringAsRawHex8(s);298 response.PutChar(';');299 }300#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)301 302#else // #if defined(__APPLE__)303 if (HostInfo::GetHostname(s)) {304 response.PutCString("hostname:");305 response.PutStringAsRawHex8(s);306 response.PutChar(';');307 }308#endif // #if defined(__APPLE__)309 // coverity[unsigned_compare]310 if (g_default_packet_timeout_sec > 0)311 response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);312 313 return SendPacketNoLock(response.GetString());314}315 316GDBRemoteCommunication::PacketResult317GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID(318 StringExtractorGDBRemote &packet) {319 // Packet format: "qProcessInfoPID:%i" where %i is the pid320 packet.SetFilePos(::strlen("qProcessInfoPID:"));321 lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID);322 if (pid != LLDB_INVALID_PROCESS_ID) {323 ProcessInstanceInfo proc_info;324 if (Host::GetProcessInfo(pid, proc_info)) {325 StreamString response;326 CreateProcessInfoResponse(proc_info, response);327 return SendPacketNoLock(response.GetString());328 }329 }330 return SendErrorResponse(1);331}332 333GDBRemoteCommunication::PacketResult334GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(335 StringExtractorGDBRemote &packet) {336 m_proc_infos_index = 0;337 m_proc_infos.clear();338 339 ProcessInstanceInfoMatch match_info;340 packet.SetFilePos(::strlen("qfProcessInfo"));341 if (packet.GetChar() == ':') {342 llvm::StringRef key;343 llvm::StringRef value;344 while (packet.GetNameColonValue(key, value)) {345 bool success = true;346 if (key == "name") {347 StringExtractor extractor(value);348 std::string file;349 extractor.GetHexByteString(file);350 match_info.GetProcessInfo().GetExecutableFile().SetFile(351 file, FileSpec::Style::native);352 } else if (key == "name_match") {353 NameMatch name_match = llvm::StringSwitch<NameMatch>(value)354 .Case("equals", NameMatch::Equals)355 .Case("starts_with", NameMatch::StartsWith)356 .Case("ends_with", NameMatch::EndsWith)357 .Case("contains", NameMatch::Contains)358 .Case("regex", NameMatch::RegularExpression)359 .Default(NameMatch::Ignore);360 match_info.SetNameMatchType(name_match);361 if (name_match == NameMatch::Ignore)362 return SendErrorResponse(2);363 } else if (key == "pid") {364 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;365 if (value.getAsInteger(0, pid))366 return SendErrorResponse(2);367 match_info.GetProcessInfo().SetProcessID(pid);368 } else if (key == "parent_pid") {369 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;370 if (value.getAsInteger(0, pid))371 return SendErrorResponse(2);372 match_info.GetProcessInfo().SetParentProcessID(pid);373 } else if (key == "uid") {374 uint32_t uid = UINT32_MAX;375 if (value.getAsInteger(0, uid))376 return SendErrorResponse(2);377 match_info.GetProcessInfo().SetUserID(uid);378 } else if (key == "gid") {379 uint32_t gid = UINT32_MAX;380 if (value.getAsInteger(0, gid))381 return SendErrorResponse(2);382 match_info.GetProcessInfo().SetGroupID(gid);383 } else if (key == "euid") {384 uint32_t uid = UINT32_MAX;385 if (value.getAsInteger(0, uid))386 return SendErrorResponse(2);387 match_info.GetProcessInfo().SetEffectiveUserID(uid);388 } else if (key == "egid") {389 uint32_t gid = UINT32_MAX;390 if (value.getAsInteger(0, gid))391 return SendErrorResponse(2);392 match_info.GetProcessInfo().SetEffectiveGroupID(gid);393 } else if (key == "all_users") {394 match_info.SetMatchAllUsers(395 OptionArgParser::ToBoolean(value, false, &success));396 } else if (key == "triple") {397 match_info.GetProcessInfo().GetArchitecture() =398 HostInfo::GetAugmentedArchSpec(value);399 } else {400 success = false;401 }402 403 if (!success)404 return SendErrorResponse(2);405 }406 }407 408 if (Host::FindProcesses(match_info, m_proc_infos)) {409 // We found something, return the first item by calling the get subsequent410 // process info packet handler...411 return Handle_qsProcessInfo(packet);412 }413 return SendErrorResponse(3);414}415 416GDBRemoteCommunication::PacketResult417GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(418 StringExtractorGDBRemote &packet) {419 if (m_proc_infos_index < m_proc_infos.size()) {420 StreamString response;421 CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response);422 ++m_proc_infos_index;423 return SendPacketNoLock(response.GetString());424 }425 return SendErrorResponse(4);426}427 428GDBRemoteCommunication::PacketResult429GDBRemoteCommunicationServerCommon::Handle_qUserName(430 StringExtractorGDBRemote &packet) {431#if LLDB_ENABLE_POSIX432 Log *log = GetLog(LLDBLog::Process);433 LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);434 435 // Packet format: "qUserName:%i" where %i is the uid436 packet.SetFilePos(::strlen("qUserName:"));437 uint32_t uid = packet.GetU32(UINT32_MAX);438 if (uid != UINT32_MAX) {439 if (std::optional<llvm::StringRef> name =440 HostInfo::GetUserIDResolver().GetUserName(uid)) {441 StreamString response;442 response.PutStringAsRawHex8(*name);443 return SendPacketNoLock(response.GetString());444 }445 }446 LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);447#endif448 return SendErrorResponse(5);449}450 451GDBRemoteCommunication::PacketResult452GDBRemoteCommunicationServerCommon::Handle_qGroupName(453 StringExtractorGDBRemote &packet) {454#if LLDB_ENABLE_POSIX455 // Packet format: "qGroupName:%i" where %i is the gid456 packet.SetFilePos(::strlen("qGroupName:"));457 uint32_t gid = packet.GetU32(UINT32_MAX);458 if (gid != UINT32_MAX) {459 if (std::optional<llvm::StringRef> name =460 HostInfo::GetUserIDResolver().GetGroupName(gid)) {461 StreamString response;462 response.PutStringAsRawHex8(*name);463 return SendPacketNoLock(response.GetString());464 }465 }466#endif467 return SendErrorResponse(6);468}469 470GDBRemoteCommunication::PacketResult471GDBRemoteCommunicationServerCommon::Handle_qSpeedTest(472 StringExtractorGDBRemote &packet) {473 packet.SetFilePos(::strlen("qSpeedTest:"));474 475 llvm::StringRef key;476 llvm::StringRef value;477 bool success = packet.GetNameColonValue(key, value);478 if (success && key == "response_size") {479 uint32_t response_size = 0;480 if (!value.getAsInteger(0, response_size)) {481 if (response_size == 0)482 return SendOKResponse();483 StreamString response;484 uint32_t bytes_left = response_size;485 response.PutCString("data:");486 while (bytes_left > 0) {487 if (bytes_left >= 26) {488 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");489 bytes_left -= 26;490 } else {491 response.Printf("%*.*s;", bytes_left, bytes_left,492 "ABCDEFGHIJKLMNOPQRSTUVWXYZ");493 bytes_left = 0;494 }495 }496 return SendPacketNoLock(response.GetString());497 }498 }499 return SendErrorResponse(7);500}501 502static GDBErrno system_errno_to_gdb(int err) {503 switch (err) {504#define HANDLE_ERRNO(name, value) \505 case name: \506 return GDB_##name;507#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"508 default:509 return GDB_EUNKNOWN;510 }511}512 513GDBRemoteCommunication::PacketResult514GDBRemoteCommunicationServerCommon::Handle_vFile_Open(515 StringExtractorGDBRemote &packet) {516 packet.SetFilePos(::strlen("vFile:open:"));517 std::string path;518 packet.GetHexByteStringTerminatedBy(path, ',');519 if (!path.empty()) {520 if (packet.GetChar() == ',') {521 auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0));522 if (packet.GetChar() == ',') {523 mode_t mode = packet.GetHexMaxU32(false, 0600);524 FileSpec path_spec(path);525 FileSystem::Instance().Resolve(path_spec);526 // Do not close fd.527 auto file = FileSystem::Instance().Open(path_spec, flags, mode, false);528 529 StreamString response;530 response.PutChar('F');531 532 int descriptor = File::kInvalidDescriptor;533 if (file) {534 descriptor = file.get()->GetDescriptor();535 response.Printf("%x", descriptor);536 } else {537 response.PutCString("-1");538 std::error_code code = errorToErrorCode(file.takeError());539 response.Printf(",%x", system_errno_to_gdb(code.value()));540 }541 542 return SendPacketNoLock(response.GetString());543 }544 }545 }546 return SendErrorResponse(18);547}548 549GDBRemoteCommunication::PacketResult550GDBRemoteCommunicationServerCommon::Handle_vFile_Close(551 StringExtractorGDBRemote &packet) {552 packet.SetFilePos(::strlen("vFile:close:"));553 int fd = packet.GetS32(-1, 16);554 int err = -1;555 int save_errno = 0;556 if (fd >= 0) {557 NativeFile file(fd, File::OpenOptions(0), true);558 Status error = file.Close();559 err = 0;560 save_errno = error.GetError();561 } else {562 save_errno = EINVAL;563 }564 StreamString response;565 response.PutChar('F');566 response.Printf("%x", err);567 if (save_errno)568 response.Printf(",%x", system_errno_to_gdb(save_errno));569 return SendPacketNoLock(response.GetString());570}571 572GDBRemoteCommunication::PacketResult573GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(574 StringExtractorGDBRemote &packet) {575 StreamGDBRemote response;576 packet.SetFilePos(::strlen("vFile:pread:"));577 int fd = packet.GetS32(-1, 16);578 if (packet.GetChar() == ',') {579 size_t count = packet.GetHexMaxU64(false, SIZE_MAX);580 if (packet.GetChar() == ',') {581 off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);582 if (count == SIZE_MAX) {583 response.Printf("F-1:%x", EINVAL);584 return SendPacketNoLock(response.GetString());585 }586 587 std::string buffer(count, 0);588 NativeFile file(fd, File::eOpenOptionReadOnly, false);589 Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);590 const int save_errno = error.GetError();591 response.PutChar('F');592 if (error.Success()) {593 response.Printf("%zx", count);594 response.PutChar(';');595 response.PutEscapedBytes(&buffer[0], count);596 } else {597 response.PutCString("-1");598 if (save_errno)599 response.Printf(",%x", system_errno_to_gdb(save_errno));600 }601 return SendPacketNoLock(response.GetString());602 }603 }604 return SendErrorResponse(21);605}606 607GDBRemoteCommunication::PacketResult608GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(609 StringExtractorGDBRemote &packet) {610 packet.SetFilePos(::strlen("vFile:pwrite:"));611 612 StreamGDBRemote response;613 response.PutChar('F');614 615 int fd = packet.GetS32(-1, 16);616 if (packet.GetChar() == ',') {617 off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);618 if (packet.GetChar() == ',') {619 std::string buffer;620 if (packet.GetEscapedBinaryData(buffer)) {621 NativeFile file(fd, File::eOpenOptionWriteOnly, false);622 size_t count = buffer.size();623 Status error =624 file.Write(static_cast<const void *>(&buffer[0]), count, offset);625 const int save_errno = error.GetError();626 if (error.Success())627 response.Printf("%zx", count);628 else {629 response.PutCString("-1");630 if (save_errno)631 response.Printf(",%x", system_errno_to_gdb(save_errno));632 }633 } else {634 response.Printf("-1,%x", EINVAL);635 }636 return SendPacketNoLock(response.GetString());637 }638 }639 return SendErrorResponse(27);640}641 642GDBRemoteCommunication::PacketResult643GDBRemoteCommunicationServerCommon::Handle_vFile_Size(644 StringExtractorGDBRemote &packet) {645 packet.SetFilePos(::strlen("vFile:size:"));646 std::string path;647 packet.GetHexByteString(path);648 if (!path.empty()) {649 uint64_t Size;650 if (llvm::sys::fs::file_size(path, Size))651 return SendErrorResponse(5);652 StreamString response;653 response.PutChar('F');654 response.PutHex64(Size);655 if (Size == UINT64_MAX) {656 response.PutChar(',');657 response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode()658 }659 return SendPacketNoLock(response.GetString());660 }661 return SendErrorResponse(22);662}663 664GDBRemoteCommunication::PacketResult665GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(666 StringExtractorGDBRemote &packet) {667 packet.SetFilePos(::strlen("vFile:mode:"));668 std::string path;669 packet.GetHexByteString(path);670 if (!path.empty()) {671 FileSpec file_spec(path);672 FileSystem::Instance().Resolve(file_spec);673 std::error_code ec;674 const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);675 StreamString response;676 if (mode != llvm::sys::fs::perms_not_known)677 response.Printf("F%x", mode);678 else679 response.Printf("F-1,%x", (int)Status(ec).GetError());680 return SendPacketNoLock(response.GetString());681 }682 return SendErrorResponse(23);683}684 685GDBRemoteCommunication::PacketResult686GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(687 StringExtractorGDBRemote &packet) {688 packet.SetFilePos(::strlen("vFile:exists:"));689 std::string path;690 packet.GetHexByteString(path);691 if (!path.empty()) {692 bool retcode = llvm::sys::fs::exists(path);693 StreamString response;694 response.PutChar('F');695 response.PutChar(',');696 if (retcode)697 response.PutChar('1');698 else699 response.PutChar('0');700 return SendPacketNoLock(response.GetString());701 }702 return SendErrorResponse(24);703}704 705GDBRemoteCommunication::PacketResult706GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(707 StringExtractorGDBRemote &packet) {708 packet.SetFilePos(::strlen("vFile:symlink:"));709 std::string dst, src;710 packet.GetHexByteStringTerminatedBy(dst, ',');711 packet.GetChar(); // Skip ',' char712 packet.GetHexByteString(src);713 714 FileSpec src_spec(src);715 FileSystem::Instance().Resolve(src_spec);716 Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst));717 718 StreamString response;719 response.Printf("F%x,%x", error.GetError(), error.GetError());720 return SendPacketNoLock(response.GetString());721}722 723GDBRemoteCommunication::PacketResult724GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(725 StringExtractorGDBRemote &packet) {726 packet.SetFilePos(::strlen("vFile:unlink:"));727 std::string path;728 packet.GetHexByteString(path);729 Status error(llvm::sys::fs::remove(path));730 StreamString response;731 response.Printf("F%x,%x", error.GetError(),732 system_errno_to_gdb(error.GetError()));733 return SendPacketNoLock(response.GetString());734}735 736GDBRemoteCommunication::PacketResult737GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(738 StringExtractorGDBRemote &packet) {739 packet.SetFilePos(::strlen("qPlatform_shell:"));740 std::string path;741 std::string working_dir;742 packet.GetHexByteStringTerminatedBy(path, ',');743 if (!path.empty()) {744 if (packet.GetChar() == ',') {745 // FIXME: add timeout to qPlatform_shell packet746 // uint32_t timeout = packet.GetHexMaxU32(false, 32);747 if (packet.GetChar() == ',')748 packet.GetHexByteString(working_dir);749 int status, signo;750 std::string output;751 FileSpec working_spec(working_dir);752 FileSystem::Instance().Resolve(working_spec);753 Status err =754 Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,755 &output, std::chrono::seconds(10));756 StreamGDBRemote response;757 if (err.Fail()) {758 response.PutCString("F,");759 response.PutHex32(UINT32_MAX);760 } else {761 response.PutCString("F,");762 response.PutHex32(status);763 response.PutChar(',');764 response.PutHex32(signo);765 response.PutChar(',');766 response.PutEscapedBytes(output.c_str(), output.size());767 }768 return SendPacketNoLock(response.GetString());769 }770 }771 return SendErrorResponse(24);772}773 774template <typename T, typename U>775static void fill_clamp(T &dest, U src, typename T::value_type fallback) {776 static_assert(std::is_unsigned<typename T::value_type>::value,777 "Destination type must be unsigned.");778 using UU = std::make_unsigned_t<U>;779 constexpr auto T_max = std::numeric_limits<typename T::value_type>::max();780 dest = src >= 0 && static_cast<UU>(src) <= T_max ? src : fallback;781}782 783GDBRemoteCommunication::PacketResult784GDBRemoteCommunicationServerCommon::Handle_vFile_FStat(785 StringExtractorGDBRemote &packet) {786 StreamGDBRemote response;787 packet.SetFilePos(::strlen("vFile:fstat:"));788 int fd = packet.GetS32(-1, 16);789 790 struct stat file_stats;791 if (::fstat(fd, &file_stats) == -1) {792 const int save_errno = errno;793 response.Printf("F-1,%x", system_errno_to_gdb(save_errno));794 return SendPacketNoLock(response.GetString());795 }796 797 GDBRemoteFStatData data;798 fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0);799 fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0);800 data.gdb_st_mode = file_stats.st_mode;801 fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX);802 fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0);803 fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0);804 fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0);805 data.gdb_st_size = file_stats.st_size;806#if !defined(_WIN32)807 data.gdb_st_blksize = file_stats.st_blksize;808 data.gdb_st_blocks = file_stats.st_blocks;809#else810 data.gdb_st_blksize = 0;811 data.gdb_st_blocks = 0;812#endif813 fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0);814 fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0);815 fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0);816 817 response.Printf("F%zx;", sizeof(data));818 response.PutEscapedBytes(&data, sizeof(data));819 return SendPacketNoLock(response.GetString());820}821 822GDBRemoteCommunication::PacketResult823GDBRemoteCommunicationServerCommon::Handle_vFile_Stat(824 StringExtractorGDBRemote &packet) {825 return SendUnimplementedResponse(826 "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");827}828 829GDBRemoteCommunication::PacketResult830GDBRemoteCommunicationServerCommon::Handle_vFile_MD5(831 StringExtractorGDBRemote &packet) {832 packet.SetFilePos(::strlen("vFile:MD5:"));833 std::string path;834 packet.GetHexByteString(path);835 if (!path.empty()) {836 StreamGDBRemote response;837 auto Result = llvm::sys::fs::md5_contents(path);838 if (!Result) {839 response.PutCString("F,");840 response.PutCString("x");841 } else {842 response.PutCString("F,");843 response.PutHex64(Result->low());844 response.PutHex64(Result->high());845 }846 return SendPacketNoLock(response.GetString());847 }848 return SendErrorResponse(25);849}850 851GDBRemoteCommunication::PacketResult852GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(853 StringExtractorGDBRemote &packet) {854 packet.SetFilePos(::strlen("qPlatform_mkdir:"));855 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);856 if (packet.GetChar() == ',') {857 std::string path;858 packet.GetHexByteString(path);859 Status error(llvm::sys::fs::create_directory(path, mode));860 861 StreamGDBRemote response;862 response.Printf("F%x", error.GetError());863 864 return SendPacketNoLock(response.GetString());865 }866 return SendErrorResponse(20);867}868 869GDBRemoteCommunication::PacketResult870GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(871 StringExtractorGDBRemote &packet) {872 packet.SetFilePos(::strlen("qPlatform_chmod:"));873 874 auto perms =875 static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX));876 if (packet.GetChar() == ',') {877 std::string path;878 packet.GetHexByteString(path);879 Status error(llvm::sys::fs::setPermissions(path, perms));880 881 StreamGDBRemote response;882 response.Printf("F%x", error.GetError());883 884 return SendPacketNoLock(response.GetString());885 }886 return SendErrorResponse(19);887}888 889GDBRemoteCommunication::PacketResult890GDBRemoteCommunicationServerCommon::Handle_qSupported(891 StringExtractorGDBRemote &packet) {892 // Parse client-indicated features.893 llvm::SmallVector<llvm::StringRef, 4> client_features;894 packet.GetStringRef().split(client_features, ';');895 return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";"));896}897 898GDBRemoteCommunication::PacketResult899GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError(900 StringExtractorGDBRemote &packet) {901 packet.SetFilePos(::strlen("QSetDetachOnError:"));902 if (packet.GetU32(0))903 m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);904 else905 m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);906 return SendOKResponse();907}908 909GDBRemoteCommunication::PacketResult910GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode(911 StringExtractorGDBRemote &packet) {912 // Send response first before changing m_send_acks to we ack this packet913 PacketResult packet_result = SendOKResponse();914 m_send_acks = false;915 return packet_result;916}917 918GDBRemoteCommunication::PacketResult919GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(920 StringExtractorGDBRemote &packet) {921 packet.SetFilePos(::strlen("QSetSTDIN:"));922 FileAction file_action;923 std::string path;924 packet.GetHexByteString(path);925 const bool read = true;926 const bool write = false;927 if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {928 m_process_launch_info.AppendFileAction(file_action);929 return SendOKResponse();930 }931 return SendErrorResponse(15);932}933 934GDBRemoteCommunication::PacketResult935GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(936 StringExtractorGDBRemote &packet) {937 packet.SetFilePos(::strlen("QSetSTDOUT:"));938 FileAction file_action;939 std::string path;940 packet.GetHexByteString(path);941 const bool read = false;942 const bool write = true;943 if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {944 m_process_launch_info.AppendFileAction(file_action);945 return SendOKResponse();946 }947 return SendErrorResponse(16);948}949 950GDBRemoteCommunication::PacketResult951GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(952 StringExtractorGDBRemote &packet) {953 packet.SetFilePos(::strlen("QSetSTDERR:"));954 FileAction file_action;955 std::string path;956 packet.GetHexByteString(path);957 const bool read = false;958 const bool write = true;959 if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {960 m_process_launch_info.AppendFileAction(file_action);961 return SendOKResponse();962 }963 return SendErrorResponse(17);964}965 966GDBRemoteCommunication::PacketResult967GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess(968 StringExtractorGDBRemote &packet) {969 if (m_process_launch_error.Success())970 return SendOKResponse();971 StreamString response;972 response.PutChar('E');973 response.PutCString(m_process_launch_error.AsCString("<unknown error>"));974 return SendPacketNoLock(response.GetString());975}976 977GDBRemoteCommunication::PacketResult978GDBRemoteCommunicationServerCommon::Handle_QEnvironment(979 StringExtractorGDBRemote &packet) {980 packet.SetFilePos(::strlen("QEnvironment:"));981 const uint32_t bytes_left = packet.GetBytesLeft();982 if (bytes_left > 0) {983 m_process_launch_info.GetEnvironment().insert(packet.Peek());984 return SendOKResponse();985 }986 return SendErrorResponse(12);987}988 989GDBRemoteCommunication::PacketResult990GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(991 StringExtractorGDBRemote &packet) {992 packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));993 const uint32_t bytes_left = packet.GetBytesLeft();994 if (bytes_left > 0) {995 std::string str;996 packet.GetHexByteString(str);997 m_process_launch_info.GetEnvironment().insert(str);998 return SendOKResponse();999 }1000 return SendErrorResponse(12);1001}1002 1003GDBRemoteCommunication::PacketResult1004GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(1005 StringExtractorGDBRemote &packet) {1006 packet.SetFilePos(::strlen("QLaunchArch:"));1007 const uint32_t bytes_left = packet.GetBytesLeft();1008 if (bytes_left > 0) {1009 const char *arch_triple = packet.Peek();1010 m_process_launch_info.SetArchitecture(1011 HostInfo::GetAugmentedArchSpec(arch_triple));1012 return SendOKResponse();1013 }1014 return SendErrorResponse(13);1015}1016 1017GDBRemoteCommunication::PacketResult1018GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {1019 // The 'A' packet is the most over designed packet ever here with redundant1020 // argument indexes, redundant argument lengths and needed hex encoded1021 // argument string values. Really all that is needed is a comma separated hex1022 // encoded argument value list, but we will stay true to the documented1023 // version of the 'A' packet here...1024 1025 Log *log = GetLog(LLDBLog::Process);1026 int actual_arg_index = 0;1027 1028 packet.SetFilePos(1); // Skip the 'A'1029 bool success = true;1030 while (success && packet.GetBytesLeft() > 0) {1031 // Decode the decimal argument string length. This length is the number of1032 // hex nibbles in the argument string value.1033 const uint32_t arg_len = packet.GetU32(UINT32_MAX);1034 if (arg_len == UINT32_MAX)1035 success = false;1036 else {1037 // Make sure the argument hex string length is followed by a comma1038 if (packet.GetChar() != ',')1039 success = false;1040 else {1041 // Decode the argument index. We ignore this really because who would1042 // really send down the arguments in a random order???1043 const uint32_t arg_idx = packet.GetU32(UINT32_MAX);1044 if (arg_idx == UINT32_MAX)1045 success = false;1046 else {1047 // Make sure the argument index is followed by a comma1048 if (packet.GetChar() != ',')1049 success = false;1050 else {1051 // Decode the argument string value from hex bytes back into a UTF81052 // string and make sure the length matches the one supplied in the1053 // packet1054 std::string arg;1055 if (packet.GetHexByteStringFixedLength(arg, arg_len) !=1056 (arg_len / 2))1057 success = false;1058 else {1059 // If there are any bytes left1060 if (packet.GetBytesLeft()) {1061 if (packet.GetChar() != ',')1062 success = false;1063 }1064 1065 if (success) {1066 if (arg_idx == 0)1067 m_process_launch_info.GetExecutableFile().SetFile(1068 arg, FileSpec::Style::native);1069 m_process_launch_info.GetArguments().AppendArgument(arg);1070 LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"",1071 __FUNCTION__, actual_arg_index, arg.c_str());1072 ++actual_arg_index;1073 }1074 }1075 }1076 }1077 }1078 }1079 }1080 1081 if (success) {1082 m_process_launch_error = LaunchProcess();1083 if (m_process_launch_error.Success())1084 return SendOKResponse();1085 LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);1086 }1087 return SendErrorResponse(8);1088}1089 1090GDBRemoteCommunication::PacketResult1091GDBRemoteCommunicationServerCommon::Handle_qEcho(1092 StringExtractorGDBRemote &packet) {1093 // Just echo back the exact same packet for qEcho...1094 return SendPacketNoLock(packet.GetStringRef());1095}1096 1097GDBRemoteCommunication::PacketResult1098GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(1099 StringExtractorGDBRemote &packet) {1100 packet.SetFilePos(::strlen("qModuleInfo:"));1101 1102 std::string module_path;1103 packet.GetHexByteStringTerminatedBy(module_path, ';');1104 if (module_path.empty())1105 return SendErrorResponse(1);1106 1107 if (packet.GetChar() != ';')1108 return SendErrorResponse(2);1109 1110 std::string triple;1111 packet.GetHexByteString(triple);1112 1113 ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);1114 if (!matched_module_spec.GetFileSpec())1115 return SendErrorResponse(3);1116 1117 const auto file_offset = matched_module_spec.GetObjectOffset();1118 const auto file_size = matched_module_spec.GetObjectSize();1119 const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");1120 1121 StreamGDBRemote response;1122 1123 if (uuid_str.empty()) {1124 auto Result = llvm::sys::fs::md5_contents(1125 matched_module_spec.GetFileSpec().GetPath());1126 if (!Result)1127 return SendErrorResponse(5);1128 response.PutCString("md5:");1129 response.PutStringAsRawHex8(Result->digest());1130 } else {1131 response.PutCString("uuid:");1132 response.PutStringAsRawHex8(uuid_str);1133 }1134 response.PutChar(';');1135 1136 const auto &module_arch = matched_module_spec.GetArchitecture();1137 response.PutCString("triple:");1138 response.PutStringAsRawHex8(module_arch.GetTriple().getTriple());1139 response.PutChar(';');1140 1141 response.PutCString("file_path:");1142 response.PutStringAsRawHex8(1143 matched_module_spec.GetFileSpec().GetPath().c_str());1144 response.PutChar(';');1145 response.PutCString("file_offset:");1146 response.PutHex64(file_offset);1147 response.PutChar(';');1148 response.PutCString("file_size:");1149 response.PutHex64(file_size);1150 response.PutChar(';');1151 1152 return SendPacketNoLock(response.GetString());1153}1154 1155GDBRemoteCommunication::PacketResult1156GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(1157 StringExtractorGDBRemote &packet) {1158 namespace json = llvm::json;1159 1160 packet.SetFilePos(::strlen("jModulesInfo:"));1161 1162 StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());1163 if (!object_sp)1164 return SendErrorResponse(1);1165 1166 StructuredData::Array *packet_array = object_sp->GetAsArray();1167 if (!packet_array)1168 return SendErrorResponse(2);1169 1170 json::Array response_array;1171 for (size_t i = 0; i < packet_array->GetSize(); ++i) {1172 StructuredData::Dictionary *query =1173 packet_array->GetItemAtIndex(i)->GetAsDictionary();1174 if (!query)1175 continue;1176 llvm::StringRef file, triple;1177 if (!query->GetValueForKeyAsString("file", file) ||1178 !query->GetValueForKeyAsString("triple", triple))1179 continue;1180 1181 ModuleSpec matched_module_spec = GetModuleInfo(file, triple);1182 if (!matched_module_spec.GetFileSpec())1183 continue;1184 1185 const auto file_offset = matched_module_spec.GetObjectOffset();1186 const auto file_size = matched_module_spec.GetObjectSize();1187 const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");1188 if (uuid_str.empty())1189 continue;1190 const auto triple_str =1191 matched_module_spec.GetArchitecture().GetTriple().getTriple();1192 const auto file_path = matched_module_spec.GetFileSpec().GetPath();1193 1194 json::Object response{{"uuid", uuid_str},1195 {"triple", triple_str},1196 {"file_path", file_path},1197 {"file_offset", static_cast<int64_t>(file_offset)},1198 {"file_size", static_cast<int64_t>(file_size)}};1199 response_array.push_back(std::move(response));1200 }1201 1202 StreamString response;1203 response.AsRawOstream() << std::move(response_array);1204 StreamGDBRemote escaped_response;1205 escaped_response.PutEscapedBytes(response.GetString().data(),1206 response.GetSize());1207 return SendPacketNoLock(escaped_response.GetString());1208}1209 1210void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(1211 const ProcessInstanceInfo &proc_info, StreamString &response) {1212 response.Printf(1213 "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",1214 proc_info.GetProcessID(), proc_info.GetParentProcessID(),1215 proc_info.GetUserID(), proc_info.GetGroupID(),1216 proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());1217 response.PutCString("name:");1218 response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str());1219 1220 response.PutChar(';');1221 response.PutCString("args:");1222 response.PutStringAsRawHex8(proc_info.GetArg0());1223 for (auto &arg : proc_info.GetArguments()) {1224 response.PutChar('-');1225 response.PutStringAsRawHex8(arg.ref());1226 }1227 1228 response.PutChar(';');1229 const ArchSpec &proc_arch = proc_info.GetArchitecture();1230 if (proc_arch.IsValid()) {1231 const llvm::Triple &proc_triple = proc_arch.GetTriple();1232 response.PutCString("triple:");1233 response.PutStringAsRawHex8(proc_triple.getTriple());1234 response.PutChar(';');1235 }1236}1237 1238void GDBRemoteCommunicationServerCommon::1239 CreateProcessInfoResponse_DebugServerStyle(1240 const ProcessInstanceInfo &proc_info, StreamString &response) {1241 response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx641242 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",1243 proc_info.GetProcessID(), proc_info.GetParentProcessID(),1244 proc_info.GetUserID(), proc_info.GetGroupID(),1245 proc_info.GetEffectiveUserID(),1246 proc_info.GetEffectiveGroupID());1247 1248 const ArchSpec &proc_arch = proc_info.GetArchitecture();1249 if (proc_arch.IsValid()) {1250 const llvm::Triple &proc_triple = proc_arch.GetTriple();1251#if defined(__APPLE__)1252 // We'll send cputype/cpusubtype.1253 const uint32_t cpu_type = proc_arch.GetMachOCPUType();1254 if (cpu_type != 0)1255 response.Printf("cputype:%" PRIx32 ";", cpu_type);1256 1257 const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();1258 if (cpu_subtype != 0)1259 response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);1260 1261 const std::string vendor = proc_triple.getVendorName().str();1262 if (!vendor.empty())1263 response.Printf("vendor:%s;", vendor.c_str());1264#else1265 // We'll send the triple.1266 response.PutCString("triple:");1267 response.PutStringAsRawHex8(proc_triple.getTriple());1268 response.PutChar(';');1269#endif1270 std::string ostype = std::string(proc_triple.getOSName());1271 // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.1272 if (proc_triple.getVendor() == llvm::Triple::Apple) {1273 switch (proc_triple.getArch()) {1274 case llvm::Triple::arm:1275 case llvm::Triple::thumb:1276 case llvm::Triple::aarch64:1277 case llvm::Triple::aarch64_32:1278 ostype = "ios";1279 break;1280 default:1281 // No change.1282 break;1283 }1284 }1285 response.Printf("ostype:%s;", ostype.c_str());1286 1287 switch (proc_arch.GetByteOrder()) {1288 case lldb::eByteOrderLittle:1289 response.PutCString("endian:little;");1290 break;1291 case lldb::eByteOrderBig:1292 response.PutCString("endian:big;");1293 break;1294 case lldb::eByteOrderPDP:1295 response.PutCString("endian:pdp;");1296 break;1297 default:1298 // Nothing.1299 break;1300 }1301 // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer1302 // size is 4 and for N64 it is 81303 std::string abi = proc_arch.GetTargetABI();1304 if (!abi.empty())1305 response.Printf("elf_abi:%s;", abi.c_str());1306 response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());1307 }1308}1309 1310FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(1311 const std::string &module_path, const ArchSpec &arch) {1312#ifdef __ANDROID__1313 return HostInfoAndroid::ResolveLibraryPath(module_path, arch);1314#else1315 FileSpec file_spec(module_path);1316 FileSystem::Instance().Resolve(file_spec);1317 return file_spec;1318#endif1319}1320 1321ModuleSpec1322GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path,1323 llvm::StringRef triple) {1324 ArchSpec arch(triple);1325 1326 FileSpec req_module_path_spec(module_path);1327 FileSystem::Instance().Resolve(req_module_path_spec);1328 1329 const FileSpec module_path_spec =1330 FindModuleFile(req_module_path_spec.GetPath(), arch);1331 1332 lldb::offset_t file_offset = 0;1333 lldb::offset_t file_size = 0;1334#ifdef __ANDROID__1335 // In Android API level 23 and above, dynamic loader is able to load .so file1336 // directly from zip file. In that case, module_path will be1337 // "zip_path!/so_path". Resolve the zip file path, .so file offset and size.1338 ZipFileResolver::FileKind file_kind = ZipFileResolver::eFileKindInvalid;1339 std::string file_path;1340 if (!ZipFileResolver::ResolveSharedLibraryPath(1341 module_path_spec, file_kind, file_path, file_offset, file_size)) {1342 return ModuleSpec();1343 }1344 lldbassert(file_kind != ZipFileResolver::eFileKindInvalid);1345 // For zip .so file, this file_path will contain only the actual zip file1346 // path for the object file processing. Otherwise it is the same as1347 // module_path.1348 const FileSpec actual_module_path_spec(file_path);1349#else1350 // It is just module_path_spec reference for other platforms.1351 const FileSpec &actual_module_path_spec = module_path_spec;1352#endif1353 1354 const ModuleSpec module_spec(actual_module_path_spec, arch);1355 1356 ModuleSpecList module_specs;1357 if (!ObjectFile::GetModuleSpecifications(actual_module_path_spec, file_offset,1358 file_size, module_specs))1359 return ModuleSpec();1360 1361 ModuleSpec matched_module_spec;1362 if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))1363 return ModuleSpec();1364 1365#ifdef __ANDROID__1366 if (file_kind == ZipFileResolver::eFileKindZip) {1367 // For zip .so file, matched_module_spec contains only the actual zip file1368 // path for the object file processing. Overwrite the matched_module_spec1369 // file spec with the original module_path_spec to pass "zip_path!/so_path"1370 // through to PlatformAndroid::DownloadModuleSlice.1371 *matched_module_spec.GetFileSpecPtr() = module_path_spec;1372 }1373#endif1374 1375 return matched_module_spec;1376}1377 1378std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures(1379 const llvm::ArrayRef<llvm::StringRef> client_features) {1380 // 128 KiB is a reasonable max packet size--debugger can always use less.1381 constexpr uint32_t max_packet_size = 128 * 1024;1382 1383 // Features common to platform server and llgs.1384 return {1385 llvm::formatv("PacketSize={0}", max_packet_size),1386 "QStartNoAckMode+",1387 "qEcho+",1388 "native-signals+",1389 };1390}1391