]>
Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright 2018-2020 Free Software Foundation, Inc. |
7d140d1a KB |
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 support for DW_OP_GNU_variable_value. | |
17 | ||
18 | load_lib dwarf.exp | |
19 | ||
20 | # This test can only be run on targets which support DWARF-2 and use gas. | |
21 | if ![dwarf2_support] { | |
22 | return 0 | |
23 | } | |
24 | ||
25 | # We'll place the output of Dwarf::assemble in varval.S. | |
26 | standard_testfile .c .S | |
27 | ||
28 | # ${testfile} is now "varval". srcfile2 is "varval.S". | |
29 | set executable ${testfile} | |
30 | set asm_file [standard_output_file ${srcfile2}] | |
31 | ||
32 | # We need to know the size of integer and address types in order | |
33 | # to write some of the debugging info we'd like to generate. | |
34 | # | |
35 | # For that, we ask GDB by debugging our varval program. | |
36 | # Any program would do, but since we already have varval | |
37 | # specifically for this testcase, might as well use that. | |
38 | if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] { | |
39 | return -1 | |
40 | } | |
111b33f0 TV |
41 | set int_size [get_sizeof "int" -1] |
42 | # gdb always assumes references are implemented as pointers. | |
43 | set addr_size [get_sizeof "void *" -1] | |
7d140d1a | 44 | |
8af58ffe TV |
45 | proc setup_exec { arg_bad } { |
46 | global asm_file executable srcfile bad | |
47 | set bad ${arg_bad} | |
e4a62c65 | 48 | |
8af58ffe TV |
49 | # Create the DWARF. |
50 | Dwarf::assemble ${asm_file} { | |
111b33f0 | 51 | global srcdir subdir srcfile bad int_size addr_size |
7d140d1a | 52 | |
8af58ffe TV |
53 | cu {} { |
54 | DW_TAG_compile_unit { | |
55 | {DW_AT_language @DW_LANG_C_plus_plus} | |
56 | } { | |
57 | declare_labels int_label ptr_label struct_label var_a_label \ | |
58 | var_b_label var_c_label var_p_label var_bad_label \ | |
59 | varval_label var_s_label var_untyped_label \ | |
60 | var_a_abstract_label var_a_concrete_label \ | |
93e55f0a TV |
61 | varval2_label varval3_def_label varval3_decl_label \ |
62 | int_array_label int_array_of_1_label | |
7d140d1a | 63 | |
7d140d1a | 64 | |
8af58ffe TV |
65 | int_label: DW_TAG_base_type { |
66 | {DW_AT_byte_size ${int_size} DW_FORM_udata} | |
67 | {DW_AT_encoding @DW_ATE_signed} | |
68 | {DW_AT_name "int"} | |
7d140d1a | 69 | } |
8af58ffe TV |
70 | |
71 | ptr_label: DW_TAG_pointer_type { | |
7d140d1a | 72 | {DW_AT_type :$int_label} |
7d140d1a | 73 | } |
7d140d1a | 74 | |
8af58ffe TV |
75 | var_a_label: DW_TAG_variable { |
76 | {DW_AT_name "var_a"} | |
7d140d1a | 77 | {DW_AT_type :${int_label}} |
8af58ffe TV |
78 | {DW_AT_external 1 DW_FORM_flag} |
79 | {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} | |
7d140d1a | 80 | } |
8af58ffe TV |
81 | |
82 | var_a_abstract_label: DW_TAG_variable { | |
e4a62c65 | 83 | {DW_AT_type :${int_label}} |
8af58ffe | 84 | {DW_AT_external 1 DW_FORM_flag} |
e4a62c65 | 85 | } |
8af58ffe TV |
86 | |
87 | var_b_label: DW_TAG_variable { | |
88 | {DW_AT_name "var_b"} | |
7d140d1a | 89 | {DW_AT_type :${int_label}} |
8af58ffe TV |
90 | {DW_AT_external 1 DW_FORM_flag} |
91 | {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_b"]} SPECIAL_expr} | |
7d140d1a | 92 | } |
8af58ffe TV |
93 | |
94 | var_c_label: DW_TAG_variable { | |
95 | {DW_AT_name "var_c"} | |
7d140d1a | 96 | {DW_AT_type :${int_label}} |
8af58ffe TV |
97 | {DW_AT_external 1 DW_FORM_flag} |
98 | {DW_AT_const_value 53 DW_FORM_sdata} | |
7d140d1a | 99 | } |
8af58ffe TV |
100 | |
101 | var_p_label: DW_TAG_variable { | |
102 | {DW_AT_name "var_p"} | |
7d140d1a | 103 | {DW_AT_type :${ptr_label}} |
8af58ffe TV |
104 | {DW_AT_external 1 DW_FORM_flag} |
105 | {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_p"]} SPECIAL_expr} | |
7d140d1a | 106 | } |
8af58ffe TV |
107 | |
108 | if { $bad } { | |
109 | var_bad_label: DW_TAG_variable { | |
110 | {DW_AT_name "var_bad"} | |
111 | {DW_AT_type :${int_label}} | |
112 | {DW_AT_external 1 DW_FORM_flag} | |
113 | } | |
7d140d1a | 114 | } |
8af58ffe TV |
115 | |
116 | struct_label: DW_TAG_structure_type { | |
117 | {DW_AT_byte_size 8*$int_size DW_FORM_sdata} | |
118 | } { | |
119 | DW_TAG_member { | |
120 | {DW_AT_name "a"} | |
121 | {DW_AT_type :$int_label} | |
122 | {DW_AT_data_member_location 0*$int_size DW_FORM_udata} | |
123 | } | |
124 | DW_TAG_member { | |
125 | {DW_AT_name "b"} | |
126 | {DW_AT_type :$int_label} | |
127 | {DW_AT_data_member_location 1*$int_size DW_FORM_udata} | |
128 | } | |
129 | DW_TAG_member { | |
130 | {DW_AT_name "c"} | |
131 | {DW_AT_type :$int_label} | |
132 | {DW_AT_data_member_location 2*$int_size DW_FORM_udata} | |
133 | } | |
134 | DW_TAG_member { | |
135 | {DW_AT_name "d"} | |
136 | {DW_AT_type :$int_label} | |
137 | {DW_AT_data_member_location 3*$int_size DW_FORM_udata} | |
138 | } | |
139 | DW_TAG_member { | |
140 | {DW_AT_name "e"} | |
141 | {DW_AT_type :$int_label} | |
142 | {DW_AT_data_member_location 4*$int_size DW_FORM_udata} | |
143 | } | |
144 | DW_TAG_member { | |
145 | {DW_AT_name "f"} | |
146 | {DW_AT_type :$int_label} | |
147 | {DW_AT_data_member_location 5*$int_size DW_FORM_udata} | |
148 | } | |
149 | DW_TAG_member { | |
150 | {DW_AT_name "g"} | |
151 | {DW_AT_type :$int_label} | |
152 | {DW_AT_data_member_location 6*$int_size DW_FORM_udata} | |
153 | } | |
154 | DW_TAG_member { | |
155 | {DW_AT_name "h"} | |
156 | {DW_AT_type :$int_label} | |
157 | {DW_AT_data_member_location 7*$int_size DW_FORM_udata} | |
158 | } | |
7d140d1a | 159 | } |
8af58ffe TV |
160 | |
161 | var_s_label: DW_TAG_variable { | |
162 | {DW_AT_name "var_s"} | |
163 | {DW_AT_type :${struct_label}} | |
164 | {DW_AT_external 1 DW_FORM_flag} | |
165 | {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_s"]} SPECIAL_expr} | |
7d140d1a | 166 | } |
8af58ffe TV |
167 | |
168 | var_untyped_label: DW_TAG_variable { | |
169 | {DW_AT_name "var_untyped"} | |
170 | {DW_AT_external 1 DW_FORM_flag} | |
171 | {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_b"]} SPECIAL_expr} | |
7d140d1a | 172 | } |
8af58ffe | 173 | |
93e55f0a TV |
174 | int_array_label: DW_TAG_array_type { |
175 | {DW_AT_type :${int_label}} | |
176 | } { | |
177 | DW_TAG_subrange_type {} | |
178 | } | |
179 | varval3_decl_label: DW_TAG_variable { | |
180 | {DW_AT_name "varval3"} | |
181 | {DW_AT_type :${int_array_label}} | |
182 | {DW_AT_external 1 DW_FORM_flag} | |
183 | {DW_AT_declaration 1 DW_FORM_flag} | |
184 | } | |
185 | int_array_of_1_label: DW_TAG_array_type { | |
186 | {DW_AT_type :${int_label}} | |
187 | } { | |
188 | DW_TAG_subrange_type { | |
189 | {DW_AT_type :$int_label} | |
190 | {DW_AT_upper_bound 0 DW_FORM_data1} | |
191 | } | |
192 | } | |
193 | varval3_def_label: DW_TAG_variable { | |
194 | {DW_AT_name "varval3"} | |
195 | {DW_AT_external 1 DW_FORM_flag} | |
196 | {DW_AT_type :${int_array_of_1_label}} | |
197 | {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} | |
198 | } | |
199 | ||
8af58ffe TV |
200 | DW_TAG_subprogram { |
201 | {MACRO_AT_func { "main" "${srcdir}/${subdir}/${srcfile}" }} | |
202 | {DW_AT_type :${int_label}} | |
203 | {DW_AT_external 1 DW_FORM_flag} | |
204 | } { | |
205 | varval_label: DW_TAG_variable { | |
206 | {DW_AT_name "varval"} | |
207 | {DW_AT_type :${int_label}} | |
208 | {DW_AT_location { | |
209 | DW_OP_GNU_variable_value ${var_a_label} | |
210 | DW_OP_stack_value | |
211 | } SPECIAL_expr} | |
212 | } | |
213 | varval2_label: DW_TAG_variable { | |
214 | {DW_AT_name "varval2"} | |
215 | {DW_AT_type :${int_label}} | |
216 | {DW_AT_location { | |
217 | DW_OP_GNU_variable_value ${var_a_abstract_label} | |
218 | DW_OP_stack_value | |
219 | } SPECIAL_expr} | |
220 | } | |
221 | var_a_concrete_label: DW_TAG_variable { | |
222 | {DW_AT_abstract_origin :${var_a_abstract_label}} | |
223 | {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} | |
224 | } | |
225 | DW_TAG_variable { | |
226 | {DW_AT_name "constval"} | |
227 | {DW_AT_type :${int_label}} | |
228 | {DW_AT_location { | |
229 | DW_OP_GNU_variable_value ${var_c_label} | |
230 | DW_OP_stack_value | |
231 | } SPECIAL_expr} | |
232 | } | |
233 | DW_TAG_variable { | |
234 | {DW_AT_name "mixedval"} | |
235 | {DW_AT_type :${int_label}} | |
236 | {DW_AT_location { | |
237 | DW_OP_GNU_variable_value ${var_c_label} | |
238 | DW_OP_GNU_variable_value ${var_b_label} | |
239 | DW_OP_div | |
240 | DW_OP_GNU_variable_value ${varval_label} | |
241 | DW_OP_plus | |
242 | DW_OP_dup | |
243 | DW_OP_plus | |
244 | DW_OP_GNU_variable_value ${varval_label} | |
245 | DW_OP_minus | |
246 | DW_OP_stack_value | |
247 | } SPECIAL_expr} | |
248 | } | |
249 | DW_TAG_variable { | |
250 | {DW_AT_name "pointerval"} | |
251 | {DW_AT_type :${ptr_label}} | |
252 | {DW_AT_location { | |
253 | DW_OP_GNU_variable_value ${var_p_label} | |
254 | DW_OP_stack_value | |
255 | } SPECIAL_expr} | |
256 | } | |
257 | if { $bad } { | |
258 | DW_TAG_variable { | |
259 | {DW_AT_name "badval"} | |
260 | {DW_AT_type :${int_label}} | |
261 | {DW_AT_location { | |
262 | DW_OP_GNU_variable_value ${var_bad_label} | |
263 | DW_OP_stack_value | |
264 | } SPECIAL_expr} | |
265 | } | |
266 | } | |
267 | DW_TAG_variable { | |
268 | {DW_AT_name "structval"} | |
269 | {DW_AT_type :${struct_label}} | |
270 | {DW_AT_location { | |
271 | DW_OP_GNU_variable_value ${var_s_label} | |
272 | DW_OP_stack_value | |
273 | } SPECIAL_expr} | |
274 | } | |
275 | DW_TAG_variable { | |
276 | {DW_AT_name "untypedval"} | |
277 | {DW_AT_location { | |
278 | DW_OP_GNU_variable_value ${var_untyped_label} | |
279 | DW_OP_stack_value | |
280 | } SPECIAL_expr} | |
281 | } | |
282 | if { $bad } { | |
283 | DW_TAG_variable { | |
284 | {DW_AT_name "bad_die_val1"} | |
285 | {DW_AT_location { | |
286 | DW_OP_GNU_variable_value 0xabcdef11 | |
287 | DW_OP_stack_value | |
288 | } SPECIAL_expr} | |
289 | } | |
290 | DW_TAG_variable { | |
291 | {DW_AT_name "bad_die_val2"} | |
292 | {DW_AT_location { | |
293 | DW_OP_GNU_variable_value ${ptr_label}+1 | |
294 | DW_OP_stack_value | |
295 | } SPECIAL_expr} | |
296 | } | |
297 | } | |
7d140d1a KB |
298 | } |
299 | } | |
300 | } | |
301 | } | |
7d140d1a | 302 | |
8af58ffe TV |
303 | if [prepare_for_testing "failed to prepare" ${executable} [list ${asm_file} ${srcfile}] {}] { |
304 | return -1 | |
305 | } | |
7d140d1a KB |
306 | } |
307 | ||
8af58ffe | 308 | if { [setup_exec 0] == -1 } { |
7d140d1a KB |
309 | return -1 |
310 | } | |
311 | ||
93e55f0a TV |
312 | with_test_prefix "pre-main" { |
313 | gdb_test "print varval3" "= \\{8\\}" "" | |
314 | } | |
315 | ||
316 | # DW_OP_GNU_variable_value implementation requires a valid frame. | |
317 | if ![runto_main] { | |
318 | return -1 | |
319 | } | |
320 | ||
7d140d1a | 321 | gdb_test "print varval" "= 8" |
e4a62c65 | 322 | gdb_test "print varval2" "= 8" |
93e55f0a | 323 | gdb_test "print varval3" "= \\{8\\}" |
7d140d1a KB |
324 | gdb_test "print constval" "= 53" |
325 | gdb_test "print mixedval" "= 42" | |
326 | gdb_test "print pointerval" "= \\(int \\*\\) $hex <var_b>" | |
327 | gdb_test "print *pointerval" "= 3" | |
7d140d1a KB |
328 | |
329 | # Jakub says: "The intended behavior is that the debug info consumer | |
330 | # computes the value of that referenced variable at the current PC, | |
331 | # and if it can compute it and pushes the value as a generic type | |
332 | # integer into the DWARF stack (it is really only meaningful when | |
333 | # referring to integral/pointer typed variables)." | |
334 | ||
335 | gdb_test "print structval" \ | |
336 | "Type of DW_OP_GNU_variable_value DIE must be an integer or pointer\\." | |
337 | ||
338 | gdb_test "print untypedval" \ | |
339 | "Type of DW_OP_GNU_variable_value DIE must be an integer or pointer\\." | |
340 | ||
8af58ffe TV |
341 | if { [setup_exec 1] == -1 } { |
342 | return -1 | |
343 | } | |
344 | ||
93e55f0a TV |
345 | # DW_OP_GNU_variable_value implementation requires a valid frame. |
346 | if ![runto_main] { | |
347 | return -1 | |
348 | } | |
8af58ffe | 349 | gdb_test "print badval" "value has been optimized out" |
7d140d1a KB |
350 | gdb_test "print bad_die_val1" \ |
351 | "invalid dwarf2 offset 0xabcdef11" | |
352 | gdb_test "print bad_die_val2" \ | |
353 | "Bad DW_OP_GNU_variable_value DIE\\." |