llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "GDBRemoteCommunicationClient.h"

#include <cmath>
#include <sys/stat.h>

#include <numeric>
#include <optional>
#include <sstream>

#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/SafeMachO.h"
#include "lldb/Host/XML.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"

#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "lldb/Host/Config.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_ZLIB
#include "llvm/Support/JSON.h"

#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif

usingnamespacelldb;
usingnamespacelldb_private::process_gdb_remote;
usingnamespacelldb_private;
usingnamespacestd::chrono;

llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,
                                                  const QOffsets &offsets) {}

// GDBRemoteCommunicationClient constructor
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
    :{}

// Destructor
GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {}

bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {}

bool GDBRemoteCommunicationClient::GetEchoSupported() {}

bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {}

bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {}

bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {}

bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {}

bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {}

bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {}

bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {}

bool GDBRemoteCommunicationClient::GetQXferSigInfoReadSupported() {}

bool GDBRemoteCommunicationClient::GetMultiprocessSupported() {}

uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {}

bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {}

void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {}

bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {}

bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {}

void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {}

void GDBRemoteCommunicationClient::GetRemoteQSupported() {}

bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {}
bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
    lldb::tid_t tid, StreamString &&payload,
    StringExtractorGDBRemote &response) {}

// Check if the target supports 'p' packet. It sends out a 'p' packet and
// checks the response. A normal packet will tell us that support is available.
//
// Takes a valid thread ID because p needs to apply to a thread.
bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {}

LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(
    lldb::tid_t tid, llvm::StringRef packetStr) {}

bool GDBRemoteCommunicationClient::GetSaveCoreSupported() const {}

StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {}

bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {}

void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {}

bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {}

bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {}

bool GDBRemoteCommunicationClient::GetDynamicLoaderProcessStateSupported() {}

bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {}

DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,
                                                          size_t len,
                                                          int32_t type) {}

Status GDBRemoteCommunicationClient::WriteMemoryTags(
    lldb::addr_t addr, size_t len, int32_t type,
    const std::vector<uint8_t> &tags) {}

bool GDBRemoteCommunicationClient::GetxPacketSupported() {}

lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {}

llvm::Error GDBRemoteCommunicationClient::LaunchProcess(const Args &args) {}

int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {}

int GDBRemoteCommunicationClient::SendEnvironmentPacket(
    char const *name_equal_value) {}

int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {}

int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
    char const *data, bool *was_supported) {}

llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {}

llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {}

std::optional<std::string> GDBRemoteCommunicationClient::GetOSBuildString() {}

std::optional<std::string>
GDBRemoteCommunicationClient::GetOSKernelDescription() {}

bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {}

ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {}

const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetProcessArchitecture() {}

bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(
    UUID &uuid, addr_t &value, bool &value_is_offset) {}

std::vector<addr_t>
GDBRemoteCommunicationClient::GetProcessStandaloneBinaries() {}

bool GDBRemoteCommunicationClient::GetGDBServerVersion() {}

void GDBRemoteCommunicationClient::MaybeEnableCompression(
    llvm::ArrayRef<llvm::StringRef> supported_compressions) {}

const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {}

uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {}

bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {}

static void ParseOSType(llvm::StringRef value, std::string &os_name,
                        std::string &environment) {}

bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {}

int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
                                                        size_t data_len) {}

const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetHostArchitecture() {}

AddressableBits GDBRemoteCommunicationClient::GetAddressableBits() {}

seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {}

addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
                                                    uint32_t permissions) {}

bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {}

Status GDBRemoteCommunicationClient::Detach(bool keep_stopped,
                                            lldb::pid_t pid) {}

Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
    lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {}

Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
    lldb::addr_t addr, MemoryRegionInfo &region) {}

Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {}

std::optional<uint32_t> GDBRemoteCommunicationClient::GetWatchpointSlotCount() {}

WatchpointHardwareFeature
GDBRemoteCommunicationClient::GetSupportedWatchpointTypes() {}

std::optional<bool> GDBRemoteCommunicationClient::GetWatchpointReportedAfter() {}

int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {}

int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {}

int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {}

bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {}

int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {}

int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {}

int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {}

bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
    StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {}

bool GDBRemoteCommunicationClient::GetProcessInfo(
    lldb::pid_t pid, ProcessInstanceInfo &process_info) {}

bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {}

uint32_t GDBRemoteCommunicationClient::FindProcesses(
    const ProcessInstanceInfoMatch &match_info,
    ProcessInstanceInfoList &process_infos) {}

bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
                                               std::string &name) {}

bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
                                                std::string &name) {}

static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
                                uint32_t recv_size) {}

duration<float>
calculate_standard_deviation(const std::vector<duration<float>> &v) {}

void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
                                                   uint32_t max_send,
                                                   uint32_t max_recv,
                                                   uint64_t recv_amount,
                                                   bool json, Stream &strm) {}

bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
                                                       uint32_t recv_size) {}

bool GDBRemoteCommunicationClient::LaunchGDBServer(
    const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
    std::string &socket_name) {}

size_t GDBRemoteCommunicationClient::QueryGDBServer(
    std::vector<std::pair<uint16_t, std::string>> &connection_urls) {}

bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {}

std::optional<PidTid> GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(
    uint64_t tid, uint64_t pid, char op) {}

bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,
                                                    uint64_t pid) {}

bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,
                                                          uint64_t pid) {}

bool GDBRemoteCommunicationClient::GetStopReply(
    StringExtractorGDBRemote &response) {}

