LLDB mainline
GDBRemoteCommunicationServerCommon.cpp
Go to the documentation of this file.
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
10
11#include <cerrno>
12
13#ifdef __APPLE__
14#include <TargetConditionals.h>
15#endif
16
17#include <chrono>
18#include <cstring>
19#include <optional>
20
22#include "lldb/Host/Config.h"
23#include "lldb/Host/File.h"
26#include "lldb/Host/Host.h"
27#include "lldb/Host/HostInfo.h"
28#include "lldb/Host/SafeMachO.h"
32#include "lldb/Utility/Endian.h"
35#include "lldb/Utility/Log.h"
38#include "llvm/ADT/StringSwitch.h"
39#include "llvm/Support/JSON.h"
40#include "llvm/TargetParser/Triple.h"
41
42#include "ProcessGDBRemoteLog.h"
44
45#ifdef __ANDROID__
48#endif
49
50using namespace lldb;
52using namespace lldb_private;
53
54#ifdef __ANDROID__
55const static uint32_t g_default_packet_timeout_sec = 20; // seconds
56#else
57const static uint32_t g_default_packet_timeout_sec = 0; // not specified
58#endif
59
60// GDBRemoteCommunicationServerCommon constructor
174}
175
176// Destructor
178 default;
179
182 StringExtractorGDBRemote &packet) {
183 StreamString response;
184
185 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
186
187 ArchSpec host_arch(HostInfo::GetArchitecture());
188 const llvm::Triple &host_triple = host_arch.GetTriple();
189 response.PutCString("triple:");
190 response.PutStringAsRawHex8(host_triple.getTriple());
191 response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
192
193 llvm::StringRef distribution_id = HostInfo::GetDistributionId();
194 if (!distribution_id.empty()) {
195 response.PutCString("distribution_id:");
196 response.PutStringAsRawHex8(distribution_id);
197 response.PutCString(";");
198 }
199
200#if defined(__APPLE__)
201 // For parity with debugserver, we'll include the vendor key.
202 response.PutCString("vendor:apple;");
203
204 // Send out MachO info.
205 uint32_t cpu = host_arch.GetMachOCPUType();
206 uint32_t sub = host_arch.GetMachOCPUSubType();
207 if (cpu != LLDB_INVALID_CPUTYPE)
208 response.Printf("cputype:%u;", cpu);
209 if (sub != LLDB_INVALID_CPUTYPE)
210 response.Printf("cpusubtype:%u;", sub);
211
212 if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) {
213// Indicate the OS type.
214#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
215 response.PutCString("ostype:tvos;");
216#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
217 response.PutCString("ostype:watchos;");
218#elif defined(TARGET_OS_XR) && TARGET_OS_XR == 1
219 response.PutCString("ostype:xros;");
220#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
221 response.PutCString("ostype:bridgeos;");
222#else
223 response.PutCString("ostype:ios;");
224#endif
225
226 // On arm, we use "synchronous" watchpoints which means the exception is
227 // delivered before the instruction executes.
228 response.PutCString("watchpoint_exceptions_received:before;");
229 } else {
230 response.PutCString("ostype:macosx;");
231 response.Printf("watchpoint_exceptions_received:after;");
232 }
233
234#else
235 if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
236 host_arch.GetMachine() == llvm::Triple::aarch64_32 ||
237 host_arch.GetMachine() == llvm::Triple::aarch64_be ||
238 host_arch.GetMachine() == llvm::Triple::arm ||
239 host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS() ||
240 host_arch.GetTriple().isPPC64() || host_arch.GetTriple().isLoongArch())
241 response.Printf("watchpoint_exceptions_received:before;");
242 else
243 response.Printf("watchpoint_exceptions_received:after;");
244#endif
245
246 switch (endian::InlHostByteOrder()) {
247 case eByteOrderBig:
248 response.PutCString("endian:big;");
249 break;
250 case eByteOrderLittle:
251 response.PutCString("endian:little;");
252 break;
253 case eByteOrderPDP:
254 response.PutCString("endian:pdp;");
255 break;
256 default:
257 response.PutCString("endian:unknown;");
258 break;
259 }
260
261 llvm::VersionTuple version = HostInfo::GetOSVersion();
262 if (!version.empty()) {
263 response.Format("os_version:{0}", version.getAsString());
264 response.PutChar(';');
265 }
266
267#if defined(__APPLE__)
268 llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();
269 if (!maccatalyst_version.empty()) {
270 response.Format("maccatalyst_version:{0}",
271 maccatalyst_version.getAsString());
272 response.PutChar(';');
273 }
274#endif
275
276 if (std::optional<std::string> s = HostInfo::GetOSBuildString()) {
277 response.PutCString("os_build:");
278 response.PutStringAsRawHex8(*s);
279 response.PutChar(';');
280 }
281 if (std::optional<std::string> s = HostInfo::GetOSKernelDescription()) {
282 response.PutCString("os_kernel:");
283 response.PutStringAsRawHex8(*s);
284 response.PutChar(';');
285 }
286
287 std::string s;
288#if defined(__APPLE__)
289
290#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
291 // For iOS devices, we are connected through a USB Mux so we never pretend to
292 // actually have a hostname as far as the remote lldb that is connecting to
293 // this lldb-platform is concerned
294 response.PutCString("hostname:");
295 response.PutStringAsRawHex8("127.0.0.1");
296 response.PutChar(';');
297#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
298 if (HostInfo::GetHostname(s)) {
299 response.PutCString("hostname:");
300 response.PutStringAsRawHex8(s);
301 response.PutChar(';');
302 }
303#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
304
305#else // #if defined(__APPLE__)
306 if (HostInfo::GetHostname(s)) {
307 response.PutCString("hostname:");
308 response.PutStringAsRawHex8(s);
309 response.PutChar(';');
310 }
311#endif // #if defined(__APPLE__)
312 // coverity[unsigned_compare]
314 response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);
315
316 return SendPacketNoLock(response.GetString());
317}
318
321 StringExtractorGDBRemote &packet) {
322 // Packet format: "qProcessInfoPID:%i" where %i is the pid
323 packet.SetFilePos(::strlen("qProcessInfoPID:"));
325 if (pid != LLDB_INVALID_PROCESS_ID) {
326 ProcessInstanceInfo proc_info;
327 if (Host::GetProcessInfo(pid, proc_info)) {
328 StreamString response;
329 CreateProcessInfoResponse(proc_info, response);
330 return SendPacketNoLock(response.GetString());
331 }
332 }
333 return SendErrorResponse(1);
334}
335
338 StringExtractorGDBRemote &packet) {
340 m_proc_infos.clear();
341
342 ProcessInstanceInfoMatch match_info;
343 packet.SetFilePos(::strlen("qfProcessInfo"));
344 if (packet.GetChar() == ':') {
345 llvm::StringRef key;
346 llvm::StringRef value;
347 while (packet.GetNameColonValue(key, value)) {
348 bool success = true;
349 if (key == "name") {
350 StringExtractor extractor(value);
351 std::string file;
352 extractor.GetHexByteString(file);
354 file, FileSpec::Style::native);
355 } else if (key == "name_match") {
356 NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
357 .Case("equals", NameMatch::Equals)
358 .Case("starts_with", NameMatch::StartsWith)
359 .Case("ends_with", NameMatch::EndsWith)
360 .Case("contains", NameMatch::Contains)
361 .Case("regex", NameMatch::RegularExpression)
362 .Default(NameMatch::Ignore);
363 match_info.SetNameMatchType(name_match);
364 if (name_match == NameMatch::Ignore)
365 return SendErrorResponse(2);
366 } else if (key == "pid") {
368 if (value.getAsInteger(0, pid))
369 return SendErrorResponse(2);
370 match_info.GetProcessInfo().SetProcessID(pid);
371 } else if (key == "parent_pid") {
373 if (value.getAsInteger(0, pid))
374 return SendErrorResponse(2);
375 match_info.GetProcessInfo().SetParentProcessID(pid);
376 } else if (key == "uid") {
377 uint32_t uid = UINT32_MAX;
378 if (value.getAsInteger(0, uid))
379 return SendErrorResponse(2);
380 match_info.GetProcessInfo().SetUserID(uid);
381 } else if (key == "gid") {
382 uint32_t gid = UINT32_MAX;
383 if (value.getAsInteger(0, gid))
384 return SendErrorResponse(2);
385 match_info.GetProcessInfo().SetGroupID(gid);
386 } else if (key == "euid") {
387 uint32_t uid = UINT32_MAX;
388 if (value.getAsInteger(0, uid))
389 return SendErrorResponse(2);
390 match_info.GetProcessInfo().SetEffectiveUserID(uid);
391 } else if (key == "egid") {
392 uint32_t gid = UINT32_MAX;
393 if (value.getAsInteger(0, gid))
394 return SendErrorResponse(2);
395 match_info.GetProcessInfo().SetEffectiveGroupID(gid);
396 } else if (key == "all_users") {
397 match_info.SetMatchAllUsers(
398 OptionArgParser::ToBoolean(value, false, &success));
399 } else if (key == "triple") {
400 match_info.GetProcessInfo().GetArchitecture() =
401 HostInfo::GetAugmentedArchSpec(value);
402 } else {
403 success = false;
404 }
405
406 if (!success)
407 return SendErrorResponse(2);
408 }
409 }
410
411 if (Host::FindProcesses(match_info, m_proc_infos)) {
412 // We found something, return the first item by calling the get subsequent
413 // process info packet handler...
414 return Handle_qsProcessInfo(packet);
415 }
416 return SendErrorResponse(3);
417}
418
430
433 StringExtractorGDBRemote &packet) {
434#if LLDB_ENABLE_POSIX
436 LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
437
438 // Packet format: "qUserName:%i" where %i is the uid
439 packet.SetFilePos(::strlen("qUserName:"));
440 uint32_t uid = packet.GetU32(UINT32_MAX);
441 if (uid != UINT32_MAX) {
442 if (std::optional<llvm::StringRef> name =
443 HostInfo::GetUserIDResolver().GetUserName(uid)) {
444 StreamString response;
445 response.PutStringAsRawHex8(*name);
446 return SendPacketNoLock(response.GetString());
447 }
448 }
449 LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
450#endif
451 return SendErrorResponse(5);
452}
453
456 StringExtractorGDBRemote &packet) {
457#if LLDB_ENABLE_POSIX
458 // Packet format: "qGroupName:%i" where %i is the gid
459 packet.SetFilePos(::strlen("qGroupName:"));
460 uint32_t gid = packet.GetU32(UINT32_MAX);
461 if (gid != UINT32_MAX) {
462 if (std::optional<llvm::StringRef> name =
463 HostInfo::GetUserIDResolver().GetGroupName(gid)) {
464 StreamString response;
465 response.PutStringAsRawHex8(*name);
466 return SendPacketNoLock(response.GetString());
467 }
468 }
469#endif
470 return SendErrorResponse(6);
471}
472
475 StringExtractorGDBRemote &packet) {
476 packet.SetFilePos(::strlen("qSpeedTest:"));
477
478 llvm::StringRef key;
479 llvm::StringRef value;
480 bool success = packet.GetNameColonValue(key, value);
481 if (success && key == "response_size") {
482 uint32_t response_size = 0;
483 if (!value.getAsInteger(0, response_size)) {
484 if (response_size == 0)
485 return SendOKResponse();
486 StreamString response;
487 uint32_t bytes_left = response_size;
488 response.PutCString("data:");
489 while (bytes_left > 0) {
490 if (bytes_left >= 26) {
491 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
492 bytes_left -= 26;
493 } else {
494 response.Printf("%*.*s;", bytes_left, bytes_left,
495 "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
496 bytes_left = 0;
497 }
498 }
499 return SendPacketNoLock(response.GetString());
500 }
501 }
502 return SendErrorResponse(7);
503}
504
506 switch (err) {
507#define HANDLE_ERRNO(name, value) \
508 case name: \
509 return GDB_##name;
510#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
511 default:
512 return GDB_EUNKNOWN;
513 }
514}
515
518 StringExtractorGDBRemote &packet) {
519 packet.SetFilePos(::strlen("vFile:open:"));
520 std::string path;
521 packet.GetHexByteStringTerminatedBy(path, ',');
522 if (!path.empty()) {
523 if (packet.GetChar() == ',') {
524 auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0));
525 if (packet.GetChar() == ',') {
526 mode_t mode = packet.GetHexMaxU32(false, 0600);
527 FileSpec path_spec(path);
528 FileSystem::Instance().Resolve(path_spec);
529 // Do not close fd.
530 auto file = FileSystem::Instance().Open(path_spec, flags, mode, false);
531
532 StreamString response;
533 response.PutChar('F');
534
535 int descriptor = File::kInvalidDescriptor;
536 if (file) {
537 descriptor = file.get()->GetDescriptor();
538 response.Printf("%x", descriptor);
539 } else {
540 response.PutCString("-1");
541 std::error_code code = errorToErrorCode(file.takeError());
542 response.Printf(",%x", system_errno_to_gdb(code.value()));
543 }
544
545 return SendPacketNoLock(response.GetString());
546 }
547 }
548 }
549 return SendErrorResponse(18);
550}
551
554 StringExtractorGDBRemote &packet) {
555 packet.SetFilePos(::strlen("vFile:close:"));
556 int fd = packet.GetS32(-1, 16);
557 int err = -1;
558 int save_errno = 0;
559 if (fd >= 0) {
560 NativeFile file(fd, File::OpenOptions(0), true);
561 Status error = file.Close();
562 err = 0;
563 save_errno = error.GetError();
564 } else {
565 save_errno = EINVAL;
566 }
567 StreamString response;
568 response.PutChar('F');
569 response.Printf("%x", err);
570 if (save_errno)
571 response.Printf(",%x", system_errno_to_gdb(save_errno));
572 return SendPacketNoLock(response.GetString());
573}
574
577 StringExtractorGDBRemote &packet) {
578 StreamGDBRemote response;
579 packet.SetFilePos(::strlen("vFile:pread:"));
580 int fd = packet.GetS32(-1, 16);
581 if (packet.GetChar() == ',') {
582 size_t count = packet.GetHexMaxU64(false, SIZE_MAX);
583 if (packet.GetChar() == ',') {
584 off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
585 if (count == SIZE_MAX) {
586 response.Printf("F-1:%x", EINVAL);
587 return SendPacketNoLock(response.GetString());
588 }
589
590 std::string buffer(count, 0);
591 NativeFile file(fd, File::eOpenOptionReadOnly, false);
592 Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
593 const int save_errno = error.GetError();
594 response.PutChar('F');
595 if (error.Success()) {
596 response.Printf("%zx", count);
597 response.PutChar(';');
598 response.PutEscapedBytes(&buffer[0], count);
599 } else {
600 response.PutCString("-1");
601 if (save_errno)
602 response.Printf(",%x", system_errno_to_gdb(save_errno));
603 }
604 return SendPacketNoLock(response.GetString());
605 }
606 }
607 return SendErrorResponse(21);
608}
609
612 StringExtractorGDBRemote &packet) {
613 packet.SetFilePos(::strlen("vFile:pwrite:"));
614
615 StreamGDBRemote response;
616 response.PutChar('F');
617
618 int fd = packet.GetS32(-1, 16);
619 if (packet.GetChar() == ',') {
620 off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
621 if (packet.GetChar() == ',') {
622 std::string buffer;
623 if (packet.GetEscapedBinaryData(buffer)) {
624 NativeFile file(fd, File::eOpenOptionWriteOnly, false);
625 size_t count = buffer.size();
626 Status error =
627 file.Write(static_cast<const void *>(&buffer[0]), count, offset);
628 const int save_errno = error.GetError();
629 if (error.Success())
630 response.Printf("%zx", count);
631 else {
632 response.PutCString("-1");
633 if (save_errno)
634 response.Printf(",%x", system_errno_to_gdb(save_errno));
635 }
636 } else {
637 response.Printf("-1,%x", EINVAL);
638 }
639 return SendPacketNoLock(response.GetString());
640 }
641 }
642 return SendErrorResponse(27);
643}
644
647 StringExtractorGDBRemote &packet) {
648 packet.SetFilePos(::strlen("vFile:size:"));
649 std::string path;
650 packet.GetHexByteString(path);
651 if (!path.empty()) {
652 uint64_t Size;
653 if (llvm::sys::fs::file_size(path, Size))
654 return SendErrorResponse(5);
655 StreamString response;
656 response.PutChar('F');
657 response.PutHex64(Size);
658 if (Size == UINT64_MAX) {
659 response.PutChar(',');
660 response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode()
661 }
662 return SendPacketNoLock(response.GetString());
663 }
664 return SendErrorResponse(22);
665}
666
669 StringExtractorGDBRemote &packet) {
670 packet.SetFilePos(::strlen("vFile:mode:"));
671 std::string path;
672 packet.GetHexByteString(path);
673 if (!path.empty()) {
674 FileSpec file_spec(path);
675 FileSystem::Instance().Resolve(file_spec);
676 std::error_code ec;
677 const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);
678 StreamString response;
679 if (mode != llvm::sys::fs::perms_not_known)
680 response.Printf("F%x", mode);
681 else
682 response.Printf("F-1,%x", (int)Status(ec).GetError());
683 return SendPacketNoLock(response.GetString());
684 }
685 return SendErrorResponse(23);
686}
687
690 StringExtractorGDBRemote &packet) {
691 packet.SetFilePos(::strlen("vFile:exists:"));
692 std::string path;
693 packet.GetHexByteString(path);
694 if (!path.empty()) {
695 bool retcode = llvm::sys::fs::exists(path);
696 StreamString response;
697 response.PutChar('F');
698 response.PutChar(',');
699 if (retcode)
700 response.PutChar('1');
701 else
702 response.PutChar('0');
703 return SendPacketNoLock(response.GetString());
704 }
705 return SendErrorResponse(24);
706}
707
710 StringExtractorGDBRemote &packet) {
711 packet.SetFilePos(::strlen("vFile:symlink:"));
712 std::string dst, src;
713 packet.GetHexByteStringTerminatedBy(dst, ',');
714 packet.GetChar(); // Skip ',' char
715 packet.GetHexByteString(src);
716
717 FileSpec src_spec(src);
718 FileSystem::Instance().Resolve(src_spec);
720
721 StreamString response;
722 response.Printf("F%x,%x", error.GetError(), error.GetError());
723 return SendPacketNoLock(response.GetString());
724}
725
728 StringExtractorGDBRemote &packet) {
729 packet.SetFilePos(::strlen("vFile:unlink:"));
730 std::string path;
731 packet.GetHexByteString(path);
732 Status error(llvm::sys::fs::remove(path));
733 StreamString response;
734 response.Printf("F%x,%x", error.GetError(),
735 system_errno_to_gdb(error.GetError()));
736 return SendPacketNoLock(response.GetString());
737}
738
741 StringExtractorGDBRemote &packet) {
742 packet.SetFilePos(::strlen("qPlatform_shell:"));
743 std::string path;
744 std::string working_dir;
745 packet.GetHexByteStringTerminatedBy(path, ',');
746 if (!path.empty()) {
747 if (packet.GetChar() == ',') {
748 // FIXME: add timeout to qPlatform_shell packet
749 // uint32_t timeout = packet.GetHexMaxU32(false, 32);
750 if (packet.GetChar() == ',')
751 packet.GetHexByteString(working_dir);
752 int status, signo;
753 std::string output;
754 FileSpec working_spec(working_dir);
755 FileSystem::Instance().Resolve(working_spec);
756 Status err =
757 Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,
758 &output, nullptr, std::chrono::seconds(10));
759 StreamGDBRemote response;
760 if (err.Fail()) {
761 response.PutCString("F,");
762 response.PutHex32(UINT32_MAX);
763 } else {
764 response.PutCString("F,");
765 response.PutHex32(status);
766 response.PutChar(',');
767 response.PutHex32(signo);
768 response.PutChar(',');
769 response.PutEscapedBytes(output.c_str(), output.size());
770 }
771 return SendPacketNoLock(response.GetString());
772 }
773 }
774 return SendErrorResponse(24);
775}
776
777template <typename T, typename U>
778static void fill_clamp(T &dest, U src, typename T::value_type fallback) {
779 static_assert(std::is_unsigned<typename T::value_type>::value,
780 "Destination type must be unsigned.");
781 using UU = std::make_unsigned_t<U>;
782 constexpr auto T_max = std::numeric_limits<typename T::value_type>::max();
783 dest = src >= 0 && static_cast<UU>(src) <= T_max ? src : fallback;
784}
785
788 StringExtractorGDBRemote &packet) {
789 StreamGDBRemote response;
790 packet.SetFilePos(::strlen("vFile:fstat:"));
791 int fd = packet.GetS32(-1, 16);
792
793 struct stat file_stats;
794 if (::fstat(fd, &file_stats) == -1) {
795 const int save_errno = errno;
796 response.Printf("F-1,%x", system_errno_to_gdb(save_errno));
797 return SendPacketNoLock(response.GetString());
798 }
799
801 fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0);
802 fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0);
803 data.gdb_st_mode = file_stats.st_mode;
804 fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX);
805 fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0);
806 fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0);
807 fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0);
808 data.gdb_st_size = file_stats.st_size;
809#if !defined(_WIN32)
810 data.gdb_st_blksize = file_stats.st_blksize;
811 data.gdb_st_blocks = file_stats.st_blocks;
812#else
813 data.gdb_st_blksize = 0;
814 data.gdb_st_blocks = 0;
815#endif
816 fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0);
817 fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0);
818 fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0);
819
820 response.Printf("F%zx;", sizeof(data));
821 response.PutEscapedBytes(&data, sizeof(data));
822 return SendPacketNoLock(response.GetString());
823}
824
827 StringExtractorGDBRemote &packet) {
829 "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
830}
831
834 StringExtractorGDBRemote &packet) {
835 packet.SetFilePos(::strlen("vFile:MD5:"));
836 std::string path;
837 packet.GetHexByteString(path);
838 if (!path.empty()) {
839 StreamGDBRemote response;
840 auto Result = llvm::sys::fs::md5_contents(path);
841 if (!Result) {
842 response.PutCString("F,");
843 response.PutCString("x");
844 } else {
845 response.PutCString("F,");
846 response.PutHex64(Result->low());
847 response.PutHex64(Result->high());
848 }
849 return SendPacketNoLock(response.GetString());
850 }
851 return SendErrorResponse(25);
852}
853
856 StringExtractorGDBRemote &packet) {
857 packet.SetFilePos(::strlen("qPlatform_mkdir:"));
858 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
859 if (packet.GetChar() == ',') {
860 std::string path;
861 packet.GetHexByteString(path);
862 Status error(llvm::sys::fs::create_directory(path, mode));
863
864 StreamGDBRemote response;
865 response.Printf("F%x", error.GetError());
866
867 return SendPacketNoLock(response.GetString());
868 }
869 return SendErrorResponse(20);
870}
871
874 StringExtractorGDBRemote &packet) {
875 packet.SetFilePos(::strlen("qPlatform_chmod:"));
876
877 auto perms =
878 static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX));
879 if (packet.GetChar() == ',') {
880 std::string path;
881 packet.GetHexByteString(path);
882 Status error(llvm::sys::fs::setPermissions(path, perms));
883
884 StreamGDBRemote response;
885 response.Printf("F%x", error.GetError());
886
887 return SendPacketNoLock(response.GetString());
888 }
889 return SendErrorResponse(19);
890}
891
894 StringExtractorGDBRemote &packet) {
895 // Parse client-indicated features.
896 llvm::SmallVector<llvm::StringRef, 4> client_features;
897 packet.GetStringRef().split(client_features, ';');
898 return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";"));
899}
900
903 StringExtractorGDBRemote &packet) {
904 packet.SetFilePos(::strlen("QSetDetachOnError:"));
905 if (packet.GetU32(0))
906 m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
907 else
908 m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
909 return SendOKResponse();
910}
911
914 StringExtractorGDBRemote &packet) {
915 // Send response first before changing m_send_acks to we ack this packet
916 PacketResult packet_result = SendOKResponse();
917 m_send_acks = false;
918 return packet_result;
919}
920
923 StringExtractorGDBRemote &packet) {
924 packet.SetFilePos(::strlen("QSetSTDIN:"));
925 FileAction file_action;
926 std::string path;
927 packet.GetHexByteString(path);
928 const bool read = true;
929 const bool write = false;
930 if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {
931 m_process_launch_info.AppendFileAction(file_action);
932 return SendOKResponse();
933 }
934 return SendErrorResponse(15);
935}
936
939 StringExtractorGDBRemote &packet) {
940 packet.SetFilePos(::strlen("QSetSTDOUT:"));
941 FileAction file_action;
942 std::string path;
943 packet.GetHexByteString(path);
944 const bool read = false;
945 const bool write = true;
946 if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {
947 m_process_launch_info.AppendFileAction(file_action);
948 return SendOKResponse();
949 }
950 return SendErrorResponse(16);
951}
952
955 StringExtractorGDBRemote &packet) {
956 packet.SetFilePos(::strlen("QSetSTDERR:"));
957 FileAction file_action;
958 std::string path;
959 packet.GetHexByteString(path);
960 const bool read = false;
961 const bool write = true;
962 if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {
963 m_process_launch_info.AppendFileAction(file_action);
964 return SendOKResponse();
965 }
966 return SendErrorResponse(17);
967}
968
971 StringExtractorGDBRemote &packet) {
972 // Format: "QSetSTDIOWindowSize:cols=N;rows=N"
973 packet.SetFilePos(::strlen("QSetSTDIOWindowSize:"));
974 llvm::StringRef body = packet.GetStringRef().substr(packet.GetFilePos());
975
976 uint16_t cols = 0;
977 uint16_t rows = 0;
978 llvm::SmallVector<llvm::StringRef, 2> fields;
979 body.split(fields, ';');
980 for (llvm::StringRef field : fields) {
981 auto [key, value] = field.split('=');
982 uint16_t *dest;
983 if (key == "cols")
984 dest = &cols;
985 else if (key == "rows")
986 dest = &rows;
987 else
988 continue;
989 unsigned parsed = 0;
990 if (value.empty() || value.getAsInteger(10, parsed) || parsed > UINT16_MAX)
991 continue;
992 *dest = static_cast<uint16_t>(parsed);
993 }
994 // 0x0 is a valid request: it signals "no terminal" and a redirection
995 // backend that supports an alternative path (anonymous pipes on Windows
996 // ConPTY) can switch on it. Reject only the malformed cases.
997 if ((cols == 0) != (rows == 0))
998 return SendErrorResponse(28);
999
1000 m_process_launch_info.SetSTDIOWindowSize(cols, rows);
1001 return SendOKResponse();
1002}
1003
1006 StringExtractorGDBRemote &packet) {
1007 if (m_process_launch_error.Success())
1008 return SendOKResponse();
1009 StreamString response;
1010 response.PutChar('E');
1011 response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
1012 return SendPacketNoLock(response.GetString());
1013}
1014
1017 StringExtractorGDBRemote &packet) {
1018 packet.SetFilePos(::strlen("QEnvironment:"));
1019 const uint32_t bytes_left = packet.GetBytesLeft();
1020 if (bytes_left > 0) {
1021 m_process_launch_info.GetEnvironment().insert(packet.Peek());
1022 return SendOKResponse();
1023 }
1024 return SendErrorResponse(12);
1025}
1026
1029 StringExtractorGDBRemote &packet) {
1030 packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
1031 const uint32_t bytes_left = packet.GetBytesLeft();
1032 if (bytes_left > 0) {
1033 std::string str;
1034 packet.GetHexByteString(str);
1035 m_process_launch_info.GetEnvironment().insert(str);
1036 return SendOKResponse();
1037 }
1038 return SendErrorResponse(12);
1039}
1040
1043 StringExtractorGDBRemote &packet) {
1044 packet.SetFilePos(::strlen("QLaunchArch:"));
1045 const uint32_t bytes_left = packet.GetBytesLeft();
1046 if (bytes_left > 0) {
1047 const char *arch_triple = packet.Peek();
1048 m_process_launch_info.SetArchitecture(
1049 HostInfo::GetAugmentedArchSpec(arch_triple));
1050 return SendOKResponse();
1051 }
1052 return SendErrorResponse(13);
1053}
1054
1057 // The 'A' packet is the most over designed packet ever here with redundant
1058 // argument indexes, redundant argument lengths and needed hex encoded
1059 // argument string values. Really all that is needed is a comma separated hex
1060 // encoded argument value list, but we will stay true to the documented
1061 // version of the 'A' packet here...
1062
1063 Log *log = GetLog(LLDBLog::Process);
1064 int actual_arg_index = 0;
1065
1066 packet.SetFilePos(1); // Skip the 'A'
1067 bool success = true;
1068 while (success && packet.GetBytesLeft() > 0) {
1069 // Decode the decimal argument string length. This length is the number of
1070 // hex nibbles in the argument string value.
1071 const uint32_t arg_len = packet.GetU32(UINT32_MAX);
1072 if (arg_len == UINT32_MAX)
1073 success = false;
1074 else {
1075 // Make sure the argument hex string length is followed by a comma
1076 if (packet.GetChar() != ',')
1077 success = false;
1078 else {
1079 // Decode the argument index. We ignore this really because who would
1080 // really send down the arguments in a random order???
1081 const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
1082 if (arg_idx == UINT32_MAX)
1083 success = false;
1084 else {
1085 // Make sure the argument index is followed by a comma
1086 if (packet.GetChar() != ',')
1087 success = false;
1088 else {
1089 // Decode the argument string value from hex bytes back into a UTF8
1090 // string and make sure the length matches the one supplied in the
1091 // packet
1092 std::string arg;
1093 if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
1094 (arg_len / 2))
1095 success = false;
1096 else {
1097 // If there are any bytes left
1098 if (packet.GetBytesLeft()) {
1099 if (packet.GetChar() != ',')
1100 success = false;
1101 }
1102
1103 if (success) {
1104 if (arg_idx == 0)
1105 m_process_launch_info.GetExecutableFile().SetFile(
1106 arg, FileSpec::Style::native);
1107 m_process_launch_info.GetArguments().AppendArgument(arg);
1108 LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"",
1109 __FUNCTION__, actual_arg_index, arg.c_str());
1110 ++actual_arg_index;
1111 }
1112 }
1113 }
1114 }
1115 }
1116 }
1117 }
1118
1119 if (success) {
1121 if (m_process_launch_error.Success())
1122 return SendOKResponse();
1123 LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
1124 }
1125 return SendErrorResponse(8);
1126}
1127
1130 StringExtractorGDBRemote &packet) {
1131 // Just echo back the exact same packet for qEcho...
1132 return SendPacketNoLock(packet.GetStringRef());
1133}
1134
1137 StringExtractorGDBRemote &packet) {
1138 packet.SetFilePos(::strlen("qModuleInfo:"));
1139
1140 std::string module_path;
1141 packet.GetHexByteStringTerminatedBy(module_path, ';');
1142 if (module_path.empty())
1143 return SendErrorResponse(1);
1144
1145 if (packet.GetChar() != ';')
1146 return SendErrorResponse(2);
1147
1148 std::string triple;
1149 packet.GetHexByteString(triple);
1150
1151 ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);
1152 if (!matched_module_spec.GetFileSpec())
1153 return SendErrorResponse(3);
1154
1155 const auto file_offset = matched_module_spec.GetObjectOffset();
1156 const auto file_size = matched_module_spec.GetObjectSize();
1157 const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1158
1159 StreamGDBRemote response;
1160
1161 if (uuid_str.empty()) {
1162 auto Result = llvm::sys::fs::md5_contents(
1163 matched_module_spec.GetFileSpec().GetPath());
1164 if (!Result)
1165 return SendErrorResponse(5);
1166 response.PutCString("md5:");
1167 response.PutStringAsRawHex8(Result->digest());
1168 } else {
1169 response.PutCString("uuid:");
1170 response.PutStringAsRawHex8(uuid_str);
1171 }
1172 response.PutChar(';');
1173
1174 const auto &module_arch = matched_module_spec.GetArchitecture();
1175 response.PutCString("triple:");
1176 response.PutStringAsRawHex8(module_arch.GetTriple().getTriple());
1177 response.PutChar(';');
1178
1179 response.PutCString("file_path:");
1180 response.PutStringAsRawHex8(
1181 matched_module_spec.GetFileSpec().GetPath().c_str());
1182 response.PutChar(';');
1183 response.PutCString("file_offset:");
1184 response.PutHex64(file_offset);
1185 response.PutChar(';');
1186 response.PutCString("file_size:");
1187 response.PutHex64(file_size);
1188 response.PutChar(';');
1189
1190 return SendPacketNoLock(response.GetString());
1191}
1192
1195 StringExtractorGDBRemote &packet) {
1196 namespace json = llvm::json;
1197
1198 packet.SetFilePos(::strlen("jModulesInfo:"));
1199
1201 if (!object_sp)
1202 return SendErrorResponse(1);
1203
1204 StructuredData::Array *packet_array = object_sp->GetAsArray();
1205 if (!packet_array)
1206 return SendErrorResponse(2);
1207
1208 json::Array response_array;
1209 for (size_t i = 0; i < packet_array->GetSize(); ++i) {
1211 packet_array->GetItemAtIndex(i)->GetAsDictionary();
1212 if (!query)
1213 continue;
1214 llvm::StringRef file, triple;
1215 if (!query->GetValueForKeyAsString("file", file) ||
1216 !query->GetValueForKeyAsString("triple", triple))
1217 continue;
1218
1219 ModuleSpec matched_module_spec = GetModuleInfo(file, triple);
1220 if (!matched_module_spec.GetFileSpec())
1221 continue;
1222
1223 const auto file_offset = matched_module_spec.GetObjectOffset();
1224 const auto file_size = matched_module_spec.GetObjectSize();
1225 const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1226 if (uuid_str.empty())
1227 continue;
1228 const auto triple_str =
1229 matched_module_spec.GetArchitecture().GetTriple().getTriple();
1230 const auto file_path = matched_module_spec.GetFileSpec().GetPath();
1231
1232 json::Object response{{"uuid", uuid_str},
1233 {"triple", triple_str},
1234 {"file_path", file_path},
1235 {"file_offset", static_cast<int64_t>(file_offset)},
1236 {"file_size", static_cast<int64_t>(file_size)}};
1237 response_array.push_back(std::move(response));
1238 }
1239
1240 StreamString response;
1241 response.AsRawOstream() << std::move(response_array);
1242 StreamGDBRemote escaped_response;
1243 escaped_response.PutEscapedBytes(response.GetString().data(),
1244 response.GetSize());
1245 return SendPacketNoLock(escaped_response.GetString());
1246}
1247
1249 const ProcessInstanceInfo &proc_info, StreamString &response) {
1250 response.Printf(
1251 "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
1252 proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1253 proc_info.GetUserID(), proc_info.GetGroupID(),
1254 proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
1255 response.PutCString("name:");
1256 response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str());
1257
1258 response.PutChar(';');
1259 response.PutCString("args:");
1260 response.PutStringAsRawHex8(proc_info.GetArg0());
1261 for (auto &arg : proc_info.GetArguments()) {
1262 response.PutChar('-');
1263 response.PutStringAsRawHex8(arg.ref());
1264 }
1265
1266 response.PutChar(';');
1267 const ArchSpec &proc_arch = proc_info.GetArchitecture();
1268 if (proc_arch.IsValid()) {
1269 const llvm::Triple &proc_triple = proc_arch.GetTriple();
1270 response.PutCString("triple:");
1271 response.PutStringAsRawHex8(proc_triple.getTriple());
1272 response.PutChar(';');
1273 }
1274}
1275
1278 const ProcessInstanceInfo &proc_info, StreamString &response) {
1279 response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
1280 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
1281 proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1282 proc_info.GetUserID(), proc_info.GetGroupID(),
1283 proc_info.GetEffectiveUserID(),
1284 proc_info.GetEffectiveGroupID());
1285
1286 const ArchSpec &proc_arch = proc_info.GetArchitecture();
1287 if (proc_arch.IsValid()) {
1288 const llvm::Triple &proc_triple = proc_arch.GetTriple();
1289#if defined(__APPLE__)
1290 // We'll send cputype/cpusubtype.
1291 const uint32_t cpu_type = proc_arch.GetMachOCPUType();
1292 if (cpu_type != 0)
1293 response.Printf("cputype:%" PRIx32 ";", cpu_type);
1294
1295 const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
1296 if (cpu_subtype != 0)
1297 response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
1298
1299 const std::string vendor = proc_triple.getVendorName().str();
1300 if (!vendor.empty())
1301 response.Printf("vendor:%s;", vendor.c_str());
1302#else
1303 // We'll send the triple.
1304 response.PutCString("triple:");
1305 response.PutStringAsRawHex8(proc_triple.getTriple());
1306 response.PutChar(';');
1307#endif
1308 std::string ostype = std::string(proc_triple.getOSName());
1309 // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
1310 if (proc_triple.getVendor() == llvm::Triple::Apple) {
1311 switch (proc_triple.getArch()) {
1312 case llvm::Triple::arm:
1313 case llvm::Triple::thumb:
1314 case llvm::Triple::aarch64:
1315 case llvm::Triple::aarch64_32:
1316 ostype = "ios";
1317 break;
1318 default:
1319 // No change.
1320 break;
1321 }
1322 }
1323 response.Printf("ostype:%s;", ostype.c_str());
1324
1325 switch (proc_arch.GetByteOrder()) {
1327 response.PutCString("endian:little;");
1328 break;
1330 response.PutCString("endian:big;");
1331 break;
1333 response.PutCString("endian:pdp;");
1334 break;
1335 default:
1336 // Nothing.
1337 break;
1338 }
1339 // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer
1340 // size is 4 and for N64 it is 8
1341 std::string abi = proc_arch.GetTargetABI();
1342 if (!abi.empty())
1343 response.Printf("elf_abi:%s;", abi.c_str());
1344 response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
1345 }
1346}
1347
1349 const std::string &module_path, const ArchSpec &arch) {
1350#ifdef __ANDROID__
1351 return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
1352#else
1353 FileSpec file_spec(module_path);
1354 FileSystem::Instance().Resolve(file_spec);
1355 return file_spec;
1356#endif
1357}
1358
1361 llvm::StringRef triple) {
1362 ArchSpec arch(triple);
1363
1364 FileSpec req_module_path_spec(module_path);
1365 FileSystem::Instance().Resolve(req_module_path_spec);
1366
1367 const FileSpec module_path_spec =
1368 FindModuleFile(req_module_path_spec.GetPath(), arch);
1369
1370 lldb::offset_t file_offset = 0;
1371 lldb::offset_t file_size = 0;
1372#ifdef __ANDROID__
1373 // In Android API level 23 and above, dynamic loader is able to load .so file
1374 // directly from zip file. In that case, module_path will be
1375 // "zip_path!/so_path". Resolve the zip file path, .so file offset and size.
1377 std::string file_path;
1379 module_path_spec, file_kind, file_path, file_offset, file_size)) {
1380 return ModuleSpec();
1381 }
1383 // For zip .so file, this file_path will contain only the actual zip file
1384 // path for the object file processing. Otherwise it is the same as
1385 // module_path.
1386 const FileSpec actual_module_path_spec(file_path);
1387#else
1388 // It is just module_path_spec reference for other platforms.
1389 const FileSpec &actual_module_path_spec = module_path_spec;
1390#endif
1391
1392 const ModuleSpec module_spec(actual_module_path_spec, arch);
1393
1395 actual_module_path_spec, file_offset, file_size);
1396 if (module_specs.GetSize() == 0)
1397 return ModuleSpec();
1398
1399 ModuleSpec matched_module_spec;
1400 if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
1401 return ModuleSpec();
1402
1403#ifdef __ANDROID__
1404 if (file_kind == ZipFileResolver::eFileKindZip) {
1405 // For zip .so file, matched_module_spec contains only the actual zip file
1406 // path for the object file processing. Overwrite the matched_module_spec
1407 // file spec with the original module_path_spec to pass "zip_path!/so_path"
1408 // through to PlatformAndroid::DownloadModuleSlice.
1409 *matched_module_spec.GetFileSpecPtr() = module_path_spec;
1410 }
1411#endif
1412
1413 return matched_module_spec;
1414}
1415
1417 const llvm::ArrayRef<llvm::StringRef> client_features) {
1418 // 128 KiB is a reasonable max packet size--debugger can always use less.
1419 constexpr uint32_t max_packet_size = 128 * 1024;
1420
1421 // Features common to platform server and llgs.
1422 return {
1423 llvm::formatv("PacketSize={0}", max_packet_size),
1424 "QStartNoAckMode+",
1425 "qEcho+",
1426 "native-signals+",
1427 };
1428}
static llvm::raw_ostream & error(Stream &strm)
static const uint32_t g_default_packet_timeout_sec
static void fill_clamp(T &dest, U src, typename T::value_type fallback)
static GDBErrno system_errno_to_gdb(int err)
#define lldbassert(x)
Definition LLDBAssert.h:16
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:364
#define LLDB_LOGF(log,...)
Definition Log.h:378
size_t GetEscapedBinaryData(std::string &str)
void SetFilePos(uint32_t idx)
uint32_t GetHexMaxU32(bool little_endian, uint32_t fail_value)
uint64_t GetHexMaxU64(bool little_endian, uint64_t fail_value)
bool GetNameColonValue(llvm::StringRef &name, llvm::StringRef &value)
size_t GetHexByteString(std::string &str)
char GetChar(char fail_value='\0')
const char * Peek()
int32_t GetS32(int32_t fail_value, int base=0)
uint64_t GetFilePos() const
size_t GetHexByteStringTerminatedBy(std::string &str, char terminator)
llvm::StringRef GetStringRef() const
size_t GetHexByteStringFixedLength(std::string &str, uint32_t nibble_length)
uint32_t GetU32(uint32_t fail_value, int base=0)
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:690
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:370
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:460
uint32_t GetMachOCPUSubType() const
Definition ArchSpec.cpp:670
bool IsMIPS() const
if MIPS architecture return true.
Definition ArchSpec.cpp:564
uint32_t GetMachOCPUType() const
Definition ArchSpec.cpp:658
std::string GetTargetABI() const
Return a string representing target application ABI.
Definition ArchSpec.cpp:568
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:739
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:682
Represents a file descriptor action to be performed during process launch.
Definition FileAction.h:21
bool Open(int fd, const FileSpec &file_spec, bool read, bool write)
Configure this action to open a file.
A file utility class.
Definition FileSpec.h:57
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
Status Symlink(const FileSpec &src, const FileSpec &dst)
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
uint32_t GetPermissions(const FileSpec &file_spec) const
Return the current permissions of the given file.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
static int kInvalidDescriptor
Definition FileBase.h:36
static FileSpec ResolveLibraryPath(const std::string &path, const ArchSpec &arch)
static Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, std::string *error_output, const Timeout< std::micro > &timeout, bool run_in_shell=true)
Run a shell command.
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition aix/Host.cpp:211
static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
bool FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
Definition ModuleSpec.h:366
uint64_t GetObjectOffset() const
Definition ModuleSpec.h:111
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
FileSpec * GetFileSpecPtr()
Definition ModuleSpec.h:51
uint64_t GetObjectSize() const
Definition ModuleSpec.h:117
Status Close() override
Flush any buffers and release any resources owned by the file.
Definition File.cpp:303
Status Read(void *dst, size_t &num_bytes, off_t &offset) override
Read bytes from a file from the specified file offset.
Status Write(const void *src, size_t &num_bytes, off_t &offset) override
Write bytes to a file at the specified file offset.
static ModuleSpecList GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataExtractorSP=lldb::DataExtractorSP())
void SetGroupID(uint32_t gid)
Definition ProcessInfo.h:58
lldb::pid_t GetProcessID() const
Definition ProcessInfo.h:66
llvm::StringRef GetArg0() const
void SetProcessID(lldb::pid_t pid)
Definition ProcessInfo.h:68
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:41
uint32_t GetUserID() const
Definition ProcessInfo.h:48
uint32_t GetGroupID() const
Definition ProcessInfo.h:50
void SetUserID(uint32_t uid)
Definition ProcessInfo.h:56
ArchSpec & GetArchitecture()
Definition ProcessInfo.h:60
void SetNameMatchType(NameMatch name_match_type)
ProcessInstanceInfo & GetProcessInfo()
void SetEffectiveGroupID(uint32_t gid)
lldb::pid_t GetParentProcessID() const
void SetParentProcessID(lldb::pid_t pid)
void SetEffectiveUserID(uint32_t uid)
An error handling class.
Definition Status.h:118
bool Fail() const
Test for error condition.
Definition Status.cpp:293
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
Definition GDBRemote.cpp:31
llvm::StringRef GetString() const
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:405
size_t PutStringAsRawHex8(llvm::StringRef s)
Definition Stream.cpp:418
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:307
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t PutChar(char ch)
Definition Stream.cpp:131
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:291
ObjectSP GetItemAtIndex(size_t idx) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
static bool ResolveSharedLibraryPath(const FileSpec &file_spec, FileKind &file_kind, std::string &file_path, lldb::offset_t &so_file_offset, lldb::offset_t &so_file_size)
virtual Status LaunchProcess()=0
Launch a process with the current launch settings.
ModuleSpec GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple)
virtual FileSpec FindModuleFile(const std::string &module_path, const ArchSpec &arch)
void RegisterMemberFunctionHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketResult(T::*handler)(StringExtractorGDBRemote &packet))
static void CreateProcessInfoResponse_DebugServerStyle(const ProcessInstanceInfo &proc_info, StreamString &response)
virtual std::vector< std::string > HandleFeatures(llvm::ArrayRef< llvm::StringRef > client_features)
static void CreateProcessInfoResponse(const ProcessInstanceInfo &proc_info, StreamString &response)
#define UINT64_MAX
#define LLDB_INVALID_CPUTYPE
#define UINT32_MAX
#define LLDB_INVALID_PROCESS_ID
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:327
NativeFilePosix NativeFile
Definition File.h:29
uint64_t offset_t
Definition lldb-types.h:85
uint64_t pid_t
Definition lldb-types.h:83
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)