14#include <TargetConditionals.h>
22#include "lldb/Host/Config.h"
38#include "llvm/ADT/StringSwitch.h"
39#include "llvm/Support/JSON.h"
40#include "llvm/TargetParser/Triple.h"
184 ArchSpec host_arch(HostInfo::GetArchitecture());
185 const llvm::Triple &host_triple = host_arch.
GetTriple();
190 llvm::StringRef distribution_id = HostInfo::GetDistributionId();
191 if (!distribution_id.empty()) {
197#if defined(__APPLE__)
205 response.
Printf(
"cputype:%u;", cpu);
207 response.
Printf(
"cpusubtype:%u;", sub);
209 if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) {
211#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
213#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
215#elif defined(TARGET_OS_XR) && TARGET_OS_XR == 1
217#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
225 response.
PutCString(
"watchpoint_exceptions_received:before;");
228 response.
Printf(
"watchpoint_exceptions_received:after;");
232 if (host_arch.
GetMachine() == llvm::Triple::aarch64 ||
233 host_arch.
GetMachine() == llvm::Triple::aarch64_32 ||
234 host_arch.
GetMachine() == llvm::Triple::aarch64_be ||
235 host_arch.
GetMachine() == llvm::Triple::arm ||
238 response.
Printf(
"watchpoint_exceptions_received:before;");
240 response.
Printf(
"watchpoint_exceptions_received:after;");
258 llvm::VersionTuple version = HostInfo::GetOSVersion();
259 if (!version.empty()) {
260 response.
Format(
"os_version:{0}", version.getAsString());
264#if defined(__APPLE__)
265 llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();
266 if (!maccatalyst_version.empty()) {
267 response.
Format(
"maccatalyst_version:{0}",
268 maccatalyst_version.getAsString());
273 if (std::optional<std::string> s = HostInfo::GetOSBuildString()) {
278 if (std::optional<std::string> s = HostInfo::GetOSKernelDescription()) {
285#if defined(__APPLE__)
287#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
295 if (HostInfo::GetHostname(s)) {
303 if (HostInfo::GetHostname(s)) {
320 packet.
SetFilePos(::strlen(
"qProcessInfoPID:"));
343 llvm::StringRef value;
351 file, FileSpec::Style::native);
352 }
else if (key ==
"name_match") {
353 NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
363 }
else if (key ==
"pid") {
365 if (value.getAsInteger(0, pid))
368 }
else if (key ==
"parent_pid") {
370 if (value.getAsInteger(0, pid))
373 }
else if (key ==
"uid") {
375 if (value.getAsInteger(0, uid))
378 }
else if (key ==
"gid") {
380 if (value.getAsInteger(0, gid))
383 }
else if (key ==
"euid") {
385 if (value.getAsInteger(0, uid))
388 }
else if (key ==
"egid") {
390 if (value.getAsInteger(0, gid))
393 }
else if (key ==
"all_users") {
396 }
else if (key ==
"triple") {
398 HostInfo::GetAugmentedArchSpec(value);
433 LLDB_LOGF(log,
"GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
439 if (std::optional<llvm::StringRef> name =
440 HostInfo::GetUserIDResolver().GetUserName(uid)) {
446 LLDB_LOGF(log,
"GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
459 if (std::optional<llvm::StringRef> name =
460 HostInfo::GetUserIDResolver().GetGroupName(gid)) {
476 llvm::StringRef value;
478 if (success && key ==
"response_size") {
479 uint32_t response_size = 0;
480 if (!value.getAsInteger(0, response_size)) {
481 if (response_size == 0)
484 uint32_t bytes_left = response_size;
486 while (bytes_left > 0) {
487 if (bytes_left >= 26) {
488 response.
PutCString(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
491 response.
Printf(
"%*.*s;", bytes_left, bytes_left,
492 "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
504#define HANDLE_ERRNO(name, value) \
507#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
534 descriptor = file.get()->GetDescriptor();
535 response.
Printf(
"%x", descriptor);
538 std::error_code code = errorToErrorCode(file.takeError());
553 int fd = packet.
GetS32(-1, 16);
560 save_errno =
error.GetError();
566 response.
Printf(
"%x", err);
577 int fd = packet.
GetS32(-1, 16);
582 if (count == SIZE_MAX) {
583 response.
Printf(
"F-1:%x", EINVAL);
587 std::string buffer(count, 0);
589 Status error = file.
Read(
static_cast<void *
>(&buffer[0]), count, offset);
590 const int save_errno =
error.GetError();
592 if (
error.Success()) {
593 response.
Printf(
"%zx", count);
615 int fd = packet.
GetS32(-1, 16);
622 size_t count = buffer.size();
624 file.
Write(
static_cast<const void *
>(&buffer[0]), count, offset);
625 const int save_errno =
error.GetError();
627 response.
Printf(
"%zx", count);
634 response.
Printf(
"-1,%x", EINVAL);
650 if (llvm::sys::fs::file_size(path, Size))
676 if (mode != llvm::sys::fs::perms_not_known)
677 response.
Printf(
"F%x", mode);
692 bool retcode = llvm::sys::fs::exists(path);
708 packet.
SetFilePos(::strlen(
"vFile:symlink:"));
709 std::string dst, src;
739 packet.
SetFilePos(::strlen(
"qPlatform_shell:"));
741 std::string working_dir;
755 &output, std::chrono::seconds(10));
774template <
typename T,
typename U>
775static void fill_clamp(T &dest, U src,
typename T::value_type fallback) {
776 static_assert(std::is_unsigned<typename T::value_type>::value,
777 "Destination type must be unsigned.");
778 using UU = std::make_unsigned_t<U>;
779 constexpr auto T_max = std::numeric_limits<typename T::value_type>::max();
780 dest = src >= 0 &&
static_cast<UU
>(src) <= T_max ? src : fallback;
788 int fd = packet.
GetS32(-1, 16);
790 struct stat file_stats;
791 if (::fstat(fd, &file_stats) == -1) {
792 const int save_errno = errno;
817 response.
Printf(
"F%zx;",
sizeof(data));
826 "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
837 auto Result = llvm::sys::fs::md5_contents(path);
854 packet.
SetFilePos(::strlen(
"qPlatform_mkdir:"));
859 Status error(llvm::sys::fs::create_directory(path, mode));
872 packet.
SetFilePos(::strlen(
"qPlatform_chmod:"));
879 Status error(llvm::sys::fs::setPermissions(path, perms));
893 llvm::SmallVector<llvm::StringRef, 4> client_features;
901 packet.
SetFilePos(::strlen(
"QSetDetachOnError:"));
915 return packet_result;
925 const bool read =
true;
926 const bool write =
false;
927 if (file_action.
Open(STDIN_FILENO,
FileSpec(path), read, write)) {
941 const bool read =
false;
942 const bool write =
true;
943 if (file_action.
Open(STDOUT_FILENO,
FileSpec(path), read, write)) {
957 const bool read =
false;
958 const bool write =
true;
959 if (file_action.
Open(STDERR_FILENO,
FileSpec(path), read, write)) {
982 if (bytes_left > 0) {
992 packet.
SetFilePos(::strlen(
"QEnvironmentHexEncoded:"));
994 if (bytes_left > 0) {
1008 if (bytes_left > 0) {
1009 const char *arch_triple = packet.
Peek();
1011 HostInfo::GetAugmentedArchSpec(arch_triple));
1026 int actual_arg_index = 0;
1029 bool success =
true;
1068 arg, FileSpec::Style::native);
1070 LLDB_LOGF(log,
"LLGSPacketHandler::%s added arg %d: \"%s\"",
1071 __FUNCTION__, actual_arg_index, arg.c_str());
1102 std::string module_path;
1104 if (module_path.empty())
1123 if (uuid_str.empty()) {
1124 auto Result = llvm::sys::fs::md5_contents(
1160 packet.
SetFilePos(::strlen(
"jModulesInfo:"));
1170 json::Array response_array;
1171 for (
size_t i = 0; i < packet_array->
GetSize(); ++i) {
1176 llvm::StringRef file, triple;
1188 if (uuid_str.empty())
1190 const auto triple_str =
1194 json::Object response{{
"uuid", uuid_str},
1195 {
"triple", triple_str},
1196 {
"file_path", file_path},
1197 {
"file_offset",
static_cast<int64_t
>(file_offset)},
1198 {
"file_size",
static_cast<int64_t
>(file_size)}};
1199 response_array.push_back(std::move(response));
1213 "pid:%" PRIu64
";ppid:%" PRIu64
";uid:%i;gid:%i;euid:%i;egid:%i;",
1231 const llvm::Triple &proc_triple = proc_arch.
GetTriple();
1241 response.
Printf(
"pid:%" PRIx64
";parent-pid:%" PRIx64
1242 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
1250 const llvm::Triple &proc_triple = proc_arch.
GetTriple();
1251#if defined(__APPLE__)
1255 response.
Printf(
"cputype:%" PRIx32
";", cpu_type);
1258 if (cpu_subtype != 0)
1259 response.
Printf(
"cpusubtype:%" PRIx32
";", cpu_subtype);
1261 const std::string vendor = proc_triple.getVendorName().str();
1262 if (!vendor.empty())
1263 response.
Printf(
"vendor:%s;", vendor.c_str());
1270 std::string ostype = std::string(proc_triple.getOSName());
1272 if (proc_triple.getVendor() == llvm::Triple::Apple) {
1273 switch (proc_triple.getArch()) {
1274 case llvm::Triple::arm:
1275 case llvm::Triple::thumb:
1276 case llvm::Triple::aarch64:
1277 case llvm::Triple::aarch64_32:
1285 response.
Printf(
"ostype:%s;", ostype.c_str());
1305 response.
Printf(
"elf_abi:%s;", abi.c_str());
1311 const std::string &module_path,
const ArchSpec &arch) {
1323 llvm::StringRef triple) {
1326 FileSpec req_module_path_spec(module_path);
1339 std::string file_path;
1341 module_path_spec, file_kind, file_path, file_offset, file_size)) {
1348 const FileSpec actual_module_path_spec(file_path);
1351 const FileSpec &actual_module_path_spec = module_path_spec;
1354 const ModuleSpec module_spec(actual_module_path_spec, arch);
1358 file_size, module_specs))
1375 return matched_module_spec;
1379 const llvm::ArrayRef<llvm::StringRef> client_features) {
1381 constexpr uint32_t max_packet_size = 128 * 1024;
1385 llvm::formatv(
"PacketSize={0}", max_packet_size),
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 LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
uint32_t GetMachOCPUSubType() const
bool IsMIPS() const
if MIPS architecture return true.
uint32_t GetMachOCPUType() const
std::string GetTargetABI() const
Return a string representing target application ABI.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
bool Open(int fd, const FileSpec &file_spec, bool read, bool write)
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
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()
static int kInvalidDescriptor
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, const Timeout< std::micro > &timeout, bool run_in_shell=true, bool hide_stderr=false)
Run a shell command.
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
bool FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
uint64_t GetObjectOffset() const
ArchSpec & GetArchitecture()
FileSpec * GetFileSpecPtr()
uint64_t GetObjectSize() const
Status Close() override
Flush any buffers and release any resources owned by the file.
Status Write(const void *buf, size_t &num_bytes) override
Write bytes from buf to a file at the current file position.
Status Read(void *buf, size_t &num_bytes) override
Read bytes from a file from the current file position into buf.
static size_t GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, ModuleSpecList &specs, lldb::DataBufferSP data_sp=lldb::DataBufferSP())
void SetGroupID(uint32_t gid)
lldb::pid_t GetProcessID() const
llvm::StringRef GetArg0() const
void SetProcessID(lldb::pid_t pid)
FileSpec & GetExecutableFile()
uint32_t GetUserID() const
uint32_t GetGroupID() const
void SetUserID(uint32_t uid)
ArchSpec & GetArchitecture()
void SetNameMatchType(NameMatch name_match_type)
void SetMatchAllUsers(bool b)
ProcessInstanceInfo & GetProcessInfo()
uint32_t GetEffectiveUserID() const
void SetEffectiveGroupID(uint32_t gid)
lldb::pid_t GetParentProcessID() const
uint32_t GetEffectiveGroupID() const
void SetParentProcessID(lldb::pid_t pid)
void SetEffectiveUserID(uint32_t uid)
bool Fail() const
Test for error condition.
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
llvm::StringRef GetString() const
void Format(const char *format, Args &&... args)
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
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
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)
PacketResult Handle_vFile_MD5(StringExtractorGDBRemote &packet)
PacketResult Handle_qEcho(StringExtractorGDBRemote &packet)
PacketResult Handle_qProcessInfoPID(StringExtractorGDBRemote &packet)
PacketResult Handle_qHostInfo(StringExtractorGDBRemote &packet)
virtual Status LaunchProcess()=0
Launch a process with the current launch settings.
GDBRemoteCommunicationServerCommon()
PacketResult Handle_qModuleInfo(StringExtractorGDBRemote &packet)
PacketResult Handle_QSetSTDERR(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_Close(StringExtractorGDBRemote &packet)
ModuleSpec GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple)
PacketResult Handle_QSetDetachOnError(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_pWrite(StringExtractorGDBRemote &packet)
PacketResult Handle_qUserName(StringExtractorGDBRemote &packet)
PacketResult Handle_qLaunchSuccess(StringExtractorGDBRemote &packet)
PacketResult Handle_QEnvironmentHexEncoded(StringExtractorGDBRemote &packet)
PacketResult Handle_qfProcessInfo(StringExtractorGDBRemote &packet)
virtual FileSpec FindModuleFile(const std::string &module_path, const ArchSpec &arch)
PacketResult Handle_vFile_Exists(StringExtractorGDBRemote &packet)
uint32_t m_proc_infos_index
PacketResult Handle_vFile_Mode(StringExtractorGDBRemote &packet)
~GDBRemoteCommunicationServerCommon() override
void RegisterMemberFunctionHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketResult(T::*handler)(StringExtractorGDBRemote &packet))
PacketResult Handle_QEnvironment(StringExtractorGDBRemote &packet)
PacketResult Handle_QSetSTDIN(StringExtractorGDBRemote &packet)
PacketResult Handle_qSpeedTest(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_FStat(StringExtractorGDBRemote &packet)
static void CreateProcessInfoResponse_DebugServerStyle(const ProcessInstanceInfo &proc_info, StreamString &response)
Status m_process_launch_error
PacketResult Handle_qPlatform_mkdir(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_symlink(StringExtractorGDBRemote &packet)
ProcessLaunchInfo m_process_launch_info
PacketResult Handle_qSupported(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_pRead(StringExtractorGDBRemote &packet)
virtual std::vector< std::string > HandleFeatures(llvm::ArrayRef< llvm::StringRef > client_features)
PacketResult Handle_QStartNoAckMode(StringExtractorGDBRemote &packet)
ProcessInstanceInfoList m_proc_infos
static void CreateProcessInfoResponse(const ProcessInstanceInfo &proc_info, StreamString &response)
PacketResult Handle_QLaunchArch(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_unlink(StringExtractorGDBRemote &packet)
PacketResult Handle_jModulesInfo(StringExtractorGDBRemote &packet)
PacketResult Handle_qPlatform_shell(StringExtractorGDBRemote &packet)
PacketResult Handle_qPlatform_chmod(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_Size(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_Open(StringExtractorGDBRemote &packet)
PacketResult Handle_QSetSTDOUT(StringExtractorGDBRemote &packet)
PacketResult Handle_qsProcessInfo(StringExtractorGDBRemote &packet)
PacketResult Handle_A(StringExtractorGDBRemote &packet)
PacketResult Handle_vFile_Stat(StringExtractorGDBRemote &packet)
PacketResult Handle_qGroupName(StringExtractorGDBRemote &packet)
GDBRemoteCommunicationServer()
PacketResult SendErrorResponse(const Status &error)
PacketResult SendUnimplementedResponse(const char *packet)
PacketResult SendOKResponse()
PacketResult SendPacketNoLock(llvm::StringRef payload)
#define LLDB_INVALID_CPUTYPE
#define LLDB_INVALID_PROCESS_ID
lldb::ByteOrder InlHostByteOrder()
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.
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)
llvm::support::ubig32_t gdb_st_ctime
llvm::support::ubig32_t gdb_st_dev
llvm::support::ubig64_t gdb_st_blksize
llvm::support::ubig64_t gdb_st_blocks
llvm::support::ubig32_t gdb_st_ino
llvm::support::ubig32_t gdb_st_gid
llvm::support::ubig32_t gdb_st_mtime
llvm::support::ubig32_t gdb_st_atime
llvm::support::ubig32_t gdb_st_uid
llvm::support::ubig32_t gdb_st_nlink
llvm::support::ubig32_t gdb_st_rdev
llvm::support::ubig64_t gdb_st_size
llvm::support::ubig32_t gdb_st_mode