| # Copyright 2017-2021 Free Software Foundation, Inc. |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| # |
| # This file is part of the gdb testsuite. |
| |
| if {![is_aarch64_target]} { |
| verbose "Skipping ${gdb_test_file_name}." |
| return |
| } |
| |
| standard_testfile |
| if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { |
| return -1 |
| } |
| |
| if ![runto_main] { |
| return -1 |
| } |
| |
| gdb_breakpoint [gdb_get_line_number "breakpoint here"] |
| gdb_continue_to_breakpoint "breakpoint here" |
| |
| # Test that GDB manages caches correctly for tagged address. |
| # Read from P2, |
| gdb_test "x p2" "$hex:\[\t \]+0x000004d2" "x p2" |
| gdb_test_no_output "set variable i = 5678" |
| # Test that *P2 is updated. |
| gdb_test "x p2" "$hex:\[\t \]+0x0000162e" "x p2, updated" |
| |
| # Read from SP1->i, |
| gdb_test "print sp1->i" " = 1234" "print SP1->i" |
| # Write to SP2->i, |
| gdb_test_no_output "set variable sp2->i = 5678" |
| # Test that SP1->i is updated. |
| gdb_test "print sp1->i" " = 5678" "print SP1->i, updated" |
| |
| gdb_test "x/d &sp2->i" "$hex:\[\t \]+5678" |
| gdb_test "x/d &sp1->i" "$hex:\[\t \]+5678" |
| |
| # Test that the same disassembly is got when disassembling function vs |
| # tagged function pointer. |
| set insn1 "" |
| set insn2 "" |
| set test "disassemble foo,+8" |
| gdb_test_multiple $test $test { |
| -re ":\[\t \]+(\[a-z\]*)\[ \r\n\]+.*:\[\t \]+(\[a-z\]*).*$gdb_prompt $" { |
| set insn1 $expect_out(1,string) |
| set insn2 $expect_out(2,string) |
| pass $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 |
| } |
| |
| gdb_test "down" |
| gdb_test "finish" |
| |
| # 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 |
| } |