forked from OSchip/llvm-project
327 lines
9.3 KiB
C++
327 lines
9.3 KiB
C++
//===-- CommunicationKDP.h --------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef liblldb_CommunicationKDP_h_
|
|
#define liblldb_CommunicationKDP_h_
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
#include <list>
|
|
#include <string>
|
|
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
#include "lldb/lldb-private.h"
|
|
#include "lldb/Core/Communication.h"
|
|
#include "lldb/Core/Listener.h"
|
|
#include "lldb/Core/StreamBuffer.h"
|
|
#include "lldb/Host/Mutex.h"
|
|
#include "lldb/Host/Predicate.h"
|
|
#include "lldb/Host/TimeValue.h"
|
|
|
|
class CommunicationKDP : public lldb_private::Communication
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
eBroadcastBitRunPacketSent = kLoUserBroadcastBit
|
|
};
|
|
|
|
const static uint32_t kMaxPacketSize = 1200;
|
|
const static uint32_t kMaxDataSize = 1024;
|
|
typedef lldb_private::StreamBuffer<1024> PacketStreamType;
|
|
typedef enum
|
|
{
|
|
KDP_CONNECT = 0u,
|
|
KDP_DISCONNECT,
|
|
KDP_HOSTINFO,
|
|
KDP_VERSION,
|
|
KDP_MAXBYTES,
|
|
KDP_READMEM,
|
|
KDP_WRITEMEM,
|
|
KDP_READREGS,
|
|
KDP_WRITEREGS,
|
|
KDP_LOAD,
|
|
KDP_IMAGEPATH,
|
|
KDP_SUSPEND,
|
|
KDP_RESUMECPUS,
|
|
KDP_EXCEPTION,
|
|
KDP_TERMINATION,
|
|
KDP_BREAKPOINT_SET,
|
|
KDP_BREAKPOINT_REMOVE,
|
|
KDP_REGIONS,
|
|
KDP_REATTACH,
|
|
KDP_HOSTREBOOT,
|
|
KDP_READMEM64,
|
|
KDP_WRITEMEM64,
|
|
KDP_BREAKPOINT_SET64,
|
|
KDP_BREAKPOINT_REMOVE64,
|
|
KDP_KERNELVERSION
|
|
} CommandType;
|
|
|
|
enum
|
|
{
|
|
KDP_FEATURE_BP = (1u << 0)
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
KDP_PROTERR_SUCCESS = 0,
|
|
KDP_PROTERR_ALREADY_CONNECTED,
|
|
KDP_PROTERR_BAD_NBYTES,
|
|
KDP_PROTERR_BADFLAVOR
|
|
} KDPError;
|
|
|
|
typedef enum
|
|
{
|
|
ePacketTypeRequest = 0x00u,
|
|
ePacketTypeReply = 0x80u,
|
|
ePacketTypeMask = 0x80u,
|
|
eCommandTypeMask = 0x7fu
|
|
} PacketType;
|
|
//------------------------------------------------------------------
|
|
// Constructors and Destructors
|
|
//------------------------------------------------------------------
|
|
CommunicationKDP (const char *comm_name);
|
|
|
|
virtual
|
|
~CommunicationKDP();
|
|
|
|
bool
|
|
SendRequestPacket (const PacketStreamType &request_packet);
|
|
|
|
// Wait for a packet within 'nsec' seconds
|
|
size_t
|
|
WaitForPacketWithTimeoutMicroSeconds (lldb_private::DataExtractor &response,
|
|
uint32_t usec);
|
|
|
|
bool
|
|
GetSequenceMutex(lldb_private::Mutex::Locker& locker);
|
|
|
|
bool
|
|
CheckForPacket (const uint8_t *src,
|
|
size_t src_len,
|
|
lldb_private::DataExtractor &packet);
|
|
bool
|
|
IsRunning() const
|
|
{
|
|
return m_public_is_running.GetValue();
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// Set the global packet timeout.
|
|
//
|
|
// For clients, this is the timeout that gets used when sending
|
|
// packets and waiting for responses. For servers, this might not
|
|
// get used, and if it doesn't this should be moved to the
|
|
// CommunicationKDPClient.
|
|
//------------------------------------------------------------------
|
|
uint32_t
|
|
SetPacketTimeout (uint32_t packet_timeout)
|
|
{
|
|
const uint32_t old_packet_timeout = m_packet_timeout;
|
|
m_packet_timeout = packet_timeout;
|
|
return old_packet_timeout;
|
|
}
|
|
|
|
uint32_t
|
|
GetPacketTimeoutInMicroSeconds () const
|
|
{
|
|
return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
|
|
}
|
|
//------------------------------------------------------------------
|
|
// Start a debugserver instance on the current host using the
|
|
// supplied connection URL.
|
|
//------------------------------------------------------------------
|
|
lldb_private::Error
|
|
StartDebugserverProcess (const char *connect_url,
|
|
const char *unix_socket_name,
|
|
lldb_private::ProcessLaunchInfo &launch_info);
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
// Public Request Packets
|
|
//------------------------------------------------------------------
|
|
bool
|
|
SendRequestConnect (uint16_t reply_port,
|
|
uint16_t exc_port,
|
|
const char *greeting);
|
|
|
|
bool
|
|
SendRequestReattach (uint16_t reply_port);
|
|
|
|
bool
|
|
SendRequestDisconnect ();
|
|
|
|
uint32_t
|
|
SendRequestReadMemory (lldb::addr_t addr,
|
|
void *dst,
|
|
uint32_t dst_size,
|
|
lldb_private::Error &error);
|
|
|
|
uint32_t
|
|
SendRequestWriteMemory (lldb::addr_t addr,
|
|
const void *src,
|
|
uint32_t src_len,
|
|
lldb_private::Error &error);
|
|
|
|
uint32_t
|
|
SendRequestReadRegisters (uint32_t cpu,
|
|
uint32_t flavor,
|
|
void *dst,
|
|
uint32_t dst_size,
|
|
lldb_private::Error &error);
|
|
|
|
const char *
|
|
GetKernelVersion ();
|
|
|
|
// Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
|
|
// const char *
|
|
// GetImagePath ();
|
|
|
|
uint32_t
|
|
GetVersion ();
|
|
|
|
uint32_t
|
|
GetFeatureFlags ();
|
|
|
|
bool
|
|
LocalBreakpointsAreSupported ()
|
|
{
|
|
return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
|
|
}
|
|
|
|
uint32_t
|
|
GetCPUMask ();
|
|
|
|
uint32_t
|
|
GetCPUType ();
|
|
|
|
uint32_t
|
|
GetCPUSubtype ();
|
|
|
|
// If cpu_mask is zero, then we will resume all CPUs
|
|
bool
|
|
SendRequestResume (uint32_t cpu_mask = 0);
|
|
|
|
bool
|
|
SendRequestSuspend ();
|
|
|
|
bool
|
|
SendRequestBreakpoint (bool set, lldb::addr_t addr);
|
|
|
|
protected:
|
|
|
|
bool
|
|
SendRequestPacketNoLock (const PacketStreamType &request_packet);
|
|
|
|
size_t
|
|
WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response,
|
|
uint32_t timeout_usec);
|
|
|
|
bool
|
|
WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
|
|
|
|
void
|
|
MakeRequestPacketHeader (CommandType request_type,
|
|
PacketStreamType &request_packet,
|
|
uint16_t request_length);
|
|
|
|
//------------------------------------------------------------------
|
|
// Protected Request Packets (use public accessors which will cache
|
|
// results.
|
|
//------------------------------------------------------------------
|
|
bool
|
|
SendRequestVersion ();
|
|
|
|
bool
|
|
SendRequestHostInfo ();
|
|
|
|
bool
|
|
SendRequestKernelVersion ();
|
|
|
|
// Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
|
|
//bool
|
|
//SendRequestImagePath ();
|
|
|
|
void
|
|
DumpPacket (lldb_private::Stream &s,
|
|
const void *data,
|
|
uint32_t data_len);
|
|
|
|
void
|
|
DumpPacket (lldb_private::Stream &s,
|
|
const lldb_private::DataExtractor& extractor);
|
|
|
|
bool
|
|
VersionIsValid() const
|
|
{
|
|
return m_kdp_version_version != 0;
|
|
}
|
|
|
|
bool
|
|
HostInfoIsValid() const
|
|
{
|
|
return m_kdp_hostinfo_cpu_type != 0;
|
|
}
|
|
|
|
bool
|
|
ExtractIsReply (uint8_t first_packet_byte) const
|
|
{
|
|
// TODO: handle big endian...
|
|
return (first_packet_byte & ePacketTypeMask) != 0;
|
|
}
|
|
|
|
CommandType
|
|
ExtractCommand (uint8_t first_packet_byte) const
|
|
{
|
|
// TODO: handle big endian...
|
|
return (CommandType)(first_packet_byte & eCommandTypeMask);
|
|
}
|
|
|
|
static const char *
|
|
GetCommandAsCString (uint8_t command);
|
|
|
|
void
|
|
ClearKDPSettings ();
|
|
|
|
bool
|
|
SendRequestAndGetReply (const CommandType command,
|
|
const uint8_t request_sequence_id,
|
|
const PacketStreamType &request_packet,
|
|
lldb_private::DataExtractor &reply_packet);
|
|
//------------------------------------------------------------------
|
|
// Classes that inherit from CommunicationKDP can see and modify these
|
|
//------------------------------------------------------------------
|
|
uint32_t m_addr_byte_size;
|
|
lldb::ByteOrder m_byte_order;
|
|
uint32_t m_packet_timeout;
|
|
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
|
|
lldb_private::Predicate<bool> m_public_is_running;
|
|
lldb_private::Predicate<bool> m_private_is_running;
|
|
uint32_t m_session_key;
|
|
uint8_t m_request_sequence_id;
|
|
uint8_t m_exception_sequence_id;
|
|
uint32_t m_kdp_version_version;
|
|
uint32_t m_kdp_version_feature;
|
|
uint32_t m_kdp_hostinfo_cpu_mask;
|
|
uint32_t m_kdp_hostinfo_cpu_type;
|
|
uint32_t m_kdp_hostinfo_cpu_subtype;
|
|
std::string m_kernel_version;
|
|
//std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
|
|
lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
|
|
private:
|
|
//------------------------------------------------------------------
|
|
// For CommunicationKDP only
|
|
//------------------------------------------------------------------
|
|
DISALLOW_COPY_AND_ASSIGN (CommunicationKDP);
|
|
};
|
|
|
|
#endif // liblldb_CommunicationKDP_h_
|