aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/aarch64-linux-nat.c8
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c8
-rw-r--r--gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp27
-rw-r--r--gdbserver/ChangeLog5
-rw-r--r--gdbserver/linux-aarch64-low.cc24
7 files changed, 71 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 979d26e..764329d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2020-12-16 Luis Machado <luis.machado@linaro.org>
+
+ * aarch64-linux-nat.c
+ (aarch64_linux_nat_target::stopped_data_address): Handle the TBI.
+
2020-12-15 Rae Kim <rae.kim@gmail.com>
* cli/cli-script.c (do_document_command): Rename from
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 77d5863..b3bbde4 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -877,6 +877,13 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
|| (siginfo.si_code & 0xffff) != TRAP_HWBKPT)
return false;
+ /* Make sure to ignore the top byte, otherwise we may not recognize a
+ hardware watchpoint hit. The stopped data addresses coming from the
+ kernel can potentially be tagged addresses. */
+ struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
+ const CORE_ADDR addr_trap
+ = address_significant (gdbarch, (CORE_ADDR) siginfo.si_addr);
+
/* Check if the address matches any watched address. */
state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
@@ -884,7 +891,6 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
const unsigned int offset
= aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
- const CORE_ADDR addr_trap = (CORE_ADDR) siginfo.si_addr;
const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 549475a..7249ae6 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2020-12-16 Luis Machado <luis.machado@linaro.org>
+
+ * gdb.arch/aarch64-tagged-pointer.c (main): Add a few more
+ pointer-based memory accesses.
+ * gdb.arch/aarch64-tagged-pointer.exp: Exercise additional
+ hw watchpoint cases.
+
2020-12-15 Rae Kim <rae.kim@gmail.com>
* gdb.base/document.exp: New test.
diff --git a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c
index 609d4f2..658c309 100644
--- a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c
+++ b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c
@@ -53,5 +53,11 @@ main (void)
}
sp1->i = 8765;
- i = 1;
+ sp2->i = 4321;
+ sp1->i = 8765;
+ sp2->i = 4321;
+ *p1 = 1;
+ *p2 = 2;
+ *p1 = 1;
+ *p2 = 2;
}
diff --git a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp
index 957571f..01c2b57 100644
--- a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp
+++ b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp
@@ -92,14 +92,21 @@ foreach_with_prefix bptype {"hbreak" "break"} {
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"
+# sp1 and p1 are untagged pointers, but sp2 and p2 are tagged pointers.
+# Cycle through all of them to make sure the following combinations work:
+#
+# hw watch on untagged address, hit on untagged address.
+# hw watch on tagged address, hit on untagged address.
+# hw watch on untagged address, hit on tagged address.
+# hw watch on tagged address, hit on tagged address.
+foreach symbol {"sp1" "sp2" "p1" "p2"} {
+ gdb_test "watch *${symbol}"
+ gdb_test "continue" \
+ "Continuing\\..*Hardware watchpoint \[0-9\]+.*" \
+ "run until watchpoint on ${symbol}"
+ gdb_test "continue" \
+ "Continuing\\..*Hardware watchpoint \[0-9\]+.*" \
+ "run until watchpoint on ${symbol}, 2nd hit"
+ delete_breakpoints
+}
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog
index 9756d4c..16a9609 100644
--- a/gdbserver/ChangeLog
+++ b/gdbserver/ChangeLog
@@ -1,3 +1,8 @@
+2020-12-16 Luis Machado <luis.machado@linaro.org>
+
+ * linux-aarch64-low.cc (address_significant): New function.
+ (aarch64_target::low_stopped_data_address): Handle the TBI.
+
2020-12-11 Andrew Burgess <andrew.burgess@embecosm.com>
* Makefile.in (IPA_LIB): Include libiberty library.
diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc
index 08208ae..f39d7c2 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -458,6 +458,23 @@ aarch64_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
return ret;
}
+/* Return the address only having significant bits. This is used to ignore
+ the top byte (TBI). */
+
+static CORE_ADDR
+address_significant (CORE_ADDR addr)
+{
+ /* Clear insignificant bits of a target address and sign extend resulting
+ address. */
+ int addr_bit = 56;
+
+ CORE_ADDR sign = (CORE_ADDR) 1 << (addr_bit - 1);
+ addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
+ addr = (addr ^ sign) - sign;
+
+ return addr;
+}
+
/* Implementation of linux target ops method "low_stopped_data_address". */
CORE_ADDR
@@ -478,6 +495,12 @@ aarch64_target::low_stopped_data_address ()
|| (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
return (CORE_ADDR) 0;
+ /* Make sure to ignore the top byte, otherwise we may not recognize a
+ hardware watchpoint hit. The stopped data addresses coming from the
+ kernel can potentially be tagged addresses. */
+ const CORE_ADDR addr_trap
+ = address_significant ((CORE_ADDR) siginfo.si_addr);
+
/* Check if the address matches any watched address. */
state = aarch64_get_debug_reg_state (pid_of (current_thread));
for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
@@ -485,7 +508,6 @@ aarch64_target::low_stopped_data_address ()
const unsigned int offset
= aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
- const CORE_ADDR addr_trap = (CORE_ADDR) siginfo.si_addr;
const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];