Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,22 @@
add_lldb_library(lldbPluginProcessMacOSXKernel PLUGIN
CommunicationKDP.cpp
ProcessKDP.cpp
ProcessKDPLog.cpp
RegisterContextKDP_arm.cpp
RegisterContextKDP_arm64.cpp
RegisterContextKDP_i386.cpp
RegisterContextKDP_x86_64.cpp
ThreadKDP.cpp
LINK_LIBS
lldbBreakpoint
lldbCore
lldbHost
lldbInterpreter
lldbSymbol
lldbTarget
lldbUtility
lldbPluginDynamicLoaderDarwinKernel
lldbPluginDynamicLoaderStatic
lldbPluginProcessUtility
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,264 @@
//===-- 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 <mutex>
#include <string>
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Communication.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Host/Predicate.h"
#include "lldb/lldb-private.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,
KDP_READPHYSMEM64,
KDP_WRITEPHYSMEM64,
KDP_READIOPORT,
KDP_WRITEIOPORT,
KDP_READMSR64,
KDP_WRITEMSR64,
KDP_DUMPINFO
} 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(std::unique_lock<std::recursive_mutex> &lock);
bool CheckForPacket(const uint8_t *src, size_t src_len,
lldb_private::DataExtractor &packet);
bool IsRunning() const { return m_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.
//------------------------------------------------------------------
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
const auto old_packet_timeout = m_packet_timeout;
m_packet_timeout = packet_timeout;
return old_packet_timeout;
}
std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
//------------------------------------------------------------------
// 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::Status &error);
uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
uint32_t src_len,
lldb_private::Status &error);
bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
lldb_private::DataExtractor &reply,
lldb_private::Status &error);
uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
uint32_t dst_size,
lldb_private::Status &error);
uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
const void *src, uint32_t src_size,
lldb_private::Status &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();
lldb_private::UUID GetUUID();
bool RemoteIsEFI();
bool RemoteIsDarwinKernel();
lldb::addr_t GetLoadAddress();
bool SendRequestResume();
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 std::chrono::microseconds &timeout);
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 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;
std::chrono::seconds m_packet_timeout;
std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving
// packets to a single thread at a time
lldb_private::Predicate<bool> m_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_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,223 @@
//===-- ProcessKDP.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_ProcessKDP_h_
#define liblldb_ProcessKDP_h_
// C Includes
// C++ Includes
#include <list>
#include <vector>
// Other libraries and framework includes
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringList.h"
#include "CommunicationKDP.h"
class ThreadKDP;
class ProcessKDP : public lldb_private::Process {
public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
static lldb::ProcessSP
CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
const lldb_private::FileSpec *crash_file_path);
static void Initialize();
static void DebuggerInitialize(lldb_private::Debugger &debugger);
static void Terminate();
static lldb_private::ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
~ProcessKDP() override;
//------------------------------------------------------------------
// Check if a given Process
//------------------------------------------------------------------
bool CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) override;
lldb_private::CommandObject *GetPluginCommandObject() override;
//------------------------------------------------------------------
// Creating a new process, or attaching to an existing one
//------------------------------------------------------------------
lldb_private::Status WillLaunch(lldb_private::Module *module) override;
lldb_private::Status
DoLaunch(lldb_private::Module *exe_module,
lldb_private::ProcessLaunchInfo &launch_info) override;
lldb_private::Status WillAttachToProcessWithID(lldb::pid_t pid) override;
lldb_private::Status
WillAttachToProcessWithName(const char *process_name,
bool wait_for_launch) override;
lldb_private::Status DoConnectRemote(lldb_private::Stream *strm,
llvm::StringRef remote_url) override;
lldb_private::Status DoAttachToProcessWithID(
lldb::pid_t pid,
const lldb_private::ProcessAttachInfo &attach_info) override;
lldb_private::Status DoAttachToProcessWithName(
const char *process_name,
const lldb_private::ProcessAttachInfo &attach_info) override;
void DidAttach(lldb_private::ArchSpec &process_arch) override;
lldb::addr_t GetImageInfoAddress() override;
lldb_private::DynamicLoader *GetDynamicLoader() override;
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
//------------------------------------------------------------------
// Process Control
//------------------------------------------------------------------
lldb_private::Status WillResume() override;
lldb_private::Status DoResume() override;
lldb_private::Status DoHalt(bool &caused_stop) override;
lldb_private::Status DoDetach(bool keep_stopped) override;
lldb_private::Status DoSignal(int signal) override;
lldb_private::Status DoDestroy() override;
void RefreshStateAfterStop() override;
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
bool IsAlive() override;
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Status &error) override;
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
lldb_private::Status &error) override;
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
lldb_private::Status &error) override;
lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override;
//----------------------------------------------------------------------
// Process Breakpoints
//----------------------------------------------------------------------
lldb_private::Status
EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
lldb_private::Status
DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
//----------------------------------------------------------------------
// Process Watchpoints
//----------------------------------------------------------------------
lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp,
bool notify = true) override;
lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp,
bool notify = true) override;
CommunicationKDP &GetCommunication() { return m_comm; }
protected:
friend class ThreadKDP;
friend class CommunicationKDP;
//----------------------------------------------------------------------
// Accessors
//----------------------------------------------------------------------
bool IsRunning(lldb::StateType state) {
return state == lldb::eStateRunning || IsStepping(state);
}
bool IsStepping(lldb::StateType state) {
return state == lldb::eStateStepping;
}
bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }
bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }
bool GetHostArchitecture(lldb_private::ArchSpec &arch);
bool ProcessIDIsValid() const;
void Clear();
bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
lldb_private::ThreadList &new_thread_list) override;
enum {
eBroadcastBitAsyncContinue = (1 << 0),
eBroadcastBitAsyncThreadShouldExit = (1 << 1)
};
lldb::ThreadSP GetKernelThread();
//------------------------------------------------------------------
/// Broadcaster event bits definitions.
//------------------------------------------------------------------
CommunicationKDP m_comm;
lldb_private::Broadcaster m_async_broadcaster;
lldb_private::HostThread m_async_thread;
lldb_private::ConstString m_dyld_plugin_name;
lldb::addr_t m_kernel_load_addr;
lldb::CommandObjectSP m_command_sp;
lldb::ThreadWP m_kernel_thread_wp;
bool StartAsyncThread();
void StopAsyncThread();
static void *AsyncThread(void *arg);
private:
//------------------------------------------------------------------
// For ProcessKDP only
//------------------------------------------------------------------
DISALLOW_COPY_AND_ASSIGN(ProcessKDP);
};
#endif // liblldb_ProcessKDP_h_

