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