[3/3] Clear non-significant bits of address in watchpoint
Commit Message
Nowadays, GDB can't set watchpoint on tagged address on AArch64,
(gdb) p p2
$1 = (int *) 0xf000fffffffff474
(gdb) watch *((int *) 0xf000fffffffff474)
Hardware watchpoint 2: *((int *) 0xf000fffffffff474)
(gdb) c
Continuing.
main () at
binutils-gdb/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c:45
45 void (*func_ptr) (void) = foo;
Unexpected error setting hardware debug registers
This patch is about setting watchpoint on a tagged address. Unlike
breakpoint, watchpoint record the expression rather than the address, and
when a watchpoint is fired, GDB checks the expression value changed
instead of matching address, so we can mask the watchpoint address by
getting rid of non-significant bits of address.
gdb:
2017-12-01 Yao Qi <yao.qi@linaro.org>
* breakpoint.c (update_watchpoint): Call
significant_addr.
gdb/testsuite:
2017-12-01 Yao Qi <yao.qi@linaro.org>
* gdb.arch/aarch64-tagged-pointer.c (main): Update.
* gdb.arch/aarch64-tagged-pointer.exp: Add tests for watchpoint.
---
gdb/breakpoint.c | 2 +-
gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c | 1 +
gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp | 14 ++++++++++++++
3 files changed, 16 insertions(+), 1 deletion(-)
Comments
Looks good to me with formatting nits pointed out below fixed.
On 12/08/2017 10:04 AM, Yao Qi wrote:
> 2017-12-01 Yao Qi <yao.qi@linaro.org>
>
> * breakpoint.c (update_watchpoint): Call
> significant_addr.
Wrong name: significant_addr -> address_significant.
Guess you went back and forth deciding the function name. :-)
> @@ -1867,7 +1867,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
> loc->gdbarch = get_type_arch (value_type (v));
>
> loc->pspace = frame_pspace;
> - loc->address = addr;
> + loc->address = address_significant (loc->gdbarch, addr);
Spurious space before '='.
Thanks,
Pedro Alves
@@ -1867,7 +1867,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
loc->gdbarch = get_type_arch (value_type (v));
loc->pspace = frame_pspace;
- loc->address = addr;
+ loc->address = address_significant (loc->gdbarch, addr);
if (bitsize != 0)
{
@@ -53,4 +53,5 @@ main (void)
}
sp1->i = 8765;
+ i = 1;
}
@@ -89,3 +89,17 @@ foreach_with_prefix bptype {"hbreak" "break"} {
gdb_test "up" "\\(\*func_ptr\\) \\(\\).*" "caller is *func_ptr"
delete_breakpoints
}
+
+gdb_test "down"
+gdb_test "finish"
+# Watch on tagged pointer.
+gdb_test "watch *sp2"
+gdb_test "continue" \
+ "Continuing\\..*Hardware watchpoint \[0-9\]+.*" \
+ "run until watchpoint on s1"
+delete_breakpoints
+
+gdb_test "watch *p2"
+gdb_test "continue" \
+ "Continuing\\..*Hardware watchpoint \[0-9\]+.*" \
+ "run until watchpoint on i"