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