diff options
author | Yao Qi <yao.qi@linaro.org> | 2017-12-08 17:27:03 +0000 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2017-12-08 17:27:03 +0000 |
commit | a0de8c21baf46c40ed8e62faef5f750b1e5453ea (patch) | |
tree | 137844459043552cc8546120dca8b353e1048f36 /gdb/testsuite/gdb.arch | |
parent | a738ea1d41daeec0cccb4ab6671f4f6d53bd9e18 (diff) | |
download | gdb-a0de8c21baf46c40ed8e62faef5f750b1e5453ea.zip gdb-a0de8c21baf46c40ed8e62faef5f750b1e5453ea.tar.gz gdb-a0de8c21baf46c40ed8e62faef5f750b1e5453ea.tar.bz2 |
Adjust breakpoint address by clearing non-significant bits
Tag in tagged address on AArch64 is treated as a non-significant bits of
address, which can be got by gdbarch method significant_addr_bit, and gdb
can clear these bits.
With this patch, when user sets a breakpoint on tagged address on AArch64,
GDB will drop the top byte of address, and put breakpoint at the new place,
as shown below,
(gdb) hbreak *func_ptr
warning: Breakpoint address adjusted from 0xf000000000400690 to 0x00400690.
Hardware assisted breakpoint 2 at 0x400690
(gdb) break *func_ptr
warning: Breakpoint address adjusted from 0xf000000000400690 to 0x00400690.
Breakpoint 3 at 0x400690
When program hits a breakpoint, the stopped pc reported by Linux kernel is
the address *without* tag, so it is better the address recorded in
breakpoint location is the one without tag too, so we can still match
breakpoint location address and stopped pc reported by Linux kernel, by
simple compare.
gdb:
2017-12-08 Yao Qi <yao.qi@linaro.org>
* breakpoint.c (adjust_breakpoint_address): Call
address_significant.
gdb/testsuite:
2017-12-08 Yao Qi <yao.qi@linaro.org>
* gdb.arch/aarch64-tagged-pointer.c (main): Update.
* gdb.arch/aarch64-tagged-pointer.exp: Add test for breakpoint.
Diffstat (limited to 'gdb/testsuite/gdb.arch')
-rw-r--r-- | gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp | 24 |
2 files changed, 32 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c index 7c90132..9bfe41e 100644 --- a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c +++ b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.c @@ -45,4 +45,12 @@ main (void) void (*func_ptr) (void) = foo; func_ptr = (void (*) (void)) ((uintptr_t) func_ptr | 0xf000000000000000ULL); sp2->i = 4321; /* breakpoint here. */ + + for (int i = 0; i < 2; i++) + { + foo (); + (*func_ptr) (); + } + + sp1->i = 8765; } diff --git a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp index 4f2b44c..fcab1b7 100644 --- a/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp +++ b/gdb/testsuite/gdb.arch/aarch64-tagged-pointer.exp @@ -65,3 +65,27 @@ gdb_test_multiple $test $test { gdb_test "disassemble func_ptr,+8" \ ":\[\t \]+$insn1\[ \r\n\]+.*:\[\t \]+$insn2.*" + +foreach_with_prefix bptype {"hbreak" "break"} { + + # Set a breakpoint on a tagged address, func_ptr, + gdb_test "$bptype *func_ptr" \ + "warning: Breakpoint address adjusted from .*reakpoint $decimal at .*" \ + "breakpoint at *func_ptr" + # Resume the program and expect it hits foo, + gdb_test "continue" \ + "Continuing\\..*Breakpoint \[0-9\]+, foo \\(\\) at .*" \ + "run until breakpoint set *func_ptr" + gdb_test "up" "foo \\(\\).*" "caller is foo" + delete_breakpoints + + # Set a breakpoint on normal function, call it through tagged + # function pointer. + gdb_test "$bptype foo" "reakpoint $decimal at .*" \ + "hardware breakpoint at foo" + gdb_test "continue" \ + "Continuing\\..*Breakpoint \[0-9\]+, foo \\(\\) at .*" \ + "run until breakpoint set foo" + gdb_test "up" "\\(\*func_ptr\\) \\(\\).*" "caller is *func_ptr" + delete_breakpoints +} |