180814287SRaphael Isemann //===-- GDBRemoteCommunicationServerCommon.cpp ----------------------------===//
2e13c2731STamas Berghammer //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e13c2731STamas Berghammer //
7e13c2731STamas Berghammer //===----------------------------------------------------------------------===//
8e13c2731STamas Berghammer 
9e13c2731STamas Berghammer #include "GDBRemoteCommunicationServerCommon.h"
10e13c2731STamas Berghammer 
1176e47d48SRaphael Isemann #include <cerrno>
12e13c2731STamas Berghammer 
13e77fce0aSTodd Fiala #ifdef __APPLE__
14e77fce0aSTodd Fiala #include <TargetConditionals.h>
15e77fce0aSTodd Fiala #endif
16e77fce0aSTodd Fiala 
17e13c2731STamas Berghammer #include <chrono>
18b9c1b51eSKate Stone #include <cstring>
19e13c2731STamas Berghammer 
206801be33SOleksiy Vyalov #include "lldb/Core/ModuleSpec.h"
21e13c2731STamas Berghammer #include "lldb/Host/Config.h"
22e13c2731STamas Berghammer #include "lldb/Host/File.h"
23eef758e9SPavel Labath #include "lldb/Host/FileAction.h"
24e13c2731STamas Berghammer #include "lldb/Host/FileSystem.h"
25e13c2731STamas Berghammer #include "lldb/Host/Host.h"
26e13c2731STamas Berghammer #include "lldb/Host/HostInfo.h"
2777044731SPavel Labath #include "lldb/Host/SafeMachO.h"
2847cbf4a0SPavel Labath #include "lldb/Interpreter/OptionArgParser.h"
296801be33SOleksiy Vyalov #include "lldb/Symbol/ObjectFile.h"
30e13c2731STamas Berghammer #include "lldb/Target/Platform.h"
3101c3243fSZachary Turner #include "lldb/Utility/Endian.h"
32ff5225bfSJonas Devlieghere #include "lldb/Utility/GDBRemote.h"
33c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
346f9e6901SZachary Turner #include "lldb/Utility/Log.h"
35bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
36bd689b9cSSaleem Abdulrasool #include "lldb/Utility/StructuredData.h"
374f8151e6SJonas Devlieghere #include "llvm/ADT/StringSwitch.h"
38b9c1b51eSKate Stone #include "llvm/ADT/Triple.h"
394f8151e6SJonas Devlieghere #include "llvm/Support/JSON.h"
40e13c2731STamas Berghammer 
41e13c2731STamas Berghammer #include "ProcessGDBRemoteLog.h"
429af71b38SPavel Labath #include "lldb/Utility/StringExtractorGDBRemote.h"
43e13c2731STamas Berghammer 
44dad4db71STamas Berghammer #ifdef __ANDROID__
45dad4db71STamas Berghammer #include "lldb/Host/android/HostInfoAndroid.h"
46dad4db71STamas Berghammer #endif
47dad4db71STamas Berghammer 
4854695a33SZachary Turner 
49e13c2731STamas Berghammer using namespace lldb;
50db264a6dSTamas Berghammer using namespace lldb_private::process_gdb_remote;
514f8151e6SJonas Devlieghere using namespace lldb_private;
52e13c2731STamas Berghammer 
532d52afd7STamas Berghammer #ifdef __ANDROID__
542d52afd7STamas Berghammer const static uint32_t g_default_packet_timeout_sec = 20; // seconds
552d52afd7STamas Berghammer #else
562d52afd7STamas Berghammer const static uint32_t g_default_packet_timeout_sec = 0; // not specified
572d52afd7STamas Berghammer #endif
582d52afd7STamas Berghammer 
59e13c2731STamas Berghammer // GDBRemoteCommunicationServerCommon constructor
GDBRemoteCommunicationServerCommon(const char * comm_name,const char * listener_name)60b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
61b9c1b51eSKate Stone     const char *comm_name, const char *listener_name)
62b9c1b51eSKate Stone     : GDBRemoteCommunicationServer(comm_name, listener_name),
63b9c1b51eSKate Stone       m_process_launch_info(), m_process_launch_error(), m_proc_infos(),
642494243eSPavel Labath       m_proc_infos_index(0) {
65e13c2731STamas Berghammer   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
66e13c2731STamas Berghammer                                 &GDBRemoteCommunicationServerCommon::Handle_A);
67b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
68b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QEnvironment,
69e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
70b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
71b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
720ddb7226SChaoren Lin       &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
73b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
74b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
75e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
76b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
77b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qGroupName,
78e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
79b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
80b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qHostInfo,
81e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
82b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
83b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
84e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
85b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
86b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
87e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
88b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
89b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qEcho,
90420562aaSGreg Clayton       &GDBRemoteCommunicationServerCommon::Handle_qEcho);
91b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
92b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
936801be33SOleksiy Vyalov       &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
94b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
952f1fbaebSPavel Labath       StringExtractorGDBRemote::eServerPacketType_jModulesInfo,
962f1fbaebSPavel Labath       &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo);
972f1fbaebSPavel Labath   RegisterMemberFunctionHandler(
98b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
99e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
100b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
101b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
102e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
103b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
104b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
105e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
106b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
107b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
108e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
109b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
110b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
111e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
112b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
113b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
114e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
115b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
116b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
117e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
118b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
119b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
120e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
121b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
122b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
123e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
124b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
125b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
126e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
127b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
128b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
129e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
130b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
131b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qSupported,
132e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qSupported);
133b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
134b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_qUserName,
135e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_qUserName);
136b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
137b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_close,
138e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
139b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
140b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_exists,
141e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
142b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
143b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_md5,
144e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
145b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
146b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_mode,
147e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
148b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
149b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_open,
150e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
151b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
152b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_pread,
153e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
154b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
155b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
156e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
157b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
158b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_size,
159e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
160b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
161a1097d31SMichał Górny       StringExtractorGDBRemote::eServerPacketType_vFile_fstat,
162a1097d31SMichał Górny       &GDBRemoteCommunicationServerCommon::Handle_vFile_FStat);
163a1097d31SMichał Górny   RegisterMemberFunctionHandler(
164b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_stat,
165e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
166b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
167b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
168e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
169b9c1b51eSKate Stone   RegisterMemberFunctionHandler(
170b9c1b51eSKate Stone       StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
171e13c2731STamas Berghammer       &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
172e13c2731STamas Berghammer }
173e13c2731STamas Berghammer 
174e13c2731STamas Berghammer // Destructor
175fd2433e1SJonas Devlieghere GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() =
176fd2433e1SJonas Devlieghere     default;
177e13c2731STamas Berghammer 
178e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qHostInfo(StringExtractorGDBRemote & packet)179b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
180b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
181e13c2731STamas Berghammer   StreamString response;
182e13c2731STamas Berghammer 
183e13c2731STamas Berghammer   // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
184e13c2731STamas Berghammer 
185e13c2731STamas Berghammer   ArchSpec host_arch(HostInfo::GetArchitecture());
186e13c2731STamas Berghammer   const llvm::Triple &host_triple = host_arch.GetTriple();
187e13c2731STamas Berghammer   response.PutCString("triple:");
1887f815a9aSPavel Labath   response.PutStringAsRawHex8(host_triple.getTriple());
189e13c2731STamas Berghammer   response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
190e13c2731STamas Berghammer 
191e13c2731STamas Berghammer   const char *distribution_id = host_arch.GetDistributionId().AsCString();
192b9c1b51eSKate Stone   if (distribution_id) {
193e13c2731STamas Berghammer     response.PutCString("distribution_id:");
1947f815a9aSPavel Labath     response.PutStringAsRawHex8(distribution_id);
195e13c2731STamas Berghammer     response.PutCString(";");
196e13c2731STamas Berghammer   }
197e13c2731STamas Berghammer 
198e13c2731STamas Berghammer #if defined(__APPLE__)
199e77fce0aSTodd Fiala   // For parity with debugserver, we'll include the vendor key.
200e77fce0aSTodd Fiala   response.PutCString("vendor:apple;");
201e77fce0aSTodd Fiala 
202e77fce0aSTodd Fiala   // Send out MachO info.
203e13c2731STamas Berghammer   uint32_t cpu = host_arch.GetMachOCPUType();
204e13c2731STamas Berghammer   uint32_t sub = host_arch.GetMachOCPUSubType();
205e13c2731STamas Berghammer   if (cpu != LLDB_INVALID_CPUTYPE)
206e13c2731STamas Berghammer     response.Printf("cputype:%u;", cpu);
207e13c2731STamas Berghammer   if (sub != LLDB_INVALID_CPUTYPE)
208e13c2731STamas Berghammer     response.Printf("cpusubtype:%u;", sub);
209e13c2731STamas Berghammer 
2103a142495SAaron Smith   if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) {
211e77fce0aSTodd Fiala // Indicate the OS type.
212e77fce0aSTodd Fiala #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
213e77fce0aSTodd Fiala     response.PutCString("ostype:tvos;");
214e77fce0aSTodd Fiala #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
215e77fce0aSTodd Fiala     response.PutCString("ostype:watchos;");
2168c0d106fSJason Molenda #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
2178c0d106fSJason Molenda     response.PutCString("ostype:bridgeos;");
218e77fce0aSTodd Fiala #else
219e77fce0aSTodd Fiala     response.PutCString("ostype:ios;");
220e77fce0aSTodd Fiala #endif
221e77fce0aSTodd Fiala 
222e77fce0aSTodd Fiala     // On arm, we use "synchronous" watchpoints which means the exception is
223e77fce0aSTodd Fiala     // delivered before the instruction executes.
224e77fce0aSTodd Fiala     response.PutCString("watchpoint_exceptions_received:before;");
225b9c1b51eSKate Stone   } else {
226e77fce0aSTodd Fiala     response.PutCString("ostype:macosx;");
227e13c2731STamas Berghammer     response.Printf("watchpoint_exceptions_received:after;");
228e77fce0aSTodd Fiala   }
229e77fce0aSTodd Fiala 
230e13c2731STamas Berghammer #else
231e68ee7f9SOmair Javaid   if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
2327dd7a360SJason Molenda       host_arch.GetMachine() == llvm::Triple::aarch64_32 ||
233e68ee7f9SOmair Javaid       host_arch.GetMachine() == llvm::Triple::aarch64_be ||
2342441aecdSOmair Javaid       host_arch.GetMachine() == llvm::Triple::arm ||
235ddb93b63SFangrui Song       host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS())
23635799963SMohit K. Bhakkad     response.Printf("watchpoint_exceptions_received:before;");
23735799963SMohit K. Bhakkad   else
238e13c2731STamas Berghammer     response.Printf("watchpoint_exceptions_received:after;");
239e13c2731STamas Berghammer #endif
240e13c2731STamas Berghammer 
241b9c1b51eSKate Stone   switch (endian::InlHostByteOrder()) {
242b9c1b51eSKate Stone   case eByteOrderBig:
243b9c1b51eSKate Stone     response.PutCString("endian:big;");
244b9c1b51eSKate Stone     break;
245b9c1b51eSKate Stone   case eByteOrderLittle:
246b9c1b51eSKate Stone     response.PutCString("endian:little;");
247b9c1b51eSKate Stone     break;
248b9c1b51eSKate Stone   case eByteOrderPDP:
249b9c1b51eSKate Stone     response.PutCString("endian:pdp;");
250b9c1b51eSKate Stone     break;
251b9c1b51eSKate Stone   default:
252b9c1b51eSKate Stone     response.PutCString("endian:unknown;");
253b9c1b51eSKate Stone     break;
254e13c2731STamas Berghammer   }
255e13c2731STamas Berghammer 
2562272c481SPavel Labath   llvm::VersionTuple version = HostInfo::GetOSVersion();
2572272c481SPavel Labath   if (!version.empty()) {
2582272c481SPavel Labath     response.Format("os_version:{0}", version.getAsString());
259e13c2731STamas Berghammer     response.PutChar(';');
260e13c2731STamas Berghammer   }
261e13c2731STamas Berghammer 
26224610611SAdrian Prantl #if defined(__APPLE__)
26324610611SAdrian Prantl   llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();
26424610611SAdrian Prantl   if (!maccatalyst_version.empty()) {
26524610611SAdrian Prantl     response.Format("maccatalyst_version:{0}",
26624610611SAdrian Prantl                     maccatalyst_version.getAsString());
26724610611SAdrian Prantl     response.PutChar(';');
26824610611SAdrian Prantl   }
26924610611SAdrian Prantl #endif
27024610611SAdrian Prantl 
2718b8070e2SPavel Labath   if (llvm::Optional<std::string> s = HostInfo::GetOSBuildString()) {
272e13c2731STamas Berghammer     response.PutCString("os_build:");
2738b8070e2SPavel Labath     response.PutStringAsRawHex8(*s);
274e13c2731STamas Berghammer     response.PutChar(';');
275e13c2731STamas Berghammer   }
2760a39a9c2SPavel Labath   if (llvm::Optional<std::string> s = HostInfo::GetOSKernelDescription()) {
277e13c2731STamas Berghammer     response.PutCString("os_kernel:");
2780a39a9c2SPavel Labath     response.PutStringAsRawHex8(*s);
279e13c2731STamas Berghammer     response.PutChar(';');
280e13c2731STamas Berghammer   }
281e13c2731STamas Berghammer 
2820a39a9c2SPavel Labath   std::string s;
283e13c2731STamas Berghammer #if defined(__APPLE__)
284e13c2731STamas Berghammer 
285e13c2731STamas Berghammer #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
28605097246SAdrian Prantl   // For iOS devices, we are connected through a USB Mux so we never pretend to
28705097246SAdrian Prantl   // actually have a hostname as far as the remote lldb that is connecting to
28805097246SAdrian Prantl   // this lldb-platform is concerned
289e13c2731STamas Berghammer   response.PutCString("hostname:");
2907f815a9aSPavel Labath   response.PutStringAsRawHex8("127.0.0.1");
291e13c2731STamas Berghammer   response.PutChar(';');
292e13c2731STamas Berghammer #else  // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
293b9c1b51eSKate Stone   if (HostInfo::GetHostname(s)) {
294e13c2731STamas Berghammer     response.PutCString("hostname:");
2957f815a9aSPavel Labath     response.PutStringAsRawHex8(s);
296e13c2731STamas Berghammer     response.PutChar(';');
297e13c2731STamas Berghammer   }
298e13c2731STamas Berghammer #endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
299e13c2731STamas Berghammer 
300e13c2731STamas Berghammer #else  // #if defined(__APPLE__)
301b9c1b51eSKate Stone   if (HostInfo::GetHostname(s)) {
302e13c2731STamas Berghammer     response.PutCString("hostname:");
3037f815a9aSPavel Labath     response.PutStringAsRawHex8(s);
304e13c2731STamas Berghammer     response.PutChar(';');
305e13c2731STamas Berghammer   }
306e13c2731STamas Berghammer #endif // #if defined(__APPLE__)
307e13c2731STamas Berghammer 
3082d52afd7STamas Berghammer   if (g_default_packet_timeout_sec > 0)
3092d52afd7STamas Berghammer     response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);
3102d52afd7STamas Berghammer 
31126709df8SZachary Turner   return SendPacketNoLock(response.GetString());
312e13c2731STamas Berghammer }
313e13c2731STamas Berghammer 
314e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qProcessInfoPID(StringExtractorGDBRemote & packet)315b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID(
316b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
317e13c2731STamas Berghammer   // Packet format: "qProcessInfoPID:%i" where %i is the pid
318e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qProcessInfoPID:"));
319e13c2731STamas Berghammer   lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID);
320b9c1b51eSKate Stone   if (pid != LLDB_INVALID_PROCESS_ID) {
321e13c2731STamas Berghammer     ProcessInstanceInfo proc_info;
322b9c1b51eSKate Stone     if (Host::GetProcessInfo(pid, proc_info)) {
323e13c2731STamas Berghammer       StreamString response;
324e13c2731STamas Berghammer       CreateProcessInfoResponse(proc_info, response);
32526709df8SZachary Turner       return SendPacketNoLock(response.GetString());
326e13c2731STamas Berghammer     }
327e13c2731STamas Berghammer   }
328e13c2731STamas Berghammer   return SendErrorResponse(1);
329e13c2731STamas Berghammer }
330e13c2731STamas Berghammer 
331e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qfProcessInfo(StringExtractorGDBRemote & packet)332b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
333b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
334e13c2731STamas Berghammer   m_proc_infos_index = 0;
335638b06cfSJonas Devlieghere   m_proc_infos.clear();
336e13c2731STamas Berghammer 
337e13c2731STamas Berghammer   ProcessInstanceInfoMatch match_info;
338e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qfProcessInfo"));
339b9c1b51eSKate Stone   if (packet.GetChar() == ':') {
34054695a33SZachary Turner     llvm::StringRef key;
34154695a33SZachary Turner     llvm::StringRef value;
342b9c1b51eSKate Stone     while (packet.GetNameColonValue(key, value)) {
343e13c2731STamas Berghammer       bool success = true;
344b9c1b51eSKate Stone       if (key.equals("name")) {
34554695a33SZachary Turner         StringExtractor extractor(value);
34654695a33SZachary Turner         std::string file;
34754695a33SZachary Turner         extractor.GetHexByteString(file);
348937348cdSJonas Devlieghere         match_info.GetProcessInfo().GetExecutableFile().SetFile(
3498f3be7a3SJonas Devlieghere             file, FileSpec::Style::native);
350b9c1b51eSKate Stone       } else if (key.equals("name_match")) {
351c4a33951SPavel Labath         NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
352c4a33951SPavel Labath                                    .Case("equals", NameMatch::Equals)
353c4a33951SPavel Labath                                    .Case("starts_with", NameMatch::StartsWith)
354c4a33951SPavel Labath                                    .Case("ends_with", NameMatch::EndsWith)
355c4a33951SPavel Labath                                    .Case("contains", NameMatch::Contains)
356c4a33951SPavel Labath                                    .Case("regex", NameMatch::RegularExpression)
357c4a33951SPavel Labath                                    .Default(NameMatch::Ignore);
35854695a33SZachary Turner         match_info.SetNameMatchType(name_match);
359c4a33951SPavel Labath         if (name_match == NameMatch::Ignore)
36054695a33SZachary Turner           return SendErrorResponse(2);
361b9c1b51eSKate Stone       } else if (key.equals("pid")) {
36254695a33SZachary Turner         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
36354695a33SZachary Turner         if (value.getAsInteger(0, pid))
36454695a33SZachary Turner           return SendErrorResponse(2);
36554695a33SZachary Turner         match_info.GetProcessInfo().SetProcessID(pid);
366b9c1b51eSKate Stone       } else if (key.equals("parent_pid")) {
36754695a33SZachary Turner         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
36854695a33SZachary Turner         if (value.getAsInteger(0, pid))
36954695a33SZachary Turner           return SendErrorResponse(2);
37054695a33SZachary Turner         match_info.GetProcessInfo().SetParentProcessID(pid);
371b9c1b51eSKate Stone       } else if (key.equals("uid")) {
37254695a33SZachary Turner         uint32_t uid = UINT32_MAX;
37354695a33SZachary Turner         if (value.getAsInteger(0, uid))
37454695a33SZachary Turner           return SendErrorResponse(2);
37554695a33SZachary Turner         match_info.GetProcessInfo().SetUserID(uid);
376b9c1b51eSKate Stone       } else if (key.equals("gid")) {
37754695a33SZachary Turner         uint32_t gid = UINT32_MAX;
37854695a33SZachary Turner         if (value.getAsInteger(0, gid))
37954695a33SZachary Turner           return SendErrorResponse(2);
38054695a33SZachary Turner         match_info.GetProcessInfo().SetGroupID(gid);
381b9c1b51eSKate Stone       } else if (key.equals("euid")) {
38254695a33SZachary Turner         uint32_t uid = UINT32_MAX;
38354695a33SZachary Turner         if (value.getAsInteger(0, uid))
38454695a33SZachary Turner           return SendErrorResponse(2);
38554695a33SZachary Turner         match_info.GetProcessInfo().SetEffectiveUserID(uid);
386b9c1b51eSKate Stone       } else if (key.equals("egid")) {
38754695a33SZachary Turner         uint32_t gid = UINT32_MAX;
38854695a33SZachary Turner         if (value.getAsInteger(0, gid))
38954695a33SZachary Turner           return SendErrorResponse(2);
39054695a33SZachary Turner         match_info.GetProcessInfo().SetEffectiveGroupID(gid);
391b9c1b51eSKate Stone       } else if (key.equals("all_users")) {
392b9c1b51eSKate Stone         match_info.SetMatchAllUsers(
39347cbf4a0SPavel Labath             OptionArgParser::ToBoolean(value, false, &success));
394b9c1b51eSKate Stone       } else if (key.equals("triple")) {
3957263f1bdSPavel Labath         match_info.GetProcessInfo().GetArchitecture() =
3967263f1bdSPavel Labath             HostInfo::GetAugmentedArchSpec(value);
397b9c1b51eSKate Stone       } else {
398e13c2731STamas Berghammer         success = false;
399e13c2731STamas Berghammer       }
400e13c2731STamas Berghammer 
401e13c2731STamas Berghammer       if (!success)
402e13c2731STamas Berghammer         return SendErrorResponse(2);
403e13c2731STamas Berghammer     }
404e13c2731STamas Berghammer   }
405e13c2731STamas Berghammer 
406b9c1b51eSKate Stone   if (Host::FindProcesses(match_info, m_proc_infos)) {
40705097246SAdrian Prantl     // We found something, return the first item by calling the get subsequent
40805097246SAdrian Prantl     // process info packet handler...
409e13c2731STamas Berghammer     return Handle_qsProcessInfo(packet);
410e13c2731STamas Berghammer   }
411e13c2731STamas Berghammer   return SendErrorResponse(3);
412e13c2731STamas Berghammer }
413e13c2731STamas Berghammer 
414e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qsProcessInfo(StringExtractorGDBRemote & packet)415b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
416b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
417638b06cfSJonas Devlieghere   if (m_proc_infos_index < m_proc_infos.size()) {
418e13c2731STamas Berghammer     StreamString response;
419638b06cfSJonas Devlieghere     CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response);
420e13c2731STamas Berghammer     ++m_proc_infos_index;
42126709df8SZachary Turner     return SendPacketNoLock(response.GetString());
422e13c2731STamas Berghammer   }
423e13c2731STamas Berghammer   return SendErrorResponse(4);
424e13c2731STamas Berghammer }
425e13c2731STamas Berghammer 
426e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qUserName(StringExtractorGDBRemote & packet)427b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qUserName(
428b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
4293011d55fSJonas Devlieghere #if LLDB_ENABLE_POSIX
430a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Process);
43163e5fb76SJonas Devlieghere   LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
4328b335671SVince Harron 
433e13c2731STamas Berghammer   // Packet format: "qUserName:%i" where %i is the uid
434e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qUserName:"));
435e13c2731STamas Berghammer   uint32_t uid = packet.GetU32(UINT32_MAX);
436b9c1b51eSKate Stone   if (uid != UINT32_MAX) {
437aa51e6a6SPavel Labath     if (llvm::Optional<llvm::StringRef> name =
438aa51e6a6SPavel Labath             HostInfo::GetUserIDResolver().GetUserName(uid)) {
439e13c2731STamas Berghammer       StreamString response;
440aa51e6a6SPavel Labath       response.PutStringAsRawHex8(*name);
44170a5ef15SZachary Turner       return SendPacketNoLock(response.GetString());
442e13c2731STamas Berghammer     }
443e13c2731STamas Berghammer   }
44463e5fb76SJonas Devlieghere   LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
445e13c2731STamas Berghammer #endif
446e13c2731STamas Berghammer   return SendErrorResponse(5);
447e13c2731STamas Berghammer }
448e13c2731STamas Berghammer 
449e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qGroupName(StringExtractorGDBRemote & packet)450b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qGroupName(
451b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
4523011d55fSJonas Devlieghere #if LLDB_ENABLE_POSIX
453e13c2731STamas Berghammer   // Packet format: "qGroupName:%i" where %i is the gid
454e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qGroupName:"));
455e13c2731STamas Berghammer   uint32_t gid = packet.GetU32(UINT32_MAX);
456b9c1b51eSKate Stone   if (gid != UINT32_MAX) {
457aa51e6a6SPavel Labath     if (llvm::Optional<llvm::StringRef> name =
458aa51e6a6SPavel Labath             HostInfo::GetUserIDResolver().GetGroupName(gid)) {
459e13c2731STamas Berghammer       StreamString response;
460aa51e6a6SPavel Labath       response.PutStringAsRawHex8(*name);
46170a5ef15SZachary Turner       return SendPacketNoLock(response.GetString());
462e13c2731STamas Berghammer     }
463e13c2731STamas Berghammer   }
464e13c2731STamas Berghammer #endif
465e13c2731STamas Berghammer   return SendErrorResponse(6);
466e13c2731STamas Berghammer }
467e13c2731STamas Berghammer 
468e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qSpeedTest(StringExtractorGDBRemote & packet)469b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qSpeedTest(
470b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
471e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qSpeedTest:"));
472e13c2731STamas Berghammer 
47354695a33SZachary Turner   llvm::StringRef key;
47454695a33SZachary Turner   llvm::StringRef value;
475e13c2731STamas Berghammer   bool success = packet.GetNameColonValue(key, value);
476b9c1b51eSKate Stone   if (success && key.equals("response_size")) {
47754695a33SZachary Turner     uint32_t response_size = 0;
478b9c1b51eSKate Stone     if (!value.getAsInteger(0, response_size)) {
479e13c2731STamas Berghammer       if (response_size == 0)
480e13c2731STamas Berghammer         return SendOKResponse();
481e13c2731STamas Berghammer       StreamString response;
482e13c2731STamas Berghammer       uint32_t bytes_left = response_size;
483e13c2731STamas Berghammer       response.PutCString("data:");
484b9c1b51eSKate Stone       while (bytes_left > 0) {
485b9c1b51eSKate Stone         if (bytes_left >= 26) {
486e13c2731STamas Berghammer           response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
487e13c2731STamas Berghammer           bytes_left -= 26;
488b9c1b51eSKate Stone         } else {
489b9c1b51eSKate Stone           response.Printf("%*.*s;", bytes_left, bytes_left,
490b9c1b51eSKate Stone                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
491e13c2731STamas Berghammer           bytes_left = 0;
492e13c2731STamas Berghammer         }
493e13c2731STamas Berghammer       }
49426709df8SZachary Turner       return SendPacketNoLock(response.GetString());
495e13c2731STamas Berghammer     }
496e13c2731STamas Berghammer   }
497e13c2731STamas Berghammer   return SendErrorResponse(7);
498e13c2731STamas Berghammer }
499e13c2731STamas Berghammer 
500e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_Open(StringExtractorGDBRemote & packet)501b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
502b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
503e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:open:"));
504e13c2731STamas Berghammer   std::string path;
505e13c2731STamas Berghammer   packet.GetHexByteStringTerminatedBy(path, ',');
506b9c1b51eSKate Stone   if (!path.empty()) {
507b9c1b51eSKate Stone     if (packet.GetChar() == ',') {
50862c9fe42SLawrence D'Anna       auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0));
509b9c1b51eSKate Stone       if (packet.GetChar() == ',') {
510e13c2731STamas Berghammer         mode_t mode = packet.GetHexMaxU32(false, 0600);
5118f3be7a3SJonas Devlieghere         FileSpec path_spec(path);
5128f3be7a3SJonas Devlieghere         FileSystem::Instance().Resolve(path_spec);
5133a142495SAaron Smith         // Do not close fd.
5142fce1137SLawrence D'Anna         auto file = FileSystem::Instance().Open(path_spec, flags, mode, false);
5152fce1137SLawrence D'Anna 
5169929cfbcSMichał Górny         StreamString response;
5179929cfbcSMichał Górny         response.PutChar('F');
5189929cfbcSMichał Górny 
5192fce1137SLawrence D'Anna         int descriptor = File::kInvalidDescriptor;
5202fce1137SLawrence D'Anna         if (file) {
5212fce1137SLawrence D'Anna           descriptor = file.get()->GetDescriptor();
5229929cfbcSMichał Górny           response.Printf("%x", descriptor);
5232fce1137SLawrence D'Anna         } else {
5249929cfbcSMichał Górny           response.PutCString("-1");
5252fce1137SLawrence D'Anna           std::error_code code = errorToErrorCode(file.takeError());
5262fce1137SLawrence D'Anna           if (code.category() == std::system_category()) {
5279929cfbcSMichał Górny             response.Printf(",%x", code.value());
5282fce1137SLawrence D'Anna           }
5292fce1137SLawrence D'Anna         }
5302fce1137SLawrence D'Anna 
53126709df8SZachary Turner         return SendPacketNoLock(response.GetString());
532e13c2731STamas Berghammer       }
533e13c2731STamas Berghammer     }
534e13c2731STamas Berghammer   }
535e13c2731STamas Berghammer   return SendErrorResponse(18);
536e13c2731STamas Berghammer }
537e13c2731STamas Berghammer 
system_errno_to_gdb(int err)5383d3017d3SMichał Górny static GDBErrno system_errno_to_gdb(int err) {
5393d3017d3SMichał Górny   switch (err) {
5403d3017d3SMichał Górny #define HANDLE_ERRNO(name, value)                                              \
5413d3017d3SMichał Górny   case name:                                                                   \
5423d3017d3SMichał Górny     return GDB_##name;
5433d3017d3SMichał Górny #include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
5443d3017d3SMichał Górny   default:
5453d3017d3SMichał Górny     return GDB_EUNKNOWN;
5463d3017d3SMichał Górny   }
5473d3017d3SMichał Górny }
5483d3017d3SMichał Górny 
549e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_Close(StringExtractorGDBRemote & packet)550b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
551b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
552e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:close:"));
5539929cfbcSMichał Górny   int fd = packet.GetS32(-1, 16);
554e13c2731STamas Berghammer   int err = -1;
555e13c2731STamas Berghammer   int save_errno = 0;
556b9c1b51eSKate Stone   if (fd >= 0) {
55762c9fe42SLawrence D'Anna     NativeFile file(fd, File::OpenOptions(0), true);
5583a142495SAaron Smith     Status error = file.Close();
5593a142495SAaron Smith     err = 0;
5603a142495SAaron Smith     save_errno = error.GetError();
561b9c1b51eSKate Stone   } else {
562e13c2731STamas Berghammer     save_errno = EINVAL;
563e13c2731STamas Berghammer   }
564e13c2731STamas Berghammer   StreamString response;
565e13c2731STamas Berghammer   response.PutChar('F');
5669929cfbcSMichał Górny   response.Printf("%x", err);
567e13c2731STamas Berghammer   if (save_errno)
5683d3017d3SMichał Górny     response.Printf(",%x", system_errno_to_gdb(save_errno));
56926709df8SZachary Turner   return SendPacketNoLock(response.GetString());
570e13c2731STamas Berghammer }
571e13c2731STamas Berghammer 
572e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_pRead(StringExtractorGDBRemote & packet)573b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
574b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
575e13c2731STamas Berghammer   StreamGDBRemote response;
576e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:pread:"));
5779929cfbcSMichał Górny   int fd = packet.GetS32(-1, 16);
578b9c1b51eSKate Stone   if (packet.GetChar() == ',') {
5799929cfbcSMichał Górny     size_t count = packet.GetHexMaxU64(false, SIZE_MAX);
580b9c1b51eSKate Stone     if (packet.GetChar() == ',') {
5819929cfbcSMichał Górny       off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
582341df3f1SPavel Labath       if (count == SIZE_MAX) {
5839929cfbcSMichał Górny         response.Printf("F-1:%x", EINVAL);
58470a5ef15SZachary Turner         return SendPacketNoLock(response.GetString());
585e13c2731STamas Berghammer       }
586e13c2731STamas Berghammer 
587e13c2731STamas Berghammer       std::string buffer(count, 0);
58814735cabSMichał Górny       NativeFile file(fd, File::eOpenOptionReadOnly, false);
5893a142495SAaron Smith       Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
5903a142495SAaron Smith       const int save_errno = error.GetError();
591e13c2731STamas Berghammer       response.PutChar('F');
5929929cfbcSMichał Górny       if (error.Success()) {
5939929cfbcSMichał Górny         response.Printf("%zx", count);
594e13c2731STamas Berghammer         response.PutChar(';');
5959929cfbcSMichał Górny         response.PutEscapedBytes(&buffer[0], count);
5969929cfbcSMichał Górny       } else {
5979929cfbcSMichał Górny         response.PutCString("-1");
5989929cfbcSMichał Górny         if (save_errno)
5993d3017d3SMichał Górny           response.Printf(",%x", system_errno_to_gdb(save_errno));
600e13c2731STamas Berghammer       }
60170a5ef15SZachary Turner       return SendPacketNoLock(response.GetString());
602e13c2731STamas Berghammer     }
603e13c2731STamas Berghammer   }
604e13c2731STamas Berghammer   return SendErrorResponse(21);
605e13c2731STamas Berghammer }
606e13c2731STamas Berghammer 
607e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_pWrite(StringExtractorGDBRemote & packet)608b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
609b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
610e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:pwrite:"));
611e13c2731STamas Berghammer 
612e13c2731STamas Berghammer   StreamGDBRemote response;
613e13c2731STamas Berghammer   response.PutChar('F');
614e13c2731STamas Berghammer 
6159929cfbcSMichał Górny   int fd = packet.GetS32(-1, 16);
616b9c1b51eSKate Stone   if (packet.GetChar() == ',') {
6179929cfbcSMichał Górny     off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
618b9c1b51eSKate Stone     if (packet.GetChar() == ',') {
619e13c2731STamas Berghammer       std::string buffer;
620b9c1b51eSKate Stone       if (packet.GetEscapedBinaryData(buffer)) {
62114735cabSMichał Górny         NativeFile file(fd, File::eOpenOptionWriteOnly, false);
6223a142495SAaron Smith         size_t count = buffer.size();
6233a142495SAaron Smith         Status error =
6243a142495SAaron Smith             file.Write(static_cast<const void *>(&buffer[0]), count, offset);
6253a142495SAaron Smith         const int save_errno = error.GetError();
6269929cfbcSMichał Górny         if (error.Success())
6279929cfbcSMichał Górny           response.Printf("%zx", count);
6289929cfbcSMichał Górny         else {
6299929cfbcSMichał Górny           response.PutCString("-1");
630e13c2731STamas Berghammer           if (save_errno)
6313d3017d3SMichał Górny             response.Printf(",%x", system_errno_to_gdb(save_errno));
6329929cfbcSMichał Górny         }
633b9c1b51eSKate Stone       } else {
6349929cfbcSMichał Górny         response.Printf("-1,%x", EINVAL);
635e13c2731STamas Berghammer       }
63670a5ef15SZachary Turner       return SendPacketNoLock(response.GetString());
637e13c2731STamas Berghammer     }
638e13c2731STamas Berghammer   }
639e13c2731STamas Berghammer   return SendErrorResponse(27);
640e13c2731STamas Berghammer }
641e13c2731STamas Berghammer 
642e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_Size(StringExtractorGDBRemote & packet)643b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
644b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
645e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:size:"));
646e13c2731STamas Berghammer   std::string path;
647e13c2731STamas Berghammer   packet.GetHexByteString(path);
648b9c1b51eSKate Stone   if (!path.empty()) {
64907db3f7eSZachary Turner     uint64_t Size;
65007db3f7eSZachary Turner     if (llvm::sys::fs::file_size(path, Size))
65107db3f7eSZachary Turner       return SendErrorResponse(5);
652e13c2731STamas Berghammer     StreamString response;
653e13c2731STamas Berghammer     response.PutChar('F');
65407db3f7eSZachary Turner     response.PutHex64(Size);
65507db3f7eSZachary Turner     if (Size == UINT64_MAX) {
656e13c2731STamas Berghammer       response.PutChar(',');
65707db3f7eSZachary Turner       response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode()
658e13c2731STamas Berghammer     }
65926709df8SZachary Turner     return SendPacketNoLock(response.GetString());
660e13c2731STamas Berghammer   }
661e13c2731STamas Berghammer   return SendErrorResponse(22);
662e13c2731STamas Berghammer }
663e13c2731STamas Berghammer 
664e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_Mode(StringExtractorGDBRemote & packet)665b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
666b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
667e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:mode:"));
668e13c2731STamas Berghammer   std::string path;
669e13c2731STamas Berghammer   packet.GetHexByteString(path);
670b9c1b51eSKate Stone   if (!path.empty()) {
6718f3be7a3SJonas Devlieghere     FileSpec file_spec(path);
6728f3be7a3SJonas Devlieghere     FileSystem::Instance().Resolve(file_spec);
67373ed6071SJonas Devlieghere     std::error_code ec;
67473ed6071SJonas Devlieghere     const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);
675e13c2731STamas Berghammer     StreamString response;
676dbb0c14dSMichał Górny     if (mode != llvm::sys::fs::perms_not_known)
6779929cfbcSMichał Górny       response.Printf("F%x", mode);
678dbb0c14dSMichał Górny     else
679dbb0c14dSMichał Górny       response.Printf("F-1,%x", (int)Status(ec).GetError());
68026709df8SZachary Turner     return SendPacketNoLock(response.GetString());
681e13c2731STamas Berghammer   }
682e13c2731STamas Berghammer   return SendErrorResponse(23);
683e13c2731STamas Berghammer }
684e13c2731STamas Berghammer 
685e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_Exists(StringExtractorGDBRemote & packet)686b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(
687b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
688e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:exists:"));
689e13c2731STamas Berghammer   std::string path;
690e13c2731STamas Berghammer   packet.GetHexByteString(path);
691b9c1b51eSKate Stone   if (!path.empty()) {
69207db3f7eSZachary Turner     bool retcode = llvm::sys::fs::exists(path);
693e13c2731STamas Berghammer     StreamString response;
694e13c2731STamas Berghammer     response.PutChar('F');
695e13c2731STamas Berghammer     response.PutChar(',');
696e13c2731STamas Berghammer     if (retcode)
697e13c2731STamas Berghammer       response.PutChar('1');
698e13c2731STamas Berghammer     else
699e13c2731STamas Berghammer       response.PutChar('0');
70026709df8SZachary Turner     return SendPacketNoLock(response.GetString());
701e13c2731STamas Berghammer   }
702e13c2731STamas Berghammer   return SendErrorResponse(24);
703e13c2731STamas Berghammer }
704e13c2731STamas Berghammer 
705e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_symlink(StringExtractorGDBRemote & packet)706b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
707b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
708e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:symlink:"));
709e13c2731STamas Berghammer   std::string dst, src;
710e13c2731STamas Berghammer   packet.GetHexByteStringTerminatedBy(dst, ',');
711e13c2731STamas Berghammer   packet.GetChar(); // Skip ',' char
712e13c2731STamas Berghammer   packet.GetHexByteString(src);
7138f3be7a3SJonas Devlieghere 
7148f3be7a3SJonas Devlieghere   FileSpec src_spec(src);
7158f3be7a3SJonas Devlieghere   FileSystem::Instance().Resolve(src_spec);
7168f3be7a3SJonas Devlieghere   Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst));
7178f3be7a3SJonas Devlieghere 
718e13c2731STamas Berghammer   StreamString response;
7199929cfbcSMichał Górny   response.Printf("F%x,%x", error.GetError(), error.GetError());
72026709df8SZachary Turner   return SendPacketNoLock(response.GetString());
721e13c2731STamas Berghammer }
722e13c2731STamas Berghammer 
723e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_unlink(StringExtractorGDBRemote & packet)724b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
725b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
726e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:unlink:"));
727e13c2731STamas Berghammer   std::string path;
728e13c2731STamas Berghammer   packet.GetHexByteString(path);
72997206d57SZachary Turner   Status error(llvm::sys::fs::remove(path));
730e13c2731STamas Berghammer   StreamString response;
7319929cfbcSMichał Górny   response.Printf("F%x,%x", error.GetError(), error.GetError());
73226709df8SZachary Turner   return SendPacketNoLock(response.GetString());
733e13c2731STamas Berghammer }
734e13c2731STamas Berghammer 
735e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qPlatform_shell(StringExtractorGDBRemote & packet)736b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
737b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
738e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qPlatform_shell:"));
739e13c2731STamas Berghammer   std::string path;
740e13c2731STamas Berghammer   std::string working_dir;
741e13c2731STamas Berghammer   packet.GetHexByteStringTerminatedBy(path, ',');
742b9c1b51eSKate Stone   if (!path.empty()) {
743b9c1b51eSKate Stone     if (packet.GetChar() == ',') {
744e13c2731STamas Berghammer       // FIXME: add timeout to qPlatform_shell packet
745e13c2731STamas Berghammer       // uint32_t timeout = packet.GetHexMaxU32(false, 32);
746e13c2731STamas Berghammer       if (packet.GetChar() == ',')
747e13c2731STamas Berghammer         packet.GetHexByteString(working_dir);
748e13c2731STamas Berghammer       int status, signo;
749e13c2731STamas Berghammer       std::string output;
7508f3be7a3SJonas Devlieghere       FileSpec working_spec(working_dir);
7518f3be7a3SJonas Devlieghere       FileSystem::Instance().Resolve(working_spec);
7528f3be7a3SJonas Devlieghere       Status err =
7538f3be7a3SJonas Devlieghere           Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,
7548f3be7a3SJonas Devlieghere                                 &output, std::chrono::seconds(10));
755e13c2731STamas Berghammer       StreamGDBRemote response;
756b9c1b51eSKate Stone       if (err.Fail()) {
757e13c2731STamas Berghammer         response.PutCString("F,");
758e13c2731STamas Berghammer         response.PutHex32(UINT32_MAX);
759b9c1b51eSKate Stone       } else {
760e13c2731STamas Berghammer         response.PutCString("F,");
761e13c2731STamas Berghammer         response.PutHex32(status);
762e13c2731STamas Berghammer         response.PutChar(',');
763e13c2731STamas Berghammer         response.PutHex32(signo);
764e13c2731STamas Berghammer         response.PutChar(',');
765e13c2731STamas Berghammer         response.PutEscapedBytes(output.c_str(), output.size());
766e13c2731STamas Berghammer       }
76726709df8SZachary Turner       return SendPacketNoLock(response.GetString());
768e13c2731STamas Berghammer     }
769e13c2731STamas Berghammer   }
770e13c2731STamas Berghammer   return SendErrorResponse(24);
771e13c2731STamas Berghammer }
772e13c2731STamas Berghammer 
773a1097d31SMichał Górny template <typename T, typename U>
fill_clamp(T & dest,U src,typename T::value_type fallback)774a1097d31SMichał Górny static void fill_clamp(T &dest, U src, typename T::value_type fallback) {
77582ce9127SMichał Górny   static_assert(std::is_unsigned<typename T::value_type>::value,
77682ce9127SMichał Górny                 "Destination type must be unsigned.");
77782ce9127SMichał Górny   using UU = typename std::make_unsigned<U>::type;
77882ce9127SMichał Górny   constexpr auto T_max = std::numeric_limits<typename T::value_type>::max();
77982ce9127SMichał Górny   dest = src >= 0 && static_cast<UU>(src) <= T_max ? src : fallback;
780a1097d31SMichał Górny }
781a1097d31SMichał Górny 
782a1097d31SMichał Górny GDBRemoteCommunication::PacketResult
Handle_vFile_FStat(StringExtractorGDBRemote & packet)783a1097d31SMichał Górny GDBRemoteCommunicationServerCommon::Handle_vFile_FStat(
784a1097d31SMichał Górny     StringExtractorGDBRemote &packet) {
785a1097d31SMichał Górny   StreamGDBRemote response;
786a1097d31SMichał Górny   packet.SetFilePos(::strlen("vFile:fstat:"));
787a1097d31SMichał Górny   int fd = packet.GetS32(-1, 16);
788a1097d31SMichał Górny 
789a1097d31SMichał Górny   struct stat file_stats;
790a1097d31SMichał Górny   if (::fstat(fd, &file_stats) == -1) {
791a1097d31SMichał Górny     const int save_errno = errno;
7923d3017d3SMichał Górny     response.Printf("F-1,%x", system_errno_to_gdb(save_errno));
793a1097d31SMichał Górny     return SendPacketNoLock(response.GetString());
794a1097d31SMichał Górny   }
795a1097d31SMichał Górny 
796a1097d31SMichał Górny   GDBRemoteFStatData data;
797a1097d31SMichał Górny   fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0);
798a1097d31SMichał Górny   fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0);
799a1097d31SMichał Górny   data.gdb_st_mode = file_stats.st_mode;
800a1097d31SMichał Górny   fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX);
801a1097d31SMichał Górny   fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0);
802a1097d31SMichał Górny   fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0);
803a1097d31SMichał Górny   fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0);
804a1097d31SMichał Górny   data.gdb_st_size = file_stats.st_size;
805a1097d31SMichał Górny #if !defined(_WIN32)
806a1097d31SMichał Górny   data.gdb_st_blksize = file_stats.st_blksize;
807a1097d31SMichał Górny   data.gdb_st_blocks = file_stats.st_blocks;
808e066c00bSMichał Górny #else
809e066c00bSMichał Górny   data.gdb_st_blksize = 0;
810e066c00bSMichał Górny   data.gdb_st_blocks = 0;
811a1097d31SMichał Górny #endif
812a1097d31SMichał Górny   fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0);
813a1097d31SMichał Górny   fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0);
814a1097d31SMichał Górny   fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0);
815a1097d31SMichał Górny 
816a1097d31SMichał Górny   response.Printf("F%zx;", sizeof(data));
817a1097d31SMichał Górny   response.PutEscapedBytes(&data, sizeof(data));
818a1097d31SMichał Górny   return SendPacketNoLock(response.GetString());
819a1097d31SMichał Górny }
820a1097d31SMichał Górny 
821e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_Stat(StringExtractorGDBRemote & packet)822b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_Stat(
823b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
824b9c1b51eSKate Stone   return SendUnimplementedResponse(
825b9c1b51eSKate Stone       "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
826e13c2731STamas Berghammer }
827e13c2731STamas Berghammer 
828e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_vFile_MD5(StringExtractorGDBRemote & packet)829b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_vFile_MD5(
830b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
831e13c2731STamas Berghammer   packet.SetFilePos(::strlen("vFile:MD5:"));
832e13c2731STamas Berghammer   std::string path;
833e13c2731STamas Berghammer   packet.GetHexByteString(path);
834b9c1b51eSKate Stone   if (!path.empty()) {
835e13c2731STamas Berghammer     StreamGDBRemote response;
836076a2599SZachary Turner     auto Result = llvm::sys::fs::md5_contents(path);
837076a2599SZachary Turner     if (!Result) {
838e13c2731STamas Berghammer       response.PutCString("F,");
839e13c2731STamas Berghammer       response.PutCString("x");
840b9c1b51eSKate Stone     } else {
841e13c2731STamas Berghammer       response.PutCString("F,");
842076a2599SZachary Turner       response.PutHex64(Result->low());
843076a2599SZachary Turner       response.PutHex64(Result->high());
844e13c2731STamas Berghammer     }
84526709df8SZachary Turner     return SendPacketNoLock(response.GetString());
846e13c2731STamas Berghammer   }
847e13c2731STamas Berghammer   return SendErrorResponse(25);
848e13c2731STamas Berghammer }
849e13c2731STamas Berghammer 
850e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qPlatform_mkdir(StringExtractorGDBRemote & packet)851b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(
852b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
853e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qPlatform_mkdir:"));
854e13c2731STamas Berghammer   mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
855b9c1b51eSKate Stone   if (packet.GetChar() == ',') {
856e13c2731STamas Berghammer     std::string path;
857e13c2731STamas Berghammer     packet.GetHexByteString(path);
85897206d57SZachary Turner     Status error(llvm::sys::fs::create_directory(path, mode));
8590f86b743STamas Berghammer 
8600f86b743STamas Berghammer     StreamGDBRemote response;
8619929cfbcSMichał Górny     response.Printf("F%x", error.GetError());
8620f86b743STamas Berghammer 
86326709df8SZachary Turner     return SendPacketNoLock(response.GetString());
864e13c2731STamas Berghammer   }
865e13c2731STamas Berghammer   return SendErrorResponse(20);
866e13c2731STamas Berghammer }
867e13c2731STamas Berghammer 
868e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qPlatform_chmod(StringExtractorGDBRemote & packet)869b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(
870b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
871e13c2731STamas Berghammer   packet.SetFilePos(::strlen("qPlatform_chmod:"));
872e13c2731STamas Berghammer 
8736934e0aaSZachary Turner   auto perms =
8746934e0aaSZachary Turner       static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX));
875b9c1b51eSKate Stone   if (packet.GetChar() == ',') {
876e13c2731STamas Berghammer     std::string path;
877e13c2731STamas Berghammer     packet.GetHexByteString(path);
87897206d57SZachary Turner     Status error(llvm::sys::fs::setPermissions(path, perms));
8790f86b743STamas Berghammer 
8800f86b743STamas Berghammer     StreamGDBRemote response;
8819929cfbcSMichał Górny     response.Printf("F%x", error.GetError());
8820f86b743STamas Berghammer 
88326709df8SZachary Turner     return SendPacketNoLock(response.GetString());
884e13c2731STamas Berghammer   }
885e13c2731STamas Berghammer   return SendErrorResponse(19);
886e13c2731STamas Berghammer }
887e13c2731STamas Berghammer 
888e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qSupported(StringExtractorGDBRemote & packet)889b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qSupported(
890b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
891aab81c2fSMichał Górny   // Parse client-indicated features.
892aab81c2fSMichał Górny   llvm::SmallVector<llvm::StringRef, 4> client_features;
893aab81c2fSMichał Górny   packet.GetStringRef().split(client_features, ';');
894aab81c2fSMichał Górny   return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";"));
895e13c2731STamas Berghammer }
896e13c2731STamas Berghammer 
897e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_QSetDetachOnError(StringExtractorGDBRemote & packet)898b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError(
899b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
900e13c2731STamas Berghammer   packet.SetFilePos(::strlen("QSetDetachOnError:"));
901e13c2731STamas Berghammer   if (packet.GetU32(0))
902e13c2731STamas Berghammer     m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
903e13c2731STamas Berghammer   else
904e13c2731STamas Berghammer     m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
905e13c2731STamas Berghammer   return SendOKResponse();
906e13c2731STamas Berghammer }
907e13c2731STamas Berghammer 
908e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_QStartNoAckMode(StringExtractorGDBRemote & packet)909b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode(
910b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
911e13c2731STamas Berghammer   // Send response first before changing m_send_acks to we ack this packet
912e13c2731STamas Berghammer   PacketResult packet_result = SendOKResponse();
913e13c2731STamas Berghammer   m_send_acks = false;
914e13c2731STamas Berghammer   return packet_result;
915e13c2731STamas Berghammer }
916e13c2731STamas Berghammer 
917e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_QSetSTDIN(StringExtractorGDBRemote & packet)918b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
919b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
920e13c2731STamas Berghammer   packet.SetFilePos(::strlen("QSetSTDIN:"));
921e13c2731STamas Berghammer   FileAction file_action;
922e13c2731STamas Berghammer   std::string path;
923e13c2731STamas Berghammer   packet.GetHexByteString(path);
9245ad891f7SPavel Labath   const bool read = true;
9255ad891f7SPavel Labath   const bool write = false;
9268f3be7a3SJonas Devlieghere   if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {
927e13c2731STamas Berghammer     m_process_launch_info.AppendFileAction(file_action);
928e13c2731STamas Berghammer     return SendOKResponse();
929e13c2731STamas Berghammer   }
930e13c2731STamas Berghammer   return SendErrorResponse(15);
931e13c2731STamas Berghammer }
932e13c2731STamas Berghammer 
933e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_QSetSTDOUT(StringExtractorGDBRemote & packet)934b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
935b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
936e13c2731STamas Berghammer   packet.SetFilePos(::strlen("QSetSTDOUT:"));
937e13c2731STamas Berghammer   FileAction file_action;
938e13c2731STamas Berghammer   std::string path;
939e13c2731STamas Berghammer   packet.GetHexByteString(path);
9405ad891f7SPavel Labath   const bool read = false;
9415ad891f7SPavel Labath   const bool write = true;
9428f3be7a3SJonas Devlieghere   if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {
943e13c2731STamas Berghammer     m_process_launch_info.AppendFileAction(file_action);
944e13c2731STamas Berghammer     return SendOKResponse();
945e13c2731STamas Berghammer   }
946e13c2731STamas Berghammer   return SendErrorResponse(16);
947e13c2731STamas Berghammer }
948e13c2731STamas Berghammer 
949e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_QSetSTDERR(StringExtractorGDBRemote & packet)950b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
951b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
952e13c2731STamas Berghammer   packet.SetFilePos(::strlen("QSetSTDERR:"));
953e13c2731STamas Berghammer   FileAction file_action;
954e13c2731STamas Berghammer   std::string path;
955e13c2731STamas Berghammer   packet.GetHexByteString(path);
9565ad891f7SPavel Labath   const bool read = false;
9575ad891f7SPavel Labath   const bool write = true;
9588f3be7a3SJonas Devlieghere   if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {
959e13c2731STamas Berghammer     m_process_launch_info.AppendFileAction(file_action);
960e13c2731STamas Berghammer     return SendOKResponse();
961e13c2731STamas Berghammer   }
962e13c2731STamas Berghammer   return SendErrorResponse(17);
963e13c2731STamas Berghammer }
964e13c2731STamas Berghammer 
965e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_qLaunchSuccess(StringExtractorGDBRemote & packet)966b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess(
967b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
968e13c2731STamas Berghammer   if (m_process_launch_error.Success())
969e13c2731STamas Berghammer     return SendOKResponse();
970e13c2731STamas Berghammer   StreamString response;
971e13c2731STamas Berghammer   response.PutChar('E');
972e13c2731STamas Berghammer   response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
97326709df8SZachary Turner   return SendPacketNoLock(response.GetString());
974e13c2731STamas Berghammer }
975e13c2731STamas Berghammer 
976e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_QEnvironment(StringExtractorGDBRemote & packet)977b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
978b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
979e13c2731STamas Berghammer   packet.SetFilePos(::strlen("QEnvironment:"));
980e13c2731STamas Berghammer   const uint32_t bytes_left = packet.GetBytesLeft();
981b9c1b51eSKate Stone   if (bytes_left > 0) {
98262930e57SPavel Labath     m_process_launch_info.GetEnvironment().insert(packet.Peek());
983e13c2731STamas Berghammer     return SendOKResponse();
984e13c2731STamas Berghammer   }
985e13c2731STamas Berghammer   return SendErrorResponse(12);
986e13c2731STamas Berghammer }
987e13c2731STamas Berghammer 
988e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_QEnvironmentHexEncoded(StringExtractorGDBRemote & packet)989b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
990b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
9910ddb7226SChaoren Lin   packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
9920ddb7226SChaoren Lin   const uint32_t bytes_left = packet.GetBytesLeft();
993b9c1b51eSKate Stone   if (bytes_left > 0) {
9940ddb7226SChaoren Lin     std::string str;
9950ddb7226SChaoren Lin     packet.GetHexByteString(str);
99662930e57SPavel Labath     m_process_launch_info.GetEnvironment().insert(str);
9970ddb7226SChaoren Lin     return SendOKResponse();
9980ddb7226SChaoren Lin   }
9990ddb7226SChaoren Lin   return SendErrorResponse(12);
10000ddb7226SChaoren Lin }
10010ddb7226SChaoren Lin 
10020ddb7226SChaoren Lin GDBRemoteCommunication::PacketResult
Handle_QLaunchArch(StringExtractorGDBRemote & packet)1003b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
1004b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
1005e13c2731STamas Berghammer   packet.SetFilePos(::strlen("QLaunchArch:"));
1006e13c2731STamas Berghammer   const uint32_t bytes_left = packet.GetBytesLeft();
1007b9c1b51eSKate Stone   if (bytes_left > 0) {
1008b9739d40SPavel Labath     const char *arch_triple = packet.Peek();
10093a142495SAaron Smith     m_process_launch_info.SetArchitecture(
10103a142495SAaron Smith         HostInfo::GetAugmentedArchSpec(arch_triple));
1011e13c2731STamas Berghammer     return SendOKResponse();
1012e13c2731STamas Berghammer   }
1013e13c2731STamas Berghammer   return SendErrorResponse(13);
1014e13c2731STamas Berghammer }
1015e13c2731STamas Berghammer 
1016e13c2731STamas Berghammer GDBRemoteCommunication::PacketResult
Handle_A(StringExtractorGDBRemote & packet)1017b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
101805097246SAdrian Prantl   // The 'A' packet is the most over designed packet ever here with redundant
101905097246SAdrian Prantl   // argument indexes, redundant argument lengths and needed hex encoded
102005097246SAdrian Prantl   // argument string values. Really all that is needed is a comma separated hex
102105097246SAdrian Prantl   // encoded argument value list, but we will stay true to the documented
102205097246SAdrian Prantl   // version of the 'A' packet here...
1023e13c2731STamas Berghammer 
1024a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Process);
1025e13c2731STamas Berghammer   int actual_arg_index = 0;
1026e13c2731STamas Berghammer 
1027e13c2731STamas Berghammer   packet.SetFilePos(1); // Skip the 'A'
1028e13c2731STamas Berghammer   bool success = true;
1029b9c1b51eSKate Stone   while (success && packet.GetBytesLeft() > 0) {
103005097246SAdrian Prantl     // Decode the decimal argument string length. This length is the number of
103105097246SAdrian Prantl     // hex nibbles in the argument string value.
1032e13c2731STamas Berghammer     const uint32_t arg_len = packet.GetU32(UINT32_MAX);
1033e13c2731STamas Berghammer     if (arg_len == UINT32_MAX)
1034e13c2731STamas Berghammer       success = false;
1035b9c1b51eSKate Stone     else {
1036e13c2731STamas Berghammer       // Make sure the argument hex string length is followed by a comma
1037e13c2731STamas Berghammer       if (packet.GetChar() != ',')
1038e13c2731STamas Berghammer         success = false;
1039b9c1b51eSKate Stone       else {
104005097246SAdrian Prantl         // Decode the argument index. We ignore this really because who would
104105097246SAdrian Prantl         // really send down the arguments in a random order???
1042e13c2731STamas Berghammer         const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
1043e13c2731STamas Berghammer         if (arg_idx == UINT32_MAX)
1044e13c2731STamas Berghammer           success = false;
1045b9c1b51eSKate Stone         else {
1046e13c2731STamas Berghammer           // Make sure the argument index is followed by a comma
1047e13c2731STamas Berghammer           if (packet.GetChar() != ',')
1048e13c2731STamas Berghammer             success = false;
1049b9c1b51eSKate Stone           else {
105005097246SAdrian Prantl             // Decode the argument string value from hex bytes back into a UTF8
105105097246SAdrian Prantl             // string and make sure the length matches the one supplied in the
105205097246SAdrian Prantl             // packet
1053e13c2731STamas Berghammer             std::string arg;
1054b9c1b51eSKate Stone             if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
1055b9c1b51eSKate Stone                 (arg_len / 2))
1056e13c2731STamas Berghammer               success = false;
1057b9c1b51eSKate Stone             else {
1058e13c2731STamas Berghammer               // If there are any bytes left
1059b9c1b51eSKate Stone               if (packet.GetBytesLeft()) {
1060e13c2731STamas Berghammer                 if (packet.GetChar() != ',')
1061e13c2731STamas Berghammer                   success = false;
1062e13c2731STamas Berghammer               }
1063e13c2731STamas Berghammer 
1064b9c1b51eSKate Stone               if (success) {
1065e13c2731STamas Berghammer                 if (arg_idx == 0)
1066937348cdSJonas Devlieghere                   m_process_launch_info.GetExecutableFile().SetFile(
10678f3be7a3SJonas Devlieghere                       arg, FileSpec::Style::native);
1068ecbb0bb1SZachary Turner                 m_process_launch_info.GetArguments().AppendArgument(arg);
106963e5fb76SJonas Devlieghere                 LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"",
1070b9c1b51eSKate Stone                           __FUNCTION__, actual_arg_index, arg.c_str());
1071e13c2731STamas Berghammer                 ++actual_arg_index;
1072e13c2731STamas Berghammer               }
1073e13c2731STamas Berghammer             }
1074e13c2731STamas Berghammer           }
1075e13c2731STamas Berghammer         }
1076e13c2731STamas Berghammer       }
1077e13c2731STamas Berghammer     }
1078e13c2731STamas Berghammer   }
1079e13c2731STamas Berghammer 
1080b9c1b51eSKate Stone   if (success) {
1081e13c2731STamas Berghammer     m_process_launch_error = LaunchProcess();
108296e600fcSPavel Labath     if (m_process_launch_error.Success())
1083e13c2731STamas Berghammer       return SendOKResponse();
108496e600fcSPavel Labath     LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
1085e13c2731STamas Berghammer   }
1086e13c2731STamas Berghammer   return SendErrorResponse(8);
1087e13c2731STamas Berghammer }
1088e13c2731STamas Berghammer 
10896801be33SOleksiy Vyalov GDBRemoteCommunication::PacketResult
Handle_qEcho(StringExtractorGDBRemote & packet)1090b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qEcho(
1091b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
1092420562aaSGreg Clayton   // Just echo back the exact same packet for qEcho...
109326709df8SZachary Turner   return SendPacketNoLock(packet.GetStringRef());
1094420562aaSGreg Clayton }
1095420562aaSGreg Clayton 
1096420562aaSGreg Clayton GDBRemoteCommunication::PacketResult
Handle_qModuleInfo(StringExtractorGDBRemote & packet)1097b9c1b51eSKate Stone GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
1098b9c1b51eSKate Stone     StringExtractorGDBRemote &packet) {
10996801be33SOleksiy Vyalov   packet.SetFilePos(::strlen("qModuleInfo:"));
11006801be33SOleksiy Vyalov 
11016801be33SOleksiy Vyalov   std::string module_path;
11026801be33SOleksiy Vyalov   packet.GetHexByteStringTerminatedBy(module_path, ';');
11036801be33SOleksiy Vyalov   if (module_path.empty())
11046801be33SOleksiy Vyalov     return SendErrorResponse(1);
11056801be33SOleksiy Vyalov 
11066801be33SOleksiy Vyalov   if (packet.GetChar() != ';')
11076801be33SOleksiy Vyalov     return SendErrorResponse(2);
11086801be33SOleksiy Vyalov 
11096801be33SOleksiy Vyalov   std::string triple;
11106801be33SOleksiy Vyalov   packet.GetHexByteString(triple);
1111dad4db71STamas Berghammer 
11122f1fbaebSPavel Labath   ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);
11132f1fbaebSPavel Labath   if (!matched_module_spec.GetFileSpec())
11146801be33SOleksiy Vyalov     return SendErrorResponse(3);
11156801be33SOleksiy Vyalov 
111663acdfdeSOleksiy Vyalov   const auto file_offset = matched_module_spec.GetObjectOffset();
111763acdfdeSOleksiy Vyalov   const auto file_size = matched_module_spec.GetObjectSize();
111863acdfdeSOleksiy Vyalov   const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
11196801be33SOleksiy Vyalov 
11206801be33SOleksiy Vyalov   StreamGDBRemote response;
11216801be33SOleksiy Vyalov 
1122b9c1b51eSKate Stone   if (uuid_str.empty()) {
11233a142495SAaron Smith     auto Result = llvm::sys::fs::md5_contents(
11243a142495SAaron Smith         matched_module_spec.GetFileSpec().GetPath());
1125076a2599SZachary Turner     if (!Result)
11266801be33SOleksiy Vyalov       return SendErrorResponse(5);
11276801be33SOleksiy Vyalov     response.PutCString("md5:");
11287f815a9aSPavel Labath     response.PutStringAsRawHex8(Result->digest());
1129b9c1b51eSKate Stone   } else {
11306801be33SOleksiy Vyalov     response.PutCString("uuid:");
11317f815a9aSPavel Labath     response.PutStringAsRawHex8(uuid_str);
11326801be33SOleksiy Vyalov   }
11336801be33SOleksiy Vyalov   response.PutChar(';');
11346801be33SOleksiy Vyalov 
11356801be33SOleksiy Vyalov   const auto &module_arch = matched_module_spec.GetArchitecture();
11366801be33SOleksiy Vyalov   response.PutCString("triple:");
11377f815a9aSPavel Labath   response.PutStringAsRawHex8(module_arch.GetTriple().getTriple());
11386801be33SOleksiy Vyalov   response.PutChar(';');
11396801be33SOleksiy Vyalov 
1140dad4db71STamas Berghammer   response.PutCString("file_path:");
1141*1b4b12a3SNico Weber   response.PutStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString());
1142dad4db71STamas Berghammer   response.PutChar(';');
11436801be33SOleksiy Vyalov   response.PutCString("file_offset:");
11446801be33SOleksiy Vyalov   response.PutHex64(file_offset);
11456801be33SOleksiy Vyalov   response.PutChar(';');
11466801be33SOleksiy Vyalov   response.PutCString("file_size:");
11476801be33SOleksiy Vyalov   response.PutHex64(file_size);
11486801be33SOleksiy Vyalov   response.PutChar(';');
11496801be33SOleksiy Vyalov 
115026709df8SZachary Turner   return SendPacketNoLock(response.GetString());
11516801be33SOleksiy Vyalov }
11526801be33SOleksiy Vyalov 
11532f1fbaebSPavel Labath GDBRemoteCommunication::PacketResult
Handle_jModulesInfo(StringExtractorGDBRemote & packet)11542f1fbaebSPavel Labath GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
11552f1fbaebSPavel Labath     StringExtractorGDBRemote &packet) {
11564f8151e6SJonas Devlieghere   namespace json = llvm::json;
11574f8151e6SJonas Devlieghere 
11582f1fbaebSPavel Labath   packet.SetFilePos(::strlen("jModulesInfo:"));
11592f1fbaebSPavel Labath 
11602f1fbaebSPavel Labath   StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());
11612f1fbaebSPavel Labath   if (!object_sp)
11622f1fbaebSPavel Labath     return SendErrorResponse(1);
11632f1fbaebSPavel Labath 
11642f1fbaebSPavel Labath   StructuredData::Array *packet_array = object_sp->GetAsArray();
11652f1fbaebSPavel Labath   if (!packet_array)
11662f1fbaebSPavel Labath     return SendErrorResponse(2);
11672f1fbaebSPavel Labath 
11684f8151e6SJonas Devlieghere   json::Array response_array;
11692f1fbaebSPavel Labath   for (size_t i = 0; i < packet_array->GetSize(); ++i) {
11702f1fbaebSPavel Labath     StructuredData::Dictionary *query =
11712f1fbaebSPavel Labath         packet_array->GetItemAtIndex(i)->GetAsDictionary();
11722f1fbaebSPavel Labath     if (!query)
11732f1fbaebSPavel Labath       continue;
11742833321fSZachary Turner     llvm::StringRef file, triple;
11752f1fbaebSPavel Labath     if (!query->GetValueForKeyAsString("file", file) ||
11762f1fbaebSPavel Labath         !query->GetValueForKeyAsString("triple", triple))
11772f1fbaebSPavel Labath       continue;
11782f1fbaebSPavel Labath 
11792f1fbaebSPavel Labath     ModuleSpec matched_module_spec = GetModuleInfo(file, triple);
11802f1fbaebSPavel Labath     if (!matched_module_spec.GetFileSpec())
11812f1fbaebSPavel Labath       continue;
11822f1fbaebSPavel Labath 
11832f1fbaebSPavel Labath     const auto file_offset = matched_module_spec.GetObjectOffset();
11842f1fbaebSPavel Labath     const auto file_size = matched_module_spec.GetObjectSize();
11852f1fbaebSPavel Labath     const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
11862f1fbaebSPavel Labath     if (uuid_str.empty())
11872f1fbaebSPavel Labath       continue;
11884f8151e6SJonas Devlieghere     const auto triple_str =
11894f8151e6SJonas Devlieghere         matched_module_spec.GetArchitecture().GetTriple().getTriple();
11904f8151e6SJonas Devlieghere     const auto file_path = matched_module_spec.GetFileSpec().GetPath();
11912f1fbaebSPavel Labath 
11924f8151e6SJonas Devlieghere     json::Object response{{"uuid", uuid_str},
11934f8151e6SJonas Devlieghere                           {"triple", triple_str},
11944f8151e6SJonas Devlieghere                           {"file_path", file_path},
11954f8151e6SJonas Devlieghere                           {"file_offset", static_cast<int64_t>(file_offset)},
11964f8151e6SJonas Devlieghere                           {"file_size", static_cast<int64_t>(file_size)}};
11974f8151e6SJonas Devlieghere     response_array.push_back(std::move(response));
11982f1fbaebSPavel Labath   }
11992f1fbaebSPavel Labath 
12002f1fbaebSPavel Labath   StreamString response;
12014f8151e6SJonas Devlieghere   response.AsRawOstream() << std::move(response_array);
12022f1fbaebSPavel Labath   StreamGDBRemote escaped_response;
1203c156427dSZachary Turner   escaped_response.PutEscapedBytes(response.GetString().data(),
1204c156427dSZachary Turner                                    response.GetSize());
12052f1fbaebSPavel Labath   return SendPacketNoLock(escaped_response.GetString());
12062f1fbaebSPavel Labath }
12072f1fbaebSPavel Labath 
CreateProcessInfoResponse(const ProcessInstanceInfo & proc_info,StreamString & response)1208b9c1b51eSKate Stone void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
1209b9c1b51eSKate Stone     const ProcessInstanceInfo &proc_info, StreamString &response) {
1210b9c1b51eSKate Stone   response.Printf(
1211b9c1b51eSKate Stone       "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
1212b9c1b51eSKate Stone       proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1213b9c1b51eSKate Stone       proc_info.GetUserID(), proc_info.GetGroupID(),
1214b9c1b51eSKate Stone       proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
1215e13c2731STamas Berghammer   response.PutCString("name:");
1216*1b4b12a3SNico Weber   response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
121748a50ee0SWalter Erquinigo 
121848a50ee0SWalter Erquinigo   response.PutChar(';');
121948a50ee0SWalter Erquinigo   response.PutCString("args:");
122048a50ee0SWalter Erquinigo   response.PutStringAsRawHex8(proc_info.GetArg0());
122148a50ee0SWalter Erquinigo   for (auto &arg : proc_info.GetArguments()) {
122248a50ee0SWalter Erquinigo     response.PutChar('-');
122348a50ee0SWalter Erquinigo     response.PutStringAsRawHex8(arg.ref());
122448a50ee0SWalter Erquinigo   }
122548a50ee0SWalter Erquinigo 
1226e13c2731STamas Berghammer   response.PutChar(';');
1227e13c2731STamas Berghammer   const ArchSpec &proc_arch = proc_info.GetArchitecture();
1228b9c1b51eSKate Stone   if (proc_arch.IsValid()) {
1229e13c2731STamas Berghammer     const llvm::Triple &proc_triple = proc_arch.GetTriple();
1230e13c2731STamas Berghammer     response.PutCString("triple:");
12317f815a9aSPavel Labath     response.PutStringAsRawHex8(proc_triple.getTriple());
1232e13c2731STamas Berghammer     response.PutChar(';');
1233e13c2731STamas Berghammer   }
1234e13c2731STamas Berghammer }
1235e13c2731STamas Berghammer 
1236b9c1b51eSKate Stone void GDBRemoteCommunicationServerCommon::
CreateProcessInfoResponse_DebugServerStyle(const ProcessInstanceInfo & proc_info,StreamString & response)1237b9c1b51eSKate Stone     CreateProcessInfoResponse_DebugServerStyle(
1238b9c1b51eSKate Stone         const ProcessInstanceInfo &proc_info, StreamString &response) {
1239b9c1b51eSKate Stone   response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
1240b9c1b51eSKate Stone                   ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
1241b9c1b51eSKate Stone                   proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1242b9c1b51eSKate Stone                   proc_info.GetUserID(), proc_info.GetGroupID(),
1243e13c2731STamas Berghammer                   proc_info.GetEffectiveUserID(),
1244e13c2731STamas Berghammer                   proc_info.GetEffectiveGroupID());
1245e13c2731STamas Berghammer 
1246e13c2731STamas Berghammer   const ArchSpec &proc_arch = proc_info.GetArchitecture();
1247b9c1b51eSKate Stone   if (proc_arch.IsValid()) {
1248e13c2731STamas Berghammer     const llvm::Triple &proc_triple = proc_arch.GetTriple();
1249e13c2731STamas Berghammer #if defined(__APPLE__)
1250e13c2731STamas Berghammer     // We'll send cputype/cpusubtype.
1251e13c2731STamas Berghammer     const uint32_t cpu_type = proc_arch.GetMachOCPUType();
1252e13c2731STamas Berghammer     if (cpu_type != 0)
1253e13c2731STamas Berghammer       response.Printf("cputype:%" PRIx32 ";", cpu_type);
1254e13c2731STamas Berghammer 
1255e13c2731STamas Berghammer     const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
1256e13c2731STamas Berghammer     if (cpu_subtype != 0)
1257e13c2731STamas Berghammer       response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
1258e13c2731STamas Berghammer 
12599a8d42e6SJonas Devlieghere     const std::string vendor = proc_triple.getVendorName().str();
1260e13c2731STamas Berghammer     if (!vendor.empty())
1261e13c2731STamas Berghammer       response.Printf("vendor:%s;", vendor.c_str());
1262e13c2731STamas Berghammer #else
1263e13c2731STamas Berghammer     // We'll send the triple.
1264e13c2731STamas Berghammer     response.PutCString("triple:");
12657f815a9aSPavel Labath     response.PutStringAsRawHex8(proc_triple.getTriple());
1266e13c2731STamas Berghammer     response.PutChar(';');
1267e13c2731STamas Berghammer #endif
1268adcd0268SBenjamin Kramer     std::string ostype = std::string(proc_triple.getOSName());
1269e13c2731STamas Berghammer     // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
1270b9c1b51eSKate Stone     if (proc_triple.getVendor() == llvm::Triple::Apple) {
1271b9c1b51eSKate Stone       switch (proc_triple.getArch()) {
1272e13c2731STamas Berghammer       case llvm::Triple::arm:
12736d9fe8c1SJason Molenda       case llvm::Triple::thumb:
1274e13c2731STamas Berghammer       case llvm::Triple::aarch64:
12757dd7a360SJason Molenda       case llvm::Triple::aarch64_32:
1276e13c2731STamas Berghammer         ostype = "ios";
1277e13c2731STamas Berghammer         break;
1278e13c2731STamas Berghammer       default:
1279e13c2731STamas Berghammer         // No change.
1280e13c2731STamas Berghammer         break;
1281e13c2731STamas Berghammer       }
1282e13c2731STamas Berghammer     }
1283e13c2731STamas Berghammer     response.Printf("ostype:%s;", ostype.c_str());
1284e13c2731STamas Berghammer 
1285b9c1b51eSKate Stone     switch (proc_arch.GetByteOrder()) {
1286b9c1b51eSKate Stone     case lldb::eByteOrderLittle:
1287b9c1b51eSKate Stone       response.PutCString("endian:little;");
1288b9c1b51eSKate Stone       break;
1289b9c1b51eSKate Stone     case lldb::eByteOrderBig:
1290b9c1b51eSKate Stone       response.PutCString("endian:big;");
1291b9c1b51eSKate Stone       break;
1292b9c1b51eSKate Stone     case lldb::eByteOrderPDP:
1293b9c1b51eSKate Stone       response.PutCString("endian:pdp;");
1294b9c1b51eSKate Stone       break;
1295e13c2731STamas Berghammer     default:
1296e13c2731STamas Berghammer       // Nothing.
1297e13c2731STamas Berghammer       break;
1298e13c2731STamas Berghammer     }
129905097246SAdrian Prantl     // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer
130005097246SAdrian Prantl     // size is 4 and for N64 it is 8
13018999edf2SNitesh Jain     std::string abi = proc_arch.GetTargetABI();
13028999edf2SNitesh Jain     if (!abi.empty())
13038999edf2SNitesh Jain       response.Printf("elf_abi:%s;", abi.c_str());
13048999edf2SNitesh Jain     response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
1305e13c2731STamas Berghammer   }
1306e13c2731STamas Berghammer }
13077cb18bf5STamas Berghammer 
FindModuleFile(const std::string & module_path,const ArchSpec & arch)1308b9c1b51eSKate Stone FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
1309b9c1b51eSKate Stone     const std::string &module_path, const ArchSpec &arch) {
13107cb18bf5STamas Berghammer #ifdef __ANDROID__
13117cb18bf5STamas Berghammer   return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
13127cb18bf5STamas Berghammer #else
13138f3be7a3SJonas Devlieghere   FileSpec file_spec(module_path);
13148f3be7a3SJonas Devlieghere   FileSystem::Instance().Resolve(file_spec);
13158f3be7a3SJonas Devlieghere   return file_spec;
13167cb18bf5STamas Berghammer #endif
13177cb18bf5STamas Berghammer }
13182f1fbaebSPavel Labath 
13192833321fSZachary Turner ModuleSpec
GetModuleInfo(llvm::StringRef module_path,llvm::StringRef triple)13202833321fSZachary Turner GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path,
13212833321fSZachary Turner                                                   llvm::StringRef triple) {
13222833321fSZachary Turner   ArchSpec arch(triple);
13232f1fbaebSPavel Labath 
13248f3be7a3SJonas Devlieghere   FileSpec req_module_path_spec(module_path);
13258f3be7a3SJonas Devlieghere   FileSystem::Instance().Resolve(req_module_path_spec);
13268f3be7a3SJonas Devlieghere 
13272f1fbaebSPavel Labath   const FileSpec module_path_spec =
13282f1fbaebSPavel Labath       FindModuleFile(req_module_path_spec.GetPath(), arch);
13292f1fbaebSPavel Labath   const ModuleSpec module_spec(module_path_spec, arch);
13302f1fbaebSPavel Labath 
13312f1fbaebSPavel Labath   ModuleSpecList module_specs;
13322f1fbaebSPavel Labath   if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0,
13332f1fbaebSPavel Labath                                            module_specs))
13342f1fbaebSPavel Labath     return ModuleSpec();
13352f1fbaebSPavel Labath 
13362f1fbaebSPavel Labath   ModuleSpec matched_module_spec;
13372f1fbaebSPavel Labath   if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
13382f1fbaebSPavel Labath     return ModuleSpec();
13392f1fbaebSPavel Labath 
13402f1fbaebSPavel Labath   return matched_module_spec;
13412f1fbaebSPavel Labath }
1342aab81c2fSMichał Górny 
HandleFeatures(const llvm::ArrayRef<llvm::StringRef> client_features)1343aab81c2fSMichał Górny std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures(
1344aab81c2fSMichał Górny     const llvm::ArrayRef<llvm::StringRef> client_features) {
1345aab81c2fSMichał Górny   // 128KBytes is a reasonable max packet size--debugger can always use less.
1346aab81c2fSMichał Górny   constexpr uint32_t max_packet_size = 128 * 1024;
1347aab81c2fSMichał Górny 
1348aab81c2fSMichał Górny   // Features common to platform server and llgs.
1349aab81c2fSMichał Górny   return {
1350aab81c2fSMichał Górny       llvm::formatv("PacketSize={0}", max_packet_size),
1351aab81c2fSMichał Górny       "QStartNoAckMode+",
1352aab81c2fSMichał Górny       "qEcho+",
13533f137236SMichał Górny       "native-signals+",
1354aab81c2fSMichał Górny   };
1355aab81c2fSMichał Górny }
1356