View File

@@ -0,0 +1,35 @@
//===-- ProcessKDPLog.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ProcessKDPLog.h"
using namespace lldb_private;
static constexpr Log::Category g_categories[] = {
{{"async"}, {"log asynchronous activity"}, KDP_LOG_ASYNC},
{{"break"}, {"log breakpoints"}, KDP_LOG_BREAKPOINTS},
{{"comm"}, {"log communication activity"}, KDP_LOG_COMM},
{{"data-long"},
{"log memory bytes for memory reads and writes for all transactions"},
KDP_LOG_MEMORY_DATA_LONG},
{{"data-short"},
{"log memory bytes for memory reads and writes for short transactions "
"only"},
KDP_LOG_MEMORY_DATA_SHORT},
{{"memory"}, {"log memory reads and writes"}, KDP_LOG_MEMORY},
{{"packets"}, {"log gdb remote packets"}, KDP_LOG_PACKETS},
{{"process"}, {"log process events and activities"}, KDP_LOG_PROCESS},
{{"step"}, {"log step related activities"}, KDP_LOG_STEP},
{{"thread"}, {"log thread events and activities"}, KDP_LOG_THREAD},
{{"watch"}, {"log watchpoint related activities"}, KDP_LOG_WATCHPOINTS},
};
Log::Channel ProcessKDPLog::g_channel(g_categories, KDP_LOG_DEFAULT);
void ProcessKDPLog::Initialize() { Log::Register("kdp-remote", g_channel); }

