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(BASE_10, pid))
369 return SendErrorResponse(2);
370 match_info.GetProcessInfo().SetProcessID(pid);
371 } else if (key == "parent_pid") {
373 if (value.getAsInteger(BASE_10, 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(BASE_10, 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(BASE_10, 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(BASE_10, 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(BASE_10, 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(BASE_16, 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 = file.Write(buffer.data(), count, offset);
627 // A pipe cannot seek, so pwrite fails on it with ESPIPE. The offset
628 // means nothing there, so write at the pipe's end instead.
629 if (error.Fail() && error.GetError() == ESPIPE) {
630 count = buffer.size();
631 error = file.Write(buffer.data(), count);
632 }
633 const int save_errno = error.GetError();
634 if (error.Success())
635 response.Printf("%zx", count);
636 else {
637 response.PutCString("-1");
638 if (save_errno)
639 response.Printf(",%x", system_errno_to_gdb(save_errno));
640 }
641 } else {
642 response.Printf("-1,%x", EINVAL);
643 }
644 return SendPacketNoLock(response.GetString());
645 }
646 }
647 return SendErrorResponse(27);
648}
649
652 StringExtractorGDBRemote &packet) {
653 packet.SetFilePos(::strlen("vFile:size:"));
654 std::string path;
655 packet.GetHexByteString(path);
656 if (!path.empty()) {
657 uint64_t Size;
658 if (llvm::sys::fs::file_size(path, Size))
659 return SendErrorResponse(5);
660 StreamString response;
661 response.PutChar('F');
662 response.PutHex64(Size);
663 if (Size == UINT64_MAX) {
664 response.PutChar(',');
665 response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode()
666 }
667 return SendPacketNoLock(response.GetString());
668 }
669 return SendErrorResponse(22);
670}
671
674 StringExtractorGDBRemote &packet) {
675 packet.SetFilePos(::strlen("vFile:mode:"));
676 std::string path;
677 packet.GetHexByteString(path);
678 if (!path.empty()) {
679 FileSpec file_spec(path);
680 FileSystem::Instance().Resolve(file_spec);
681 std::error_code ec;
682 const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);
683 StreamString response;
684 if (mode != llvm::sys::fs::perms_not_known)
685 response.Printf("F%x", mode);
686 else
687 response.Printf("F-1,%x", (int)Status(ec).GetError());
688 return SendPacketNoLock(response.GetString());
689 }
690 return SendErrorResponse(23);
691}
692
695 StringExtractorGDBRemote &packet) {
696 packet.SetFilePos(::strlen("vFile:exists:"));
697 std::string path;
698 packet.GetHexByteString(path);
699 if (!path.empty()) {
700 bool retcode = llvm::sys::fs::exists(path);
701 StreamString response;
702 response.PutChar('F');
703 response.PutChar(',');
704 if (retcode)
705 response.PutChar('1');
706 else
707 response.PutChar('0');
708 return SendPacketNoLock(response.GetString());
709 }
710 return SendErrorResponse(24);
711}
712
715 StringExtractorGDBRemote &packet) {
716 packet.SetFilePos(::strlen("vFile:symlink:"));
717 std::string dst, src;
718 packet.GetHexByteStringTerminatedBy(dst, ',');
719 packet.GetChar(); // Skip ',' char
720 packet.GetHexByteString(src);
721
722 FileSpec src_spec(src);
723 FileSystem::Instance().Resolve(src_spec);
725
726 StreamString response;
727 response.Printf("F%x,%x", error.GetError(), error.GetError());
728 return SendPacketNoLock(response.GetString());
729}
730
733 StringExtractorGDBRemote &packet) {
734 packet.SetFilePos(::strlen("vFile:unlink:"));
735 std::string path;
736 packet.GetHexByteString(path);
737 Status error(llvm::sys::fs::remove(path));
738 StreamString response;
739 response.Printf("F%x,%x", error.GetError(),
740 system_errno_to_gdb(error.GetError()));
741 return SendPacketNoLock(response.GetString());
742}
743
746 StringExtractorGDBRemote &packet) {
747 packet.SetFilePos(::strlen("qPlatform_shell:"));
748 std::string path;
749 std::string working_dir;
750 packet.GetHexByteStringTerminatedBy(path, ',');
751 if (!path.empty()) {
752 if (packet.GetChar() == ',') {
753 // FIXME: add timeout to qPlatform_shell packet
754 // uint32_t timeout = packet.GetHexMaxU32(false, 32);
755 if (packet.GetChar() == ',')
756 packet.GetHexByteString(working_dir);
757 int status, signo;
758 std::string output;
759 FileSpec working_spec(working_dir);
760 FileSystem::Instance().Resolve(working_spec);
761 Status err =
762 Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,
763 &output, nullptr, std::chrono::seconds(10));
764 StreamGDBRemote response;
765 if (err.Fail()) {
766 response.PutCString("F,");
767 response.PutHex32(UINT32_MAX);
768 } else {
769 response.PutCString("F,");
770 response.PutHex32(status);
771 response.PutChar(',');
772 response.PutHex32(signo);
773 response.PutChar(',');
774 response.PutEscapedBytes(output.c_str(), output.size());
775 }
776 return SendPacketNoLock(response.GetString());
777 }
778 }
779 return SendErrorResponse(24);
780}
781
782template <typename T, typename U>
783static void fill_clamp(T &dest, U src, typename T::value_type fallback) {
784 static_assert(std::is_unsigned<typename T::value_type>::value,
785 "Destination type must be unsigned.");
786 using UU = std::make_unsigned_t<U>;
787 constexpr auto T_max = std::numeric_limits<typename T::value_type>::max();
788 dest = src >= 0 && static_cast<UU>(src) <= T_max ? src : fallback;
789}
790
793 StringExtractorGDBRemote &packet) {
794 StreamGDBRemote response;
795 packet.SetFilePos(::strlen("vFile:fstat:"));
796 int fd = packet.GetS32(-1, 16);
797
798 struct stat file_stats;
799 if (::fstat(fd, &file_stats) == -1) {
800 const int save_errno = errno;
801 response.Printf("F-1,%x", system_errno_to_gdb(save_errno));
802 return SendPacketNoLock(response.GetString());
803 }
804
806 fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0);
807 fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0);
808 data.gdb_st_mode = file_stats.st_mode;
809 fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX);
810 fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0);
811 fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0);
812 fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0);
813 data.gdb_st_size = file_stats.st_size;
814#if !defined(_WIN32)
815 data.gdb_st_blksize = file_stats.st_blksize;
816 data.gdb_st_blocks = file_stats.st_blocks;
817#else
818 data.gdb_st_blksize = 0;
819 data.gdb_st_blocks = 0;
820#endif
821 fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0);
822 fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0);
823 fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0);
824
825 response.Printf("F%zx;", sizeof(data));
826 response.PutEscapedBytes(&data, sizeof(data));
827 return SendPacketNoLock(response.GetString());
828}
829
832 StringExtractorGDBRemote &packet) {
834 "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
835}
836
839 StringExtractorGDBRemote &packet) {
840 packet.SetFilePos(::strlen("vFile:MD5:"));
841 std::string path;
842 packet.GetHexByteString(path);
843 if (!path.empty()) {
844 StreamGDBRemote response;
845 auto Result = llvm::sys::fs::md5_contents(path);
846 if (!Result) {
847 response.PutCString("F,");
848 response.PutCString("x");
849 } else {
850 response.PutCString("F,");
851 response.PutHex64(Result->low());
852 response.PutHex64(Result->high());
853 }
854 return SendPacketNoLock(response.GetString());
855 }
856 return SendErrorResponse(25);
857}
858
861 StringExtractorGDBRemote &packet) {
862 packet.SetFilePos(::strlen("qPlatform_mkdir:"));
863 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
864 if (packet.GetChar() == ',') {
865 std::string path;
866 packet.GetHexByteString(path);
867 Status error(llvm::sys::fs::create_directory(path, mode));
868
869 StreamGDBRemote response;
870 response.Printf("F%x", error.GetError());
871
872 return SendPacketNoLock(response.GetString());
873 }
874 return SendErrorResponse(20);
875}
876
879 StringExtractorGDBRemote &packet) {
880 packet.SetFilePos(::strlen("qPlatform_chmod:"));
881
882 auto perms =
883 static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX));
884 if (packet.GetChar() == ',') {
885 std::string path;
886 packet.GetHexByteString(path);
887 Status error(llvm::sys::fs::setPermissions(path, perms));
888
889 StreamGDBRemote response;
890 response.Printf("F%x", error.GetError());
891
892 return SendPacketNoLock(response.GetString());
893 }
894 return SendErrorResponse(19);
895}
896
899 StringExtractorGDBRemote &packet) {
900 // Parse client-indicated features.
901 llvm::SmallVector<llvm::StringRef, 4> client_features;
902 packet.GetStringRef().split(client_features, ';');
903 return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";"));
904}
905
908 StringExtractorGDBRemote &packet) {
909 packet.SetFilePos(::strlen("QSetDetachOnError:"));
910 if (packet.GetU32(0))
911 m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
912 else
913 m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
914 return SendOKResponse();
915}
916
919 StringExtractorGDBRemote &packet) {
920 // Send response first before changing m_send_acks to we ack this packet
921 PacketResult packet_result = SendOKResponse();
922 m_send_acks = false;
923 return packet_result;
924}
925
928 StringExtractorGDBRemote &packet) {
929 packet.SetFilePos(::strlen("QSetSTDIN:"));
930 FileAction file_action;
931 std::string path;
932 packet.GetHexByteString(path);
933 const bool read = true;
934 const bool write = false;
935 if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {
936 m_process_launch_info.AppendFileAction(file_action);
937 return SendOKResponse();
938 }
939 return SendErrorResponse(15);
940}
941
944 StringExtractorGDBRemote &packet) {
945 packet.SetFilePos(::strlen("QSetSTDOUT:"));
946 FileAction file_action;
947 std::string path;
948 packet.GetHexByteString(path);
949 const bool read = false;
950 const bool write = true;
951 if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {
952 m_process_launch_info.AppendFileAction(file_action);
953 return SendOKResponse();
954 }
955 return SendErrorResponse(16);
956}
957
960 StringExtractorGDBRemote &packet) {
961 packet.SetFilePos(::strlen("QSetSTDERR:"));
962 FileAction file_action;
963 std::string path;
964 packet.GetHexByteString(path);
965 const bool read = false;
966 const bool write = true;
967 if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {
968 m_process_launch_info.AppendFileAction(file_action);
969 return SendOKResponse();
970 }
971 return SendErrorResponse(17);
972}
973
976 StringExtractorGDBRemote &packet) {
977 // Format: "QSetSTDIOWindowSize:cols=N;rows=N"
978 packet.SetFilePos(::strlen("QSetSTDIOWindowSize:"));
979 llvm::StringRef body = packet.GetStringRef().substr(packet.GetFilePos());
980
981 uint16_t cols = 0;
982 uint16_t rows = 0;
983 llvm::SmallVector<llvm::StringRef, 2> fields;
984 body.split(fields, ';');
985 for (llvm::StringRef field : fields) {
986 auto [key, value] = field.split('=');
987 uint16_t *dest;
988 if (key == "cols")
989 dest = &cols;
990 else if (key == "rows")
991 dest = &rows;
992 else
993 continue;
994 unsigned parsed = 0;
995 if (value.empty() || value.getAsInteger(BASE_10, parsed) ||
996 parsed > UINT16_MAX)
997 continue;
998 *dest = static_cast<uint16_t>(parsed);
999 }
1000 // 0x0 is a valid request: it signals "no terminal" and a redirection
1001 // backend that supports an alternative path (anonymous pipes on Windows
1002 // ConPTY) can switch on it. Reject only the malformed cases.
1003 if ((cols == 0) != (rows == 0))
1004 return SendErrorResponse(28);
1005
1006 m_process_launch_info.SetSTDIOWindowSize(cols, rows);
1007 return SendOKResponse();
1008}
1009
1012 StringExtractorGDBRemote &packet) {
1013 if (m_process_launch_error.Success())
1014 return SendOKResponse();
1015 StreamString response;
1016 response.PutChar('E');
1017 response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
1018 return SendPacketNoLock(response.GetString());
1019}
1020
1023 StringExtractorGDBRemote &packet) {
1024 packet.SetFilePos(::strlen("QEnvironment:"));
1025 const uint32_t bytes_left = packet.GetBytesLeft();
1026 if (bytes_left > 0) {
1027 m_process_launch_info.GetEnvironment().insert(packet.Peek());
1028 return SendOKResponse();
1029 }
1030 return SendErrorResponse(12);
1031}
1032
1035 StringExtractorGDBRemote &packet) {
1036 packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
1037 const uint32_t bytes_left = packet.GetBytesLeft();
1038 if (bytes_left > 0) {
1039 std::string str;
1040 packet.GetHexByteString(str);
1041 m_process_launch_info.GetEnvironment().insert(str);
1042 return SendOKResponse();
1043 }
1044 return SendErrorResponse(12);
1045}
1046
1049 StringExtractorGDBRemote &packet) {
1050 packet.SetFilePos(::strlen("QLaunchArch:"));
1051 const uint32_t bytes_left = packet.GetBytesLeft();
1052 if (bytes_left > 0) {
1053 const char *arch_triple = packet.Peek();
1054 m_process_launch_info.SetArchitecture(
1055 HostInfo::GetAugmentedArchSpec(arch_triple));
1056 return SendOKResponse();
1057 }
1058 return SendErrorResponse(13);
1059}
1060
1063 // The 'A' packet is the most over designed packet ever here with redundant
1064 // argument indexes, redundant argument lengths and needed hex encoded
1065 // argument string values. Really all that is needed is a comma separated hex
1066 // encoded argument value list, but we will stay true to the documented
1067 // version of the 'A' packet here...
1068
1069 Log *log = GetLog(LLDBLog::Process);
1070 int actual_arg_index = 0;
1071
1072 packet.SetFilePos(1); // Skip the 'A'
1073 bool success = true;
1074 while (success && packet.GetBytesLeft() > 0) {
1075 // Decode the decimal argument string length. This length is the number of
1076 // hex nibbles in the argument string value.
1077 const uint32_t arg_len = packet.GetU32(UINT32_MAX);
1078 if (arg_len == UINT32_MAX)
1079 success = false;
1080 else {
1081 // Make sure the argument hex string length is followed by a comma
1082 if (packet.GetChar() != ',')
1083 success = false;
1084 else {
1085 // Decode the argument index. We ignore this really because who would
1086 // really send down the arguments in a random order???
1087 const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
1088 if (arg_idx == UINT32_MAX)
1089 success = false;
1090 else {
1091 // Make sure the argument index is followed by a comma
1092 if (packet.GetChar() != ',')
1093 success = false;
1094 else {
1095 // Decode the argument string value from hex bytes back into a UTF8
1096 // string and make sure the length matches the one supplied in the
1097 // packet
1098 std::string arg;
1099 if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
1100 (arg_len / 2))
1101 success = false;
1102 else {
1103 // If there are any bytes left
1104 if (packet.GetBytesLeft()) {
1105 if (packet.GetChar() != ',')
1106 success = false;
1107 }
1108
1109 if (success) {
1110 if (arg_idx == 0)
1111 m_process_launch_info.GetExecutableFile().SetFile(
1112 arg, FileSpec::Style::native);
1113 m_process_launch_info.GetArguments().AppendArgument(arg);
1114 LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"",
1115 __FUNCTION__, actual_arg_index, arg.c_str());
1116 ++actual_arg_index;
1117 }
1118 }
1119 }
1120 }
1121 }
1122 }
1123 }
1124
1125 if (success) {
1127 if (m_process_launch_error.Success())
1128 return SendOKResponse();
1129 LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
1130 }
1131 return SendErrorResponse(8);
1132}
1133
1136 StringExtractorGDBRemote &packet) {
1137 // Just echo back the exact same packet for qEcho...
1138 return SendPacketNoLock(packet.GetStringRef());
1139}
1140
1143 StringExtractorGDBRemote &packet) {
1144 packet.SetFilePos(::strlen("qModuleInfo:"));
1145
1146 std::string module_path;
1147 packet.GetHexByteStringTerminatedBy(module_path, ';');
1148 if (module_path.empty())
1149 return SendErrorResponse(1);
1150
1151 if (packet.GetChar() != ';')
1152 return SendErrorResponse(2);
1153
1154 std::string triple;
1155 packet.GetHexByteString(triple);
1156
1157 ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);
1158 if (!matched_module_spec.GetFileSpec())
1159 return SendErrorResponse(3);
1160
1161 const auto file_offset = matched_module_spec.GetObjectOffset();
1162 const auto file_size = matched_module_spec.GetObjectSize();
1163 const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1164
1165 StreamGDBRemote response;
1166
1167 if (uuid_str.empty()) {
1168 auto Result = llvm::sys::fs::md5_contents(
1169 matched_module_spec.GetFileSpec().GetPath());
1170 if (!Result)
1171 return SendErrorResponse(5);
1172 response.PutCString("md5:");
1173 response.PutStringAsRawHex8(Result->digest());
1174 } else {
1175 response.PutCString("uuid:");
1176 response.PutStringAsRawHex8(uuid_str);
1177 }
1178 response.PutChar(';');
1179
1180 const auto &module_arch = matched_module_spec.GetArchitecture();
1181 response.PutCString("triple:");
1182 response.PutStringAsRawHex8(module_arch.GetTriple().getTriple());
1183 response.PutChar(';');
1184
1185 response.PutCString("file_path:");
1186 response.PutStringAsRawHex8(
1187 matched_module_spec.GetFileSpec().GetPath().c_str());
1188 response.PutChar(';');
1189 response.PutCString("file_offset:");
1190 response.PutHex64(file_offset);
1191 response.PutChar(';');
1192 response.PutCString("file_size:");
1193 response.PutHex64(file_size);
1194 response.PutChar(';');
1195
1196 return SendPacketNoLock(response.GetString());
1197}
1198
1201 StringExtractorGDBRemote &packet) {
1202 namespace json = llvm::json;
1203
1204 packet.SetFilePos(::strlen("jModulesInfo:"));
1205
1207 if (!object_sp)
1208 return SendErrorResponse(1);
1209
1210 StructuredData::Array *packet_array = object_sp->GetAsArray();
1211 if (!packet_array)
1212 return SendErrorResponse(2);
1213
1214 json::Array response_array;
1215 for (size_t i = 0; i < packet_array->GetSize(); ++i) {
1217 packet_array->GetItemAtIndex(i)->GetAsDictionary();
1218 if (!query)
1219 continue;
1220 llvm::StringRef file, triple;
1221 if (!query->GetValueForKeyAsString("file", file) ||
1222 !query->GetValueForKeyAsString("triple", triple))
1223 continue;
1224
1225 ModuleSpec matched_module_spec = GetModuleInfo(file, triple);
1226 if (!matched_module_spec.GetFileSpec())
1227 continue;
1228
1229 const auto file_offset = matched_module_spec.GetObjectOffset();
1230 const auto file_size = matched_module_spec.GetObjectSize();
1231 const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1232 if (uuid_str.empty())
1233 continue;
1234 const auto triple_str =
1235 matched_module_spec.GetArchitecture().GetTriple().getTriple();
1236 const auto file_path = matched_module_spec.GetFileSpec().GetPath();
1237
1238 json::Object response{{"uuid", uuid_str},
1239 {"triple", triple_str},
1240 {"file_path", file_path},
1241 {"file_offset", static_cast<int64_t>(file_offset)},
1242 {"file_size", static_cast<int64_t>(file_size)}};
1243 response_array.push_back(std::move(response));
1244 }
1245
1246 StreamString response;
1247 response.AsRawOstream() << std::move(response_array);
1248 StreamGDBRemote escaped_response;
1249 escaped_response.PutEscapedBytes(response.GetString().data(),
1250 response.GetSize());
1251 return SendPacketNoLock(escaped_response.GetString());
1252}
1253
1255 const ProcessInstanceInfo &proc_info, StreamString &response) {
1256 response.Printf(
1257 "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
1258 proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1259 proc_info.GetUserID(), proc_info.GetGroupID(),
1260 proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
1261 response.PutCString("name:");
1262 response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str());
1263
1264 response.PutChar(';');
1265 response.PutCString("args:");
1266 response.PutStringAsRawHex8(proc_info.GetArg0());
1267 for (auto &arg : proc_info.GetArguments()) {
1268 response.PutChar('-');
1269 response.PutStringAsRawHex8(arg.ref());
1270 }
1271
1272 response.PutChar(';');
1273 const ArchSpec &proc_arch = proc_info.GetArchitecture();
1274 if (proc_arch.IsValid()) {
1275 const llvm::Triple &proc_triple = proc_arch.GetTriple();
1276 response.PutCString("triple:");
1277 response.PutStringAsRawHex8(proc_triple.getTriple());
1278 response.PutChar(';');
1279 }
1280}
1281
1284 const ProcessInstanceInfo &proc_info, StreamString &response) {
1285 response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
1286 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
1287 proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1288 proc_info.GetUserID(), proc_info.GetGroupID(),
1289 proc_info.GetEffectiveUserID(),
1290 proc_info.GetEffectiveGroupID());
1291
1292 const ArchSpec &proc_arch = proc_info.GetArchitecture();
1293 if (proc_arch.IsValid()) {
1294 const llvm::Triple &proc_triple = proc_arch.GetTriple();
1295#if defined(__APPLE__)
1296 // We'll send cputype/cpusubtype.
1297 const uint32_t cpu_type = proc_arch.GetMachOCPUType();
1298 if (cpu_type != 0)
1299 response.Printf("cputype:%" PRIx32 ";", cpu_type);
1300
1301 const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
1302 if (cpu_subtype != 0)
1303 response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
1304
1305 const std::string vendor = proc_triple.getVendorName().str();
1306 if (!vendor.empty())
1307 response.Printf("vendor:%s;", vendor.c_str());
1308#else
1309 // We'll send the triple.
1310 response.PutCString("triple:");
1311 response.PutStringAsRawHex8(proc_triple.getTriple());
1312 response.PutChar(';');
1313#endif
1314 std::string ostype = std::string(proc_triple.getOSName());
1315 // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
1316 if (proc_triple.getVendor() == llvm::Triple::Apple) {
1317 switch (proc_triple.getArch()) {
1318 case llvm::Triple::arm:
1319 case llvm::Triple::thumb:
1320 case llvm::Triple::aarch64:
1321 case llvm::Triple::aarch64_32:
1322 ostype = "ios";
1323 break;
1324 default:
1325 // No change.
1326 break;
1327 }
1328 }
1329 response.Printf("ostype:%s;", ostype.c_str());
1330
1331 switch (proc_arch.GetByteOrder()) {
1333 response.PutCString("endian:little;");
1334 break;
1336 response.PutCString("endian:big;");
1337 break;
1339 response.PutCString("endian:pdp;");
1340 break;
1341 default:
1342 // Nothing.
1343 break;
1344 }
1345 // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer
1346 // size is 4 and for N64 it is 8
1347 std::string abi = proc_arch.GetTargetABI();
1348 if (!abi.empty())
1349 response.Printf("elf_abi:%s;", abi.c_str());
1350 response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
1351 }
1352}
1353
1355 const std::string &module_path, const ArchSpec &arch) {
1356#ifdef __ANDROID__
1357 return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
1358#else
1359 FileSpec file_spec(module_path);
1360 FileSystem::Instance().Resolve(file_spec);
1361 return file_spec;
1362#endif
1363}
1364
1367 llvm::StringRef triple) {
1368 ArchSpec arch(triple);
1369
1370 FileSpec req_module_path_spec(module_path);
1371 FileSystem::Instance().Resolve(req_module_path_spec);
1372
1373 const FileSpec module_path_spec =
1374 FindModuleFile(req_module_path_spec.GetPath(), arch);
1375
1376 lldb::offset_t file_offset = 0;
1377 lldb::offset_t file_size = 0;
1378#ifdef __ANDROID__
1379 // In Android API level 23 and above, dynamic loader is able to load .so file
1380 // directly from zip file. In that case, module_path will be
1381 // "zip_path!/so_path". Resolve the zip file path, .so file offset and size.
1383 std::string file_path;
1385 module_path_spec, file_kind, file_path, file_offset, file_size)) {
1386 return ModuleSpec();
1387 }
1389 // For zip .so file, this file_path will contain only the actual zip file
1390 // path for the object file processing. Otherwise it is the same as
1391 // module_path.
1392 const FileSpec actual_module_path_spec(file_path);
1393#else
1394 // It is just module_path_spec reference for other platforms.
1395 const FileSpec &actual_module_path_spec = module_path_spec;
1396#endif
1397
1398 const ModuleSpec module_spec(actual_module_path_spec, arch);
1399
1401 actual_module_path_spec, file_offset, file_size);
1402 if (module_specs.GetSize() == 0)
1403 return ModuleSpec();
1404
1405 ModuleSpec matched_module_spec;
1406 if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
1407 return ModuleSpec();
1408
1409#ifdef __ANDROID__
1410 if (file_kind == ZipFileResolver::eFileKindZip) {
1411 // For zip .so file, matched_module_spec contains only the actual zip file
1412 // path for the object file processing. Overwrite the matched_module_spec
1413 // file spec with the original module_path_spec to pass "zip_path!/so_path"
1414 // through to PlatformAndroid::DownloadModuleSlice.
1415 *matched_module_spec.GetFileSpecPtr() = module_path_spec;
1416 }
1417#endif
1418
1419 return matched_module_spec;
1420}
1421
1423 const llvm::ArrayRef<llvm::StringRef> client_features) {
1424 // 128 KiB is a reasonable max packet size--debugger can always use less.
1425 constexpr uint32_t max_packet_size = 128 * 1024;
1426
1427 // Features common to platform server and llgs.
1428 return {
1429 llvm::formatv("PacketSize={0}", max_packet_size),
1430 "QStartNoAckMode+",
1431 "qEcho+",
1432 "native-signals+",
1433 };
1434}
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:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
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:894
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:455
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:547
uint32_t GetMachOCPUSubType() const
Definition ArchSpec.cpp:878
bool IsMIPS() const
if MIPS architecture return true.
Definition ArchSpec.cpp:752
uint32_t GetMachOCPUType() const
Definition ArchSpec.cpp:874
std::string GetTargetABI() const
Return a string representing target application ABI.
Definition ArchSpec.cpp:756
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:943
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:886
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:56
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:380
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:396
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:338
NativeFilePosix NativeFile
Definition File.h:29
uint64_t offset_t
Definition lldb-types.h:86
uint64_t pid_t
Definition lldb-types.h:84
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)