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