View File

@@ -0,0 +1,43 @@
//===-- ProcessKDPLog.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_ProcessKDPLog_h_
#define liblldb_ProcessKDPLog_h_
#include "lldb/Utility/Log.h"
#define KDP_LOG_PROCESS (1u << 1)
#define KDP_LOG_THREAD (1u << 2)
#define KDP_LOG_PACKETS (1u << 3)
#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
#define KDP_LOG_MEMORY_DATA_SHORT \
(1u << 5) // Log short memory reads/writes bytes
#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
#define KDP_LOG_BREAKPOINTS (1u << 7)
#define KDP_LOG_WATCHPOINTS (1u << 8)
#define KDP_LOG_STEP (1u << 9)
#define KDP_LOG_COMM (1u << 10)
#define KDP_LOG_ASYNC (1u << 11)
#define KDP_LOG_ALL (UINT32_MAX)
#define KDP_LOG_DEFAULT KDP_LOG_PACKETS
namespace lldb_private {
class ProcessKDPLog {
static Log::Channel g_channel;
public:
static void Initialize();
static Log *GetLogIfAllCategoriesSet(uint32_t mask) {
return g_channel.GetLogIfAll(mask);
}
};
}
#endif // liblldb_ProcessKDPLog_h_

View File

@@ -0,0 +1,151 @@
//===-- RegisterContextKDP_arm.cpp ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "RegisterContextKDP_arm.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "ProcessKDP.h"
#include "ThreadKDP.h"
using namespace lldb;
using namespace lldb_private;
RegisterContextKDP_arm::RegisterContextKDP_arm(ThreadKDP &thread,
uint32_t concrete_frame_idx)
: RegisterContextDarwin_arm(thread, concrete_frame_idx),
m_kdp_thread(thread) {}
RegisterContextKDP_arm::~RegisterContextKDP_arm() {}
int RegisterContextKDP_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
const DBG &dbg) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}

View File

@@ -0,0 +1,48 @@
//===-- RegisterContextKDP_arm.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_RegisterContextKDP_arm_h_
#define liblldb_RegisterContextKDP_arm_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
class ThreadKDP;
class RegisterContextKDP_arm : public RegisterContextDarwin_arm {
public:
RegisterContextKDP_arm(ThreadKDP &thread, uint32_t concrete_frame_idx);
virtual ~RegisterContextKDP_arm();
protected:
virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
ThreadKDP &m_kdp_thread;
};
#endif // liblldb_RegisterContextKDP_arm_h_

View File

@@ -0,0 +1,152 @@
//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "RegisterContextKDP_arm64.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "ProcessKDP.h"
#include "ThreadKDP.h"
using namespace lldb;
using namespace lldb_private;
RegisterContextKDP_arm64::RegisterContextKDP_arm64(ThreadKDP &thread,
uint32_t concrete_frame_idx)
: RegisterContextDarwin_arm64(thread, concrete_frame_idx),
m_kdp_thread(thread) {}
RegisterContextKDP_arm64::~RegisterContextKDP_arm64() {}
int RegisterContextKDP_arm64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm64::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm64::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm64::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm64::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm64::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm64::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_arm64::DoWriteDBG(lldb::tid_t tid, int flavor,
const DBG &dbg) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}

View File

@@ -0,0 +1,49 @@
//===-- RegisterContextKDP_arm64.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_RegisterContextKDP_arm64_h_
#define liblldb_RegisterContextKDP_arm64_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
class ThreadKDP;
class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 {
public:
RegisterContextKDP_arm64(ThreadKDP &thread, uint32_t concrete_frame_idx);
virtual ~RegisterContextKDP_arm64();
protected:
virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
ThreadKDP &m_kdp_thread;
};
#endif // liblldb_RegisterContextKDP_arm64_h_

View File

