brintos

brintos / llvm-project-archived public Read only

0
0
Text · 48.7 KiB · 4a11172 Raw
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