1*0b57cec5SDimitry Andric //===-- GDBRemoteCommunicationServerCommon.cpp ------------------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "GDBRemoteCommunicationServerCommon.h"
10*0b57cec5SDimitry Andric 
11*0b57cec5SDimitry Andric #include <errno.h>
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #ifdef __APPLE__
14*0b57cec5SDimitry Andric #include <TargetConditionals.h>
15*0b57cec5SDimitry Andric #endif
16*0b57cec5SDimitry Andric 
17*0b57cec5SDimitry Andric #include <chrono>
18*0b57cec5SDimitry Andric #include <cstring>
19*0b57cec5SDimitry Andric 
20*0b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
21*0b57cec5SDimitry Andric #include "lldb/Host/Config.h"
22*0b57cec5SDimitry Andric #include "lldb/Host/File.h"
23*0b57cec5SDimitry Andric #include "lldb/Host/FileAction.h"
24*0b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h"
25*0b57cec5SDimitry Andric #include "lldb/Host/Host.h"
26*0b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h"
27*0b57cec5SDimitry Andric #include "lldb/Host/SafeMachO.h"
28*0b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
29*0b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
30*0b57cec5SDimitry Andric #include "lldb/Target/Platform.h"
31*0b57cec5SDimitry Andric #include "lldb/Utility/Endian.h"
32*0b57cec5SDimitry Andric #include "lldb/Utility/JSON.h"
33*0b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
34*0b57cec5SDimitry Andric #include "lldb/Utility/StreamGDBRemote.h"
35*0b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
36*0b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h"
37*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h"
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric #include "ProcessGDBRemoteLog.h"
40*0b57cec5SDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h"
41*0b57cec5SDimitry Andric 
42*0b57cec5SDimitry Andric #ifdef __ANDROID__
43*0b57cec5SDimitry Andric #include "lldb/Host/android/HostInfoAndroid.h"
44*0b57cec5SDimitry Andric #endif
45*0b57cec5SDimitry Andric 
46*0b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric using namespace lldb;
49*0b57cec5SDimitry Andric using namespace lldb_private;
50*0b57cec5SDimitry Andric using namespace lldb_private::process_gdb_remote;
51*0b57cec5SDimitry Andric 
52*0b57cec5SDimitry Andric #ifdef __ANDROID__
53*0b57cec5SDimitry Andric const static uint32_t g_default_packet_timeout_sec = 20; // seconds
54*0b57cec5SDimitry Andric #else
55*0b57cec5SDimitry Andric const static uint32_t g_default_packet_timeout_sec = 0; // not specified
56*0b57cec5SDimitry Andric #endif
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric // GDBRemoteCommunicationServerCommon constructor
59*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
60*0b57cec5SDimitry Andric     const char *comm_name, const char *listener_name)
61*0b57cec5SDimitry Andric     : GDBRemoteCommunicationServer(comm_name, listener_name),
62*0b57cec5SDimitry Andric       m_process_launch_info(), m_process_launch_error(), m_proc_infos(),
63*0b57cec5SDimitry Andric       m_proc_infos_index(0), m_thread_suffix_supported(false),
64*0b57cec5SDimitry Andric       m_list_threads_in_stop_reply(false) {
65*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
66*0b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerCommon::Handle_A);
67*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
68*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QEnvironment,
69*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
70*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
71*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
72*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
73*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
74*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
75*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
76*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
77*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qGroupName,
78*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
79*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
80*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qHostInfo,
81*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
82*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
83*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
84*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
85*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
86*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
87*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
88*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
89*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
90*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
91*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
92*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qEcho,
93*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qEcho);
94*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
95*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
96*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
97*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
98*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_jModulesInfo,
99*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo);
100*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
101*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
102*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
103*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
104*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
105*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
106*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
107*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
108*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
109*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
110*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
111*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
112*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
113*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
114*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
115*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
116*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
117*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
118*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
119*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
120*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
121*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
122*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
123*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
124*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
125*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
126*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
127*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
128*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
129*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
130*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
131*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
132*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
133*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
134*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qSupported,
135*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qSupported);
136*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
137*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
138*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
139*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
140*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qUserName,
141*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_qUserName);
142*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
143*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_close,
144*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
145*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
146*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_exists,
147*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
148*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
149*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_md5,
150*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
151*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
152*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_mode,
153*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
154*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
155*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_open,
156*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
157*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
158*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_pread,
159*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
160*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
161*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
162*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
163*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
164*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_size,
165*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
166*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
167*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_stat,
168*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
169*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
170*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
171*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
172*0b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
173*0b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
174*0b57cec5SDimitry Andric       &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
175*0b57cec5SDimitry Andric }
176*0b57cec5SDimitry Andric 
177*0b57cec5SDimitry Andric // Destructor
178*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {}
179*0b57cec5SDimitry Andric 
180*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
181*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
182*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
183*0b57cec5SDimitry Andric   StreamString response;
184*0b57cec5SDimitry Andric 
185*0b57cec5SDimitry Andric   // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
186*0b57cec5SDimitry Andric 
187*0b57cec5SDimitry Andric   ArchSpec host_arch(HostInfo::GetArchitecture());
188*0b57cec5SDimitry Andric   const llvm::Triple &host_triple = host_arch.GetTriple();
189*0b57cec5SDimitry Andric   response.PutCString("triple:");
190*0b57cec5SDimitry Andric   response.PutStringAsRawHex8(host_triple.getTriple());
191*0b57cec5SDimitry Andric   response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
192*0b57cec5SDimitry Andric 
193*0b57cec5SDimitry Andric   const char *distribution_id = host_arch.GetDistributionId().AsCString();
194*0b57cec5SDimitry Andric   if (distribution_id) {
195*0b57cec5SDimitry Andric     response.PutCString("distribution_id:");
196*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(distribution_id);
197*0b57cec5SDimitry Andric     response.PutCString(";");
198*0b57cec5SDimitry Andric   }
199*0b57cec5SDimitry Andric 
200*0b57cec5SDimitry Andric #if defined(__APPLE__)
201*0b57cec5SDimitry Andric   // For parity with debugserver, we'll include the vendor key.
202*0b57cec5SDimitry Andric   response.PutCString("vendor:apple;");
203*0b57cec5SDimitry Andric 
204*0b57cec5SDimitry Andric   // Send out MachO info.
205*0b57cec5SDimitry Andric   uint32_t cpu = host_arch.GetMachOCPUType();
206*0b57cec5SDimitry Andric   uint32_t sub = host_arch.GetMachOCPUSubType();
207*0b57cec5SDimitry Andric   if (cpu != LLDB_INVALID_CPUTYPE)
208*0b57cec5SDimitry Andric     response.Printf("cputype:%u;", cpu);
209*0b57cec5SDimitry Andric   if (sub != LLDB_INVALID_CPUTYPE)
210*0b57cec5SDimitry Andric     response.Printf("cpusubtype:%u;", sub);
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric   if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) {
213*0b57cec5SDimitry Andric // Indicate the OS type.
214*0b57cec5SDimitry Andric #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
215*0b57cec5SDimitry Andric     response.PutCString("ostype:tvos;");
216*0b57cec5SDimitry Andric #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
217*0b57cec5SDimitry Andric     response.PutCString("ostype:watchos;");
218*0b57cec5SDimitry Andric #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
219*0b57cec5SDimitry Andric     response.PutCString("ostype:bridgeos;");
220*0b57cec5SDimitry Andric #else
221*0b57cec5SDimitry Andric     response.PutCString("ostype:ios;");
222*0b57cec5SDimitry Andric #endif
223*0b57cec5SDimitry Andric 
224*0b57cec5SDimitry Andric     // On arm, we use "synchronous" watchpoints which means the exception is
225*0b57cec5SDimitry Andric     // delivered before the instruction executes.
226*0b57cec5SDimitry Andric     response.PutCString("watchpoint_exceptions_received:before;");
227*0b57cec5SDimitry Andric   } else {
228*0b57cec5SDimitry Andric     response.PutCString("ostype:macosx;");
229*0b57cec5SDimitry Andric     response.Printf("watchpoint_exceptions_received:after;");
230*0b57cec5SDimitry Andric   }
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric #else
233*0b57cec5SDimitry Andric   if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
234*0b57cec5SDimitry Andric       host_arch.GetMachine() == llvm::Triple::aarch64_be ||
235*0b57cec5SDimitry Andric       host_arch.GetMachine() == llvm::Triple::arm ||
236*0b57cec5SDimitry Andric       host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS())
237*0b57cec5SDimitry Andric     response.Printf("watchpoint_exceptions_received:before;");
238*0b57cec5SDimitry Andric   else
239*0b57cec5SDimitry Andric     response.Printf("watchpoint_exceptions_received:after;");
240*0b57cec5SDimitry Andric #endif
241*0b57cec5SDimitry Andric 
242*0b57cec5SDimitry Andric   switch (endian::InlHostByteOrder()) {
243*0b57cec5SDimitry Andric   case eByteOrderBig:
244*0b57cec5SDimitry Andric     response.PutCString("endian:big;");
245*0b57cec5SDimitry Andric     break;
246*0b57cec5SDimitry Andric   case eByteOrderLittle:
247*0b57cec5SDimitry Andric     response.PutCString("endian:little;");
248*0b57cec5SDimitry Andric     break;
249*0b57cec5SDimitry Andric   case eByteOrderPDP:
250*0b57cec5SDimitry Andric     response.PutCString("endian:pdp;");
251*0b57cec5SDimitry Andric     break;
252*0b57cec5SDimitry Andric   default:
253*0b57cec5SDimitry Andric     response.PutCString("endian:unknown;");
254*0b57cec5SDimitry Andric     break;
255*0b57cec5SDimitry Andric   }
256*0b57cec5SDimitry Andric 
257*0b57cec5SDimitry Andric   llvm::VersionTuple version = HostInfo::GetOSVersion();
258*0b57cec5SDimitry Andric   if (!version.empty()) {
259*0b57cec5SDimitry Andric     response.Format("os_version:{0}", version.getAsString());
260*0b57cec5SDimitry Andric     response.PutChar(';');
261*0b57cec5SDimitry Andric   }
262*0b57cec5SDimitry Andric 
263*0b57cec5SDimitry Andric   std::string s;
264*0b57cec5SDimitry Andric   if (HostInfo::GetOSBuildString(s)) {
265*0b57cec5SDimitry Andric     response.PutCString("os_build:");
266*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(s);
267*0b57cec5SDimitry Andric     response.PutChar(';');
268*0b57cec5SDimitry Andric   }
269*0b57cec5SDimitry Andric   if (HostInfo::GetOSKernelDescription(s)) {
270*0b57cec5SDimitry Andric     response.PutCString("os_kernel:");
271*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(s);
272*0b57cec5SDimitry Andric     response.PutChar(';');
273*0b57cec5SDimitry Andric   }
274*0b57cec5SDimitry Andric 
275*0b57cec5SDimitry Andric #if defined(__APPLE__)
276*0b57cec5SDimitry Andric 
277*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
278*0b57cec5SDimitry Andric   // For iOS devices, we are connected through a USB Mux so we never pretend to
279*0b57cec5SDimitry Andric   // actually have a hostname as far as the remote lldb that is connecting to
280*0b57cec5SDimitry Andric   // this lldb-platform is concerned
281*0b57cec5SDimitry Andric   response.PutCString("hostname:");
282*0b57cec5SDimitry Andric   response.PutStringAsRawHex8("127.0.0.1");
283*0b57cec5SDimitry Andric   response.PutChar(';');
284*0b57cec5SDimitry Andric #else  // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
285*0b57cec5SDimitry Andric   if (HostInfo::GetHostname(s)) {
286*0b57cec5SDimitry Andric     response.PutCString("hostname:");
287*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(s);
288*0b57cec5SDimitry Andric     response.PutChar(';');
289*0b57cec5SDimitry Andric   }
290*0b57cec5SDimitry Andric #endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
291*0b57cec5SDimitry Andric 
292*0b57cec5SDimitry Andric #else  // #if defined(__APPLE__)
293*0b57cec5SDimitry Andric   if (HostInfo::GetHostname(s)) {
294*0b57cec5SDimitry Andric     response.PutCString("hostname:");
295*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(s);
296*0b57cec5SDimitry Andric     response.PutChar(';');
297*0b57cec5SDimitry Andric   }
298*0b57cec5SDimitry Andric #endif // #if defined(__APPLE__)
299*0b57cec5SDimitry Andric 
300*0b57cec5SDimitry Andric   if (g_default_packet_timeout_sec > 0)
301*0b57cec5SDimitry Andric     response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);
302*0b57cec5SDimitry Andric 
303*0b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
304*0b57cec5SDimitry Andric }
305*0b57cec5SDimitry Andric 
306*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
307*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID(
308*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
309*0b57cec5SDimitry Andric   // Packet format: "qProcessInfoPID:%i" where %i is the pid
310*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qProcessInfoPID:"));
311*0b57cec5SDimitry Andric   lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID);
312*0b57cec5SDimitry Andric   if (pid != LLDB_INVALID_PROCESS_ID) {
313*0b57cec5SDimitry Andric     ProcessInstanceInfo proc_info;
314*0b57cec5SDimitry Andric     if (Host::GetProcessInfo(pid, proc_info)) {
315*0b57cec5SDimitry Andric       StreamString response;
316*0b57cec5SDimitry Andric       CreateProcessInfoResponse(proc_info, response);
317*0b57cec5SDimitry Andric       return SendPacketNoLock(response.GetString());
318*0b57cec5SDimitry Andric     }
319*0b57cec5SDimitry Andric   }
320*0b57cec5SDimitry Andric   return SendErrorResponse(1);
321*0b57cec5SDimitry Andric }
322*0b57cec5SDimitry Andric 
323*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
324*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
325*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
326*0b57cec5SDimitry Andric   m_proc_infos_index = 0;
327*0b57cec5SDimitry Andric   m_proc_infos.Clear();
328*0b57cec5SDimitry Andric 
329*0b57cec5SDimitry Andric   ProcessInstanceInfoMatch match_info;
330*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qfProcessInfo"));
331*0b57cec5SDimitry Andric   if (packet.GetChar() == ':') {
332*0b57cec5SDimitry Andric     llvm::StringRef key;
333*0b57cec5SDimitry Andric     llvm::StringRef value;
334*0b57cec5SDimitry Andric     while (packet.GetNameColonValue(key, value)) {
335*0b57cec5SDimitry Andric       bool success = true;
336*0b57cec5SDimitry Andric       if (key.equals("name")) {
337*0b57cec5SDimitry Andric         StringExtractor extractor(value);
338*0b57cec5SDimitry Andric         std::string file;
339*0b57cec5SDimitry Andric         extractor.GetHexByteString(file);
340*0b57cec5SDimitry Andric         match_info.GetProcessInfo().GetExecutableFile().SetFile(
341*0b57cec5SDimitry Andric             file, FileSpec::Style::native);
342*0b57cec5SDimitry Andric       } else if (key.equals("name_match")) {
343*0b57cec5SDimitry Andric         NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
344*0b57cec5SDimitry Andric                                    .Case("equals", NameMatch::Equals)
345*0b57cec5SDimitry Andric                                    .Case("starts_with", NameMatch::StartsWith)
346*0b57cec5SDimitry Andric                                    .Case("ends_with", NameMatch::EndsWith)
347*0b57cec5SDimitry Andric                                    .Case("contains", NameMatch::Contains)
348*0b57cec5SDimitry Andric                                    .Case("regex", NameMatch::RegularExpression)
349*0b57cec5SDimitry Andric                                    .Default(NameMatch::Ignore);
350*0b57cec5SDimitry Andric         match_info.SetNameMatchType(name_match);
351*0b57cec5SDimitry Andric         if (name_match == NameMatch::Ignore)
352*0b57cec5SDimitry Andric           return SendErrorResponse(2);
353*0b57cec5SDimitry Andric       } else if (key.equals("pid")) {
354*0b57cec5SDimitry Andric         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
355*0b57cec5SDimitry Andric         if (value.getAsInteger(0, pid))
356*0b57cec5SDimitry Andric           return SendErrorResponse(2);
357*0b57cec5SDimitry Andric         match_info.GetProcessInfo().SetProcessID(pid);
358*0b57cec5SDimitry Andric       } else if (key.equals("parent_pid")) {
359*0b57cec5SDimitry Andric         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
360*0b57cec5SDimitry Andric         if (value.getAsInteger(0, pid))
361*0b57cec5SDimitry Andric           return SendErrorResponse(2);
362*0b57cec5SDimitry Andric         match_info.GetProcessInfo().SetParentProcessID(pid);
363*0b57cec5SDimitry Andric       } else if (key.equals("uid")) {
364*0b57cec5SDimitry Andric         uint32_t uid = UINT32_MAX;
365*0b57cec5SDimitry Andric         if (value.getAsInteger(0, uid))
366*0b57cec5SDimitry Andric           return SendErrorResponse(2);
367*0b57cec5SDimitry Andric         match_info.GetProcessInfo().SetUserID(uid);
368*0b57cec5SDimitry Andric       } else if (key.equals("gid")) {
369*0b57cec5SDimitry Andric         uint32_t gid = UINT32_MAX;
370*0b57cec5SDimitry Andric         if (value.getAsInteger(0, gid))
371*0b57cec5SDimitry Andric           return SendErrorResponse(2);
372*0b57cec5SDimitry Andric         match_info.GetProcessInfo().SetGroupID(gid);
373*0b57cec5SDimitry Andric       } else if (key.equals("euid")) {
374*0b57cec5SDimitry Andric         uint32_t uid = UINT32_MAX;
375*0b57cec5SDimitry Andric         if (value.getAsInteger(0, uid))
376*0b57cec5SDimitry Andric           return SendErrorResponse(2);
377*0b57cec5SDimitry Andric         match_info.GetProcessInfo().SetEffectiveUserID(uid);
378*0b57cec5SDimitry Andric       } else if (key.equals("egid")) {
379*0b57cec5SDimitry Andric         uint32_t gid = UINT32_MAX;
380*0b57cec5SDimitry Andric         if (value.getAsInteger(0, gid))
381*0b57cec5SDimitry Andric           return SendErrorResponse(2);
382*0b57cec5SDimitry Andric         match_info.GetProcessInfo().SetEffectiveGroupID(gid);
383*0b57cec5SDimitry Andric       } else if (key.equals("all_users")) {
384*0b57cec5SDimitry Andric         match_info.SetMatchAllUsers(
385*0b57cec5SDimitry Andric             OptionArgParser::ToBoolean(value, false, &success));
386*0b57cec5SDimitry Andric       } else if (key.equals("triple")) {
387*0b57cec5SDimitry Andric         match_info.GetProcessInfo().GetArchitecture() =
388*0b57cec5SDimitry Andric             HostInfo::GetAugmentedArchSpec(value);
389*0b57cec5SDimitry Andric       } else {
390*0b57cec5SDimitry Andric         success = false;
391*0b57cec5SDimitry Andric       }
392*0b57cec5SDimitry Andric 
393*0b57cec5SDimitry Andric       if (!success)
394*0b57cec5SDimitry Andric         return SendErrorResponse(2);
395*0b57cec5SDimitry Andric     }
396*0b57cec5SDimitry Andric   }
397*0b57cec5SDimitry Andric 
398*0b57cec5SDimitry Andric   if (Host::FindProcesses(match_info, m_proc_infos)) {
399*0b57cec5SDimitry Andric     // We found something, return the first item by calling the get subsequent
400*0b57cec5SDimitry Andric     // process info packet handler...
401*0b57cec5SDimitry Andric     return Handle_qsProcessInfo(packet);
402*0b57cec5SDimitry Andric   }
403*0b57cec5SDimitry Andric   return SendErrorResponse(3);
404*0b57cec5SDimitry Andric }
405*0b57cec5SDimitry Andric 
406*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
407*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
408*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
409*0b57cec5SDimitry Andric   if (m_proc_infos_index < m_proc_infos.GetSize()) {
410*0b57cec5SDimitry Andric     StreamString response;
411*0b57cec5SDimitry Andric     CreateProcessInfoResponse(
412*0b57cec5SDimitry Andric         m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
413*0b57cec5SDimitry Andric     ++m_proc_infos_index;
414*0b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
415*0b57cec5SDimitry Andric   }
416*0b57cec5SDimitry Andric   return SendErrorResponse(4);
417*0b57cec5SDimitry Andric }
418*0b57cec5SDimitry Andric 
419*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
420*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qUserName(
421*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
422*0b57cec5SDimitry Andric #if !defined(LLDB_DISABLE_POSIX)
423*0b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
424*0b57cec5SDimitry Andric   if (log)
425*0b57cec5SDimitry Andric     log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
426*0b57cec5SDimitry Andric 
427*0b57cec5SDimitry Andric   // Packet format: "qUserName:%i" where %i is the uid
428*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qUserName:"));
429*0b57cec5SDimitry Andric   uint32_t uid = packet.GetU32(UINT32_MAX);
430*0b57cec5SDimitry Andric   if (uid != UINT32_MAX) {
431*0b57cec5SDimitry Andric     if (llvm::Optional<llvm::StringRef> name =
432*0b57cec5SDimitry Andric             HostInfo::GetUserIDResolver().GetUserName(uid)) {
433*0b57cec5SDimitry Andric       StreamString response;
434*0b57cec5SDimitry Andric       response.PutStringAsRawHex8(*name);
435*0b57cec5SDimitry Andric       return SendPacketNoLock(response.GetString());
436*0b57cec5SDimitry Andric     }
437*0b57cec5SDimitry Andric   }
438*0b57cec5SDimitry Andric   if (log)
439*0b57cec5SDimitry Andric     log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
440*0b57cec5SDimitry Andric #endif
441*0b57cec5SDimitry Andric   return SendErrorResponse(5);
442*0b57cec5SDimitry Andric }
443*0b57cec5SDimitry Andric 
444*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
445*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qGroupName(
446*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
447*0b57cec5SDimitry Andric #if !defined(LLDB_DISABLE_POSIX)
448*0b57cec5SDimitry Andric   // Packet format: "qGroupName:%i" where %i is the gid
449*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qGroupName:"));
450*0b57cec5SDimitry Andric   uint32_t gid = packet.GetU32(UINT32_MAX);
451*0b57cec5SDimitry Andric   if (gid != UINT32_MAX) {
452*0b57cec5SDimitry Andric     if (llvm::Optional<llvm::StringRef> name =
453*0b57cec5SDimitry Andric             HostInfo::GetUserIDResolver().GetGroupName(gid)) {
454*0b57cec5SDimitry Andric       StreamString response;
455*0b57cec5SDimitry Andric       response.PutStringAsRawHex8(*name);
456*0b57cec5SDimitry Andric       return SendPacketNoLock(response.GetString());
457*0b57cec5SDimitry Andric     }
458*0b57cec5SDimitry Andric   }
459*0b57cec5SDimitry Andric #endif
460*0b57cec5SDimitry Andric   return SendErrorResponse(6);
461*0b57cec5SDimitry Andric }
462*0b57cec5SDimitry Andric 
463*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
464*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qSpeedTest(
465*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
466*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qSpeedTest:"));
467*0b57cec5SDimitry Andric 
468*0b57cec5SDimitry Andric   llvm::StringRef key;
469*0b57cec5SDimitry Andric   llvm::StringRef value;
470*0b57cec5SDimitry Andric   bool success = packet.GetNameColonValue(key, value);
471*0b57cec5SDimitry Andric   if (success && key.equals("response_size")) {
472*0b57cec5SDimitry Andric     uint32_t response_size = 0;
473*0b57cec5SDimitry Andric     if (!value.getAsInteger(0, response_size)) {
474*0b57cec5SDimitry Andric       if (response_size == 0)
475*0b57cec5SDimitry Andric         return SendOKResponse();
476*0b57cec5SDimitry Andric       StreamString response;
477*0b57cec5SDimitry Andric       uint32_t bytes_left = response_size;
478*0b57cec5SDimitry Andric       response.PutCString("data:");
479*0b57cec5SDimitry Andric       while (bytes_left > 0) {
480*0b57cec5SDimitry Andric         if (bytes_left >= 26) {
481*0b57cec5SDimitry Andric           response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
482*0b57cec5SDimitry Andric           bytes_left -= 26;
483*0b57cec5SDimitry Andric         } else {
484*0b57cec5SDimitry Andric           response.Printf("%*.*s;", bytes_left, bytes_left,
485*0b57cec5SDimitry Andric                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
486*0b57cec5SDimitry Andric           bytes_left = 0;
487*0b57cec5SDimitry Andric         }
488*0b57cec5SDimitry Andric       }
489*0b57cec5SDimitry Andric       return SendPacketNoLock(response.GetString());
490*0b57cec5SDimitry Andric     }
491*0b57cec5SDimitry Andric   }
492*0b57cec5SDimitry Andric   return SendErrorResponse(7);
493*0b57cec5SDimitry Andric }
494*0b57cec5SDimitry Andric 
495*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
496*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
497*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
498*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:open:"));
499*0b57cec5SDimitry Andric   std::string path;
500*0b57cec5SDimitry Andric   packet.GetHexByteStringTerminatedBy(path, ',');
501*0b57cec5SDimitry Andric   if (!path.empty()) {
502*0b57cec5SDimitry Andric     if (packet.GetChar() == ',') {
503*0b57cec5SDimitry Andric       uint32_t flags = packet.GetHexMaxU32(false, 0);
504*0b57cec5SDimitry Andric       if (packet.GetChar() == ',') {
505*0b57cec5SDimitry Andric         mode_t mode = packet.GetHexMaxU32(false, 0600);
506*0b57cec5SDimitry Andric         FileSpec path_spec(path);
507*0b57cec5SDimitry Andric         FileSystem::Instance().Resolve(path_spec);
508*0b57cec5SDimitry Andric         File file;
509*0b57cec5SDimitry Andric         // Do not close fd.
510*0b57cec5SDimitry Andric         Status error =
511*0b57cec5SDimitry Andric             FileSystem::Instance().Open(file, path_spec, flags, mode, false);
512*0b57cec5SDimitry Andric         const int save_errno = error.GetError();
513*0b57cec5SDimitry Andric         StreamString response;
514*0b57cec5SDimitry Andric         response.PutChar('F');
515*0b57cec5SDimitry Andric         response.Printf("%i", file.GetDescriptor());
516*0b57cec5SDimitry Andric         if (save_errno)
517*0b57cec5SDimitry Andric           response.Printf(",%i", save_errno);
518*0b57cec5SDimitry Andric         return SendPacketNoLock(response.GetString());
519*0b57cec5SDimitry Andric       }
520*0b57cec5SDimitry Andric     }
521*0b57cec5SDimitry Andric   }
522*0b57cec5SDimitry Andric   return SendErrorResponse(18);
523*0b57cec5SDimitry Andric }
524*0b57cec5SDimitry Andric 
525*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
526*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
527*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
528*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:close:"));
529*0b57cec5SDimitry Andric   int fd = packet.GetS32(-1);
530*0b57cec5SDimitry Andric   int err = -1;
531*0b57cec5SDimitry Andric   int save_errno = 0;
532*0b57cec5SDimitry Andric   if (fd >= 0) {
533*0b57cec5SDimitry Andric     File file(fd, true);
534*0b57cec5SDimitry Andric     Status error = file.Close();
535*0b57cec5SDimitry Andric     err = 0;
536*0b57cec5SDimitry Andric     save_errno = error.GetError();
537*0b57cec5SDimitry Andric   } else {
538*0b57cec5SDimitry Andric     save_errno = EINVAL;
539*0b57cec5SDimitry Andric   }
540*0b57cec5SDimitry Andric   StreamString response;
541*0b57cec5SDimitry Andric   response.PutChar('F');
542*0b57cec5SDimitry Andric   response.Printf("%i", err);
543*0b57cec5SDimitry Andric   if (save_errno)
544*0b57cec5SDimitry Andric     response.Printf(",%i", save_errno);
545*0b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
546*0b57cec5SDimitry Andric }
547*0b57cec5SDimitry Andric 
548*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
549*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
550*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
551*0b57cec5SDimitry Andric   StreamGDBRemote response;
552*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:pread:"));
553*0b57cec5SDimitry Andric   int fd = packet.GetS32(-1);
554*0b57cec5SDimitry Andric   if (packet.GetChar() == ',') {
555*0b57cec5SDimitry Andric     size_t count = packet.GetU64(UINT64_MAX);
556*0b57cec5SDimitry Andric     if (packet.GetChar() == ',') {
557*0b57cec5SDimitry Andric       off_t offset = packet.GetU64(UINT32_MAX);
558*0b57cec5SDimitry Andric       if (count == UINT64_MAX) {
559*0b57cec5SDimitry Andric         response.Printf("F-1:%i", EINVAL);
560*0b57cec5SDimitry Andric         return SendPacketNoLock(response.GetString());
561*0b57cec5SDimitry Andric       }
562*0b57cec5SDimitry Andric 
563*0b57cec5SDimitry Andric       std::string buffer(count, 0);
564*0b57cec5SDimitry Andric       File file(fd, false);
565*0b57cec5SDimitry Andric       Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
566*0b57cec5SDimitry Andric       const ssize_t bytes_read = error.Success() ? count : -1;
567*0b57cec5SDimitry Andric       const int save_errno = error.GetError();
568*0b57cec5SDimitry Andric       response.PutChar('F');
569*0b57cec5SDimitry Andric       response.Printf("%zi", bytes_read);
570*0b57cec5SDimitry Andric       if (save_errno)
571*0b57cec5SDimitry Andric         response.Printf(",%i", save_errno);
572*0b57cec5SDimitry Andric       else {
573*0b57cec5SDimitry Andric         response.PutChar(';');
574*0b57cec5SDimitry Andric         response.PutEscapedBytes(&buffer[0], bytes_read);
575*0b57cec5SDimitry Andric       }
576*0b57cec5SDimitry Andric       return SendPacketNoLock(response.GetString());
577*0b57cec5SDimitry Andric     }
578*0b57cec5SDimitry Andric   }
579*0b57cec5SDimitry Andric   return SendErrorResponse(21);
580*0b57cec5SDimitry Andric }
581*0b57cec5SDimitry Andric 
582*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
583*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
584*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
585*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:pwrite:"));
586*0b57cec5SDimitry Andric 
587*0b57cec5SDimitry Andric   StreamGDBRemote response;
588*0b57cec5SDimitry Andric   response.PutChar('F');
589*0b57cec5SDimitry Andric 
590*0b57cec5SDimitry Andric   int fd = packet.GetU32(UINT32_MAX);
591*0b57cec5SDimitry Andric   if (packet.GetChar() == ',') {
592*0b57cec5SDimitry Andric     off_t offset = packet.GetU64(UINT32_MAX);
593*0b57cec5SDimitry Andric     if (packet.GetChar() == ',') {
594*0b57cec5SDimitry Andric       std::string buffer;
595*0b57cec5SDimitry Andric       if (packet.GetEscapedBinaryData(buffer)) {
596*0b57cec5SDimitry Andric         File file(fd, false);
597*0b57cec5SDimitry Andric         size_t count = buffer.size();
598*0b57cec5SDimitry Andric         Status error =
599*0b57cec5SDimitry Andric             file.Write(static_cast<const void *>(&buffer[0]), count, offset);
600*0b57cec5SDimitry Andric         const ssize_t bytes_written = error.Success() ? count : -1;
601*0b57cec5SDimitry Andric         const int save_errno = error.GetError();
602*0b57cec5SDimitry Andric         response.Printf("%zi", bytes_written);
603*0b57cec5SDimitry Andric         if (save_errno)
604*0b57cec5SDimitry Andric           response.Printf(",%i", save_errno);
605*0b57cec5SDimitry Andric       } else {
606*0b57cec5SDimitry Andric         response.Printf("-1,%i", EINVAL);
607*0b57cec5SDimitry Andric       }
608*0b57cec5SDimitry Andric       return SendPacketNoLock(response.GetString());
609*0b57cec5SDimitry Andric     }
610*0b57cec5SDimitry Andric   }
611*0b57cec5SDimitry Andric   return SendErrorResponse(27);
612*0b57cec5SDimitry Andric }
613*0b57cec5SDimitry Andric 
614*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
615*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
616*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
617*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:size:"));
618*0b57cec5SDimitry Andric   std::string path;
619*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
620*0b57cec5SDimitry Andric   if (!path.empty()) {
621*0b57cec5SDimitry Andric     uint64_t Size;
622*0b57cec5SDimitry Andric     if (llvm::sys::fs::file_size(path, Size))
623*0b57cec5SDimitry Andric       return SendErrorResponse(5);
624*0b57cec5SDimitry Andric     StreamString response;
625*0b57cec5SDimitry Andric     response.PutChar('F');
626*0b57cec5SDimitry Andric     response.PutHex64(Size);
627*0b57cec5SDimitry Andric     if (Size == UINT64_MAX) {
628*0b57cec5SDimitry Andric       response.PutChar(',');
629*0b57cec5SDimitry Andric       response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode()
630*0b57cec5SDimitry Andric     }
631*0b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
632*0b57cec5SDimitry Andric   }
633*0b57cec5SDimitry Andric   return SendErrorResponse(22);
634*0b57cec5SDimitry Andric }
635*0b57cec5SDimitry Andric 
636*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
637*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
638*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
639*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:mode:"));
640*0b57cec5SDimitry Andric   std::string path;
641*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
642*0b57cec5SDimitry Andric   if (!path.empty()) {
643*0b57cec5SDimitry Andric     FileSpec file_spec(path);
644*0b57cec5SDimitry Andric     FileSystem::Instance().Resolve(file_spec);
645*0b57cec5SDimitry Andric     std::error_code ec;
646*0b57cec5SDimitry Andric     const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);
647*0b57cec5SDimitry Andric     StreamString response;
648*0b57cec5SDimitry Andric     response.Printf("F%u", mode);
649*0b57cec5SDimitry Andric     if (mode == 0 || ec)
650*0b57cec5SDimitry Andric       response.Printf(",%i", (int)Status(ec).GetError());
651*0b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
652*0b57cec5SDimitry Andric   }
653*0b57cec5SDimitry Andric   return SendErrorResponse(23);
654*0b57cec5SDimitry Andric }
655*0b57cec5SDimitry Andric 
656*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
657*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(
658*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
659*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:exists:"));
660*0b57cec5SDimitry Andric   std::string path;
661*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
662*0b57cec5SDimitry Andric   if (!path.empty()) {
663*0b57cec5SDimitry Andric     bool retcode = llvm::sys::fs::exists(path);
664*0b57cec5SDimitry Andric     StreamString response;
665*0b57cec5SDimitry Andric     response.PutChar('F');
666*0b57cec5SDimitry Andric     response.PutChar(',');
667*0b57cec5SDimitry Andric     if (retcode)
668*0b57cec5SDimitry Andric       response.PutChar('1');
669*0b57cec5SDimitry Andric     else
670*0b57cec5SDimitry Andric       response.PutChar('0');
671*0b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
672*0b57cec5SDimitry Andric   }
673*0b57cec5SDimitry Andric   return SendErrorResponse(24);
674*0b57cec5SDimitry Andric }
675*0b57cec5SDimitry Andric 
676*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
677*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
678*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
679*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:symlink:"));
680*0b57cec5SDimitry Andric   std::string dst, src;
681*0b57cec5SDimitry Andric   packet.GetHexByteStringTerminatedBy(dst, ',');
682*0b57cec5SDimitry Andric   packet.GetChar(); // Skip ',' char
683*0b57cec5SDimitry Andric   packet.GetHexByteString(src);
684*0b57cec5SDimitry Andric 
685*0b57cec5SDimitry Andric   FileSpec src_spec(src);
686*0b57cec5SDimitry Andric   FileSystem::Instance().Resolve(src_spec);
687*0b57cec5SDimitry Andric   Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst));
688*0b57cec5SDimitry Andric 
689*0b57cec5SDimitry Andric   StreamString response;
690*0b57cec5SDimitry Andric   response.Printf("F%u,%u", error.GetError(), error.GetError());
691*0b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
692*0b57cec5SDimitry Andric }
693*0b57cec5SDimitry Andric 
694*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
695*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
696*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
697*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:unlink:"));
698*0b57cec5SDimitry Andric   std::string path;
699*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
700*0b57cec5SDimitry Andric   Status error(llvm::sys::fs::remove(path));
701*0b57cec5SDimitry Andric   StreamString response;
702*0b57cec5SDimitry Andric   response.Printf("F%u,%u", error.GetError(), error.GetError());
703*0b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
704*0b57cec5SDimitry Andric }
705*0b57cec5SDimitry Andric 
706*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
707*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
708*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
709*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qPlatform_shell:"));
710*0b57cec5SDimitry Andric   std::string path;
711*0b57cec5SDimitry Andric   std::string working_dir;
712*0b57cec5SDimitry Andric   packet.GetHexByteStringTerminatedBy(path, ',');
713*0b57cec5SDimitry Andric   if (!path.empty()) {
714*0b57cec5SDimitry Andric     if (packet.GetChar() == ',') {
715*0b57cec5SDimitry Andric       // FIXME: add timeout to qPlatform_shell packet
716*0b57cec5SDimitry Andric       // uint32_t timeout = packet.GetHexMaxU32(false, 32);
717*0b57cec5SDimitry Andric       if (packet.GetChar() == ',')
718*0b57cec5SDimitry Andric         packet.GetHexByteString(working_dir);
719*0b57cec5SDimitry Andric       int status, signo;
720*0b57cec5SDimitry Andric       std::string output;
721*0b57cec5SDimitry Andric       FileSpec working_spec(working_dir);
722*0b57cec5SDimitry Andric       FileSystem::Instance().Resolve(working_spec);
723*0b57cec5SDimitry Andric       Status err =
724*0b57cec5SDimitry Andric           Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,
725*0b57cec5SDimitry Andric                                 &output, std::chrono::seconds(10));
726*0b57cec5SDimitry Andric       StreamGDBRemote response;
727*0b57cec5SDimitry Andric       if (err.Fail()) {
728*0b57cec5SDimitry Andric         response.PutCString("F,");
729*0b57cec5SDimitry Andric         response.PutHex32(UINT32_MAX);
730*0b57cec5SDimitry Andric       } else {
731*0b57cec5SDimitry Andric         response.PutCString("F,");
732*0b57cec5SDimitry Andric         response.PutHex32(status);
733*0b57cec5SDimitry Andric         response.PutChar(',');
734*0b57cec5SDimitry Andric         response.PutHex32(signo);
735*0b57cec5SDimitry Andric         response.PutChar(',');
736*0b57cec5SDimitry Andric         response.PutEscapedBytes(output.c_str(), output.size());
737*0b57cec5SDimitry Andric       }
738*0b57cec5SDimitry Andric       return SendPacketNoLock(response.GetString());
739*0b57cec5SDimitry Andric     }
740*0b57cec5SDimitry Andric   }
741*0b57cec5SDimitry Andric   return SendErrorResponse(24);
742*0b57cec5SDimitry Andric }
743*0b57cec5SDimitry Andric 
744*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
745*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_Stat(
746*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
747*0b57cec5SDimitry Andric   return SendUnimplementedResponse(
748*0b57cec5SDimitry Andric       "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
749*0b57cec5SDimitry Andric }
750*0b57cec5SDimitry Andric 
751*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
752*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_vFile_MD5(
753*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
754*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vFile:MD5:"));
755*0b57cec5SDimitry Andric   std::string path;
756*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
757*0b57cec5SDimitry Andric   if (!path.empty()) {
758*0b57cec5SDimitry Andric     StreamGDBRemote response;
759*0b57cec5SDimitry Andric     auto Result = llvm::sys::fs::md5_contents(path);
760*0b57cec5SDimitry Andric     if (!Result) {
761*0b57cec5SDimitry Andric       response.PutCString("F,");
762*0b57cec5SDimitry Andric       response.PutCString("x");
763*0b57cec5SDimitry Andric     } else {
764*0b57cec5SDimitry Andric       response.PutCString("F,");
765*0b57cec5SDimitry Andric       response.PutHex64(Result->low());
766*0b57cec5SDimitry Andric       response.PutHex64(Result->high());
767*0b57cec5SDimitry Andric     }
768*0b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
769*0b57cec5SDimitry Andric   }
770*0b57cec5SDimitry Andric   return SendErrorResponse(25);
771*0b57cec5SDimitry Andric }
772*0b57cec5SDimitry Andric 
773*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
774*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(
775*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
776*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qPlatform_mkdir:"));
777*0b57cec5SDimitry Andric   mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
778*0b57cec5SDimitry Andric   if (packet.GetChar() == ',') {
779*0b57cec5SDimitry Andric     std::string path;
780*0b57cec5SDimitry Andric     packet.GetHexByteString(path);
781*0b57cec5SDimitry Andric     Status error(llvm::sys::fs::create_directory(path, mode));
782*0b57cec5SDimitry Andric 
783*0b57cec5SDimitry Andric     StreamGDBRemote response;
784*0b57cec5SDimitry Andric     response.Printf("F%u", error.GetError());
785*0b57cec5SDimitry Andric 
786*0b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
787*0b57cec5SDimitry Andric   }
788*0b57cec5SDimitry Andric   return SendErrorResponse(20);
789*0b57cec5SDimitry Andric }
790*0b57cec5SDimitry Andric 
791*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
792*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(
793*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
794*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qPlatform_chmod:"));
795*0b57cec5SDimitry Andric 
796*0b57cec5SDimitry Andric   auto perms =
797*0b57cec5SDimitry Andric       static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX));
798*0b57cec5SDimitry Andric   if (packet.GetChar() == ',') {
799*0b57cec5SDimitry Andric     std::string path;
800*0b57cec5SDimitry Andric     packet.GetHexByteString(path);
801*0b57cec5SDimitry Andric     Status error(llvm::sys::fs::setPermissions(path, perms));
802*0b57cec5SDimitry Andric 
803*0b57cec5SDimitry Andric     StreamGDBRemote response;
804*0b57cec5SDimitry Andric     response.Printf("F%u", error.GetError());
805*0b57cec5SDimitry Andric 
806*0b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
807*0b57cec5SDimitry Andric   }
808*0b57cec5SDimitry Andric   return SendErrorResponse(19);
809*0b57cec5SDimitry Andric }
810*0b57cec5SDimitry Andric 
811*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
812*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qSupported(
813*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
814*0b57cec5SDimitry Andric   StreamGDBRemote response;
815*0b57cec5SDimitry Andric 
816*0b57cec5SDimitry Andric   // Features common to lldb-platform and llgs.
817*0b57cec5SDimitry Andric   uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet
818*0b57cec5SDimitry Andric                                          // size--debugger can always use less
819*0b57cec5SDimitry Andric   response.Printf("PacketSize=%x", max_packet_size);
820*0b57cec5SDimitry Andric 
821*0b57cec5SDimitry Andric   response.PutCString(";QStartNoAckMode+");
822*0b57cec5SDimitry Andric   response.PutCString(";QThreadSuffixSupported+");
823*0b57cec5SDimitry Andric   response.PutCString(";QListThreadsInStopReply+");
824*0b57cec5SDimitry Andric   response.PutCString(";qEcho+");
825*0b57cec5SDimitry Andric #if defined(__linux__) || defined(__NetBSD__)
826*0b57cec5SDimitry Andric   response.PutCString(";QPassSignals+");
827*0b57cec5SDimitry Andric   response.PutCString(";qXfer:auxv:read+");
828*0b57cec5SDimitry Andric #endif
829*0b57cec5SDimitry Andric 
830*0b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
831*0b57cec5SDimitry Andric }
832*0b57cec5SDimitry Andric 
833*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
834*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported(
835*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
836*0b57cec5SDimitry Andric   m_thread_suffix_supported = true;
837*0b57cec5SDimitry Andric   return SendOKResponse();
838*0b57cec5SDimitry Andric }
839*0b57cec5SDimitry Andric 
840*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
841*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply(
842*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
843*0b57cec5SDimitry Andric   m_list_threads_in_stop_reply = true;
844*0b57cec5SDimitry Andric   return SendOKResponse();
845*0b57cec5SDimitry Andric }
846*0b57cec5SDimitry Andric 
847*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
848*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError(
849*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
850*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QSetDetachOnError:"));
851*0b57cec5SDimitry Andric   if (packet.GetU32(0))
852*0b57cec5SDimitry Andric     m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
853*0b57cec5SDimitry Andric   else
854*0b57cec5SDimitry Andric     m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
855*0b57cec5SDimitry Andric   return SendOKResponse();
856*0b57cec5SDimitry Andric }
857*0b57cec5SDimitry Andric 
858*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
859*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode(
860*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
861*0b57cec5SDimitry Andric   // Send response first before changing m_send_acks to we ack this packet
862*0b57cec5SDimitry Andric   PacketResult packet_result = SendOKResponse();
863*0b57cec5SDimitry Andric   m_send_acks = false;
864*0b57cec5SDimitry Andric   return packet_result;
865*0b57cec5SDimitry Andric }
866*0b57cec5SDimitry Andric 
867*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
868*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
869*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
870*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QSetSTDIN:"));
871*0b57cec5SDimitry Andric   FileAction file_action;
872*0b57cec5SDimitry Andric   std::string path;
873*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
874*0b57cec5SDimitry Andric   const bool read = true;
875*0b57cec5SDimitry Andric   const bool write = false;
876*0b57cec5SDimitry Andric   if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {
877*0b57cec5SDimitry Andric     m_process_launch_info.AppendFileAction(file_action);
878*0b57cec5SDimitry Andric     return SendOKResponse();
879*0b57cec5SDimitry Andric   }
880*0b57cec5SDimitry Andric   return SendErrorResponse(15);
881*0b57cec5SDimitry Andric }
882*0b57cec5SDimitry Andric 
883*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
884*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
885*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
886*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QSetSTDOUT:"));
887*0b57cec5SDimitry Andric   FileAction file_action;
888*0b57cec5SDimitry Andric   std::string path;
889*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
890*0b57cec5SDimitry Andric   const bool read = false;
891*0b57cec5SDimitry Andric   const bool write = true;
892*0b57cec5SDimitry Andric   if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {
893*0b57cec5SDimitry Andric     m_process_launch_info.AppendFileAction(file_action);
894*0b57cec5SDimitry Andric     return SendOKResponse();
895*0b57cec5SDimitry Andric   }
896*0b57cec5SDimitry Andric   return SendErrorResponse(16);
897*0b57cec5SDimitry Andric }
898*0b57cec5SDimitry Andric 
899*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
900*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
901*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
902*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QSetSTDERR:"));
903*0b57cec5SDimitry Andric   FileAction file_action;
904*0b57cec5SDimitry Andric   std::string path;
905*0b57cec5SDimitry Andric   packet.GetHexByteString(path);
906*0b57cec5SDimitry Andric   const bool read = false;
907*0b57cec5SDimitry Andric   const bool write = true;
908*0b57cec5SDimitry Andric   if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {
909*0b57cec5SDimitry Andric     m_process_launch_info.AppendFileAction(file_action);
910*0b57cec5SDimitry Andric     return SendOKResponse();
911*0b57cec5SDimitry Andric   }
912*0b57cec5SDimitry Andric   return SendErrorResponse(17);
913*0b57cec5SDimitry Andric }
914*0b57cec5SDimitry Andric 
915*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
916*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess(
917*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
918*0b57cec5SDimitry Andric   if (m_process_launch_error.Success())
919*0b57cec5SDimitry Andric     return SendOKResponse();
920*0b57cec5SDimitry Andric   StreamString response;
921*0b57cec5SDimitry Andric   response.PutChar('E');
922*0b57cec5SDimitry Andric   response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
923*0b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
924*0b57cec5SDimitry Andric }
925*0b57cec5SDimitry Andric 
926*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
927*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
928*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
929*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QEnvironment:"));
930*0b57cec5SDimitry Andric   const uint32_t bytes_left = packet.GetBytesLeft();
931*0b57cec5SDimitry Andric   if (bytes_left > 0) {
932*0b57cec5SDimitry Andric     m_process_launch_info.GetEnvironment().insert(packet.Peek());
933*0b57cec5SDimitry Andric     return SendOKResponse();
934*0b57cec5SDimitry Andric   }
935*0b57cec5SDimitry Andric   return SendErrorResponse(12);
936*0b57cec5SDimitry Andric }
937*0b57cec5SDimitry Andric 
938*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
939*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
940*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
941*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
942*0b57cec5SDimitry Andric   const uint32_t bytes_left = packet.GetBytesLeft();
943*0b57cec5SDimitry Andric   if (bytes_left > 0) {
944*0b57cec5SDimitry Andric     std::string str;
945*0b57cec5SDimitry Andric     packet.GetHexByteString(str);
946*0b57cec5SDimitry Andric     m_process_launch_info.GetEnvironment().insert(str);
947*0b57cec5SDimitry Andric     return SendOKResponse();
948*0b57cec5SDimitry Andric   }
949*0b57cec5SDimitry Andric   return SendErrorResponse(12);
950*0b57cec5SDimitry Andric }
951*0b57cec5SDimitry Andric 
952*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
953*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
954*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
955*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QLaunchArch:"));
956*0b57cec5SDimitry Andric   const uint32_t bytes_left = packet.GetBytesLeft();
957*0b57cec5SDimitry Andric   if (bytes_left > 0) {
958*0b57cec5SDimitry Andric     const char *arch_triple = packet.Peek();
959*0b57cec5SDimitry Andric     m_process_launch_info.SetArchitecture(
960*0b57cec5SDimitry Andric         HostInfo::GetAugmentedArchSpec(arch_triple));
961*0b57cec5SDimitry Andric     return SendOKResponse();
962*0b57cec5SDimitry Andric   }
963*0b57cec5SDimitry Andric   return SendErrorResponse(13);
964*0b57cec5SDimitry Andric }
965*0b57cec5SDimitry Andric 
966*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
967*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
968*0b57cec5SDimitry Andric   // The 'A' packet is the most over designed packet ever here with redundant
969*0b57cec5SDimitry Andric   // argument indexes, redundant argument lengths and needed hex encoded
970*0b57cec5SDimitry Andric   // argument string values. Really all that is needed is a comma separated hex
971*0b57cec5SDimitry Andric   // encoded argument value list, but we will stay true to the documented
972*0b57cec5SDimitry Andric   // version of the 'A' packet here...
973*0b57cec5SDimitry Andric 
974*0b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
975*0b57cec5SDimitry Andric   int actual_arg_index = 0;
976*0b57cec5SDimitry Andric 
977*0b57cec5SDimitry Andric   packet.SetFilePos(1); // Skip the 'A'
978*0b57cec5SDimitry Andric   bool success = true;
979*0b57cec5SDimitry Andric   while (success && packet.GetBytesLeft() > 0) {
980*0b57cec5SDimitry Andric     // Decode the decimal argument string length. This length is the number of
981*0b57cec5SDimitry Andric     // hex nibbles in the argument string value.
982*0b57cec5SDimitry Andric     const uint32_t arg_len = packet.GetU32(UINT32_MAX);
983*0b57cec5SDimitry Andric     if (arg_len == UINT32_MAX)
984*0b57cec5SDimitry Andric       success = false;
985*0b57cec5SDimitry Andric     else {
986*0b57cec5SDimitry Andric       // Make sure the argument hex string length is followed by a comma
987*0b57cec5SDimitry Andric       if (packet.GetChar() != ',')
988*0b57cec5SDimitry Andric         success = false;
989*0b57cec5SDimitry Andric       else {
990*0b57cec5SDimitry Andric         // Decode the argument index. We ignore this really because who would
991*0b57cec5SDimitry Andric         // really send down the arguments in a random order???
992*0b57cec5SDimitry Andric         const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
993*0b57cec5SDimitry Andric         if (arg_idx == UINT32_MAX)
994*0b57cec5SDimitry Andric           success = false;
995*0b57cec5SDimitry Andric         else {
996*0b57cec5SDimitry Andric           // Make sure the argument index is followed by a comma
997*0b57cec5SDimitry Andric           if (packet.GetChar() != ',')
998*0b57cec5SDimitry Andric             success = false;
999*0b57cec5SDimitry Andric           else {
1000*0b57cec5SDimitry Andric             // Decode the argument string value from hex bytes back into a UTF8
1001*0b57cec5SDimitry Andric             // string and make sure the length matches the one supplied in the
1002*0b57cec5SDimitry Andric             // packet
1003*0b57cec5SDimitry Andric             std::string arg;
1004*0b57cec5SDimitry Andric             if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
1005*0b57cec5SDimitry Andric                 (arg_len / 2))
1006*0b57cec5SDimitry Andric               success = false;
1007*0b57cec5SDimitry Andric             else {
1008*0b57cec5SDimitry Andric               // If there are any bytes left
1009*0b57cec5SDimitry Andric               if (packet.GetBytesLeft()) {
1010*0b57cec5SDimitry Andric                 if (packet.GetChar() != ',')
1011*0b57cec5SDimitry Andric                   success = false;
1012*0b57cec5SDimitry Andric               }
1013*0b57cec5SDimitry Andric 
1014*0b57cec5SDimitry Andric               if (success) {
1015*0b57cec5SDimitry Andric                 if (arg_idx == 0)
1016*0b57cec5SDimitry Andric                   m_process_launch_info.GetExecutableFile().SetFile(
1017*0b57cec5SDimitry Andric                       arg, FileSpec::Style::native);
1018*0b57cec5SDimitry Andric                 m_process_launch_info.GetArguments().AppendArgument(arg);
1019*0b57cec5SDimitry Andric                 if (log)
1020*0b57cec5SDimitry Andric                   log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
1021*0b57cec5SDimitry Andric                               __FUNCTION__, actual_arg_index, arg.c_str());
1022*0b57cec5SDimitry Andric                 ++actual_arg_index;
1023*0b57cec5SDimitry Andric               }
1024*0b57cec5SDimitry Andric             }
1025*0b57cec5SDimitry Andric           }
1026*0b57cec5SDimitry Andric         }
1027*0b57cec5SDimitry Andric       }
1028*0b57cec5SDimitry Andric     }
1029*0b57cec5SDimitry Andric   }
1030*0b57cec5SDimitry Andric 
1031*0b57cec5SDimitry Andric   if (success) {
1032*0b57cec5SDimitry Andric     m_process_launch_error = LaunchProcess();
1033*0b57cec5SDimitry Andric     if (m_process_launch_error.Success())
1034*0b57cec5SDimitry Andric       return SendOKResponse();
1035*0b57cec5SDimitry Andric     LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
1036*0b57cec5SDimitry Andric   }
1037*0b57cec5SDimitry Andric   return SendErrorResponse(8);
1038*0b57cec5SDimitry Andric }
1039*0b57cec5SDimitry Andric 
1040*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1041*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qEcho(
1042*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
1043*0b57cec5SDimitry Andric   // Just echo back the exact same packet for qEcho...
1044*0b57cec5SDimitry Andric   return SendPacketNoLock(packet.GetStringRef());
1045*0b57cec5SDimitry Andric }
1046*0b57cec5SDimitry Andric 
1047*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1048*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
1049*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
1050*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("qModuleInfo:"));
1051*0b57cec5SDimitry Andric 
1052*0b57cec5SDimitry Andric   std::string module_path;
1053*0b57cec5SDimitry Andric   packet.GetHexByteStringTerminatedBy(module_path, ';');
1054*0b57cec5SDimitry Andric   if (module_path.empty())
1055*0b57cec5SDimitry Andric     return SendErrorResponse(1);
1056*0b57cec5SDimitry Andric 
1057*0b57cec5SDimitry Andric   if (packet.GetChar() != ';')
1058*0b57cec5SDimitry Andric     return SendErrorResponse(2);
1059*0b57cec5SDimitry Andric 
1060*0b57cec5SDimitry Andric   std::string triple;
1061*0b57cec5SDimitry Andric   packet.GetHexByteString(triple);
1062*0b57cec5SDimitry Andric 
1063*0b57cec5SDimitry Andric   ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);
1064*0b57cec5SDimitry Andric   if (!matched_module_spec.GetFileSpec())
1065*0b57cec5SDimitry Andric     return SendErrorResponse(3);
1066*0b57cec5SDimitry Andric 
1067*0b57cec5SDimitry Andric   const auto file_offset = matched_module_spec.GetObjectOffset();
1068*0b57cec5SDimitry Andric   const auto file_size = matched_module_spec.GetObjectSize();
1069*0b57cec5SDimitry Andric   const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1070*0b57cec5SDimitry Andric 
1071*0b57cec5SDimitry Andric   StreamGDBRemote response;
1072*0b57cec5SDimitry Andric 
1073*0b57cec5SDimitry Andric   if (uuid_str.empty()) {
1074*0b57cec5SDimitry Andric     auto Result = llvm::sys::fs::md5_contents(
1075*0b57cec5SDimitry Andric         matched_module_spec.GetFileSpec().GetPath());
1076*0b57cec5SDimitry Andric     if (!Result)
1077*0b57cec5SDimitry Andric       return SendErrorResponse(5);
1078*0b57cec5SDimitry Andric     response.PutCString("md5:");
1079*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(Result->digest());
1080*0b57cec5SDimitry Andric   } else {
1081*0b57cec5SDimitry Andric     response.PutCString("uuid:");
1082*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(uuid_str);
1083*0b57cec5SDimitry Andric   }
1084*0b57cec5SDimitry Andric   response.PutChar(';');
1085*0b57cec5SDimitry Andric 
1086*0b57cec5SDimitry Andric   const auto &module_arch = matched_module_spec.GetArchitecture();
1087*0b57cec5SDimitry Andric   response.PutCString("triple:");
1088*0b57cec5SDimitry Andric   response.PutStringAsRawHex8(module_arch.GetTriple().getTriple());
1089*0b57cec5SDimitry Andric   response.PutChar(';');
1090*0b57cec5SDimitry Andric 
1091*0b57cec5SDimitry Andric   response.PutCString("file_path:");
1092*0b57cec5SDimitry Andric   response.PutStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString());
1093*0b57cec5SDimitry Andric   response.PutChar(';');
1094*0b57cec5SDimitry Andric   response.PutCString("file_offset:");
1095*0b57cec5SDimitry Andric   response.PutHex64(file_offset);
1096*0b57cec5SDimitry Andric   response.PutChar(';');
1097*0b57cec5SDimitry Andric   response.PutCString("file_size:");
1098*0b57cec5SDimitry Andric   response.PutHex64(file_size);
1099*0b57cec5SDimitry Andric   response.PutChar(';');
1100*0b57cec5SDimitry Andric 
1101*0b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
1102*0b57cec5SDimitry Andric }
1103*0b57cec5SDimitry Andric 
1104*0b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1105*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
1106*0b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
1107*0b57cec5SDimitry Andric   packet.SetFilePos(::strlen("jModulesInfo:"));
1108*0b57cec5SDimitry Andric 
1109*0b57cec5SDimitry Andric   StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());
1110*0b57cec5SDimitry Andric   if (!object_sp)
1111*0b57cec5SDimitry Andric     return SendErrorResponse(1);
1112*0b57cec5SDimitry Andric 
1113*0b57cec5SDimitry Andric   StructuredData::Array *packet_array = object_sp->GetAsArray();
1114*0b57cec5SDimitry Andric   if (!packet_array)
1115*0b57cec5SDimitry Andric     return SendErrorResponse(2);
1116*0b57cec5SDimitry Andric 
1117*0b57cec5SDimitry Andric   JSONArray::SP response_array_sp = std::make_shared<JSONArray>();
1118*0b57cec5SDimitry Andric   for (size_t i = 0; i < packet_array->GetSize(); ++i) {
1119*0b57cec5SDimitry Andric     StructuredData::Dictionary *query =
1120*0b57cec5SDimitry Andric         packet_array->GetItemAtIndex(i)->GetAsDictionary();
1121*0b57cec5SDimitry Andric     if (!query)
1122*0b57cec5SDimitry Andric       continue;
1123*0b57cec5SDimitry Andric     llvm::StringRef file, triple;
1124*0b57cec5SDimitry Andric     if (!query->GetValueForKeyAsString("file", file) ||
1125*0b57cec5SDimitry Andric         !query->GetValueForKeyAsString("triple", triple))
1126*0b57cec5SDimitry Andric       continue;
1127*0b57cec5SDimitry Andric 
1128*0b57cec5SDimitry Andric     ModuleSpec matched_module_spec = GetModuleInfo(file, triple);
1129*0b57cec5SDimitry Andric     if (!matched_module_spec.GetFileSpec())
1130*0b57cec5SDimitry Andric       continue;
1131*0b57cec5SDimitry Andric 
1132*0b57cec5SDimitry Andric     const auto file_offset = matched_module_spec.GetObjectOffset();
1133*0b57cec5SDimitry Andric     const auto file_size = matched_module_spec.GetObjectSize();
1134*0b57cec5SDimitry Andric     const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1135*0b57cec5SDimitry Andric 
1136*0b57cec5SDimitry Andric     if (uuid_str.empty())
1137*0b57cec5SDimitry Andric       continue;
1138*0b57cec5SDimitry Andric 
1139*0b57cec5SDimitry Andric     JSONObject::SP response = std::make_shared<JSONObject>();
1140*0b57cec5SDimitry Andric     response_array_sp->AppendObject(response);
1141*0b57cec5SDimitry Andric     response->SetObject("uuid", std::make_shared<JSONString>(uuid_str));
1142*0b57cec5SDimitry Andric     response->SetObject(
1143*0b57cec5SDimitry Andric         "triple",
1144*0b57cec5SDimitry Andric         std::make_shared<JSONString>(
1145*0b57cec5SDimitry Andric             matched_module_spec.GetArchitecture().GetTriple().getTriple()));
1146*0b57cec5SDimitry Andric     response->SetObject("file_path",
1147*0b57cec5SDimitry Andric                         std::make_shared<JSONString>(
1148*0b57cec5SDimitry Andric                             matched_module_spec.GetFileSpec().GetPath()));
1149*0b57cec5SDimitry Andric     response->SetObject("file_offset",
1150*0b57cec5SDimitry Andric                         std::make_shared<JSONNumber>(file_offset));
1151*0b57cec5SDimitry Andric     response->SetObject("file_size", std::make_shared<JSONNumber>(file_size));
1152*0b57cec5SDimitry Andric   }
1153*0b57cec5SDimitry Andric 
1154*0b57cec5SDimitry Andric   StreamString response;
1155*0b57cec5SDimitry Andric   response_array_sp->Write(response);
1156*0b57cec5SDimitry Andric   StreamGDBRemote escaped_response;
1157*0b57cec5SDimitry Andric   escaped_response.PutEscapedBytes(response.GetString().data(),
1158*0b57cec5SDimitry Andric                                    response.GetSize());
1159*0b57cec5SDimitry Andric   return SendPacketNoLock(escaped_response.GetString());
1160*0b57cec5SDimitry Andric }
1161*0b57cec5SDimitry Andric 
1162*0b57cec5SDimitry Andric void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
1163*0b57cec5SDimitry Andric     const ProcessInstanceInfo &proc_info, StreamString &response) {
1164*0b57cec5SDimitry Andric   response.Printf(
1165*0b57cec5SDimitry Andric       "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
1166*0b57cec5SDimitry Andric       proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1167*0b57cec5SDimitry Andric       proc_info.GetUserID(), proc_info.GetGroupID(),
1168*0b57cec5SDimitry Andric       proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
1169*0b57cec5SDimitry Andric   response.PutCString("name:");
1170*0b57cec5SDimitry Andric   response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
1171*0b57cec5SDimitry Andric   response.PutChar(';');
1172*0b57cec5SDimitry Andric   const ArchSpec &proc_arch = proc_info.GetArchitecture();
1173*0b57cec5SDimitry Andric   if (proc_arch.IsValid()) {
1174*0b57cec5SDimitry Andric     const llvm::Triple &proc_triple = proc_arch.GetTriple();
1175*0b57cec5SDimitry Andric     response.PutCString("triple:");
1176*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(proc_triple.getTriple());
1177*0b57cec5SDimitry Andric     response.PutChar(';');
1178*0b57cec5SDimitry Andric   }
1179*0b57cec5SDimitry Andric }
1180*0b57cec5SDimitry Andric 
1181*0b57cec5SDimitry Andric void GDBRemoteCommunicationServerCommon::
1182*0b57cec5SDimitry Andric     CreateProcessInfoResponse_DebugServerStyle(
1183*0b57cec5SDimitry Andric         const ProcessInstanceInfo &proc_info, StreamString &response) {
1184*0b57cec5SDimitry Andric   response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
1185*0b57cec5SDimitry Andric                   ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
1186*0b57cec5SDimitry Andric                   proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1187*0b57cec5SDimitry Andric                   proc_info.GetUserID(), proc_info.GetGroupID(),
1188*0b57cec5SDimitry Andric                   proc_info.GetEffectiveUserID(),
1189*0b57cec5SDimitry Andric                   proc_info.GetEffectiveGroupID());
1190*0b57cec5SDimitry Andric 
1191*0b57cec5SDimitry Andric   const ArchSpec &proc_arch = proc_info.GetArchitecture();
1192*0b57cec5SDimitry Andric   if (proc_arch.IsValid()) {
1193*0b57cec5SDimitry Andric     const llvm::Triple &proc_triple = proc_arch.GetTriple();
1194*0b57cec5SDimitry Andric #if defined(__APPLE__)
1195*0b57cec5SDimitry Andric     // We'll send cputype/cpusubtype.
1196*0b57cec5SDimitry Andric     const uint32_t cpu_type = proc_arch.GetMachOCPUType();
1197*0b57cec5SDimitry Andric     if (cpu_type != 0)
1198*0b57cec5SDimitry Andric       response.Printf("cputype:%" PRIx32 ";", cpu_type);
1199*0b57cec5SDimitry Andric 
1200*0b57cec5SDimitry Andric     const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
1201*0b57cec5SDimitry Andric     if (cpu_subtype != 0)
1202*0b57cec5SDimitry Andric       response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
1203*0b57cec5SDimitry Andric 
1204*0b57cec5SDimitry Andric     const std::string vendor = proc_triple.getVendorName();
1205*0b57cec5SDimitry Andric     if (!vendor.empty())
1206*0b57cec5SDimitry Andric       response.Printf("vendor:%s;", vendor.c_str());
1207*0b57cec5SDimitry Andric #else
1208*0b57cec5SDimitry Andric     // We'll send the triple.
1209*0b57cec5SDimitry Andric     response.PutCString("triple:");
1210*0b57cec5SDimitry Andric     response.PutStringAsRawHex8(proc_triple.getTriple());
1211*0b57cec5SDimitry Andric     response.PutChar(';');
1212*0b57cec5SDimitry Andric #endif
1213*0b57cec5SDimitry Andric     std::string ostype = proc_triple.getOSName();
1214*0b57cec5SDimitry Andric     // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
1215*0b57cec5SDimitry Andric     if (proc_triple.getVendor() == llvm::Triple::Apple) {
1216*0b57cec5SDimitry Andric       switch (proc_triple.getArch()) {
1217*0b57cec5SDimitry Andric       case llvm::Triple::arm:
1218*0b57cec5SDimitry Andric       case llvm::Triple::thumb:
1219*0b57cec5SDimitry Andric       case llvm::Triple::aarch64:
1220*0b57cec5SDimitry Andric         ostype = "ios";
1221*0b57cec5SDimitry Andric         break;
1222*0b57cec5SDimitry Andric       default:
1223*0b57cec5SDimitry Andric         // No change.
1224*0b57cec5SDimitry Andric         break;
1225*0b57cec5SDimitry Andric       }
1226*0b57cec5SDimitry Andric     }
1227*0b57cec5SDimitry Andric     response.Printf("ostype:%s;", ostype.c_str());
1228*0b57cec5SDimitry Andric 
1229*0b57cec5SDimitry Andric     switch (proc_arch.GetByteOrder()) {
1230*0b57cec5SDimitry Andric     case lldb::eByteOrderLittle:
1231*0b57cec5SDimitry Andric       response.PutCString("endian:little;");
1232*0b57cec5SDimitry Andric       break;
1233*0b57cec5SDimitry Andric     case lldb::eByteOrderBig:
1234*0b57cec5SDimitry Andric       response.PutCString("endian:big;");
1235*0b57cec5SDimitry Andric       break;
1236*0b57cec5SDimitry Andric     case lldb::eByteOrderPDP:
1237*0b57cec5SDimitry Andric       response.PutCString("endian:pdp;");
1238*0b57cec5SDimitry Andric       break;
1239*0b57cec5SDimitry Andric     default:
1240*0b57cec5SDimitry Andric       // Nothing.
1241*0b57cec5SDimitry Andric       break;
1242*0b57cec5SDimitry Andric     }
1243*0b57cec5SDimitry Andric     // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer
1244*0b57cec5SDimitry Andric     // size is 4 and for N64 it is 8
1245*0b57cec5SDimitry Andric     std::string abi = proc_arch.GetTargetABI();
1246*0b57cec5SDimitry Andric     if (!abi.empty())
1247*0b57cec5SDimitry Andric       response.Printf("elf_abi:%s;", abi.c_str());
1248*0b57cec5SDimitry Andric     response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
1249*0b57cec5SDimitry Andric   }
1250*0b57cec5SDimitry Andric }
1251*0b57cec5SDimitry Andric 
1252*0b57cec5SDimitry Andric FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
1253*0b57cec5SDimitry Andric     const std::string &module_path, const ArchSpec &arch) {
1254*0b57cec5SDimitry Andric #ifdef __ANDROID__
1255*0b57cec5SDimitry Andric   return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
1256*0b57cec5SDimitry Andric #else
1257*0b57cec5SDimitry Andric   FileSpec file_spec(module_path);
1258*0b57cec5SDimitry Andric   FileSystem::Instance().Resolve(file_spec);
1259*0b57cec5SDimitry Andric   return file_spec;
1260*0b57cec5SDimitry Andric #endif
1261*0b57cec5SDimitry Andric }
1262*0b57cec5SDimitry Andric 
1263*0b57cec5SDimitry Andric ModuleSpec
1264*0b57cec5SDimitry Andric GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path,
1265*0b57cec5SDimitry Andric                                                   llvm::StringRef triple) {
1266*0b57cec5SDimitry Andric   ArchSpec arch(triple);
1267*0b57cec5SDimitry Andric 
1268*0b57cec5SDimitry Andric   FileSpec req_module_path_spec(module_path);
1269*0b57cec5SDimitry Andric   FileSystem::Instance().Resolve(req_module_path_spec);
1270*0b57cec5SDimitry Andric 
1271*0b57cec5SDimitry Andric   const FileSpec module_path_spec =
1272*0b57cec5SDimitry Andric       FindModuleFile(req_module_path_spec.GetPath(), arch);
1273*0b57cec5SDimitry Andric   const ModuleSpec module_spec(module_path_spec, arch);
1274*0b57cec5SDimitry Andric 
1275*0b57cec5SDimitry Andric   ModuleSpecList module_specs;
1276*0b57cec5SDimitry Andric   if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0,
1277*0b57cec5SDimitry Andric                                            module_specs))
1278*0b57cec5SDimitry Andric     return ModuleSpec();
1279*0b57cec5SDimitry Andric 
1280*0b57cec5SDimitry Andric   ModuleSpec matched_module_spec;
1281*0b57cec5SDimitry Andric   if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
1282*0b57cec5SDimitry Andric     return ModuleSpec();
1283*0b57cec5SDimitry Andric 
1284*0b57cec5SDimitry Andric   return matched_module_spec;
1285*0b57cec5SDimitry Andric }
1286