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