diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/aarch64-linux-nat.c | 8 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp | 27 | ||||
-rw-r--r-- | gdbserver/ChangeLog | 5 | ||||
-rw-r--r-- | gdbserver/linux-aarch64-low.cc | 24 |
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]; |