bool GDBRemoteCommunicationClient::GetThreadStopInfo(
    lldb::tid_t tid, StringExtractorGDBRemote &response) {}

uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
    GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
    std::chrono::seconds timeout) {}

std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(
    bool &sequence_mutex_unavailable) {}

size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
    std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {}

lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {}

lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
    llvm::StringRef command,
    const FileSpec &
        working_dir, // Pass empty FileSpec to use the current working directory
    int *status_ptr, // Pass NULL if you don't want the process exit status
    int *signo_ptr,  // Pass NULL if you don't want the signal that caused the
                     // process to exit
    std::string
        *command_output, // Pass NULL if you don't want the command output
    const Timeout<std::micro> &timeout) {}

Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
                                                   uint32_t file_permissions) {}

Status
GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
                                                 uint32_t file_permissions) {}

static int gdb_errno_to_system(int err) {}

static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
                                          uint64_t fail_result, Status &error) {}
lldb::user_id_t
GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
                                       File::OpenOptions flags, mode_t mode,
                                       Status &error) {}

bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
                                             Status &error) {}

std::optional<GDBRemoteFStatData>
GDBRemoteCommunicationClient::FStat(lldb::user_id_t fd) {}

std::optional<GDBRemoteFStatData>
GDBRemoteCommunicationClient::Stat(const lldb_private::FileSpec &file_spec) {}

// Extension of host I/O packets to get the file size.
lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
    const lldb_private::FileSpec &file_spec) {}

void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(
    CompletionRequest &request, bool only_dir) {}

Status
GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
                                                 uint32_t &file_permissions) {}

uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
                                                uint64_t offset, void *dst,
                                                uint64_t dst_len,
                                                Status &error) {}

uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
                                                 uint64_t offset,
                                                 const void *src,
                                                 uint64_t src_len,
                                                 Status &error) {}

Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
                                                   const FileSpec &dst) {}

Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {}

// Extension of host I/O packets to get whether a file exists.
bool GDBRemoteCommunicationClient::GetFileExists(
    const lldb_private::FileSpec &file_spec) {}

llvm::ErrorOr<llvm::MD5::MD5Result> GDBRemoteCommunicationClient::CalculateMD5(
    const lldb_private::FileSpec &file_spec) {}

bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {}

DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
                                                        uint32_t reg) {}

DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {}

bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
                                                 uint32_t reg_num,
                                                 llvm::ArrayRef<uint8_t> data) {}

bool GDBRemoteCommunicationClient::WriteAllRegisters(
    lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {}

bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
                                                     uint32_t &save_id) {}

bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
                                                        uint32_t save_id) {}

bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {}

llvm::Expected<TraceSupportedResponse>
GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) {}

llvm::Error
GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request,
                                            std::chrono::seconds timeout) {}

llvm::Error
GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
                                             std::chrono::seconds timeout) {}

llvm::Expected<std::string>
GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type,
                                                std::chrono::seconds timeout) {}

llvm::Expected<std::vector<uint8_t>>
GDBRemoteCommunicationClient::SendTraceGetBinaryData(
    const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {}

std::optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {}

bool GDBRemoteCommunicationClient::GetModuleInfo(
    const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
    ModuleSpec &module_spec) {}

static std::optional<ModuleSpec>
ParseModuleSpec(StructuredData::Dictionary *dict) {}

std::optional<std::vector<ModuleSpec>>
GDBRemoteCommunicationClient::GetModulesInfo(
    llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {}

// query the target remote for extended information using the qXfer packet
//
// example: object='features', annex='target.xml'
// return: <xml output> or error
llvm::Expected<std::string>
GDBRemoteCommunicationClient::ReadExtFeature(llvm::StringRef object,
                                             llvm::StringRef annex) {}

// Notify the target that gdb is prepared to serve symbol lookup requests.
//  packet: "qSymbol::"
//  reply:
//  OK                  The target does not need to look up any (more) symbols.
//  qSymbol:<sym_name>  The target requests the value of symbol sym_name (hex
//  encoded).
//                      LLDB may provide the value by sending another qSymbol
//                      packet
//                      in the form of"qSymbol:<sym_value>:<sym_name>".
//
//  Three examples:
//
//  lldb sends:    qSymbol::
//  lldb receives: OK
//     Remote gdb stub does not need to know the addresses of any symbols, lldb
//     does not
//     need to ask again in this session.
//
//  lldb sends:    qSymbol::
//  lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
//  lldb sends:    qSymbol::64697370617463685f71756575655f6f666673657473
//  lldb receives: OK
//     Remote gdb stub asks for address of 'dispatch_queue_offsets'.  lldb does
//     not know
//     the address at this time.  lldb needs to send qSymbol:: again when it has
//     more
//     solibs loaded.
//
//  lldb sends:    qSymbol::
//  lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
//  lldb sends:    qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
//  lldb receives: OK
//     Remote gdb stub asks for address of 'dispatch_queue_offsets'.  lldb says
//     that it
//     is at address 0x2bc97554.  Remote gdb stub sends 'OK' indicating that it
//     does not
//     need any more symbols.  lldb does not need to ask again in this session.

void GDBRemoteCommunicationClient::ServeSymbolLookups(
    lldb_private::Process *process) {}

StructuredData::Array *
GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {}

Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
    llvm::ArrayRef<int32_t> signals) {}

Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
    llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) {}

void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {}

bool GDBRemoteCommunicationClient::UsesNativeSignals() {}

llvm::Expected<int> GDBRemoteCommunicationClient::KillProcess(lldb::pid_t pid) {}