[Lldb-commits] [lldb] r244750 - Fix AArch64 watchpoint handlers in NativeRegisterContextLinux_arm64
Omair Javaid via lldb-commits
lldb-commits at lists.llvm.org
Wed Aug 12 06:42:25 PDT 2015
Author: omjavaid
Date: Wed Aug 12 08:42:24 2015
New Revision: 244750
URL: http://llvm.org/viewvc/llvm-project?rev=244750&view=rev
Log:
Fix AArch64 watchpoint handlers in NativeRegisterContextLinux_arm64
http://reviews.llvm.org/D11899
Modified:
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp?rev=244750&r1=244749&r2=244750&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp Wed Aug 12 08:42:24 2015
@@ -391,16 +391,8 @@ NativeRegisterContextLinux_arm64::SetHar
if (log)
log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
-
- // Check if our hardware breakpoint and watchpoint information is updated.
- if (m_refresh_hwdebug_info)
- {
- ReadHardwareDebugInfo (m_max_hwp_supported, m_max_hbp_supported);
- m_refresh_hwdebug_info = false;
- }
+ // Read hardware breakpoint and watchpoint information.
+ ReadHardwareDebugInfo ();
uint32_t control_value, bp_index;
@@ -443,7 +435,8 @@ NativeRegisterContextLinux_arm64::SetHar
m_hbr_regs[bp_index].control = control_value;
m_hbr_regs[bp_index].refcount = 1;
- //TODO: PTRACE CALL HERE for an UPDATE
+ // PTRACE call to set corresponding hardware breakpoint register.
+ WriteHardwareDebugRegs(eDREGTypeBREAK);
}
else
m_hbr_regs[bp_index].refcount++;
@@ -459,6 +452,9 @@ NativeRegisterContextLinux_arm64::ClearH
if (log)
log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ // Read hardware breakpoint and watchpoint information.
+ ReadHardwareDebugInfo ();
+
if (hw_idx >= m_max_hbp_supported)
return false;
@@ -474,8 +470,8 @@ NativeRegisterContextLinux_arm64::ClearH
m_hbr_regs[hw_idx].address = 0;
m_hbr_regs[hw_idx].refcount = 0;
- //TODO: PTRACE CALL HERE for an UPDATE
- return true;
+ // PTRACE call to clear corresponding hardware breakpoint register.
+ WriteHardwareDebugRegs(eDREGTypeBREAK);
}
return false;
@@ -489,6 +485,9 @@ NativeRegisterContextLinux_arm64::NumSup
if (log)
log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ // Read hardware breakpoint and watchpoint information.
+ ReadHardwareDebugInfo ();
+
return m_max_hwp_supported;
}
@@ -499,33 +498,36 @@ NativeRegisterContextLinux_arm64::SetHar
if (log)
log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
-
- // Check if our hardware breakpoint and watchpoint information is updated.
- if (m_refresh_hwdebug_info)
- {
- ReadHardwareDebugInfo (m_max_hwp_supported, m_max_hbp_supported);
- m_refresh_hwdebug_info = false;
- }
+ // Read hardware breakpoint and watchpoint information.
+ ReadHardwareDebugInfo ();
uint32_t control_value, wp_index;
-
- if (watch_flags != 0x1 && watch_flags != 0x2 && watch_flags != 0x3)
- return 0;//Error ("Invalid read/write bits for watchpoint");
+ // Check if we are setting watchpoint other than read/write/access
+ // Also update watchpoint flag to match AArch64 write-read bit configuration.
+ switch (watch_flags)
+ {
+ case 1:
+ watch_flags = 2;
+ break;
+ case 2:
+ watch_flags = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
// Check if size has a valid hardware watchpoint length.
if (size != 1 && size != 2 && size != 4 && size != 8)
- return 0;//Error ("Invalid size for watchpoint");
+ return LLDB_INVALID_INDEX32;
// Check 8-byte alignment for hardware watchpoint target address.
// TODO: Add support for watching un-aligned addresses
if (addr & 0x07)
- return 0;//Error ("LLDB for AArch64 currently supports 8-byte alignment for hardware watchpoint target address.");
+ return LLDB_INVALID_INDEX32;
// Setup control value
control_value = watch_flags << 3;
@@ -554,12 +556,13 @@ NativeRegisterContextLinux_arm64::SetHar
// Add new or update existing watchpoint
if ((m_hwp_regs[wp_index].control & 1) == 0)
{
+ // Update watchpoint in local cache
m_hwp_regs[wp_index].address = addr;
m_hwp_regs[wp_index].control = control_value;
m_hwp_regs[wp_index].refcount = 1;
// PTRACE call to set corresponding watchpoint register.
- WriteHardwareDebugRegs(&addr, &control_value, 0, wp_index);
+ WriteHardwareDebugRegs(eDREGTypeWATCH);
}
else
m_hwp_regs[wp_index].refcount++;
@@ -575,9 +578,8 @@ NativeRegisterContextLinux_arm64::ClearH
if (log)
log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return false;
+ // Read hardware breakpoint and watchpoint information.
+ ReadHardwareDebugInfo ();
if (wp_index >= m_max_hwp_supported)
return false;
@@ -590,12 +592,13 @@ NativeRegisterContextLinux_arm64::ClearH
}
else if (m_hwp_regs[wp_index].refcount == 1)
{
+ // Update watchpoint in local cache
m_hwp_regs[wp_index].control &= ~1;
m_hwp_regs[wp_index].address = 0;
m_hwp_regs[wp_index].refcount = 0;
- //TODO: PTRACE CALL HERE for an UPDATE
- WriteHardwareDebugRegs(&m_hwp_regs[wp_index].address, &m_hwp_regs[wp_index].control, 0, wp_index);
+ // Ptrace call to update hardware debug registers
+ WriteHardwareDebugRegs(eDREGTypeWATCH);
return true;
}
@@ -610,22 +613,20 @@ NativeRegisterContextLinux_arm64::ClearA
if (log)
log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-
- Error ml_error;
- ml_error.SetErrorToErrno();
- if (!process_sp)
- return ml_error;
+ // Read hardware breakpoint and watchpoint information.
+ ReadHardwareDebugInfo ();
for (uint32_t i = 0; i < m_max_hwp_supported; i++)
{
if (m_hwp_regs[i].control & 0x01)
{
+ // Clear watchpoints in local cache
m_hwp_regs[i].control &= ~1;
m_hwp_regs[i].address = 0;
m_hwp_regs[i].refcount = 0;
- WriteHardwareDebugRegs(&m_hwp_regs[i].address, &m_hwp_regs[i].control, 0, i);
+ // Ptrace call to update hardware debug registers
+ WriteHardwareDebugRegs(eDREGTypeWATCH);
}
}
@@ -712,9 +713,13 @@ NativeRegisterContextLinux_arm64::GetWat
}
Error
-NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo(unsigned int &watch_count,
- unsigned int &break_count)
+NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo()
{
+ if (!m_refresh_hwdebug_info)
+ {
+ return Error();
+ }
+
::pid_t tid = m_thread.GetID();
int regset = NT_ARM_HW_WATCH;
@@ -725,20 +730,19 @@ NativeRegisterContextLinux_arm64::ReadHa
ioVec.iov_base = &dreg_state;
ioVec.iov_len = sizeof (dreg_state);
error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, ioVec.iov_len);
- watch_count = dreg_state.dbg_info & 0xff;
+ m_max_hwp_supported = dreg_state.dbg_info & 0xff;
regset = NT_ARM_HW_BREAK;
error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, ioVec.iov_len);
- break_count = dreg_state.dbg_info & 0xff;
+ m_max_hbp_supported = dreg_state.dbg_info & 0xff;
+
+ m_refresh_hwdebug_info = false;
return error;
}
Error
-NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(lldb::addr_t *addr_buf,
- uint32_t *cntrl_buf,
- int type,
- int count)
+NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType)
{
struct iovec ioVec;
struct user_hwdebug_state dreg_state;
@@ -748,18 +752,28 @@ NativeRegisterContextLinux_arm64::WriteH
ioVec.iov_base = &dreg_state;
ioVec.iov_len = sizeof (dreg_state);
- if (type == 0)
- type = NT_ARM_HW_WATCH;
- else
- type = NT_ARM_HW_BREAK;
+ if (hwbType == eDREGTypeWATCH)
+ {
+ hwbType = NT_ARM_HW_WATCH;
- for (int i = 0; i < count; i++)
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++)
+ {
+ dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
+ dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
+ }
+ }
+ else
{
- dreg_state.dbg_regs[i].addr = addr_buf[i];
- dreg_state.dbg_regs[i].ctrl = cntrl_buf[i];
+ hwbType = NT_ARM_HW_BREAK;
+
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++)
+ {
+ dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address;
+ dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control;
+ }
}
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &type, &ioVec, ioVec.iov_len);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &hwbType, &ioVec, ioVec.iov_len);
}
Error
Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h?rev=244750&r1=244749&r2=244750&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h Wed Aug 12 08:42:24 2015
@@ -82,6 +82,13 @@ namespace process_linux {
bool
WatchpointIsEnabled(uint32_t wp_index);
+ // Debug register type select
+ enum DREGType
+ {
+ eDREGTypeWATCH = 0,
+ eDREGTypeBREAK
+ };
+
protected:
Error
DoReadRegisterValue(uint32_t offset,
@@ -172,10 +179,10 @@ namespace process_linux {
IsFPR(unsigned reg) const;
Error
- ReadHardwareDebugInfo(unsigned int &watch_count , unsigned int &break_count);
+ ReadHardwareDebugInfo();
Error
- WriteHardwareDebugRegs(lldb::addr_t *addr_buf, uint32_t *cntrl_buf, int type, int count);
+ WriteHardwareDebugRegs(int hwbType);
};
} // namespace process_linux
More information about the lldb-commits
mailing list