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