GDB: trad-frame: Store length of value_bytes in trad_frame_saved_reg
[binutils-gdb.git] / gdb / testsuite / gdb.base / ptype-offsets.exp
blob68748da612ad92c84f586c74fb90e9cc4a879d2d
1 # This testcase is part of GDB, the GNU debugger.
3 # Copyright 2017-2024 Free Software Foundation, Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # This testcase exercises the "ptype /o" feature, which can be used to
19 # print the offsets and sizes of each field of a struct/union/class.
21 standard_testfile .cc
23 # Test only works on LP64 targets. That's how we guarantee that the
24 # expected holes will be present in the struct.
25 if { ![is_lp64_target] } {
26 untested "test work only on lp64 targets"
27 return 0
30 if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
31 { debug c++ }] } {
32 return -1
35 # Test general offset printing, ctor/dtor printing, union, formatting.
36 gdb_test "ptype /o struct abc" \
37 [string_to_regexp [multi_line \
38 "/* offset | size */ type = struct abc \{" \
39 "/* 8 | 8 */ void *field1;" \
40 "/* 16: 0 | 4 */ unsigned int field2 : 1;" \
41 "/* XXX 7-bit hole */" \
42 "/* XXX 3-byte hole */" \
43 "/* 20 | 4 */ int field3;" \
44 "/* 24 | 1 */ signed char field4;" \
45 "/* XXX 7-byte hole */" \
46 "/* 32 | 8 */ uint64_t field5;" \
47 "/* 40 | 8 */ union \{" \
48 "/* 8 */ void *field6;" \
49 "/* 4 */ int field7;" \
50 "" \
51 " /* total size (bytes): 8 */" \
52 " \} field8;" \
53 "/* 48 | 2 */ my_int_type field9;" \
54 "/* XXX 6-byte padding */" \
55 "" \
56 " /* total size (bytes): 56 */" \
57 " \}"]]
59 # test "ptype /ox"
60 gdb_test "ptype /ox struct abc" \
61 [string_to_regexp [multi_line \
62 "/* offset | size */ type = struct abc {" \
63 "/* 0x0008 | 0x0008 */ void *field1;" \
64 "/* 0x0010: 0x0 | 0x0004 */ unsigned int field2 : 1;" \
65 "/* XXX 7-bit hole */" \
66 "/* XXX 3-byte hole */" \
67 "/* 0x0014 | 0x0004 */ int field3;" \
68 "/* 0x0018 | 0x0001 */ signed char field4;" \
69 "/* XXX 7-byte hole */" \
70 "/* 0x0020 | 0x0008 */ uint64_t field5;" \
71 "/* 0x0028 | 0x0008 */ union \{" \
72 "/* 0x0008 */ void *field6;" \
73 "/* 0x0004 */ int field7;" \
74 "" \
75 " /* total size (bytes): 8 */" \
76 " \} field8;" \
77 "/* 0x0030 | 0x0002 */ my_int_type field9;" \
78 "/* XXX 6-byte padding */" \
79 "" \
80 " /* total size (bytes): 56 */" \
81 " \}"]]
83 # Test "ptype /oTM".
84 gdb_test "ptype /oTM struct abc" \
85 [string_to_regexp [multi_line \
86 "/* offset | size */ type = struct abc \{" \
87 "/* 8 | 8 */ void *field1;" \
88 "/* 16: 0 | 4 */ unsigned int field2 : 1;" \
89 "/* XXX 7-bit hole */" \
90 "/* XXX 3-byte hole */" \
91 "/* 20 | 4 */ int field3;" \
92 "/* 24 | 1 */ signed char field4;" \
93 "/* XXX 7-byte hole */" \
94 "/* 32 | 8 */ uint64_t field5;" \
95 "/* 40 | 8 */ union \{" \
96 "/* 8 */ void *field6;" \
97 "/* 4 */ int field7;" \
98 "" \
99 " /* total size (bytes): 8 */" \
100 " \} field8;" \
101 "/* 48 | 2 */ my_int_type field9;" \
102 "" \
103 " abc(void);" \
104 " ~abc(void);" \
105 "" \
106 " typedef short my_int_type;" \
107 "/* XXX 6-byte padding */" \
108 "" \
109 " /* total size (bytes): 56 */" \
110 " \}"]]
112 # Test "ptype /TMo". This should be the same as "ptype /o".
113 gdb_test "ptype /TMo struct abc" \
114 [string_to_regexp [multi_line \
115 "/* offset | size */ type = struct abc \{" \
116 "/* 8 | 8 */ void *field1;" \
117 "/* 16: 0 | 4 */ unsigned int field2 : 1;" \
118 "/* XXX 7-bit hole */" \
119 "/* XXX 3-byte hole */" \
120 "/* 20 | 4 */ int field3;" \
121 "/* 24 | 1 */ signed char field4;" \
122 "/* XXX 7-byte hole */" \
123 "/* 32 | 8 */ uint64_t field5;" \
124 "/* 40 | 8 */ union \{" \
125 "/* 8 */ void *field6;" \
126 "/* 4 */ int field7;" \
127 "" \
128 " /* total size (bytes): 8 */" \
129 " \} field8;" \
130 "/* 48 | 2 */ my_int_type field9;" \
131 "/* XXX 6-byte padding */" \
132 "" \
133 " /* total size (bytes): 56 */" \
134 " \}"]]
136 # Test nested structs.
137 gdb_test "ptype /o struct pqr" \
138 [string_to_regexp [multi_line \
139 "/* offset | size */ type = struct pqr \{" \
140 "/* 0 | 4 */ int ff1;" \
141 "/* XXX 4-byte hole */" \
142 "/* 8 | 40 */ struct xyz \{" \
143 "/* 8 | 4 */ int f1;" \
144 "/* 12 | 1 */ signed char f2;" \
145 "/* XXX 3-byte hole */" \
146 "/* 16 | 8 */ void *f3;" \
147 "/* 24 | 24 */ struct tuv \{" \
148 "/* 24 | 4 */ int a1;" \
149 "/* XXX 4-byte hole */" \
150 "/* 32 | 8 */ signed char *a2;" \
151 "/* 40 | 4 */ int a3;" \
152 "/* XXX 4-byte padding */" \
153 "" \
154 " /* total size (bytes): 24 */" \
155 " \} f4;" \
156 "" \
157 " /* total size (bytes): 40 */" \
158 " \} ff2;" \
159 "/* 48 | 1 */ signed char ff3;" \
160 "/* XXX 7-byte padding */" \
161 "" \
162 " /* total size (bytes): 56 */" \
163 " \}"]]
165 # Test nested struct with /x
166 gdb_test "ptype /ox struct pqr" \
167 [string_to_regexp [multi_line \
168 "/* offset | size */ type = struct pqr \{" \
169 "/* 0x0000 | 0x0004 */ int ff1;" \
170 "/* XXX 4-byte hole */" \
171 "/* 0x0008 | 0x0028 */ struct xyz \{" \
172 "/* 0x0008 | 0x0004 */ int f1;" \
173 "/* 0x000c | 0x0001 */ signed char f2;" \
174 "/* XXX 3-byte hole */" \
175 "/* 0x0010 | 0x0008 */ void *f3;" \
176 "/* 0x0018 | 0x0018 */ struct tuv \{" \
177 "/* 0x0018 | 0x0004 */ int a1;" \
178 "/* XXX 4-byte hole */" \
179 "/* 0x0020 | 0x0008 */ signed char *a2;" \
180 "/* 0x0028 | 0x0004 */ int a3;" \
181 "/* XXX 4-byte padding */" \
182 "" \
183 " /* total size (bytes): 24 */" \
184 " \} f4;" \
185 "" \
186 " /* total size (bytes): 40 */" \
187 " \} ff2;" \
188 "/* 0x0030 | 0x0001 */ signed char ff3;" \
189 "/* XXX 7-byte padding */" \
190 "" \
191 " /* total size (bytes): 56 */" \
192 " \}"]]
195 # Test that the offset is properly reset when we are printing a union
196 # and go inside two inner structs.
197 # This also tests a struct inside a struct inside a union.
198 gdb_test "ptype /o union qwe" \
199 [string_to_regexp [multi_line \
200 "/* offset | size */ type = union qwe \{" \
201 "/* 24 */ struct tuv \{" \
202 "/* 0 | 4 */ int a1;" \
203 "/* XXX 4-byte hole */" \
204 "/* 8 | 8 */ signed char *a2;" \
205 "/* 16 | 4 */ int a3;" \
206 "/* XXX 4-byte padding */" \
207 "" \
208 " /* total size (bytes): 24 */" \
209 " \} fff1;" \
210 "/* 40 */ struct xyz \{" \
211 "/* 0 | 4 */ int f1;" \
212 "/* 4 | 1 */ signed char f2;" \
213 "/* XXX 3-byte hole */" \
214 "/* 8 | 8 */ void *f3;" \
215 "/* 16 | 24 */ struct tuv \{" \
216 "/* 16 | 4 */ int a1;" \
217 "/* XXX 4-byte hole */" \
218 "/* 24 | 8 */ signed char *a2;" \
219 "/* 32 | 4 */ int a3;" \
220 "/* XXX 4-byte padding */" \
221 "" \
222 " /* total size (bytes): 24 */" \
223 " \} f4;" \
224 "" \
225 " /* total size (bytes): 40 */" \
226 " \} fff2;" \
227 "" \
228 " /* total size (bytes): 40 */" \
229 " \}"]]
231 # Test printing a struct that contains a union, and that also
232 # contains a struct.
233 gdb_test "ptype /o struct poi" \
234 [string_to_regexp [multi_line \
235 "/* offset | size */ type = struct poi \{" \
236 "/* 0 | 4 */ int f1;" \
237 "/* XXX 4-byte hole */" \
238 "/* 8 | 40 */ union qwe \{" \
239 "/* 24 */ struct tuv \{" \
240 "/* 8 | 4 */ int a1;" \
241 "/* XXX 4-byte hole */" \
242 "/* 16 | 8 */ signed char *a2;" \
243 "/* 24 | 4 */ int a3;" \
244 "/* XXX 4-byte padding */" \
245 "" \
246 " /* total size (bytes): 24 */" \
247 " \} fff1;" \
248 "/* 40 */ struct xyz \{" \
249 "/* 8 | 4 */ int f1;" \
250 "/* 12 | 1 */ signed char f2;" \
251 "/* XXX 3-byte hole */" \
252 "/* 16 | 8 */ void *f3;" \
253 "/* 24 | 24 */ struct tuv \{" \
254 "/* 24 | 4 */ int a1;" \
255 "/* XXX 4-byte hole */" \
256 "/* 32 | 8 */ signed char *a2;" \
257 "/* 40 | 4 */ int a3;" \
258 "/* XXX 4-byte padding */" \
259 "" \
260 " /* total size (bytes): 24 */" \
261 " \} f4;" \
262 "" \
263 " /* total size (bytes): 40 */" \
264 " \} fff2;" \
265 "/* XXX 32-byte padding */" \
266 "" \
267 " /* total size (bytes): 40 */" \
268 " \} f2;" \
269 "/* 48 | 2 */ uint16_t f3;" \
270 "/* XXX 6-byte hole */" \
271 "/* 56 | 56 */ struct pqr \{" \
272 "/* 56 | 4 */ int ff1;" \
273 "/* XXX 4-byte hole */" \
274 "/* 64 | 40 */ struct xyz \{" \
275 "/* 64 | 4 */ int f1;" \
276 "/* 68 | 1 */ signed char f2;" \
277 "/* XXX 3-byte hole */" \
278 "/* 72 | 8 */ void *f3;" \
279 "/* 80 | 24 */ struct tuv \{" \
280 "/* 80 | 4 */ int a1;" \
281 "/* XXX 4-byte hole */" \
282 "/* 88 | 8 */ signed char *a2;" \
283 "/* 96 | 4 */ int a3;" \
284 "/* XXX 4-byte padding */" \
285 "" \
286 " /* total size (bytes): 24 */" \
287 " \} f4;" \
288 "" \
289 " /* total size (bytes): 40 */" \
290 " \} ff2;" \
291 "/* 104 | 1 */ signed char ff3;" \
292 "/* XXX 7-byte padding */" \
293 "" \
294 " /* total size (bytes): 56 */" \
295 " \} f4;" \
296 "" \
297 " /* total size (bytes): 112 */" \
298 " \}"]]
300 # Test printing a struct with several bitfields, laid out in various
301 # ways.
303 # Because dealing with bitfields and offsets is difficult, it can be
304 # tricky to confirm that the output of this command is accurate. A
305 # nice way to do that is to use GDB's "x" command and print the actual
306 # memory layout of the struct. In order to differentiate between
307 # bitfields and non-bitfield variables, one can assign "-1" to every
308 # bitfield in the struct. An example of the output of "x" using
309 # "struct tyu" is:
311 # (gdb) x/24xb &e
312 # 0x7fffffffd540: 0xff 0xff 0xff 0x1f 0x00 0x00 0x00 0x00
313 # 0x7fffffffd548: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
314 # 0x7fffffffd550: 0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00
315 gdb_test "ptype /o struct tyu" \
316 [string_to_regexp [multi_line \
317 "/* offset | size */ type = struct tyu \{" \
318 "/* 0: 0 | 4 */ int a1 : 1;" \
319 "/* 0: 1 | 4 */ int a2 : 3;" \
320 "/* 0: 4 | 4 */ int a3 : 23;" \
321 "/* 3: 3 | 1 */ signed char a4 : 2;" \
322 "/* XXX 3-bit hole */" \
323 "/* XXX 4-byte hole */" \
324 "/* 8 | 8 */ int64_t a5;" \
325 "/* 16: 0 | 4 */ int a6 : 5;" \
326 "/* 16: 5 | 8 */ int64_t a7 : 3;" \
327 "/* XXX 7-byte padding */" \
328 "" \
329 " /* total size (bytes): 24 */" \
330 " \}"]]
332 gdb_test "ptype /o struct asd" \
333 [string_to_regexp [multi_line \
334 "/* offset | size */ type = struct asd \{" \
335 "/* 0 | 32 */ struct asd::jkl \{" \
336 "/* 0 | 8 */ signed char *f1;" \
337 "/* 8 | 8 */ union \{" \
338 "/* 8 */ void *ff1;" \
339 "" \
340 " /* total size (bytes): 8 */" \
341 " \} f2;" \
342 "/* 16 | 8 */ union \{" \
343 "/* 8 */ signed char *ff2;" \
344 "" \
345 " /* total size (bytes): 8 */" \
346 " \} f3;" \
347 "/* 24: 0 | 4 */ int f4 : 5;" \
348 "/* 24: 5 | 4 */ unsigned int f5 : 1;" \
349 "/* XXX 2-bit hole */" \
350 "/* XXX 1-byte hole */" \
351 "/* 26 | 2 */ short f6;" \
352 "/* XXX 4-byte padding */" \
353 "" \
354 " /* total size (bytes): 32 */" \
355 " \} f7;" \
356 "/* 32 | 8 */ unsigned long f8;" \
357 "/* 40 | 8 */ signed char *f9;" \
358 "/* 48: 0 | 4 */ int f10 : 4;" \
359 "/* 48: 4 | 4 */ unsigned int f11 : 1;" \
360 "/* 48: 5 | 4 */ unsigned int f12 : 1;" \
361 "/* 48: 6 | 4 */ unsigned int f13 : 1;" \
362 "/* 48: 7 | 4 */ unsigned int f14 : 1;" \
363 "/* XXX 7-byte hole */" \
364 "/* 56 | 8 */ void *f15;" \
365 "/* 64 | 8 */ void *f16;" \
366 "" \
367 " /* total size (bytes): 72 */" \
368 " \}"]]
370 # Test that we don't print any header when issuing a "ptype /o" on a
371 # non-struct, non-union, non-class type.
372 gdb_test "ptype /o int" "int"
373 gdb_test "ptype /o uint8_t" "char"
375 # Test that the "whatis" command doesn't print anything related to the
376 # "offsets" feature, even when receiving the "/o" parameter.
377 set test "whatis /o asd"
378 gdb_test_multiple "$test" "$test" {
379 -re "^$test\r\ntype = asd\r\n$gdb_prompt $" {
380 pass $test
384 # Test that printing a struct with a static member of itself doesn't
385 # get us into an infinite loop.
386 gdb_test "ptype/o static_member" \
387 [string_to_regexp [multi_line \
388 "/* offset | size */ type = struct static_member \{" \
389 " static static_member Empty;" \
390 "/* 0 | 4 */ int abc;" \
391 "" \
392 " /* total size (bytes): 4 */" \
393 " \}"]]
395 # Test that the "no data fields" text is indented properly.
396 gdb_test "ptype/o empty_member" \
397 [string_to_regexp [multi_line \
398 "/* offset | size */ type = struct empty_member \{" \
399 "/* 0 | 1 */ struct {" \
400 " <no data fields>" \
401 "" \
402 " /* total size (bytes): 1 */" \
403 " } empty;" \
404 "/* XXX 3-byte hole */" \
405 "/* 4 | 4 */ int an_int;" \
406 "" \
407 " /* total size (bytes): 8 */" \
408 " \}"]]
410 with_test_prefix "with_hex_default" {
411 # Test setting default display to hex
412 gdb_test_no_output "set print type hex on"
413 gdb_test "show print type hex" \
414 "Display of struct members offsets and sizes in hexadecimal is on"
416 # test "ptype /o" is now equivalent to "ptype /ox"
417 gdb_test "ptype /o struct abc" \
418 [string_to_regexp [multi_line \
419 "/* offset | size */ type = struct abc \{" \
420 "/* 0x0008 | 0x0008 */ void *field1;" \
421 "/* 0x0010: 0x0 | 0x0004 */ unsigned int field2 : 1;" \
422 "/* XXX 7-bit hole */" \
423 "/* XXX 3-byte hole */" \
424 "/* 0x0014 | 0x0004 */ int field3;" \
425 "/* 0x0018 | 0x0001 */ signed char field4;" \
426 "/* XXX 7-byte hole */" \
427 "/* 0x0020 | 0x0008 */ uint64_t field5;" \
428 "/* 0x0028 | 0x0008 */ union \{" \
429 "/* 0x0008 */ void *field6;" \
430 "/* 0x0004 */ int field7;" \
431 "" \
432 " /* total size (bytes): 8 */" \
433 " \} field8;" \
434 "/* 0x0030 | 0x0002 */ my_int_type field9;" \
435 "/* XXX 6-byte padding */" \
436 "" \
437 " /* total size (bytes): 56 */" \
438 " \}"]]
440 gdb_test "ptype /od struct abc" \
441 [string_to_regexp [multi_line \
442 "/* offset | size */ type = struct abc \{" \
443 "/* 8 | 8 */ void *field1;" \
444 "/* 16: 0 | 4 */ unsigned int field2 : 1;" \
445 "/* XXX 7-bit hole */" \
446 "/* XXX 3-byte hole */" \
447 "/* 20 | 4 */ int field3;" \
448 "/* 24 | 1 */ signed char field4;" \
449 "/* XXX 7-byte hole */" \
450 "/* 32 | 8 */ uint64_t field5;" \
451 "/* 40 | 8 */ union \{" \
452 "/* 8 */ void *field6;" \
453 "/* 4 */ int field7;" \
454 "" \
455 " /* total size (bytes): 8 */" \
456 " \} field8;" \
457 "/* 48 | 2 */ my_int_type field9;" \
458 "/* XXX 6-byte padding */" \
459 "" \
460 " /* total size (bytes): 56 */" \
461 " \}"]]
463 # restore
464 gdb_test_no_output "set print type hex off"
467 gdb_test_no_output "set language asm"
468 gdb_test "ptype/o struct tuv" \
469 [string_to_regexp [multi_line \
470 "/* offset | size */ type = struct tuv \{" \
471 "/* 0 | 4 */ int a1;" \
472 "/* XXX 4-byte hole */" \
473 "/* 8 | 8 */ signed char *a2;" \
474 "/* 16 | 4 */ int a3;" \
475 "/* XXX 4-byte padding */" \
476 "" \
477 " /* total size (bytes): 24 */" \
478 " \}"]]