1# Copyright 2014-2015 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# Test alternating between watchpoint types, watching a sliding window 17# of addresses (thus alternating between aligned and unaligned 18# addresses). Only a single watchpoint exists at any given time. On 19# targets that only update the debug registers on resume, this 20# stresses the debug register setup code, both in GDB and in the 21# target/kernel as one watchpoint replaces the other in a single 22# operation. (Note that we don't have any of these watchpoints 23# trigger.) 24 25if [target_info exists gdb,no_hardware_watchpoints] { 26 unsupported "no target support" 27 return 28} 29 30standard_testfile 31 32if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { 33 return -1 34} 35 36if ![runto_main] then { 37 fail "Can't run to main" 38 return 0 39} 40 41# The line we'll be stepping. 42set srcline [gdb_get_line_number "stepi line"] 43 44# The address the program is stopped at currently. 45set cur_addr "" 46 47# Get the current PC. 48 49proc get_pc {} { 50 global hex gdb_prompt 51 52 set addr "" 53 set test "get PC" 54 gdb_test_multiple "p /x \$pc" "$test" { 55 -re " = ($hex).*$gdb_prompt $" { 56 set addr $expect_out(1,string) 57 pass "$test" 58 } 59 } 60 61 return $addr 62} 63 64 65# Issue a stepi, and make sure the program advanced past the current 66# instruction (stored in the CUR_ADDR global). 67 68proc stepi {} { 69 global hex gdb_prompt cur_addr 70 71 set srcline " for (i = 0; i < 100000; i++); /* stepi line */" 72 set test "stepi advanced" 73 gdb_test_multiple "stepi" $test { 74 -re "($hex).*[string_to_regexp $srcline]\r\n$gdb_prompt $" { 75 set addr $expect_out(1,string) 76 if {$addr != $cur_addr} { 77 pass $test 78 } else { 79 fail $test 80 } 81 set cur_addr addr 82 } 83 } 84} 85 86gdb_breakpoint $srcline 87gdb_continue_to_breakpoint "stepi line" 88 89# The test tries various sequences of different types of watchpoints. 90# Probe for support first. 91 92# So we get an immediate warning/error if the target doesn't support a 93# given watchpoint type. 94gdb_test_no_output "set breakpoint always-inserted on" 95 96# The list of supported commands. Below we'll probe for support and 97# add elements to this list. 98set cmds {} 99 100foreach cmd {"watch" "awatch" "rwatch"} { 101 set test $cmd 102 gdb_test_multiple "$cmd buf.byte\[0\]" $test { 103 -re "You may have requested too many.*$gdb_prompt $" { 104 unsupported $test 105 } 106 -re "Target does not support.*$gdb_prompt $" { 107 unsupported $test 108 } 109 -re "$gdb_prompt $" { 110 pass $test 111 lappend cmds $cmd 112 } 113 } 114 115 delete_breakpoints 116} 117 118set test "hbreak" 119gdb_test_multiple "hbreak main" $test { 120 -re "You may have requested too many.*$gdb_prompt $" { 121 unsupported $test 122 } 123 -re "No hardware breakpoint support.*$gdb_prompt $" { 124 unsupported $test 125 } 126 -re "$gdb_prompt $" { 127 pass $test 128 lappend cmds "hbreak" 129 } 130} 131 132delete_breakpoints 133 134set cur_addr [get_pc] 135 136# Return true if the memory range [buf.byte + OFFSET, +WIDTH] can be 137# monitored by CMD, otherwise return false. 138 139proc valid_addr_p {cmd offset width} { 140 141 if { [istarget "aarch64*-*-linux*"] } { 142 # The aarch64 Linux kernel port only accepts 4-byte aligned addresses 143 # for hardware breakpoints and 8-byte aligned addresses for hardware 144 # watchpoints. However, both GDB and GDBserver support unaligned 145 # watchpoints by using more than one properly aligned watchpoint 146 # registers to represent the whole unaligned region. Breakpoint 147 # addresses must still be aligned though. 148 if {$cmd == "hbreak" } { 149 if { [expr ($offset) % 4] != 0 } { 150 return 0 151 } 152 } 153 } elseif { [istarget "arm*-*-linux*"] } { 154 if { $cmd == "hbreak" } { 155 # Breakpoints must be of length 2 (thumb) or 4 (ARM) bytes. 156 if { $width != 2 && $width != 4 } { 157 return 0 158 } 159 } else { 160 # Watchpoints can be of length 1, 2, 4 or 8 bytes. 161 if { [expr $width % 2] != 0 } { 162 return 0 163 } 164 } 165 166 if { [expr ($offset) % 8] == 0 && $width == 8 } { 167 # If WIDTH is 8 byte, the address should be 8-byte aligned. 168 return 1 169 } elseif { [expr ($offset) % 4] == 0 } { 170 return 1 171 } elseif { [expr ($offset) % 4] == 2 && $width == 2 } { 172 # Halfword watchpoints and breakpoints. 173 return 1 174 } elseif { [expr ($offset) % 4] == 1 && $width == 1 && $cmd != "hbreak" } { 175 # Single byte watchpoints. 176 return 1 177 } else { 178 return 0 179 } 180 } 181 182 return 1 183} 184 185# Watch WIDTH bytes at BASE + OFFSET. CMD specifices the specific 186# type of watchpoint to use. If CMD is "hbreak", WIDTH is ignored. 187 188proc watch_command {cmd base offset width} { 189 global srcfile srcline hex 190 191 if {$cmd == "hbreak"} { 192 set expr "*(buf.byte + $base + $offset)" 193 gdb_test "hbreak $expr" "Hardware assisted breakpoint \[0-9\]+ at $hex" 194 } elseif {$cmd == "watch"} { 195 set expr "*(buf.byte + $base + $offset)@$width" 196 gdb_test "$cmd $expr" \ 197 "Hardware watchpoint \[0-9\]+: [string_to_regexp $expr]" 198 } elseif {$cmd == "awatch"} { 199 set expr "*(buf.byte + $base + $offset)@$width" 200 gdb_test "$cmd $expr" \ 201 "Hardware access \\(read/write\\) watchpoint \[0-9\]+: [string_to_regexp $expr]" 202 } elseif {$cmd == "rwatch"} { 203 set expr "*(buf.byte + $base + $offset)@$width" 204 gdb_test "$cmd $expr" \ 205 "Hardware read watchpoint \[0-9\]+: [string_to_regexp $expr]" 206 } 207} 208 209# Run test proper. See intro for description. 210 211foreach always_inserted {"off" "on" } { 212 gdb_test_no_output "set breakpoint always-inserted $always_inserted" 213 foreach cmd1 $cmds { 214 foreach cmd2 $cmds { 215 for {set width 1} {$width < 4} {incr width} { 216 217 if {$cmd1 == "hbreak" && $cmd2 == "hbreak" && $width > 1} { 218 # hbreak ignores WIDTH, no use testing more than 219 # once. 220 continue 221 } 222 223 for {set x 0} {$x < 4} {incr x} { 224 225 if { ![valid_addr_p $cmd1 $x $width] 226 || ![valid_addr_p $cmd2 $x+1 $width] } { 227 # Skip tests if requested address or length 228 # of breakpoint or watchpoint don't meet 229 # target or kernel requirements. 230 continue 231 } 232 233 set prefix "always-inserted $always_inserted: " 234 append prefix "$cmd1 x $cmd2: " 235 with_test_prefix "$prefix: width $width, iter $x" { 236 with_test_prefix "base + 0" { 237 watch_command $cmd1 $x 0 $width 238 stepi 239 gdb_test_no_output "delete \$bpnum" 240 } 241 with_test_prefix "base + 1" { 242 watch_command $cmd2 $x 1 $width 243 stepi 244 gdb_test_no_output "delete \$bpnum" 245 } 246 } 247 } 248 } 249 } 250 } 251} 252