@@ -0,0 +1,119 @@
//===-- RegisterContextKDP_i386.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "RegisterContextKDP_i386.h"
#include "ProcessKDP.h"
#include "ThreadKDP.h"
using namespace lldb;
using namespace lldb_private;
RegisterContextKDP_i386::RegisterContextKDP_i386(ThreadKDP &thread,
uint32_t concrete_frame_idx)
: RegisterContextDarwin_i386(thread, concrete_frame_idx),
m_kdp_thread(thread) {}
RegisterContextKDP_i386::~RegisterContextKDP_i386() {}
int RegisterContextKDP_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}

View File

@@ -0,0 +1,43 @@
//===-- RegisterContextKDP_i386.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_RegisterContextKDP_i386_h_
#define liblldb_RegisterContextKDP_i386_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
class ThreadKDP;
class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 {
public:
RegisterContextKDP_i386(ThreadKDP &thread, uint32_t concrete_frame_idx);
virtual ~RegisterContextKDP_i386();
protected:
virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
ThreadKDP &m_kdp_thread;
};
#endif // liblldb_RegisterContextKDP_i386_h_

View File

@@ -0,0 +1,122 @@
//===-- RegisterContextKDP_x86_64.cpp ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "RegisterContextKDP_x86_64.h"
#include "ProcessKDP.h"
#include "ThreadKDP.h"
using namespace lldb;
using namespace lldb_private;
RegisterContextKDP_x86_64::RegisterContextKDP_x86_64(
ThreadKDP &thread, uint32_t concrete_frame_idx)
: RegisterContextDarwin_x86_64(thread, concrete_frame_idx),
m_kdp_thread(thread) {}
RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64() {}
int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_x86_64::DoReadFPU(lldb::tid_t tid, int flavor,
FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}
int RegisterContextKDP_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
Status error;
if (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
error)) {
if (error.Success())
return 0;
}
}
return -1;
}

View File

@@ -0,0 +1,43 @@
//===-- RegisterContextKDP_x86_64.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_RegisterContextKDP_x86_64_h_
#define liblldb_RegisterContextKDP_x86_64_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
class ThreadKDP;
class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 {
public:
RegisterContextKDP_x86_64(ThreadKDP &thread, uint32_t concrete_frame_idx);
virtual ~RegisterContextKDP_x86_64();
protected:
virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
ThreadKDP &m_kdp_thread;
};
#endif // liblldb_RegisterContextKDP_x86_64_h_

View File

