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