blob: 1472b65b607752f5e639d2064db985bae06870d5 [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),
Tamas Berghammere13c2732015-02-11 10:29:30 +000061 m_process_launch_info (),
62 m_process_launch_error (),
63 m_proc_infos (),
64 m_proc_infos_index (0),
65 m_thread_suffix_supported (false),
66 m_list_threads_in_stop_reply (false)
67{
68 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
69 &GDBRemoteCommunicationServerCommon::Handle_A);
70 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironment,
71 &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
Chaoren Lin0ddb7222015-03-31 22:37:59 +000072 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
73 &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
Tamas Berghammere13c2732015-02-11 10:29:30 +000074 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);
Tamas Berghammere13c2732015-02-11 10:29:30 +000080 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
81 &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
82 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
83 &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
84 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
85 &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
Greg Clayton420562a2015-05-29 00:15:15 +000086 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qEcho,
87 &GDBRemoteCommunicationServerCommon::Handle_qEcho);
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
Omair Javaide68ee7f2015-08-18 08:28:06 +0000184 if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
185 host_arch.GetMachine() == llvm::Triple::aarch64_be ||
Omair Javaid2441aec2015-08-25 18:22:04 +0000186 host_arch.GetMachine() == llvm::Triple::arm ||
187 host_arch.GetMachine() == llvm::Triple::armeb ||
Omair Javaide68ee7f2015-08-18 08:28:06 +0000188 host_arch.GetMachine() == llvm::Triple::mips64 ||
Mohit K. Bhakkad5380a8b2015-10-14 05:42:11 +0000189 host_arch.GetMachine() == llvm::Triple::mips64el ||
190 host_arch.GetMachine() == llvm::Triple::mips ||
191 host_arch.GetMachine() == llvm::Triple::mipsel)
Mohit K. Bhakkad35799962015-06-18 04:53:18 +0000192 response.Printf("watchpoint_exceptions_received:before;");
193 else
194 response.Printf("watchpoint_exceptions_received:after;");
Tamas Berghammere13c2732015-02-11 10:29:30 +0000195#endif
196
Bruce Mitchener9ccb9702015-11-07 04:40:13 +0000197 switch (endian::InlHostByteOrder())
Tamas Berghammere13c2732015-02-11 10:29:30 +0000198 {
199 case eByteOrderBig: response.PutCString ("endian:big;"); break;
200 case eByteOrderLittle: response.PutCString ("endian:little;"); break;
201 case eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
202 default: response.PutCString ("endian:unknown;"); break;
203 }
204
205 uint32_t major = UINT32_MAX;
206 uint32_t minor = UINT32_MAX;
207 uint32_t update = UINT32_MAX;
208 if (HostInfo::GetOSVersion(major, minor, update))
209 {
210 if (major != UINT32_MAX)
211 {
212 response.Printf("os_version:%u", major);
213 if (minor != UINT32_MAX)
214 {
215 response.Printf(".%u", minor);
216 if (update != UINT32_MAX)
217 response.Printf(".%u", update);
218 }
219 response.PutChar(';');
220 }
221 }
222
223 std::string s;
224 if (HostInfo::GetOSBuildString(s))
225 {
226 response.PutCString ("os_build:");
227 response.PutCStringAsRawHex8(s.c_str());
228 response.PutChar(';');
229 }
230 if (HostInfo::GetOSKernelDescription(s))
231 {
232 response.PutCString ("os_kernel:");
233 response.PutCStringAsRawHex8(s.c_str());
234 response.PutChar(';');
235 }
236
237#if defined(__APPLE__)
238
239#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
240 // For iOS devices, we are connected through a USB Mux so we never pretend
241 // to actually have a hostname as far as the remote lldb that is connecting
242 // to this lldb-platform is concerned
243 response.PutCString ("hostname:");
244 response.PutCStringAsRawHex8("127.0.0.1");
245 response.PutChar(';');
246#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
247 if (HostInfo::GetHostname(s))
248 {
249 response.PutCString ("hostname:");
250 response.PutCStringAsRawHex8(s.c_str());
251 response.PutChar(';');
252 }
253#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
254
255#else // #if defined(__APPLE__)
256 if (HostInfo::GetHostname(s))
257 {
258 response.PutCString ("hostname:");
259 response.PutCStringAsRawHex8(s.c_str());
260 response.PutChar(';');
261 }
262#endif // #if defined(__APPLE__)
263
Tamas Berghammer2d52afd2015-02-26 11:37:21 +0000264 if (g_default_packet_timeout_sec > 0)
265 response.Printf ("default_packet_timeout:%u;", g_default_packet_timeout_sec);
266
Zachary Turner26709df2016-08-27 15:52:29 +0000267 return SendPacketNoLock (response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000268}
269
270GDBRemoteCommunication::PacketResult
271GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
272{
273 // Packet format: "qProcessInfoPID:%i" where %i is the pid
274 packet.SetFilePos (::strlen ("qProcessInfoPID:"));
275 lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
276 if (pid != LLDB_INVALID_PROCESS_ID)
277 {
278 ProcessInstanceInfo proc_info;
279 if (Host::GetProcessInfo (pid, proc_info))
280 {
281 StreamString response;
282 CreateProcessInfoResponse (proc_info, response);
Zachary Turner26709df2016-08-27 15:52:29 +0000283 return SendPacketNoLock (response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000284 }
285 }
286 return SendErrorResponse (1);
287}
288
289GDBRemoteCommunication::PacketResult
290GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
291{
292 m_proc_infos_index = 0;
293 m_proc_infos.Clear();
294
295 ProcessInstanceInfoMatch match_info;
296 packet.SetFilePos(::strlen ("qfProcessInfo"));
297 if (packet.GetChar() == ':')
298 {
299
300 std::string key;
301 std::string value;
302 while (packet.GetNameColonValue(key, value))
303 {
304 bool success = true;
305 if (key.compare("name") == 0)
306 {
307 StringExtractor extractor;
308 extractor.GetStringRef().swap(value);
309 extractor.GetHexByteString (value);
310 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false);
311 }
312 else if (key.compare("name_match") == 0)
313 {
314 if (value.compare("equals") == 0)
315 {
316 match_info.SetNameMatchType (eNameMatchEquals);
317 }
318 else if (value.compare("starts_with") == 0)
319 {
320 match_info.SetNameMatchType (eNameMatchStartsWith);
321 }
322 else if (value.compare("ends_with") == 0)
323 {
324 match_info.SetNameMatchType (eNameMatchEndsWith);
325 }
326 else if (value.compare("contains") == 0)
327 {
328 match_info.SetNameMatchType (eNameMatchContains);
329 }
330 else if (value.compare("regex") == 0)
331 {
332 match_info.SetNameMatchType (eNameMatchRegularExpression);
333 }
334 else
335 {
336 success = false;
337 }
338 }
339 else if (key.compare("pid") == 0)
340 {
341 match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
342 }
343 else if (key.compare("parent_pid") == 0)
344 {
345 match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
346 }
347 else if (key.compare("uid") == 0)
348 {
349 match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
350 }
351 else if (key.compare("gid") == 0)
352 {
353 match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
354 }
355 else if (key.compare("euid") == 0)
356 {
357 match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
358 }
359 else if (key.compare("egid") == 0)
360 {
361 match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
362 }
363 else if (key.compare("all_users") == 0)
364 {
365 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
366 }
367 else if (key.compare("triple") == 0)
368 {
369 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL);
370 }
371 else
372 {
373 success = false;
374 }
375
376 if (!success)
377 return SendErrorResponse (2);
378 }
379 }
380
381 if (Host::FindProcesses (match_info, m_proc_infos))
382 {
383 // We found something, return the first item by calling the get
384 // subsequent process info packet handler...
385 return Handle_qsProcessInfo (packet);
386 }
387 return SendErrorResponse (3);
388}
389
390GDBRemoteCommunication::PacketResult
391GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
392{
393 if (m_proc_infos_index < m_proc_infos.GetSize())
394 {
395 StreamString response;
396 CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
397 ++m_proc_infos_index;
Zachary Turner26709df2016-08-27 15:52:29 +0000398 return SendPacketNoLock (response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000399 }
400 return SendErrorResponse (4);
401}
402
403GDBRemoteCommunication::PacketResult
404GDBRemoteCommunicationServerCommon::Handle_qUserName (StringExtractorGDBRemote &packet)
405{
406#if !defined(LLDB_DISABLE_POSIX)
Vince Harron8b335672015-05-12 01:10:56 +0000407 Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
408 if (log)
409 log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
410
Tamas Berghammere13c2732015-02-11 10:29:30 +0000411 // Packet format: "qUserName:%i" where %i is the uid
412 packet.SetFilePos(::strlen ("qUserName:"));
413 uint32_t uid = packet.GetU32 (UINT32_MAX);
414 if (uid != UINT32_MAX)
415 {
416 std::string name;
417 if (HostInfo::LookupUserName(uid, name))
418 {
419 StreamString response;
420 response.PutCStringAsRawHex8 (name.c_str());
421 return SendPacketNoLock (response.GetData(), response.GetSize());
422 }
423 }
Vince Harron8b335672015-05-12 01:10:56 +0000424 if (log)
425 log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
Tamas Berghammere13c2732015-02-11 10:29:30 +0000426#endif
427 return SendErrorResponse (5);
428
429}
430
431GDBRemoteCommunication::PacketResult
432GDBRemoteCommunicationServerCommon::Handle_qGroupName (StringExtractorGDBRemote &packet)
433{
434#if !defined(LLDB_DISABLE_POSIX)
435 // Packet format: "qGroupName:%i" where %i is the gid
436 packet.SetFilePos(::strlen ("qGroupName:"));
437 uint32_t gid = packet.GetU32 (UINT32_MAX);
438 if (gid != UINT32_MAX)
439 {
440 std::string name;
441 if (HostInfo::LookupGroupName(gid, name))
442 {
443 StreamString response;
444 response.PutCStringAsRawHex8 (name.c_str());
445 return SendPacketNoLock (response.GetData(), response.GetSize());
446 }
447 }
448#endif
449 return SendErrorResponse (6);
450}
451
452GDBRemoteCommunication::PacketResult
453GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
454{
455 packet.SetFilePos(::strlen ("qSpeedTest:"));
456
457 std::string key;
458 std::string value;
459 bool success = packet.GetNameColonValue(key, value);
460 if (success && key.compare("response_size") == 0)
461 {
462 uint32_t response_size = StringConvert::ToUInt32(value.c_str(), 0, 0, &success);
463 if (success)
464 {
465 if (response_size == 0)
466 return SendOKResponse();
467 StreamString response;
468 uint32_t bytes_left = response_size;
469 response.PutCString("data:");
470 while (bytes_left > 0)
471 {
472 if (bytes_left >= 26)
473 {
474 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
475 bytes_left -= 26;
476 }
477 else
478 {
479 response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
480 bytes_left = 0;
481 }
482 }
Zachary Turner26709df2016-08-27 15:52:29 +0000483 return SendPacketNoLock (response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000484 }
485 }
486 return SendErrorResponse (7);
487}
488
489GDBRemoteCommunication::PacketResult
Tamas Berghammere13c2732015-02-11 10:29:30 +0000490GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote &packet)
491{
492 packet.SetFilePos(::strlen("vFile:open:"));
493 std::string path;
494 packet.GetHexByteStringTerminatedBy(path,',');
495 if (!path.empty())
496 {
497 if (packet.GetChar() == ',')
498 {
Robert Flackebc56092015-03-18 13:55:48 +0000499 uint32_t flags = File::ConvertOpenOptionsForPOSIXOpen(
500 packet.GetHexMaxU32(false, 0));
Tamas Berghammere13c2732015-02-11 10:29:30 +0000501 if (packet.GetChar() == ',')
502 {
503 mode_t mode = packet.GetHexMaxU32(false, 0600);
504 Error error;
Chaoren Lind3173f32015-05-29 19:52:29 +0000505 const FileSpec path_spec{path, true};
506 int fd = ::open(path_spec.GetCString(), flags, mode);
Tamas Berghammere13c2732015-02-11 10:29:30 +0000507 const int save_errno = fd == -1 ? errno : 0;
508 StreamString response;
509 response.PutChar('F');
510 response.Printf("%i", fd);
511 if (save_errno)
512 response.Printf(",%i", save_errno);
Zachary Turner26709df2016-08-27 15:52:29 +0000513 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000514 }
515 }
516 }
517 return SendErrorResponse(18);
518}
519
520GDBRemoteCommunication::PacketResult
521GDBRemoteCommunicationServerCommon::Handle_vFile_Close (StringExtractorGDBRemote &packet)
522{
523 packet.SetFilePos(::strlen("vFile:close:"));
524 int fd = packet.GetS32(-1);
525 Error error;
526 int err = -1;
527 int save_errno = 0;
528 if (fd >= 0)
529 {
530 err = close(fd);
531 save_errno = err == -1 ? errno : 0;
532 }
533 else
534 {
535 save_errno = EINVAL;
536 }
537 StreamString response;
538 response.PutChar('F');
539 response.Printf("%i", err);
540 if (save_errno)
541 response.Printf(",%i", save_errno);
Zachary Turner26709df2016-08-27 15:52:29 +0000542 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000543}
544
545GDBRemoteCommunication::PacketResult
546GDBRemoteCommunicationServerCommon::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
547{
548#ifdef _WIN32
549 // Not implemented on Windows
550 return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
551#else
552 StreamGDBRemote response;
553 packet.SetFilePos(::strlen("vFile:pread:"));
554 int fd = packet.GetS32(-1);
555 if (packet.GetChar() == ',')
556 {
557 uint64_t count = packet.GetU64(UINT64_MAX);
558 if (packet.GetChar() == ',')
559 {
560 uint64_t offset = packet.GetU64(UINT32_MAX);
561 if (count == UINT64_MAX)
562 {
563 response.Printf("F-1:%i", EINVAL);
564 return SendPacketNoLock(response.GetData(), response.GetSize());
565 }
566
567 std::string buffer(count, 0);
568 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
569 const int save_errno = bytes_read == -1 ? errno : 0;
570 response.PutChar('F');
571 response.Printf("%zi", bytes_read);
572 if (save_errno)
573 response.Printf(",%i", save_errno);
574 else
575 {
576 response.PutChar(';');
577 response.PutEscapedBytes(&buffer[0], bytes_read);
578 }
579 return SendPacketNoLock(response.GetData(), response.GetSize());
580 }
581 }
582 return SendErrorResponse(21);
583
584#endif
585}
586
587GDBRemoteCommunication::PacketResult
588GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
589{
590#ifdef _WIN32
591 return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite() unimplemented");
592#else
593 packet.SetFilePos(::strlen("vFile:pwrite:"));
594
595 StreamGDBRemote response;
596 response.PutChar('F');
597
598 int fd = packet.GetU32(UINT32_MAX);
599 if (packet.GetChar() == ',')
600 {
601 off_t offset = packet.GetU64(UINT32_MAX);
602 if (packet.GetChar() == ',')
603 {
604 std::string buffer;
605 if (packet.GetEscapedBinaryData(buffer))
606 {
607 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset);
608 const int save_errno = bytes_written == -1 ? errno : 0;
609 response.Printf("%zi", bytes_written);
610 if (save_errno)
611 response.Printf(",%i", save_errno);
612 }
613 else
614 {
615 response.Printf ("-1,%i", EINVAL);
616 }
617 return SendPacketNoLock(response.GetData(), response.GetSize());
618 }
619 }
620 return SendErrorResponse(27);
621#endif
622}
623
624GDBRemoteCommunication::PacketResult
625GDBRemoteCommunicationServerCommon::Handle_vFile_Size (StringExtractorGDBRemote &packet)
626{
627 packet.SetFilePos(::strlen("vFile:size:"));
628 std::string path;
629 packet.GetHexByteString(path);
630 if (!path.empty())
631 {
632 lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path.c_str(), false));
633 StreamString response;
634 response.PutChar('F');
635 response.PutHex64(retcode);
636 if (retcode == UINT64_MAX)
637 {
638 response.PutChar(',');
639 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode()
640 }
Zachary Turner26709df2016-08-27 15:52:29 +0000641 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000642 }
643 return SendErrorResponse(22);
644}
645
646GDBRemoteCommunication::PacketResult
647GDBRemoteCommunicationServerCommon::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
648{
649 packet.SetFilePos(::strlen("vFile:mode:"));
650 std::string path;
651 packet.GetHexByteString(path);
652 if (!path.empty())
653 {
654 Error error;
Chaoren Lind3173f32015-05-29 19:52:29 +0000655 const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
Tamas Berghammere13c2732015-02-11 10:29:30 +0000656 StreamString response;
657 response.Printf("F%u", mode);
658 if (mode == 0 || error.Fail())
659 response.Printf(",%i", (int)error.GetError());
Zachary Turner26709df2016-08-27 15:52:29 +0000660 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000661 }
662 return SendErrorResponse(23);
663}
664
665GDBRemoteCommunication::PacketResult
666GDBRemoteCommunicationServerCommon::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
667{
668 packet.SetFilePos(::strlen("vFile:exists:"));
669 std::string path;
670 packet.GetHexByteString(path);
671 if (!path.empty())
672 {
673 bool retcode = FileSystem::GetFileExists(FileSpec(path.c_str(), false));
674 StreamString response;
675 response.PutChar('F');
676 response.PutChar(',');
677 if (retcode)
678 response.PutChar('1');
679 else
680 response.PutChar('0');
Zachary Turner26709df2016-08-27 15:52:29 +0000681 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000682 }
683 return SendErrorResponse(24);
684}
685
686GDBRemoteCommunication::PacketResult
687GDBRemoteCommunicationServerCommon::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
688{
689 packet.SetFilePos(::strlen("vFile:symlink:"));
690 std::string dst, src;
691 packet.GetHexByteStringTerminatedBy(dst, ',');
692 packet.GetChar(); // Skip ',' char
693 packet.GetHexByteString(src);
Chaoren Lind3173f32015-05-29 19:52:29 +0000694 Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
Tamas Berghammere13c2732015-02-11 10:29:30 +0000695 StreamString response;
696 response.Printf("F%u,%u", error.GetError(), error.GetError());
Zachary Turner26709df2016-08-27 15:52:29 +0000697 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000698}
699
700GDBRemoteCommunication::PacketResult
701GDBRemoteCommunicationServerCommon::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
702{
703 packet.SetFilePos(::strlen("vFile:unlink:"));
704 std::string path;
705 packet.GetHexByteString(path);
Chaoren Lind3173f32015-05-29 19:52:29 +0000706 Error error = FileSystem::Unlink(FileSpec{path, true});
Tamas Berghammere13c2732015-02-11 10:29:30 +0000707 StreamString response;
708 response.Printf("F%u,%u", error.GetError(), error.GetError());
Zachary Turner26709df2016-08-27 15:52:29 +0000709 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000710}
711
712GDBRemoteCommunication::PacketResult
713GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
714{
715 packet.SetFilePos(::strlen("qPlatform_shell:"));
716 std::string path;
717 std::string working_dir;
718 packet.GetHexByteStringTerminatedBy(path,',');
719 if (!path.empty())
720 {
721 if (packet.GetChar() == ',')
722 {
723 // FIXME: add timeout to qPlatform_shell packet
724 // uint32_t timeout = packet.GetHexMaxU32(false, 32);
725 uint32_t timeout = 10;
726 if (packet.GetChar() == ',')
727 packet.GetHexByteString(working_dir);
728 int status, signo;
729 std::string output;
730 Error err = Host::RunShellCommand(path.c_str(),
Chaoren Lind3173f32015-05-29 19:52:29 +0000731 FileSpec{working_dir, true},
Tamas Berghammere13c2732015-02-11 10:29:30 +0000732 &status, &signo, &output, timeout);
733 StreamGDBRemote response;
734 if (err.Fail())
735 {
736 response.PutCString("F,");
737 response.PutHex32(UINT32_MAX);
738 }
739 else
740 {
741 response.PutCString("F,");
742 response.PutHex32(status);
743 response.PutChar(',');
744 response.PutHex32(signo);
745 response.PutChar(',');
746 response.PutEscapedBytes(output.c_str(), output.size());
747 }
Zachary Turner26709df2016-08-27 15:52:29 +0000748 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000749 }
750 }
751 return SendErrorResponse(24);
752}
753
754
755GDBRemoteCommunication::PacketResult
756GDBRemoteCommunicationServerCommon::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
757{
758 return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
759}
760
761GDBRemoteCommunication::PacketResult
762GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
763{
764 packet.SetFilePos(::strlen("vFile:MD5:"));
765 std::string path;
766 packet.GetHexByteString(path);
767 if (!path.empty())
768 {
769 uint64_t a,b;
770 StreamGDBRemote response;
Oleksiy Vyalov6801be32015-02-25 22:15:44 +0000771 if (!FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b))
Tamas Berghammere13c2732015-02-11 10:29:30 +0000772 {
773 response.PutCString("F,");
774 response.PutCString("x");
775 }
776 else
777 {
778 response.PutCString("F,");
779 response.PutHex64(a);
780 response.PutHex64(b);
781 }
Zachary Turner26709df2016-08-27 15:52:29 +0000782 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000783 }
784 return SendErrorResponse(25);
785}
786
787GDBRemoteCommunication::PacketResult
788GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
789{
790 packet.SetFilePos(::strlen("qPlatform_mkdir:"));
791 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
792 if (packet.GetChar() == ',')
793 {
794 std::string path;
795 packet.GetHexByteString(path);
Chaoren Lind3173f32015-05-29 19:52:29 +0000796 Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
797
Tamas Berghammer0f86b742015-02-23 11:03:08 +0000798 StreamGDBRemote response;
799 response.Printf("F%u", error.GetError());
800
Zachary Turner26709df2016-08-27 15:52:29 +0000801 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000802 }
803 return SendErrorResponse(20);
804}
805
806GDBRemoteCommunication::PacketResult
807GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
808{
809 packet.SetFilePos(::strlen("qPlatform_chmod:"));
810
811 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
812 if (packet.GetChar() == ',')
813 {
814 std::string path;
815 packet.GetHexByteString(path);
Chaoren Lind3173f32015-05-29 19:52:29 +0000816 Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
Tamas Berghammer0f86b742015-02-23 11:03:08 +0000817
818 StreamGDBRemote response;
819 response.Printf("F%u", error.GetError());
820
Zachary Turner26709df2016-08-27 15:52:29 +0000821 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000822 }
823 return SendErrorResponse(19);
824}
825
826GDBRemoteCommunication::PacketResult
827GDBRemoteCommunicationServerCommon::Handle_qSupported (StringExtractorGDBRemote &packet)
828{
829 StreamGDBRemote response;
830
831 // Features common to lldb-platform and llgs.
832 uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less
833 response.Printf ("PacketSize=%x", max_packet_size);
834
835 response.PutCString (";QStartNoAckMode+");
836 response.PutCString (";QThreadSuffixSupported+");
837 response.PutCString (";QListThreadsInStopReply+");
Ying Chen53406832015-05-29 01:02:07 +0000838 response.PutCString (";qEcho+");
Tamas Berghammere13c2732015-02-11 10:29:30 +0000839#if defined(__linux__)
840 response.PutCString (";qXfer:auxv:read+");
841#endif
842
Zachary Turner26709df2016-08-27 15:52:29 +0000843 return SendPacketNoLock(response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000844}
845
846GDBRemoteCommunication::PacketResult
847GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet)
848{
849 m_thread_suffix_supported = true;
850 return SendOKResponse();
851}
852
853GDBRemoteCommunication::PacketResult
854GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet)
855{
856 m_list_threads_in_stop_reply = true;
857 return SendOKResponse();
858}
859
860GDBRemoteCommunication::PacketResult
861GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError (StringExtractorGDBRemote &packet)
862{
863 packet.SetFilePos(::strlen ("QSetDetachOnError:"));
864 if (packet.GetU32(0))
865 m_process_launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
866 else
867 m_process_launch_info.GetFlags().Clear (eLaunchFlagDetachOnError);
868 return SendOKResponse ();
869}
870
871GDBRemoteCommunication::PacketResult
872GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
873{
874 // Send response first before changing m_send_acks to we ack this packet
875 PacketResult packet_result = SendOKResponse ();
876 m_send_acks = false;
877 return packet_result;
878}
879
880GDBRemoteCommunication::PacketResult
881GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
882{
883 packet.SetFilePos(::strlen ("QSetSTDIN:"));
884 FileAction file_action;
885 std::string path;
886 packet.GetHexByteString(path);
Pavel Labath5ad891f2016-07-21 14:54:03 +0000887 const bool read = true;
888 const bool write = false;
Chaoren Lind3173f32015-05-29 19:52:29 +0000889 if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write))
Tamas Berghammere13c2732015-02-11 10:29:30 +0000890 {
891 m_process_launch_info.AppendFileAction(file_action);
892 return SendOKResponse ();
893 }
894 return SendErrorResponse (15);
895}
896
897GDBRemoteCommunication::PacketResult
898GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
899{
900 packet.SetFilePos(::strlen ("QSetSTDOUT:"));
901 FileAction file_action;
902 std::string path;
903 packet.GetHexByteString(path);
Pavel Labath5ad891f2016-07-21 14:54:03 +0000904 const bool read = false;
905 const bool write = true;
Chaoren Lind3173f32015-05-29 19:52:29 +0000906 if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write))
Tamas Berghammere13c2732015-02-11 10:29:30 +0000907 {
908 m_process_launch_info.AppendFileAction(file_action);
909 return SendOKResponse ();
910 }
911 return SendErrorResponse (16);
912}
913
914GDBRemoteCommunication::PacketResult
915GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
916{
917 packet.SetFilePos(::strlen ("QSetSTDERR:"));
918 FileAction file_action;
919 std::string path;
920 packet.GetHexByteString(path);
Pavel Labath5ad891f2016-07-21 14:54:03 +0000921 const bool read = false;
922 const bool write = true;
Chaoren Lind3173f32015-05-29 19:52:29 +0000923 if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write))
Tamas Berghammere13c2732015-02-11 10:29:30 +0000924 {
925 m_process_launch_info.AppendFileAction(file_action);
926 return SendOKResponse ();
927 }
928 return SendErrorResponse (17);
929}
930
931GDBRemoteCommunication::PacketResult
932GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
933{
934 if (m_process_launch_error.Success())
935 return SendOKResponse();
936 StreamString response;
937 response.PutChar('E');
938 response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
Zachary Turner26709df2016-08-27 15:52:29 +0000939 return SendPacketNoLock (response.GetString());
Tamas Berghammere13c2732015-02-11 10:29:30 +0000940}
941
942GDBRemoteCommunication::PacketResult
943GDBRemoteCommunicationServerCommon::Handle_QEnvironment (StringExtractorGDBRemote &packet)
944{
945 packet.SetFilePos(::strlen ("QEnvironment:"));
946 const uint32_t bytes_left = packet.GetBytesLeft();
947 if (bytes_left > 0)
948 {
949 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
950 return SendOKResponse ();
951 }
952 return SendErrorResponse (12);
953}
954
955GDBRemoteCommunication::PacketResult
Chaoren Lin0ddb7222015-03-31 22:37:59 +0000956GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet)
957{
958 packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
959 const uint32_t bytes_left = packet.GetBytesLeft();
960 if (bytes_left > 0)
961 {
962 std::string str;
963 packet.GetHexByteString(str);
964 m_process_launch_info.GetEnvironmentEntries().AppendArgument(str.c_str());
965 return SendOKResponse();
966 }
967 return SendErrorResponse(12);
968}
969
970GDBRemoteCommunication::PacketResult
Tamas Berghammere13c2732015-02-11 10:29:30 +0000971GDBRemoteCommunicationServerCommon::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
972{
973 packet.SetFilePos(::strlen ("QLaunchArch:"));
974 const uint32_t bytes_left = packet.GetBytesLeft();
975 if (bytes_left > 0)
976 {
977 const char* arch_triple = packet.Peek();
978 ArchSpec arch_spec(arch_triple,NULL);
979 m_process_launch_info.SetArchitecture(arch_spec);
980 return SendOKResponse();
981 }
982 return SendErrorResponse(13);
983}
984
985GDBRemoteCommunication::PacketResult
986GDBRemoteCommunicationServerCommon::Handle_A (StringExtractorGDBRemote &packet)
987{
988 // The 'A' packet is the most over designed packet ever here with
989 // redundant argument indexes, redundant argument lengths and needed hex
990 // encoded argument string values. Really all that is needed is a comma
991 // separated hex encoded argument value list, but we will stay true to the
992 // documented version of the 'A' packet here...
993
994 Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
995 int actual_arg_index = 0;
996
997 packet.SetFilePos(1); // Skip the 'A'
998 bool success = true;
999 while (success && packet.GetBytesLeft() > 0)
1000 {
1001 // Decode the decimal argument string length. This length is the
1002 // number of hex nibbles in the argument string value.
1003 const uint32_t arg_len = packet.GetU32(UINT32_MAX);
1004 if (arg_len == UINT32_MAX)
1005 success = false;
1006 else
1007 {
1008 // Make sure the argument hex string length is followed by a comma
1009 if (packet.GetChar() != ',')
1010 success = false;
1011 else
1012 {
1013 // Decode the argument index. We ignore this really because
1014 // who would really send down the arguments in a random order???
1015 const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
1016 if (arg_idx == UINT32_MAX)
1017 success = false;
1018 else
1019 {
1020 // Make sure the argument index is followed by a comma
1021 if (packet.GetChar() != ',')
1022 success = false;
1023 else
1024 {
1025 // Decode the argument string value from hex bytes
1026 // back into a UTF8 string and make sure the length
1027 // matches the one supplied in the packet
1028 std::string arg;
1029 if (packet.GetHexByteStringFixedLength(arg, arg_len) != (arg_len / 2))
1030 success = false;
1031 else
1032 {
1033 // If there are any bytes left
1034 if (packet.GetBytesLeft())
1035 {
1036 if (packet.GetChar() != ',')
1037 success = false;
1038 }
1039
1040 if (success)
1041 {
1042 if (arg_idx == 0)
1043 m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
1044 m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
1045 if (log)
1046 log->Printf ("LLGSPacketHandler::%s added arg %d: \"%s\"", __FUNCTION__, actual_arg_index, arg.c_str ());
1047 ++actual_arg_index;
1048 }
1049 }
1050 }
1051 }
1052 }
1053 }
1054 }
1055
1056 if (success)
1057 {
1058 m_process_launch_error = LaunchProcess ();
1059 if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1060 {
1061 return SendOKResponse ();
1062 }
1063 else
1064 {
1065 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
1066 if (log)
1067 log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
1068 __FUNCTION__,
1069 m_process_launch_error.AsCString());
1070
1071 }
1072 }
1073 return SendErrorResponse (8);
1074}
1075
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001076GDBRemoteCommunication::PacketResult
Greg Clayton420562a2015-05-29 00:15:15 +00001077GDBRemoteCommunicationServerCommon::Handle_qEcho (StringExtractorGDBRemote &packet)
1078{
1079 // Just echo back the exact same packet for qEcho...
Zachary Turner26709df2016-08-27 15:52:29 +00001080 return SendPacketNoLock(packet.GetStringRef());
Greg Clayton420562a2015-05-29 00:15:15 +00001081}
1082
1083GDBRemoteCommunication::PacketResult
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001084GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote &packet)
1085{
1086 packet.SetFilePos(::strlen ("qModuleInfo:"));
1087
1088 std::string module_path;
1089 packet.GetHexByteStringTerminatedBy(module_path, ';');
1090 if (module_path.empty())
1091 return SendErrorResponse (1);
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001092
1093 if (packet.GetChar() != ';')
1094 return SendErrorResponse (2);
1095
1096 std::string triple;
1097 packet.GetHexByteString(triple);
Tamas Berghammerdad4db72015-03-13 11:16:08 +00001098 ArchSpec arch(triple.c_str());
1099
Oleksiy Vyalov7d9d9412015-04-16 07:02:56 +00001100 const FileSpec req_module_path_spec(module_path.c_str(), true);
1101 const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch);
Tamas Berghammerdad4db72015-03-13 11:16:08 +00001102 const ModuleSpec module_spec(module_path_spec, arch);
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001103
1104 ModuleSpecList module_specs;
1105 if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs))
1106 return SendErrorResponse (3);
1107
1108 ModuleSpec matched_module_spec;
1109 if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
1110 return SendErrorResponse (4);
1111
Oleksiy Vyalov63acdfd2015-03-10 01:15:28 +00001112 const auto file_offset = matched_module_spec.GetObjectOffset();
1113 const auto file_size = matched_module_spec.GetObjectSize();
1114 const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001115
1116 StreamGDBRemote response;
1117
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001118 if (uuid_str.empty())
1119 {
1120 std::string md5_hash;
Oleksiy Vyalov63acdfd2015-03-10 01:15:28 +00001121 if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), file_offset, file_size, md5_hash))
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001122 return SendErrorResponse (5);
1123 response.PutCString ("md5:");
1124 response.PutCStringAsRawHex8(md5_hash.c_str());
1125 }
1126 else{
1127 response.PutCString ("uuid:");
1128 response.PutCStringAsRawHex8(uuid_str.c_str());
1129 }
1130 response.PutChar(';');
1131
1132 const auto &module_arch = matched_module_spec.GetArchitecture();
1133 response.PutCString("triple:");
1134 response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str());
1135 response.PutChar(';');
1136
Tamas Berghammerdad4db72015-03-13 11:16:08 +00001137 response.PutCString("file_path:");
Chaoren Lind3173f32015-05-29 19:52:29 +00001138 response.PutCStringAsRawHex8(module_path_spec.GetCString());
Tamas Berghammerdad4db72015-03-13 11:16:08 +00001139 response.PutChar(';');
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001140 response.PutCString("file_offset:");
1141 response.PutHex64(file_offset);
1142 response.PutChar(';');
1143 response.PutCString("file_size:");
1144 response.PutHex64(file_size);
1145 response.PutChar(';');
1146
Zachary Turner26709df2016-08-27 15:52:29 +00001147 return SendPacketNoLock(response.GetString());
Oleksiy Vyalov6801be32015-02-25 22:15:44 +00001148}
1149
Tamas Berghammere13c2732015-02-11 10:29:30 +00001150void
1151GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
1152 StreamString &response)
1153{
1154 response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
1155 proc_info.GetProcessID(),
1156 proc_info.GetParentProcessID(),
1157 proc_info.GetUserID(),
1158 proc_info.GetGroupID(),
1159 proc_info.GetEffectiveUserID(),
1160 proc_info.GetEffectiveGroupID());
1161 response.PutCString ("name:");
Chaoren Lind3173f32015-05-29 19:52:29 +00001162 response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
Tamas Berghammere13c2732015-02-11 10:29:30 +00001163 response.PutChar(';');
1164 const ArchSpec &proc_arch = proc_info.GetArchitecture();
1165 if (proc_arch.IsValid())
1166 {
1167 const llvm::Triple &proc_triple = proc_arch.GetTriple();
1168 response.PutCString("triple:");
1169 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
1170 response.PutChar(';');
1171 }
1172}
1173
1174void
1175GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse_DebugServerStyle (
1176 const ProcessInstanceInfo &proc_info, StreamString &response)
1177{
1178 response.Printf ("pid:%" PRIx64 ";parent-pid:%" PRIx64 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
1179 proc_info.GetProcessID(),
1180 proc_info.GetParentProcessID(),
1181 proc_info.GetUserID(),
1182 proc_info.GetGroupID(),
1183 proc_info.GetEffectiveUserID(),
1184 proc_info.GetEffectiveGroupID());
1185
1186 const ArchSpec &proc_arch = proc_info.GetArchitecture();
1187 if (proc_arch.IsValid())
1188 {
1189 const llvm::Triple &proc_triple = proc_arch.GetTriple();
1190#if defined(__APPLE__)
1191 // We'll send cputype/cpusubtype.
1192 const uint32_t cpu_type = proc_arch.GetMachOCPUType();
1193 if (cpu_type != 0)
1194 response.Printf ("cputype:%" PRIx32 ";", cpu_type);
1195
1196 const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
1197 if (cpu_subtype != 0)
1198 response.Printf ("cpusubtype:%" PRIx32 ";", cpu_subtype);
1199
1200 const std::string vendor = proc_triple.getVendorName ();
1201 if (!vendor.empty ())
1202 response.Printf ("vendor:%s;", vendor.c_str ());
1203#else
1204 // We'll send the triple.
1205 response.PutCString("triple:");
1206 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
1207 response.PutChar(';');
1208#endif
1209 std::string ostype = proc_triple.getOSName ();
1210 // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
1211 if (proc_triple.getVendor () == llvm::Triple::Apple)
1212 {
1213 switch (proc_triple.getArch ())
1214 {
1215 case llvm::Triple::arm:
Jason Molenda6d9fe8c2015-08-21 00:13:37 +00001216 case llvm::Triple::thumb:
Tamas Berghammere13c2732015-02-11 10:29:30 +00001217 case llvm::Triple::aarch64:
1218 ostype = "ios";
1219 break;
1220 default:
1221 // No change.
1222 break;
1223 }
1224 }
1225 response.Printf ("ostype:%s;", ostype.c_str ());
1226
1227
1228 switch (proc_arch.GetByteOrder ())
1229 {
1230 case lldb::eByteOrderLittle: response.PutCString ("endian:little;"); break;
1231 case lldb::eByteOrderBig: response.PutCString ("endian:big;"); break;
1232 case lldb::eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
1233 default:
1234 // Nothing.
1235 break;
1236 }
1237
1238 if (proc_triple.isArch64Bit ())
1239 response.PutCString ("ptrsize:8;");
1240 else if (proc_triple.isArch32Bit ())
1241 response.PutCString ("ptrsize:4;");
1242 else if (proc_triple.isArch16Bit ())
1243 response.PutCString ("ptrsize:2;");
1244 }
1245}
Tamas Berghammer7cb18bf2015-03-24 11:15:23 +00001246
1247FileSpec
1248GDBRemoteCommunicationServerCommon::FindModuleFile(const std::string& module_path,
1249 const ArchSpec& arch)
1250{
1251#ifdef __ANDROID__
1252 return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
1253#else
1254 return FileSpec(module_path.c_str(), true);
1255#endif
1256}