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