Commit | Line | Data |
---|---|---|
0fec99e8 PA |
1 | # Copyright 2014 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 | standard_testfile | |
19 | ||
20 | if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { | |
21 | return -1 | |
22 | } | |
23 | ||
24 | if ![runto main] { | |
25 | return -1 | |
26 | } | |
27 | ||
28 | delete_breakpoints | |
29 | ||
30 | # Get the bounds of a function, and write them to FUNC_LO (inclusive), | |
31 | # FUNC_HI (exclusive). Return true on success and false on failure. | |
32 | proc get_function_bounds {function func_lo func_hi} { | |
33 | global gdb_prompt | |
34 | global hex decimal | |
35 | ||
36 | upvar $func_lo lo | |
37 | upvar $func_hi hi | |
38 | ||
39 | set lo "" | |
40 | set size "" | |
41 | ||
42 | set test "get lo address of $function" | |
43 | gdb_test_multiple "disassemble $function" $test { | |
44 | -re "($hex) .*$hex <\\+($decimal)>:\[^\r\n\]+\r\nEnd of assembler dump\.\r\n$gdb_prompt $" { | |
45 | set lo $expect_out(1,string) | |
46 | set size $expect_out(2,string) | |
47 | pass $test | |
48 | } | |
49 | } | |
50 | ||
51 | if { $lo == "" || $size == "" } { | |
52 | return false | |
53 | } | |
54 | ||
55 | # Account for the size of the last instruction. | |
56 | set test "get hi address of $function" | |
57 | gdb_test_multiple "x/2i $function+$size" $test { | |
58 | -re ".*$hex <$function\\+$size>:\[^\r\n\]+\r\n\[ \]+($hex).*\.\r\n$gdb_prompt $" { | |
59 | set hi $expect_out(1,string) | |
60 | pass $test | |
61 | } | |
62 | } | |
63 | ||
64 | if { $hi == "" } { | |
65 | return false | |
66 | } | |
67 | ||
68 | # Remove unnecessary leading 0's (0x00000ADDR => 0xADDR) so we can | |
69 | # easily do matches. Disassemble includes leading zeros, while | |
70 | # x/i doesn't. | |
71 | regsub -all "0x0\+" $lo "0x" lo | |
72 | regsub -all "0x0\+" $hi "0x" hi | |
73 | ||
74 | return true | |
75 | } | |
76 | ||
77 | # Get the address where the thread is currently stopped. | |
78 | proc get_curr_insn {} { | |
79 | global gdb_prompt | |
80 | global hex | |
81 | ||
82 | set pc "" | |
83 | set test "get current insn" | |
84 | gdb_test_multiple "p /x \$pc" $test { | |
85 | -re " = ($hex)\r\n$gdb_prompt $" { | |
86 | set pc $expect_out(1,string) | |
87 | pass $test | |
88 | } | |
89 | } | |
90 | ||
91 | return $pc | |
92 | } | |
93 | ||
94 | # Get the address of where a single-step should land. | |
95 | proc get_next_insn {} { | |
96 | global gdb_prompt | |
97 | global hex | |
98 | ||
99 | set next "" | |
100 | set test "get next insn" | |
101 | gdb_test_multiple "x/2i \$pc" $test { | |
102 | -re "$hex .*:\[^\r\n\]+\r\n\[ \]+($hex).*\.\r\n$gdb_prompt $" { | |
103 | set next $expect_out(1,string) | |
104 | pass $test | |
105 | } | |
106 | } | |
107 | ||
108 | return $next | |
109 | } | |
110 | ||
111 | ||
112 | if ![get_function_bounds "main" main_lo main_hi] { | |
113 | # Can't do the following tests if main's bounds are unknown. | |
114 | return -1 | |
115 | } | |
116 | ||
117 | # Manually create a read-only memory region that covers 'main'. | |
118 | gdb_test_no_output "mem $main_lo $main_hi ro" \ | |
119 | "create read-only mem region covering main" | |
120 | ||
121 | # So that we don't fail inserting breakpoints on addresses outside | |
122 | # main, like the internal event breakpoints. | |
123 | gdb_test_no_output "set mem inaccessible-by-default off" | |
124 | ||
125 | # So we get an immediate warning/error without needing to resume the | |
126 | # target. | |
127 | gdb_test_no_output "set breakpoint always-inserted on" | |
128 | ||
129 | # Disable the automatic fallback to HW breakpoints. We want a | |
130 | # software breakpoint to be attempted, and to fail. | |
131 | gdb_test_no_output "set breakpoint auto-hw off" | |
132 | ||
133 | # Confirm manual writes to the read-only memory region fail. | |
134 | gdb_test "p /x *(char *) $main_lo = 1" \ | |
135 | "Cannot access memory at address $main_lo" \ | |
136 | "writing to read-only memory fails" | |
137 | ||
138 | # Ensure that inserting a software breakpoint in a known-read-only | |
139 | # region fails. | |
140 | gdb_test "break *$main_lo" \ | |
141 | "Cannot insert breakpoint .*Cannot set software breakpoint at read-only address $main_lo.*" \ | |
142 | "inserting software breakpoint in read-only memory fails" |