summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp661
1 files changed, 436 insertions, 225 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index aef1ae995cb..ea6d6c318ca 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -7,19 +7,31 @@
//
//===----------------------------------------------------------------------===//
+#if defined (__arm64__) || defined (__aarch64__)
+
#include "NativeRegisterContextLinux_arm64.h"
-#include "lldb/lldb-private-forward.h"
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
-#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
+
#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "lldb/Core/Log.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
+
+// System includes - They have to be included after framework includes because they define some
+// macros which collide with variable names in other modules
+#include <sys/socket.h>
+// NT_PRSTATUS and NT_FPREGSET definition
+#include <elf.h>
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
+#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
using namespace lldb;
using namespace lldb_private;
@@ -125,13 +137,341 @@ g_reg_sets_arm64[k_num_register_sets] =
{ "Floating Point Registers", "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 }
};
-NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *reg_info_interface_p) :
- NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p)
+namespace
+{
+
+class ReadRegOperation : public NativeProcessLinux::Operation
+{
+public:
+ ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name, RegisterValue &value) :
+ m_tid(tid),
+ m_offset(static_cast<uintptr_t>(offset)),
+ m_reg_name(reg_name),
+ m_value(value)
+ { }
+
+ void
+ Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ uintptr_t m_offset;
+ const char *m_reg_name;
+ RegisterValue &m_value;
+};
+
+class WriteRegOperation : public NativeProcessLinux::Operation
+{
+public:
+ WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, const RegisterValue &value) :
+ m_tid(tid),
+ m_offset(offset),
+ m_reg_name(reg_name),
+ m_value(value)
+ { }
+
+ void
+ Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ uintptr_t m_offset;
+ const char *m_reg_name;
+ const RegisterValue &m_value;
+};
+
+class ReadGPROperation : public NativeProcessLinux::Operation
+{
+public:
+ ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+ { }
+
+ void Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ void *m_buf;
+ size_t m_buf_size;
+};
+
+class WriteGPROperation : public NativeProcessLinux::Operation
+{
+public:
+ WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) :
+ m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+ { }
+
+ void Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ void *m_buf;
+ size_t m_buf_size;
+};
+
+class ReadFPROperation : public NativeProcessLinux::Operation
+{
+public:
+ ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
+ : m_tid(tid),
+ m_buf(buf),
+ m_buf_size(buf_size)
+ { }
+
+ void Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ void *m_buf;
+ size_t m_buf_size;
+};
+
+class WriteFPROperation : public NativeProcessLinux::Operation
+{
+public:
+ WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+ { }
+
+ void Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ void *m_buf;
+ size_t m_buf_size;
+};
+
+class ReadDBGROperation : public NativeProcessLinux::Operation
+{
+public:
+ ReadDBGROperation(lldb::tid_t tid, unsigned int &count_wp, unsigned int &count_bp)
+ : m_tid(tid),
+ m_count_wp(count_wp),
+ m_count_bp(count_bp)
+ { }
+
+ void Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ unsigned int &m_count_wp;
+ unsigned int &m_count_bp;
+};
+
+class WriteDBGROperation : public NativeProcessLinux::Operation
+{
+public:
+ WriteDBGROperation(lldb::tid_t tid, lldb::addr_t *addr_buf,
+ uint32_t *cntrl_buf, int type, int count)
+ : m_tid(tid),
+ m_address(addr_buf),
+ m_control(cntrl_buf),
+ m_type(type),
+ m_count(count)
+ { }
+
+ void Execute(NativeProcessLinux *monitor) override;
+
+private:
+ lldb::tid_t m_tid;
+ lldb::addr_t * m_address;
+ uint32_t * m_control;
+ int m_type;
+ int m_count;
+};
+
+} // end of anonymous namespace
+
+void
+ReadRegOperation::Execute(NativeProcessLinux *monitor)
+{
+ if (m_offset > sizeof(struct user_pt_regs))
+ {
+ uintptr_t offset = m_offset - sizeof(struct user_pt_regs);
+ if (offset > sizeof(struct user_fpsimd_state))
+ {
+ m_error.SetErrorString("invalid offset value");
+ return;
+ }
+ elf_fpregset_t regs;
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+ if (m_error.Success())
+ {
+ ArchSpec arch;
+ if (monitor->GetArchitecture(arch))
+ m_value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16, arch.GetByteOrder());
+ else
+ m_error.SetErrorString("failed to get architecture");
+ }
+ }
+ else
+ {
+ elf_gregset_t regs;
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+ if (m_error.Success())
+ {
+ ArchSpec arch;
+ if (monitor->GetArchitecture(arch))
+ m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder());
+ else
+ m_error.SetErrorString("failed to get architecture");
+ }
+ }
+}
+
+void
+WriteRegOperation::Execute(NativeProcessLinux *monitor)
+{
+ if (m_offset > sizeof(struct user_pt_regs))
+ {
+ uintptr_t offset = m_offset - sizeof(struct user_pt_regs);
+ if (offset > sizeof(struct user_fpsimd_state))
+ {
+ m_error.SetErrorString("invalid offset value");
+ return;
+ }
+ elf_fpregset_t regs;
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+ if (m_error.Success())
+ {
+ ::memcpy((void *)(((unsigned char *)(&regs)) + offset), m_value.GetBytes(), 16);
+ NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+ }
+ }
+ else
+ {
+ elf_gregset_t regs;
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+ if (m_error.Success())
+ {
+ ::memcpy((void *)(((unsigned char *)(&regs)) + m_offset), m_value.GetBytes(), 8);
+ NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+ }
+ }
+}
+
+void
+ReadGPROperation::Execute(NativeProcessLinux *monitor)
+{
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+
+ ioVec.iov_base = m_buf;
+ ioVec.iov_len = m_buf_size;
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+WriteGPROperation::Execute(NativeProcessLinux *monitor)
+{
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+
+ ioVec.iov_base = m_buf;
+ ioVec.iov_len = m_buf_size;
+ NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+ReadFPROperation::Execute(NativeProcessLinux *monitor)
+{
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = m_buf;
+ ioVec.iov_len = m_buf_size;
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+WriteFPROperation::Execute(NativeProcessLinux *monitor)
{
- switch (reg_info_interface_p->m_target_arch.GetMachine())
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = m_buf;
+ ioVec.iov_len = m_buf_size;
+ NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+ReadDBGROperation::Execute(NativeProcessLinux *monitor)
+{
+ int regset = NT_ARM_HW_WATCH;
+ struct iovec ioVec;
+ struct user_hwdebug_state dreg_state;
+
+ ioVec.iov_base = &dreg_state;
+ ioVec.iov_len = sizeof (dreg_state);
+
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, ioVec.iov_len, m_error);
+
+ m_count_wp = dreg_state.dbg_info & 0xff;
+ regset = NT_ARM_HW_BREAK;
+
+ NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, ioVec.iov_len, m_error);
+ m_count_bp = dreg_state.dbg_info & 0xff;
+}
+
+void
+WriteDBGROperation::Execute(NativeProcessLinux *monitor)
+{
+ struct iovec ioVec;
+ struct user_hwdebug_state dreg_state;
+
+ memset (&dreg_state, 0, sizeof (dreg_state));
+ ioVec.iov_base = &dreg_state;
+ ioVec.iov_len = sizeof (dreg_state);
+
+ if (m_type == 0)
+ m_type = NT_ARM_HW_WATCH;
+ else
+ m_type = NT_ARM_HW_BREAK;
+
+ for (int i = 0; i < m_count; i++)
+ {
+ dreg_state.dbg_regs[i].addr = m_address[i];
+ dreg_state.dbg_regs[i].ctrl = m_control[i];
+ }
+
+ NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &m_type, &ioVec, ioVec.iov_len, m_error);
+}
+
+NativeRegisterContextLinux*
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+{
+ return new NativeRegisterContextLinux_arm64(target_arch, native_thread, concrete_frame_idx);
+}
+
+NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) :
+ NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm64(target_arch))
+{
+ switch (target_arch.GetMachine())
{
case llvm::Triple::aarch64:
m_reg_info.num_registers = k_num_registers_arm64;
@@ -189,11 +529,9 @@ NativeRegisterContextLinux_arm64::ReadRegister (const RegisterInfo *reg_info, Re
if (IsFPR(reg))
{
- if (!ReadFPR())
- {
- error.SetErrorString ("failed to read floating point register");
+ error = ReadFPR();
+ if (error.Fail())
return error;
- }
}
else
{
@@ -279,10 +617,9 @@ NativeRegisterContextLinux_arm64::WriteRegister (const RegisterInfo *reg_info, c
return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
}
- if (!WriteFPR())
- {
- return Error ("NativeRegisterContextLinux_arm64::WriteRegister: WriteFPR failed");
- }
+ Error error = WriteFPR();
+ if (error.Fail())
+ return error;
return Error ();
}
@@ -299,17 +636,13 @@ NativeRegisterContextLinux_arm64::ReadAllRegisterValues (lldb::DataBufferSP &dat
if (!data_sp)
return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
- if (!ReadGPR ())
- {
- error.SetErrorString ("ReadGPR() failed");
+ error = ReadGPR();
+ if (error.Fail())
return error;
- }
- if (!ReadFPR ())
- {
- error.SetErrorString ("ReadFPR() failed");
+ error = ReadFPR();
+ if (error.Fail())
return error;
- }
uint8_t *dst = data_sp->GetBytes ();
if (dst == nullptr)
@@ -351,120 +684,20 @@ NativeRegisterContextLinux_arm64::WriteAllRegisterValues (const lldb::DataBuffer
}
::memcpy (&m_gpr_arm64, src, GetRegisterInfoInterface ().GetGPRSize ());
- if (!WriteGPR ())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
+ error = WriteGPR();
+ if (error.Fail())
return error;
- }
src += GetRegisterInfoInterface ().GetGPRSize ();
::memcpy (&m_fpr, src, sizeof(m_fpr));
- if (!WriteFPR ())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
+ error = WriteFPR();
+ if (error.Fail())
return error;
- }
return error;
}
-Error
-NativeRegisterContextLinux_arm64::WriteRegisterRaw (uint32_t reg_index, const RegisterValue &reg_value)
-{
- Error error;
-
- uint32_t reg_to_write = reg_index;
- RegisterValue value_to_write = reg_value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- error = ReadRegister(full_reg_info, full_value);
- if (error.Fail ())
- return error;
-
- lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = reg_value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- {
- error.SetErrorString ("NativeProcessProtocol is NULL");
- return error;
- }
-
- const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
- assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
- if (!register_to_write_info_p)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_arm64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
- return error;
- }
-
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
- return process_p->WriteRegisterValue(m_thread.GetID(),
- register_to_write_info_p->byte_offset,
- register_to_write_info_p->name,
- value_to_write);
-}
-
-Error
-NativeRegisterContextLinux_arm64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
-{
- Error error;
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
- if (!reg_info)
- {
- error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
- return error;
- }
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- {
- error.SetErrorString ("NativeProcessProtocol is NULL");
- return error;
- }
-
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
- return process_p->ReadRegisterValue(m_thread.GetID(),
- reg_info->byte_offset,
- reg_info->name,
- reg_info->byte_size,
- reg_value);
-}
-
bool
NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const
{
@@ -472,79 +705,11 @@ NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const
}
bool
-NativeRegisterContextLinux_arm64::ReadGPR()
-{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
- return process_p->ReadGPR (m_thread.GetID (), &m_gpr_arm64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
-}
-
-bool
-NativeRegisterContextLinux_arm64::WriteGPR()
-{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
- return process_p->WriteGPR (m_thread.GetID (), &m_gpr_arm64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
-}
-
-bool
NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const
{
return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-bool
-NativeRegisterContextLinux_arm64::ReadFPR ()
-{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
-
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
- return process_p->ReadFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
-}
-
-bool
-NativeRegisterContextLinux_arm64::WriteFPR ()
-{
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
-
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
- return process_p->WriteFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
-}
-
-lldb::ByteOrder
-NativeRegisterContextLinux_arm64::GetByteOrder() const
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return byte_order;
-
- if (!process_sp->GetByteOrder (byte_order))
- {
- // FIXME log here
- }
-
- return byte_order;
-}
-
-size_t
-NativeRegisterContextLinux_arm64::GetGPRSize() const
-{
- return GetRegisterInfoInterface().GetGPRSize();
-}
-
uint32_t
NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
{
@@ -557,12 +722,10 @@ NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size
if (!process_sp)
return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
// Check if our hardware breakpoint and watchpoint information is updated.
if (m_refresh_hwdebug_info)
{
- process_p->ReadHardwareDebugInfo (m_thread.GetID (), m_max_hwp_supported,
- m_max_hbp_supported);
+ ReadHardwareDebugInfo (m_max_hwp_supported, m_max_hbp_supported);
m_refresh_hwdebug_info = false;
}
@@ -668,12 +831,11 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
if (!process_sp)
return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+
// Check if our hardware breakpoint and watchpoint information is updated.
if (m_refresh_hwdebug_info)
{
- process_p->ReadHardwareDebugInfo (m_thread.GetID (), m_max_hwp_supported,
- m_max_hbp_supported);
+ ReadHardwareDebugInfo (m_max_hwp_supported, m_max_hbp_supported);
m_refresh_hwdebug_info = false;
}
@@ -724,8 +886,7 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
m_hwp_regs[wp_index].refcount = 1;
// PTRACE call to set corresponding watchpoint register.
- process_p->WriteHardwareDebugRegs(m_thread.GetID (), &addr,
- &control_value, 0, wp_index);
+ WriteHardwareDebugRegs(&addr, &control_value, 0, wp_index);
}
else
m_hwp_regs[wp_index].refcount++;
@@ -745,8 +906,6 @@ NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
if (!process_sp)
return false;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
if (wp_index >= m_max_hwp_supported)
return false;
@@ -763,10 +922,7 @@ NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
m_hwp_regs[wp_index].refcount = 0;
//TODO: PTRACE CALL HERE for an UPDATE
- process_p->WriteHardwareDebugRegs(m_thread.GetID (),
- &m_hwp_regs[wp_index].address,
- &m_hwp_regs[wp_index].control,
- 0, wp_index);
+ WriteHardwareDebugRegs(&m_hwp_regs[wp_index].address, &m_hwp_regs[wp_index].control, 0, wp_index);
return true;
}
@@ -788,8 +944,6 @@ NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
if (!process_sp)
return ml_error;
- NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
for (uint32_t i = 0; i < m_max_hwp_supported; i++)
{
if (m_hwp_regs[i].control & 0x01)
@@ -798,10 +952,7 @@ NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
m_hwp_regs[i].address = 0;
m_hwp_regs[i].refcount = 0;
- process_p->WriteHardwareDebugRegs(m_thread.GetID (),
- &m_hwp_regs[i].address,
- &m_hwp_regs[i].control,
- 0, i);
+ WriteHardwareDebugRegs(&m_hwp_regs[i].address, &m_hwp_regs[i].control, 0, i);
}
}
@@ -887,13 +1038,73 @@ NativeRegisterContextLinux_arm64::GetWatchpointAddress (uint32_t wp_index)
return LLDB_INVALID_ADDRESS;
}
-bool
-NativeRegisterContextLinux_arm64::HardwareSingleStep (bool enable)
+Error
+NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo(unsigned int &watch_count,
+ unsigned int &break_count)
{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess());
+ if (!process_sp)
+ return Error("NativeProcessProtocol is NULL");
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*>(process_sp.get());
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ ReadDBGROperation op(m_thread.GetID(), watch_count, break_count);
+ return process_p->DoOperation(&op);
+}
- return false;
+Error
+NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(lldb::addr_t *addr_buf,
+ uint32_t *cntrl_buf,
+ int type,
+ int count)
+{
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess());
+ if (!process_sp)
+ return Error("NativeProcessProtocol is NULL");
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*>(process_sp.get());
+
+ WriteDBGROperation op(m_thread.GetID(), addr_buf, cntrl_buf, type, count);
+ return process_p->DoOperation(&op);
}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetReadRegisterValueOperation(uint32_t offset,
+ const char* reg_name,
+ uint32_t size,
+ RegisterValue &value)
+{
+ return NativeProcessLinux::OperationUP(new ReadRegOperation(m_thread.GetID(), offset, reg_name, value));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetWriteRegisterValueOperation(uint32_t offset,
+ const char* reg_name,
+ const RegisterValue &value)
+{
+ return NativeProcessLinux::OperationUP(new WriteRegOperation(m_thread.GetID(), offset, reg_name, value));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetReadGPROperation(void *buf, size_t buf_size)
+{
+ return NativeProcessLinux::OperationUP(new ReadGPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetWriteGPROperation(void *buf, size_t buf_size)
+{
+ return NativeProcessLinux::OperationUP(new WriteGPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetReadFPROperation(void *buf, size_t buf_size)
+{
+ return NativeProcessLinux::OperationUP(new ReadFPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetWriteFPROperation(void *buf, size_t buf_size)
+{
+ return NativeProcessLinux::OperationUP(new WriteFPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+#endif // defined (__arm64__) || defined (__aarch64__)
OpenPOWER on IntegriCloud