Commit | Line | Data |
---|---|---|
32d0add0 | 1 | # Copyright 2013-2015 Free Software Foundation, Inc. |
b39a8faf YQ |
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 | load_lib dwarf.exp | |
16 | ||
17 | # This test can only be run on targets which support DWARF-2 and use gas. | |
18 | if {![dwarf2_support]} { | |
19 | return 0 | |
20 | } | |
21 | ||
22 | standard_testfile .c entry-values-dw.S | |
23 | ||
24 | if {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \ | |
25 | object {nodebug}] != ""} { | |
26 | return -1 | |
27 | } | |
28 | ||
9d85a0ec YQ |
29 | # Start GDB and load object file, compute the offset of the |
30 | # instruction in bar returned from foo. It is needed in the Dwarf | |
31 | # Assembler. | |
b39a8faf YQ |
32 | |
33 | gdb_exit | |
34 | gdb_start | |
35 | gdb_reinitialize_dir $srcdir/$subdir | |
36 | gdb_load ${binfile}1.o | |
37 | ||
9d85a0ec | 38 | set returned_from_foo "" |
b39a8faf | 39 | |
3f983d47 YZ |
40 | if { [istarget "arm*-*-*"] || [istarget "aarch64*-*-*"] } { |
41 | set call_insn "bl" | |
d674a709 AA |
42 | } elseif { [istarget "s390*-*-*"] } { |
43 | set call_insn "brasl" | |
2b239efb LM |
44 | } elseif { [istarget "powerpc*-*-*"] } { |
45 | set call_insn "bl" | |
acc018ac YQ |
46 | } elseif { [istarget "mips*-*-*"] } { |
47 | # Skip the delay slot after the instruction used to make a call | |
48 | # (which can be a jump or a branch) if it has one. | |
49 | # | |
50 | # JUMP (or BRANCH) foo | |
51 | # insn1 | |
52 | # insn2 | |
53 | # | |
54 | # Most MIPS instructions used to make calls have a delay slot. | |
55 | # These include JAL, JALS, JALX, JALR, JALRS, BAL and BALS. | |
56 | # In this case the program continues from `insn2' when `foo' | |
57 | # returns. The only exception is JALRC, in which case execution | |
58 | # resumes from `insn1' instead. | |
59 | set call_insn {jalrc|[jb]al[sxr]*[ \t][^\r\n]+\r\n} | |
3f983d47 YZ |
60 | } else { |
61 | set call_insn "call" | |
62 | } | |
63 | ||
9d85a0ec | 64 | # Calculate the offset of the instruction in bar returned from foo. |
b39a8faf YQ |
65 | set test "disassemble bar" |
66 | gdb_test_multiple $test $test { | |
84429e27 | 67 | -re ".*$hex <\\+$decimal>:\[ \t\]+$call_insn\[^\r\n\]+\r\n\[ \]+$hex <\\+($decimal)>:.*$gdb_prompt $" { |
9d85a0ec | 68 | set returned_from_foo $expect_out(1,string) |
b39a8faf YQ |
69 | } |
70 | -re ".*$gdb_prompt $" { | |
71 | fail $test | |
72 | } | |
73 | } | |
74 | ||
9d85a0ec | 75 | if { [string equal $returned_from_foo ""] } { |
b39a8faf YQ |
76 | fail "Find the call or branch instruction offset in bar" |
77 | # The following test makes no sense if the offset is unknown. We need | |
78 | # to update the pattern above to match call or branch instruction for | |
79 | # the target architecture. | |
80 | return -1 | |
81 | } | |
82 | ||
b39a8faf YQ |
83 | gdb_exit |
84 | ||
85 | # Make some DWARF for the test. | |
86 | set asm_file [standard_output_file $srcfile2] | |
87 | Dwarf::assemble $asm_file { | |
88 | declare_labels int_label foo_label | |
9d85a0ec | 89 | global returned_from_foo |
84429e27 YQ |
90 | global srcdir subdir srcfile |
91 | ||
92 | set bar_result [function_range bar ${srcdir}/${subdir}/${srcfile}] | |
93 | set bar_start [lindex $bar_result 0] | |
94 | set bar_length [lindex $bar_result 1] | |
b39a8faf YQ |
95 | |
96 | cu {} { | |
97 | compile_unit {{language @DW_LANG_C}} { | |
98 | int_label: base_type { | |
99 | {name int} | |
100 | {encoding @DW_ATE_signed} | |
101 | {byte_size 4 DW_FORM_sdata} | |
102 | } | |
103 | ||
104 | foo_label: subprogram { | |
f2e0d4b4 | 105 | {decl_file 1 sdata} |
84429e27 | 106 | {MACRO_AT_func { foo ${srcdir}/${subdir}/${srcfile} }} |
b39a8faf YQ |
107 | } { |
108 | formal_parameter { | |
109 | {type :$int_label} | |
110 | {name i} | |
111 | {location {DW_OP_reg0} SPECIAL_expr} | |
112 | } | |
113 | formal_parameter { | |
114 | {type :$int_label} | |
115 | {name j} | |
116 | {location {DW_OP_reg1} SPECIAL_expr} | |
117 | } | |
118 | } | |
119 | ||
120 | subprogram { | |
121 | {name bar} | |
f2e0d4b4 | 122 | {decl_file 1 sdata} |
84429e27 YQ |
123 | {low_pc $bar_start addr} |
124 | {high_pc "$bar_start + $bar_length" addr} | |
f2e0d4b4 | 125 | {GNU_all_call_sites 1 sdata} |
b39a8faf YQ |
126 | } { |
127 | formal_parameter { | |
128 | {type :$int_label} | |
129 | {name i} | |
130 | } | |
131 | ||
132 | GNU_call_site { | |
9d85a0ec | 133 | {low_pc "$bar_start + $returned_from_foo" addr} |
b39a8faf YQ |
134 | {abstract_origin :$foo_label} |
135 | } { | |
136 | # Faked entry values are reference to variables 'global1' | |
137 | # and 'global2' and faked locations are register 0 and | |
138 | # register 1. | |
139 | GNU_call_site_parameter { | |
140 | {location {DW_OP_reg0} SPECIAL_expr} | |
141 | {GNU_call_site_value { | |
142 | addr global1 | |
143 | deref_size 4 | |
144 | } SPECIAL_expr} | |
145 | } | |
146 | GNU_call_site_parameter { | |
147 | {location {DW_OP_reg1} SPECIAL_expr} | |
148 | {GNU_call_site_value { | |
149 | addr global2 | |
150 | deref_size 4 | |
151 | } SPECIAL_expr} | |
152 | } | |
153 | } | |
154 | } | |
155 | } | |
156 | } | |
157 | } | |
158 | ||
159 | if {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} { | |
160 | return -1 | |
161 | } | |
162 | ||
163 | if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \ | |
164 | "${binfile}" executable {}] != ""} { | |
165 | return -1 | |
166 | } | |
167 | ||
168 | clean_restart ${testfile} | |
169 | ||
170 | if ![runto_main] { | |
171 | fail "Can't run to main" | |
172 | return -1 | |
173 | } | |
174 | ||
175 | gdb_breakpoint "foo" | |
176 | ||
177 | gdb_continue_to_breakpoint "foo" | |
178 | ||
179 | gdb_test_no_output "set print entry-values both" | |
180 | ||
181 | gdb_test_sequence "bt" "bt (1)" { | |
182 | "\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=2, j=[-]?[0-9]+, j@entry=3\\)" | |
183 | "\[\r\n\]#1 .* bar \\(i=<optimized out>, i@entry=<optimized out>\\)" | |
184 | "\[\r\n\]#2 .* main \\(\\)" | |
185 | } | |
186 | ||
187 | # Update global variables 'global1' and 'global2' and test that the | |
188 | # entry values are updated too. | |
189 | ||
190 | gdb_test_no_output "set var global1=10" | |
191 | gdb_test_no_output "set var global2=11" | |
192 | ||
193 | gdb_test_sequence "bt" "bt (2)" { | |
194 | "\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=10, j=[-]?[0-9]+, j@entry=11\\)" | |
195 | "\[\r\n\]#1 .* bar \\(i=<optimized out>, i@entry=<optimized out>\\)" | |
196 | "\[\r\n\]#2 .* main \\(\\)" | |
197 | } | |
b1224238 YQ |
198 | |
199 | # Restart GDB and trace. | |
200 | ||
201 | clean_restart $binfile | |
202 | ||
203 | load_lib "trace-support.exp" | |
204 | ||
205 | if ![runto_main] { | |
206 | fail "Can't run to main to check for trace support" | |
207 | return -1 | |
208 | } | |
209 | ||
210 | if ![gdb_target_supports_trace] { | |
211 | unsupported "target does not support trace" | |
212 | return -1 | |
213 | } | |
214 | ||
215 | gdb_test "trace foo" "Tracepoint $decimal at .*" | |
216 | ||
217 | if [is_amd64_regs_target] { | |
218 | set spreg "\$rsp" | |
219 | } elseif [is_x86_like_target] { | |
220 | set spreg "\$esp" | |
221 | } else { | |
222 | set spreg "\$sp" | |
223 | } | |
224 | ||
225 | # Collect arguments i and j. Collect 'global1' which is entry value | |
226 | # of argument i. Don't collect 'global2' to test the entry value of | |
227 | # argument j. | |
228 | ||
229 | gdb_trace_setactions "set action for tracepoint 1" "" \ | |
230 | "collect i, j, global1, \(\*\(void \*\*\) \($spreg\)\) @ 64" "^$" | |
231 | ||
232 | gdb_test_no_output "tstart" | |
233 | ||
234 | gdb_breakpoint "end" | |
235 | gdb_continue_to_breakpoint "end" | |
236 | ||
237 | gdb_test_no_output "tstop" | |
238 | ||
239 | gdb_test "tfind" "Found trace frame 0, .*" "tfind start" | |
240 | ||
241 | # Since 'global2' is not collected, j@entry is expected to be 'unavailable'. | |
242 | gdb_test "bt 1" "#0 .* foo \\(i=\[-\]?$decimal, i@entry=2, j=\[-\]?$decimal, j@entry=<unavailable>\\).*" | |
243 | ||
6211c335 YQ |
244 | # Test that unavailable "j@entry" is not shown when command option |
245 | # --skip-unavailable is used. | |
246 | gdb_test "interpreter-exec mi \"-stack-list-arguments --skip-unavailable --simple-values\"" \ | |
247 | "\r\n\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"i\",type=\"int\",value=\".*\"},{name=\"i@entry\",type=\"int\",value=\"2\"},{name=\"j\",type=\"int\",value=\".*\"}\\\]},frame=.*\\\].*" | |
248 | ||
b1224238 | 249 | gdb_test "tfind" "Target failed to find requested trace frame\..*" |