forked from OSchip/llvm-project
Fix for AArch64 watchpoint cache corruption in case of ptrace failure
Same fix has been submitted for Arm. Review can be found here: Differential revision: http://reviews.llvm.org/D14051 llvm-svn: 252298
This commit is contained in:
parent
5762a4f9d1
commit
f24741d9dc
|
@ -435,7 +435,7 @@ NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size
|
||||||
if (bp_index == LLDB_INVALID_INDEX32)
|
if (bp_index == LLDB_INVALID_INDEX32)
|
||||||
return LLDB_INVALID_INDEX32;
|
return LLDB_INVALID_INDEX32;
|
||||||
|
|
||||||
// Add new or update existing watchpoint
|
// Add new or update existing breakpoint
|
||||||
if ((m_hbr_regs[bp_index].control & 1) == 0)
|
if ((m_hbr_regs[bp_index].control & 1) == 0)
|
||||||
{
|
{
|
||||||
m_hbr_regs[bp_index].address = addr;
|
m_hbr_regs[bp_index].address = addr;
|
||||||
|
@ -446,8 +446,14 @@ NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size
|
||||||
error = WriteHardwareDebugRegs(eDREGTypeBREAK);
|
error = WriteHardwareDebugRegs(eDREGTypeBREAK);
|
||||||
|
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
|
{
|
||||||
|
m_hbr_regs[bp_index].address = 0;
|
||||||
|
m_hbr_regs[bp_index].control &= ~1;
|
||||||
|
m_hbr_regs[bp_index].refcount = 0;
|
||||||
|
|
||||||
return LLDB_INVALID_INDEX32;
|
return LLDB_INVALID_INDEX32;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_hbr_regs[bp_index].refcount++;
|
m_hbr_regs[bp_index].refcount++;
|
||||||
|
|
||||||
|
@ -481,6 +487,11 @@ NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint (uint32_t hw_idx)
|
||||||
}
|
}
|
||||||
else if (m_hbr_regs[hw_idx].refcount == 1)
|
else if (m_hbr_regs[hw_idx].refcount == 1)
|
||||||
{
|
{
|
||||||
|
// Create a backup we can revert to in case of failure.
|
||||||
|
lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
|
||||||
|
uint32_t tempControl = m_hbr_regs[hw_idx].control;
|
||||||
|
uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
|
||||||
|
|
||||||
m_hbr_regs[hw_idx].control &= ~1;
|
m_hbr_regs[hw_idx].control &= ~1;
|
||||||
m_hbr_regs[hw_idx].address = 0;
|
m_hbr_regs[hw_idx].address = 0;
|
||||||
m_hbr_regs[hw_idx].refcount = 0;
|
m_hbr_regs[hw_idx].refcount = 0;
|
||||||
|
@ -489,7 +500,13 @@ NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint (uint32_t hw_idx)
|
||||||
WriteHardwareDebugRegs(eDREGTypeBREAK);
|
WriteHardwareDebugRegs(eDREGTypeBREAK);
|
||||||
|
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
|
{
|
||||||
|
m_hbr_regs[hw_idx].control = tempControl;
|
||||||
|
m_hbr_regs[hw_idx].address = tempAddr;
|
||||||
|
m_hbr_regs[hw_idx].refcount = tempRefCount;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -595,8 +612,14 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
|
||||||
error = WriteHardwareDebugRegs(eDREGTypeWATCH);
|
error = WriteHardwareDebugRegs(eDREGTypeWATCH);
|
||||||
|
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
|
{
|
||||||
|
m_hwp_regs[wp_index].address = 0;
|
||||||
|
m_hwp_regs[wp_index].control &= ~1;
|
||||||
|
m_hwp_regs[wp_index].refcount = 0;
|
||||||
|
|
||||||
return LLDB_INVALID_INDEX32;
|
return LLDB_INVALID_INDEX32;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_hwp_regs[wp_index].refcount++;
|
m_hwp_regs[wp_index].refcount++;
|
||||||
|
|
||||||
|
@ -630,6 +653,11 @@ NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
|
||||||
}
|
}
|
||||||
else if (m_hwp_regs[wp_index].refcount == 1)
|
else if (m_hwp_regs[wp_index].refcount == 1)
|
||||||
{
|
{
|
||||||
|
// Create a backup we can revert to in case of failure.
|
||||||
|
lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
|
||||||
|
uint32_t tempControl = m_hwp_regs[wp_index].control;
|
||||||
|
uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
|
||||||
|
|
||||||
// Update watchpoint in local cache
|
// Update watchpoint in local cache
|
||||||
m_hwp_regs[wp_index].control &= ~1;
|
m_hwp_regs[wp_index].control &= ~1;
|
||||||
m_hwp_regs[wp_index].address = 0;
|
m_hwp_regs[wp_index].address = 0;
|
||||||
|
@ -639,7 +667,13 @@ NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
|
||||||
error = WriteHardwareDebugRegs(eDREGTypeWATCH);
|
error = WriteHardwareDebugRegs(eDREGTypeWATCH);
|
||||||
|
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
|
{
|
||||||
|
m_hwp_regs[wp_index].control = tempControl;
|
||||||
|
m_hwp_regs[wp_index].address = tempAddr;
|
||||||
|
m_hwp_regs[wp_index].refcount = tempRefCount;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -663,10 +697,18 @@ NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
lldb::addr_t tempAddr = 0;
|
||||||
|
uint32_t tempControl = 0, tempRefCount = 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < m_max_hwp_supported; i++)
|
for (uint32_t i = 0; i < m_max_hwp_supported; i++)
|
||||||
{
|
{
|
||||||
if (m_hwp_regs[i].control & 0x01)
|
if (m_hwp_regs[i].control & 0x01)
|
||||||
{
|
{
|
||||||
|
// Create a backup we can revert to in case of failure.
|
||||||
|
tempAddr = m_hwp_regs[i].address;
|
||||||
|
tempControl = m_hwp_regs[i].control;
|
||||||
|
tempRefCount = m_hwp_regs[i].refcount;
|
||||||
|
|
||||||
// Clear watchpoints in local cache
|
// Clear watchpoints in local cache
|
||||||
m_hwp_regs[i].control &= ~1;
|
m_hwp_regs[i].control &= ~1;
|
||||||
m_hwp_regs[i].address = 0;
|
m_hwp_regs[i].address = 0;
|
||||||
|
@ -676,9 +718,15 @@ NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
|
||||||
error = WriteHardwareDebugRegs(eDREGTypeWATCH);
|
error = WriteHardwareDebugRegs(eDREGTypeWATCH);
|
||||||
|
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
|
{
|
||||||
|
m_hwp_regs[i].control = tempControl;
|
||||||
|
m_hwp_regs[i].address = tempAddr;
|
||||||
|
m_hwp_regs[i].refcount = tempRefCount;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Error();
|
return Error();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue