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