1# Copyright 2017-2023 Free Software Foundation, Inc. 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15# 16# This file is part of the gdb testsuite. 17 18# Test inserting read watchpoints on unaligned addresses. 19 20if {[skip_hw_watchpoint_tests]} { 21 return 0 22} 23 24standard_testfile 25if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { 26 return -1 27} 28 29if ![runto_main] { 30 return -1 31} 32 33gdb_breakpoint [gdb_get_line_number "start_again"] "Breakpoint $decimal at $hex" "start_again" 34 35set sizes {1 2 4 8} 36array set alignedend {1 1 2 2 3 4 4 4 5 8 6 8 7 8 8 8} 37 38set rwatch "rwatch" 39set rwatch_exp "Hardware read watchpoint" 40if {[istarget "s390*-*-*"]} { 41 # Target does not support this type of hardware watchpoint." 42 set rwatch "watch" 43 set rwatch_exp "Hardware watchpoint" 44} 45 46foreach wpsize $sizes { 47 for {set wpoffset 0} {$wpoffset < 8 / $wpsize} {incr wpoffset} { 48 set wpstart [expr $wpoffset * $wpsize] 49 set wpend [expr ($wpoffset + 1) * $wpsize] 50 set wpendaligned $alignedend($wpend) 51 foreach rdsize $sizes { 52 for {set rdoffset 0} {$rdoffset < 8 / $rdsize} {incr rdoffset} { 53 set rdstart [expr $rdoffset * $rdsize] 54 set rdend [expr ($rdoffset + 1) * $rdsize] 55 set expect_hit [expr max ($wpstart, $rdstart) < min ($wpend, $rdend)] 56 set test "$rwatch data.u.size$wpsize\[$wpoffset\]" 57 set wpnum "" 58 gdb_test_multiple $test $test { 59 -re "$rwatch_exp (\[0-9\]+): .*\r\n$gdb_prompt $" { 60 set wpnum $expect_out(1,string) 61 } 62 -re "Expression cannot be implemented with read/access watchpoint.\r\n$gdb_prompt $" { 63 if {$wpsize == 8 && [istarget "arm*-*-*"]} { 64 untested $test 65 continue 66 } 67 fail $test 68 } 69 } 70 gdb_test_no_output -nopass "set variable size = $rdsize" 71 gdb_test_no_output -nopass "set variable offset = $rdoffset" 72 set test "continue" 73 set got_hit 0 74 gdb_test_multiple $test $test { 75 -re "$rwatch_exp $wpnum:.*alue = .*\r\n$gdb_prompt $" { 76 set got_hit 1 77 send_gdb "continue\n" 78 exp_continue 79 } 80 -re " start_again .*\r\n$gdb_prompt $" { 81 } 82 } 83 gdb_test_no_output -nopass "delete $wpnum" 84 set test "wp(size=$wpsize offset=$wpoffset) rd(size=$rdsize offset=$rdoffset) expect=$expect_hit" 85 if {$expect_hit == $got_hit} { 86 pass $test 87 } else { 88 # We do not know if we run on a fixed Linux kernel 89 # or not. Report XFAIL only in the FAIL case. 90 if {$expect_hit == 0 && $rdstart < $wpendaligned} { 91 setup_xfail external/20207 "aarch64*-*-linux*" 92 } 93 if {!$expect_hit && [expr max ($wpstart / 8, $rdstart / 8) < min (($wpend + 7) / 8, ($rdend + 7) / 8)]} { 94 setup_xfail breakpoints/23131 "powerpc*-*-*" 95 } 96 fail $test 97 } 98 } 99 } 100 } 101} 102 103foreach wpcount {4 7} { 104 array set wpoffset_to_wpnum {} 105 for {set wpoffset 1} {$wpoffset <= $wpcount} {incr wpoffset} { 106 set test "$rwatch data.u.size1\[$wpoffset\]" 107 set wpnum "" 108 gdb_test_multiple $test $test { 109 -re "$rwatch_exp (\[0-9\]+): .*\r\n$gdb_prompt $" { 110 set wpoffset_to_wpnum($wpoffset) $expect_out(1,string) 111 } 112 -re "There are not enough available hardware resources for this watchpoint.\r\n$gdb_prompt $" { 113 if {$wpoffset > 1} { 114 setup_xfail breakpoints/23131 "powerpc*-*-*" 115 setup_xfail breakpoints/23131 "arm*-*-*" 116 } 117 fail $test 118 set wpoffset_to_wpnum($wpoffset) 0 119 } 120 } 121 } 122 gdb_test_no_output -nopass "set variable size = 1" 123 gdb_test_no_output -nopass "set variable offset = 1" 124 set test "continue" 125 set got_hit 0 126 gdb_test_multiple $test $test { 127 -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" { 128 } 129 -re "$rwatch_exp $wpoffset_to_wpnum(1):.*alue = .*\r\n$gdb_prompt $" { 130 set got_hit 1 131 send_gdb "continue\n" 132 exp_continue 133 } 134 -re " start_again .*\r\n$gdb_prompt $" { 135 } 136 } 137 for {set wpoffset 1} {$wpoffset <= $wpcount} {incr wpoffset} { 138 if {$wpoffset_to_wpnum($wpoffset)} { 139 gdb_test_no_output "delete $wpoffset_to_wpnum($wpoffset)" "" 140 } 141 } 142 set test "wpcount($wpcount)" 143 if {!$wpoffset_to_wpnum([expr $wpcount - 1])} { 144 untested $test 145 continue 146 } 147 if {$wpcount > 4} { 148 if {![istarget "s390*-*-*"]} { 149 setup_kfail tdep/22389 *-*-* 150 } 151 } 152 gdb_assert $got_hit $test 153} 154 155if ![runto_main] { 156 return -1 157} 158gdb_breakpoint [gdb_get_line_number "final_return"] "Breakpoint $decimal at $hex" "final_return" 159set test {watch data.u.size8twice[1]} 160set wpnum 0 161gdb_test_multiple $test $test { 162 -re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { 163 set wpnum $expect_out(1,string) 164 pass $gdb_test_name 165 } 166 -re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { 167 if {[istarget "arm*-*-*"]} { 168 untested $gdb_test_name 169 } else { 170 fail $gdb_test_name 171 } 172 } 173} 174if {$wpnum} { 175 set test "continue" 176 set got_hit 0 177 gdb_test_multiple $test $test { 178 -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" { 179 } 180 -re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" { 181 set got_hit 1 182 send_gdb "continue\n" 183 exp_continue 184 } 185 -re " final_return .*\r\n$gdb_prompt $" { 186 } 187 } 188 gdb_assert $got_hit "size8twice write" 189} 190