1# Copyright 2017-2020 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 untested "could not run to main" 31 return -1 32} 33 34gdb_breakpoint [gdb_get_line_number "start_again"] "Breakpoint $decimal at $hex" "start_again" 35 36set sizes {1 2 4 8} 37array set alignedend {1 1 2 2 3 4 4 4 5 8 6 8 7 8 8 8} 38 39set rwatch "rwatch" 40set rwatch_exp "Hardware read watchpoint" 41if {[istarget "s390*-*-*"]} { 42 # Target does not support this type of hardware watchpoint." 43 set rwatch "watch" 44 set rwatch_exp "Hardware watchpoint" 45} 46 47foreach wpsize $sizes { 48 for {set wpoffset 0} {$wpoffset < 8 / $wpsize} {incr wpoffset} { 49 set wpstart [expr $wpoffset * $wpsize] 50 set wpend [expr ($wpoffset + 1) * $wpsize] 51 set wpendaligned $alignedend($wpend) 52 foreach rdsize $sizes { 53 for {set rdoffset 0} {$rdoffset < 8 / $rdsize} {incr rdoffset} { 54 set rdstart [expr $rdoffset * $rdsize] 55 set rdend [expr ($rdoffset + 1) * $rdsize] 56 set expect_hit [expr max ($wpstart, $rdstart) < min ($wpend, $rdend)] 57 set test "$rwatch data.u.size$wpsize\[$wpoffset\]" 58 set wpnum "" 59 gdb_test_multiple $test $test { 60 -re "$rwatch_exp (\[0-9\]+): .*\r\n$gdb_prompt $" { 61 set wpnum $expect_out(1,string) 62 } 63 -re "Expression cannot be implemented with read/access watchpoint.\r\n$gdb_prompt $" { 64 if {$wpsize == 8 && [istarget "arm*-*-*"]} { 65 untested $test 66 continue 67 } 68 fail $test 69 } 70 } 71 gdb_test_no_output "set variable size = $rdsize" "" 72 gdb_test_no_output "set variable offset = $rdoffset" "" 73 set test "continue" 74 set got_hit 0 75 gdb_test_multiple $test $test { 76 -re "$rwatch_exp $wpnum:.*alue = .*\r\n$gdb_prompt $" { 77 set got_hit 1 78 send_gdb "continue\n" 79 exp_continue 80 } 81 -re " start_again .*\r\n$gdb_prompt $" { 82 } 83 } 84 gdb_test_no_output "delete $wpnum" "" 85 set test "wp(size=$wpsize offset=$wpoffset) rd(size=$rdsize offset=$rdoffset) expect=$expect_hit" 86 if {$expect_hit == $got_hit} { 87 pass $test 88 } else { 89 # We do not know if we run on a fixed Linux kernel 90 # or not. Report XFAIL only in the FAIL case. 91 if {$expect_hit == 0 && $rdstart < $wpendaligned} { 92 setup_xfail external/20207 "aarch64*-*-linux*" 93 } 94 if {!$expect_hit && [expr max ($wpstart / 8, $rdstart / 8) < min (($wpend + 7) / 8, ($rdend + 7) / 8)]} { 95 setup_xfail breakpoints/23131 "powerpc*-*-*" 96 } 97 fail $test 98 } 99 } 100 } 101 } 102} 103 104foreach wpcount {4 7} { 105 array set wpoffset_to_wpnum {} 106 for {set wpoffset 1} {$wpoffset <= $wpcount} {incr wpoffset} { 107 set test "$rwatch data.u.size1\[$wpoffset\]" 108 set wpnum "" 109 gdb_test_multiple $test $test { 110 -re "$rwatch_exp (\[0-9\]+): .*\r\n$gdb_prompt $" { 111 set wpoffset_to_wpnum($wpoffset) $expect_out(1,string) 112 } 113 -re "There are not enough available hardware resources for this watchpoint.\r\n$gdb_prompt $" { 114 if {$wpoffset > 1} { 115 setup_xfail breakpoints/23131 "powerpc*-*-*" 116 setup_xfail breakpoints/23131 "arm*-*-*" 117 } 118 fail $test 119 set wpoffset_to_wpnum($wpoffset) 0 120 } 121 } 122 } 123 gdb_test_no_output "set variable size = 1" "" 124 gdb_test_no_output "set variable offset = 1" "" 125 set test "continue" 126 set got_hit 0 127 gdb_test_multiple $test $test { 128 -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" { 129 } 130 -re "$rwatch_exp $wpoffset_to_wpnum(1):.*alue = .*\r\n$gdb_prompt $" { 131 set got_hit 1 132 send_gdb "continue\n" 133 exp_continue 134 } 135 -re " start_again .*\r\n$gdb_prompt $" { 136 } 137 } 138 for {set wpoffset 1} {$wpoffset <= $wpcount} {incr wpoffset} { 139 if {$wpoffset_to_wpnum($wpoffset)} { 140 gdb_test_no_output "delete $wpoffset_to_wpnum($wpoffset)" "" 141 } 142 } 143 set test "wpcount($wpcount)" 144 if {!$wpoffset_to_wpnum([expr $wpcount - 1])} { 145 untested $test 146 continue 147 } 148 if {$wpcount > 4} { 149 if {![istarget "s390*-*-*"]} { 150 setup_kfail tdep/22389 *-*-* 151 } 152 } 153 gdb_assert $got_hit $test 154} 155 156if ![runto_main] { 157 return -1 158} 159gdb_breakpoint [gdb_get_line_number "final_return"] "Breakpoint $decimal at $hex" "final_return" 160set test {watch data.u.size8twice[1]} 161set wpnum "" 162gdb_test_multiple $test $test { 163 -re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { 164 set wpnum $expect_out(1,string) 165 } 166 -re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { 167 if {[istarget "arm*-*-*"]} { 168 untested $test 169 set wpnum 0 170 } 171 } 172} 173if {$wpnum} { 174 set test "continue" 175 set got_hit 0 176 gdb_test_multiple $test $test { 177 -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" { 178 } 179 -re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" { 180 set got_hit 1 181 send_gdb "continue\n" 182 exp_continue 183 } 184 -re " final_return .*\r\n$gdb_prompt $" { 185 } 186 } 187 gdb_assert $got_hit "size8twice write" 188} 189