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