Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright 2017-2020 Free Software Foundation, Inc. |
0567c986 AA |
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 reading/writing variables with non-trivial DWARF locations. In | |
17 | # particular the test uses register- and memory locations as well as | |
18 | # composite locations with register- and memory pieces. | |
19 | ||
20 | load_lib dwarf.exp | |
21 | ||
22 | # This test can only be run on targets which support DWARF-2 and use gas. | |
23 | if {![dwarf2_support]} { | |
24 | return 0 | |
25 | } | |
26 | ||
27 | # Choose suitable integer registers for the test. | |
28 | ||
29 | set dwarf_regnum {0 1} | |
30 | ||
5524b525 | 31 | if { [is_aarch64_target] } { |
0567c986 | 32 | set regname {x0 x1} |
5524b525 | 33 | } elseif { [is_aarch32_target] |
0567c986 AA |
34 | || [istarget "s390*-*-*" ] |
35 | || [istarget "powerpc*-*-*"] | |
36 | || [istarget "rs6000*-*-aix*"] } { | |
37 | set regname {r0 r1} | |
5524b525 AA |
38 | } elseif { [is_x86_like_target] } { |
39 | set regname {eax ecx} | |
40 | } elseif { [is_amd64_regs_target] } { | |
0567c986 AA |
41 | set regname {rax rdx} |
42 | } else { | |
43 | verbose "Skipping tests for accessing DWARF-described variables." | |
44 | return | |
45 | } | |
46 | ||
47 | standard_testfile .c ${gdb_test_file_name}-dw.S | |
48 | ||
49 | # Make some DWARF for the test. | |
50 | ||
51 | set asm_file [standard_output_file $srcfile2] | |
52 | Dwarf::assemble $asm_file { | |
53 | global srcdir subdir srcfile | |
54 | global dwarf_regnum regname | |
55 | ||
56 | set buf_var [gdb_target_symbol buf] | |
57 | ||
58 | cu {} { | |
59 | DW_TAG_compile_unit { | |
60 | {DW_AT_name var-pieces-dw.c} | |
61 | {DW_AT_comp_dir /tmp} | |
62 | } { | |
63 | declare_labels char_type_label | |
64 | declare_labels int_type_label short_type_label | |
3bf31011 AA |
65 | declare_labels array_a8_label struct_s_label struct_t_label |
66 | declare_labels struct_st_label | |
0567c986 AA |
67 | |
68 | # char | |
69 | char_type_label: base_type { | |
70 | {name "char"} | |
71 | {encoding @DW_ATE_unsigned_char} | |
72 | {byte_size 1 DW_FORM_sdata} | |
73 | } | |
74 | ||
75 | # int | |
76 | int_type_label: base_type { | |
77 | {name "int"} | |
78 | {encoding @DW_ATE_signed} | |
79 | {byte_size 4 DW_FORM_sdata} | |
80 | } | |
81 | ||
82 | # char [8] | |
83 | array_a8_label: array_type { | |
84 | {type :$char_type_label} | |
85 | } { | |
86 | subrange_type { | |
87 | {type :$int_type_label} | |
88 | {upper_bound 7 DW_FORM_udata} | |
89 | } | |
90 | } | |
91 | ||
92 | # struct s { char a, b, c, d; }; | |
93 | struct_s_label: structure_type { | |
94 | {name "s"} | |
95 | {byte_size 4 DW_FORM_sdata} | |
96 | } { | |
97 | member { | |
98 | {name "a"} | |
99 | {type :$char_type_label} | |
100 | {data_member_location 0 DW_FORM_udata} | |
101 | } | |
102 | member { | |
103 | {name "b"} | |
104 | {type :$char_type_label} | |
105 | {data_member_location 1 DW_FORM_udata} | |
106 | } | |
107 | member { | |
108 | {name "c"} | |
109 | {type :$char_type_label} | |
110 | {data_member_location 2 DW_FORM_udata} | |
111 | } | |
112 | member { | |
113 | {name "d"} | |
114 | {type :$char_type_label} | |
115 | {data_member_location 3 DW_FORM_udata} | |
116 | } | |
117 | } | |
118 | ||
3bf31011 AA |
119 | # struct t { int u, x:9, y:13, z:10; }; |
120 | struct_t_label: structure_type { | |
121 | {name "t"} | |
122 | {byte_size 8 DW_FORM_sdata} | |
123 | } { | |
124 | member { | |
125 | {name "u"} | |
126 | {type :$int_type_label} | |
127 | } | |
128 | member { | |
129 | {name "x"} | |
130 | {type :$int_type_label} | |
131 | {data_member_location 4 DW_FORM_udata} | |
132 | {bit_size 9 DW_FORM_udata} | |
133 | } | |
134 | member { | |
135 | {name "y"} | |
136 | {type :$int_type_label} | |
137 | {data_bit_offset 41 DW_FORM_udata} | |
138 | {bit_size 13 DW_FORM_udata} | |
139 | } | |
140 | member { | |
141 | {name "z"} | |
142 | {type :$int_type_label} | |
143 | {data_bit_offset 54 DW_FORM_udata} | |
144 | {bit_size 10 DW_FORM_udata} | |
145 | } | |
146 | } | |
147 | ||
148 | # struct st { struct s s; struct t t; }; | |
149 | struct_st_label: structure_type { | |
150 | {name "st"} | |
151 | {byte_size 12 DW_FORM_udata} | |
152 | } { | |
153 | member { | |
154 | {name "s"} | |
155 | {type :$struct_s_label} | |
156 | } | |
157 | member { | |
158 | {name "t"} | |
159 | {type :$struct_t_label} | |
160 | {data_member_location 4 DW_FORM_udata} | |
161 | } | |
162 | } | |
163 | ||
0567c986 AA |
164 | DW_TAG_subprogram { |
165 | {MACRO_AT_func { main ${srcdir}/${subdir}/${srcfile} }} | |
166 | {DW_AT_external 1 flag} | |
167 | } { | |
168 | # Simple memory location. | |
169 | DW_TAG_variable { | |
170 | {name "a"} | |
171 | {type :$array_a8_label} | |
172 | {location { | |
173 | addr $buf_var | |
174 | } SPECIAL_expr} | |
175 | } | |
176 | # Memory pieces: two bytes from &buf[2], and two bytes | |
177 | # from &buf[0]. | |
178 | DW_TAG_variable { | |
179 | {name "s1"} | |
180 | {type :$struct_s_label} | |
181 | {location { | |
182 | addr $buf_var | |
183 | plus_uconst 2 | |
184 | piece 2 | |
185 | addr $buf_var | |
186 | piece 2 | |
187 | } SPECIAL_expr} | |
188 | } | |
189 | # Register- and memory pieces: one byte each from r0, | |
190 | # &buf[4], r1, and &buf[5]. | |
191 | DW_TAG_variable { | |
192 | {name "s2"} | |
193 | {type :$struct_s_label} | |
194 | {location { | |
195 | regx [lindex $dwarf_regnum 0] | |
196 | piece 1 | |
197 | addr "$buf_var + 4" | |
198 | piece 1 | |
199 | regx [lindex $dwarf_regnum 1] | |
200 | piece 1 | |
201 | addr "$buf_var + 5" | |
202 | piece 1 | |
203 | } SPECIAL_expr} | |
204 | } | |
3bf31011 AA |
205 | # Memory pieces for bitfield access: 8 bytes optimized |
206 | # out, 3 bytes from &buf[3], and 1 byte from &buf[1]. | |
207 | DW_TAG_variable { | |
208 | {name "st1"} | |
209 | {type :$struct_st_label} | |
210 | {location { | |
211 | piece 8 | |
212 | addr "$buf_var + 3" | |
213 | piece 3 | |
214 | addr "$buf_var + 1" | |
215 | piece 1 | |
216 | } SPECIAL_expr} | |
217 | } | |
03c8af18 AA |
218 | # Register pieces for bitfield access: 4 bytes optimized |
219 | # out, 3 bytes from r0, and 1 byte from r1. | |
220 | DW_TAG_variable { | |
221 | {name "t2"} | |
222 | {type :$struct_t_label} | |
223 | {location { | |
224 | piece 4 | |
225 | regx [lindex $dwarf_regnum 0] | |
226 | piece 3 | |
227 | regx [lindex $dwarf_regnum 1] | |
228 | piece 1 | |
229 | } SPECIAL_expr} | |
230 | } | |
65d84b76 AA |
231 | # One piece per bitfield, using piece offsets: 32 bits of |
232 | # an implicit value, 9 bits of a stack value, 13 bits of | |
233 | # r0, and 10 bits of buf. | |
234 | DW_TAG_variable { | |
235 | {name "t3"} | |
236 | {type :$struct_t_label} | |
237 | {location { | |
238 | implicit_value 0x12 0x34 0x56 0x78 0x9a | |
239 | bit_piece 32 4 | |
240 | const2s -280 | |
241 | stack_value | |
242 | bit_piece 9 2 | |
243 | regx [lindex $dwarf_regnum 0] | |
244 | bit_piece 13 14 | |
245 | addr $buf_var | |
246 | bit_piece 10 42 | |
247 | } SPECIAL_expr} | |
248 | } | |
0567c986 AA |
249 | } |
250 | } | |
251 | } | |
252 | } | |
253 | ||
254 | if { [prepare_for_testing ${testfile}.exp ${testfile} \ | |
255 | [list $srcfile $asm_file] {nodebug}] } { | |
256 | return -1 | |
257 | } | |
258 | ||
259 | if ![runto_main] { | |
260 | return -1 | |
261 | } | |
262 | ||
3bf31011 AA |
263 | # Determine byte order. |
264 | set endian [get_endianness] | |
265 | ||
0567c986 AA |
266 | # Byte-aligned memory pieces. |
267 | gdb_test "print/d s1" " = \\{a = 2, b = 3, c = 0, d = 1\\}" \ | |
268 | "s1 == re-ordered buf" | |
269 | gdb_test_no_output "set var s1.a = 63" | |
270 | gdb_test "print/d s1" " = \\{a = 63, b = 3, c = 0, d = 1\\}" \ | |
271 | "verify s1.a" | |
272 | gdb_test "print/d a" " = \\{0, 1, 63, 3, 4, 5, 6, 7\\}" \ | |
273 | "verify s1.a through a" | |
d5d1163e AA |
274 | gdb_test_no_output "set var s1.b = 42" |
275 | gdb_test "print/d s1" " = \\{a = 63, b = 42, c = 0, d = 1\\}" \ | |
276 | "verify s1.b" | |
277 | gdb_test "print/d a" " = \\{0, 1, 63, 42, 4, 5, 6, 7\\}" \ | |
278 | "verify s1.b through a" | |
0567c986 AA |
279 | |
280 | # Byte-aligned register- and memory pieces. | |
281 | gdb_test_no_output "set var \$[lindex $regname 0] = 81" \ | |
282 | "init reg for s2.a" | |
283 | gdb_test_no_output "set var \$[lindex $regname 1] = 28" \ | |
284 | "init reg for s2.c" | |
d6382fff | 285 | gdb_test "print/u s2" " = \\{a = 81, b = 4, c = 28, d = 5\\}" \ |
0567c986 AA |
286 | "initialized s2 from mem and regs" |
287 | gdb_test_no_output "set var s2.c += s2.a + s2.b - s2.d" | |
d6382fff | 288 | gdb_test "print/u s2" " = \\{a = 81, b = 4, c = 108, d = 5\\}" \ |
0567c986 | 289 | "verify s2.c" |
d6382fff | 290 | gdb_test "print/u \$[lindex $regname 1]" " = 108" \ |
0567c986 AA |
291 | "verify s2.c through reg" |
292 | gdb_test_no_output "set var s2 = {191, 73, 231, 123}" \ | |
293 | "re-initialize s2" | |
d6382fff | 294 | gdb_test "print/u s2" " = \\{a = 191, b = 73, c = 231, d = 123\\}" \ |
0567c986 | 295 | "verify re-initialized s2" |
3bf31011 AA |
296 | |
297 | # Unaligned bitfield access through byte-aligned pieces. | |
298 | gdb_test_no_output "set var a = { 0 }" | |
299 | gdb_test_no_output "set var st1.t.x = -7" | |
300 | gdb_test_no_output "set var st1.t.z = 340" | |
301 | gdb_test_no_output "set var st1.t.y = 1234" | |
302 | gdb_test "print st1.t" " = \\{u = <optimized out>, x = -7, y = 1234, z = 340\\}" \ | |
303 | "verify st1.t" | |
304 | switch $endian { | |
305 | little {set val "0x55, 0x0, 0xf9, 0xa5, 0x9"} | |
306 | big {set val "0x54, 0x0, 0xfc, 0x93, 0x49"} | |
307 | } | |
308 | # | -- | z:2-9 | -- | x:0-7 | x:8 y:0-6 | y:7-12 z:0-1 | -- | -- | | |
309 | # \_______________________________________________/ | |
310 | # val | |
311 | gdb_test "print/x a" " = \\{0x0, ${val}, 0x0, 0x0\\}" \ | |
312 | "verify st1 through a" | |
03c8af18 AA |
313 | |
314 | switch $endian { big {set val 0x7ffc} little {set val 0x3ffe00} } | |
315 | gdb_test_no_output "set var \$[lindex $regname 0] = $val" \ | |
316 | "init t2, first piece" | |
317 | gdb_test_no_output "set var \$[lindex $regname 1] = 0" \ | |
318 | "init t2, second piece" | |
319 | gdb_test "print/d t2" " = \\{u = <optimized out>, x = 0, y = -1, z = 0\\}" \ | |
320 | "initialized t2 from regs" | |
321 | gdb_test_no_output "set var t2.y = 2641" | |
322 | gdb_test_no_output "set var t2.z = -400" | |
323 | gdb_test_no_output "set var t2.x = 200" | |
324 | gdb_test "print t2.x + t2.y + t2.z" " = 2441" | |
65d84b76 AA |
325 | |
326 | # Bitfield access through pieces with nonzero piece offsets. | |
327 | gdb_test_no_output "set var \$[lindex $regname 0] = 0xa8000" \ | |
328 | "init reg for t3.y" | |
329 | gdb_test_no_output "set var *(char \[2\] *) (a + 5) = { 70, 82 }" \ | |
330 | "init mem for t3.z" | |
331 | switch $endian { | |
332 | little {set val "u = -1484430527, x = -70, y = 42, z = 145"} | |
333 | big {set val "u = 591751049, x = -70, y = 42, z = 101"} | |
334 | } | |
335 | gdb_test "print t3" " = \\{$val\\}" \ | |
336 | "initialized t3 from reg and mem" | |
337 | gdb_test_no_output "set var t3.y = -1" \ | |
338 | "overwrite t3.y" | |
339 | gdb_test "print/x \$[lindex $regname 0]" " = 0x7ffc000" \ | |
340 | "verify t3.y through reg" | |
341 | gdb_test_no_output "set var t3.z = -614" \ | |
342 | "overwrite t3.z" | |
343 | switch $endian {big {set val "0x59, 0xa2"} little {set val "0x6a, 0x56"}} | |
344 | gdb_test "print/x *(char \[2\] *) (a + 5)" " = \\{$val\\}" \ | |
345 | "verify t3.z through mem" |