xref: /netbsd-src/external/gpl3/gdb/dist/gdb/testsuite/gdb.base/watchpoint-unaligned.exp (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
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