@@ -0,0 +1,170 @@
//===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ThreadKDP.h"
#include "lldb/Utility/SafeMachO.h"
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/State.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "ProcessKDP.h"
#include "ProcessKDPLog.h"
#include "RegisterContextKDP_arm.h"
#include "RegisterContextKDP_arm64.h"
#include "RegisterContextKDP_i386.h"
#include "RegisterContextKDP_x86_64.h"
using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
// Thread Registers
//----------------------------------------------------------------------
ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid)
: Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
}
ThreadKDP::~ThreadKDP() {
Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
DestroyThread();
}
const char *ThreadKDP::GetName() {
if (m_thread_name.empty())
return NULL;
return m_thread_name.c_str();
}
const char *ThreadKDP::GetQueueName() { return NULL; }
void ThreadKDP::RefreshStateAfterStop() {
// Invalidate all registers in our register context. We don't set "force" to
// true because the stop reply packet might have had some register values
// that were expedited and these will already be copied into the register
// context by the time this function gets called. The KDPRegisterContext
// class has been made smart enough to detect when it needs to invalidate
// which registers are valid by putting hooks in the register read and
// register supply functions where they check the process stop ID and do
// the right thing.
const bool force = false;
lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
if (reg_ctx_sp)
reg_ctx_sp->InvalidateIfNeeded(force);
}
bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
void ThreadKDP::Dump(Log *log, uint32_t index) {}
bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
if (m_reg_context_sp.get() == NULL)
m_reg_context_sp = CreateRegisterContextForFrame(NULL);
return m_reg_context_sp;
}
lldb::RegisterContextSP
ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
lldb::RegisterContextSP reg_ctx_sp;
uint32_t concrete_frame_idx = 0;
if (frame)
concrete_frame_idx = frame->GetConcreteFrameIndex();
if (concrete_frame_idx == 0) {
ProcessSP process_sp(CalculateProcess());
if (process_sp) {
switch (static_cast<ProcessKDP *>(process_sp.get())
->GetCommunication()
.GetCPUType()) {
case llvm::MachO::CPU_TYPE_ARM:
reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx));
break;
case llvm::MachO::CPU_TYPE_ARM64:
reg_ctx_sp.reset(
new RegisterContextKDP_arm64(*this, concrete_frame_idx));
break;
case llvm::MachO::CPU_TYPE_I386:
reg_ctx_sp.reset(
new RegisterContextKDP_i386(*this, concrete_frame_idx));
break;
case llvm::MachO::CPU_TYPE_X86_64:
reg_ctx_sp.reset(
new RegisterContextKDP_x86_64(*this, concrete_frame_idx));
break;
default:
llvm_unreachable("Add CPU type support in KDP");
}
}
} else {
Unwind *unwinder = GetUnwinder();
if (unwinder)
reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
}
bool ThreadKDP::CalculateStopInfo() {
ProcessSP process_sp(GetProcess());
if (process_sp) {
if (m_cached_stop_info_sp) {
SetStopInfo(m_cached_stop_info_sp);
} else {
SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
}
return true;
}
return false;
}
void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
const DataExtractor &exc_reply_packet) {
lldb::offset_t offset = 0;
uint8_t reply_command = exc_reply_packet.GetU8(&offset);
if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
offset = 8;
const uint32_t count = exc_reply_packet.GetU32(&offset);
if (count >= 1) {
// const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
offset += 4; // Skip the useless CPU field
const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
// We have to make a copy of the stop info because the thread list
// will iterate through the threads and clear all stop infos..
// Let the StopInfoMachException::CreateStopReasonWithMachException()
// function update the PC if needed as we might hit a software breakpoint
// and need to decrement the PC (i386 and x86_64 need this) and KDP
// doesn't do this for us.
const bool pc_already_adjusted = false;
const bool adjust_pc_if_needed = true;
m_cached_stop_info_sp =
StopInfoMachException::CreateStopReasonWithMachException(
*this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
adjust_pc_if_needed);
}
}
}

View File

@@ -0,0 +1,77 @@
//===-- ThreadKDP.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_ThreadKDP_h_
#define liblldb_ThreadKDP_h_
#include <string>
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
class ProcessKDP;
class ThreadKDP : public lldb_private::Thread {
public:
ThreadKDP(lldb_private::Process &process, lldb::tid_t tid);
virtual ~ThreadKDP();
virtual void RefreshStateAfterStop();
virtual const char *GetName();
virtual const char *GetQueueName();
virtual lldb::RegisterContextSP GetRegisterContext();
virtual lldb::RegisterContextSP
CreateRegisterContextForFrame(lldb_private::StackFrame *frame);
void Dump(lldb_private::Log *log, uint32_t index);
static bool ThreadIDIsValid(lldb::tid_t thread);
bool ShouldStop(bool &step_more);
const char *GetBasicInfoAsString();
void SetName(const char *name) {
if (name && name[0])
m_thread_name.assign(name);
else
m_thread_name.clear();
}
lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
m_thread_dispatch_qaddr = thread_dispatch_qaddr;
}
void SetStopInfoFrom_KDP_EXCEPTION(
const lldb_private::DataExtractor &exc_reply_packet);
protected:
friend class ProcessKDP;
//------------------------------------------------------------------
// Member variables.
//------------------------------------------------------------------
std::string m_thread_name;
std::string m_dispatch_queue_name;
lldb::addr_t m_thread_dispatch_qaddr;
lldb::StopInfoSP m_cached_stop_info_sp;
//------------------------------------------------------------------
// Protected member functions.
//------------------------------------------------------------------
virtual bool CalculateStopInfo();
};
#endif // liblldb_ThreadKDP_h_