[Lldb-commits] [lldb] r273863 - Allow unaligned byte/word selection watchpoints for arm- linux/android targets.
Omair Javaid via lldb-commits
lldb-commits at lists.llvm.org
Mon Jun 27 04:18:23 PDT 2016
Author: omjavaid
Date: Mon Jun 27 06:18:23 2016
New Revision: 273863
URL: http://llvm.org/viewvc/llvm-project?rev=273863&view=rev
Log:
Allow unaligned byte/word selection watchpoints for arm- linux/android targets.
Differential revision: http://reviews.llvm.org/D21516
Modified:
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp?rev=273863&r1=273862&r2=273863&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp Mon Jun 27 06:18:23 2016
@@ -614,6 +614,7 @@ NativeRegisterContextLinux_arm::SetHardw
return LLDB_INVALID_INDEX32;
uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
+ lldb::addr_t real_addr = addr;
// Check if we are setting watchpoint other than read/write/access
// Also update watchpoint flag to match Arm write-read bit configuration.
@@ -637,7 +638,24 @@ NativeRegisterContextLinux_arm::SetHardw
if (size == 0 || size > 4)
return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
+ // Check 4-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 4-byte alligned addresses as well.
+ if (addr & 0x03)
+ {
+ uint8_t watch_mask = (addr & 0x03) + size;
+
+ if (watch_mask > 0x04)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
+
+ addr = addr & (~0x03);
+ }
+
+ // We can only watch up to four bytes that follow a 4 byte aligned address
// per watchpoint register pair, so make sure we can properly encode this.
addr_word_offset = addr % 4;
byte_mask = ((1u << size) - 1u) << addr_word_offset;
@@ -682,6 +700,7 @@ NativeRegisterContextLinux_arm::SetHardw
if ((m_hwp_regs[wp_index].control & 1) == 0)
{
// Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
m_hwp_regs[wp_index].address = addr;
m_hwp_regs[wp_index].control = control_value;
m_hwp_regs[wp_index].refcount = 1;
@@ -864,6 +883,7 @@ NativeRegisterContextLinux_arm::GetWatch
if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
&& trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
{
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
return Error();
}
}
@@ -884,7 +904,24 @@ NativeRegisterContextLinux_arm::GetWatch
return LLDB_INVALID_ADDRESS;
if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].address;
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_arm::GetWatchpointHitAddress (uint32_t wp_index)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
else
return LLDB_INVALID_ADDRESS;
}
Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h?rev=273863&r1=273862&r2=273863&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h Mon Jun 27 06:18:23 2016
@@ -74,6 +74,9 @@ namespace process_linux {
GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
lldb::addr_t
+ GetWatchpointHitAddress (uint32_t wp_index) override;
+
+ lldb::addr_t
GetWatchpointAddress (uint32_t wp_index) override;
uint32_t
@@ -162,6 +165,8 @@ namespace process_linux {
struct DREG
{
lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
uint32_t control; // Breakpoint/watchpoint control value.
uint32_t refcount; // Serves as enable/disable and refernce counter.
};
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=273863&r1=273862&r2=273863&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Jun 27 06:18:23 2016
@@ -2060,7 +2060,7 @@ ProcessGDBRemote::SetThreadStopInfo (lld
WatchpointSP wp_sp;
ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
if ((core >= ArchSpec::kCore_mips_first && core <= ArchSpec::kCore_mips_last) ||
- (core >= ArchSpec::eCore_arm_arm64 && core <= ArchSpec::eCore_arm_aarch64))
+ (core >= ArchSpec::eCore_arm_generic && core <= ArchSpec::eCore_arm_aarch64))
wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr);
if (!wp_sp)
wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
More information about the lldb-commits
mailing list