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