Implement pahole-like 'ptype /o' option
[external/binutils.git] / gdb / testsuite / gdb.base / ptype-offsets.exp
1 # This testcase is part of GDB, the GNU debugger.
2
3 # Copyright 2017 Free Software Foundation, Inc.
4
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.
9 #
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.
14 #
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/>.
17
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.
20
21 standard_testfile .cc
22
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
28 }
29
30 if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
31           { debug c++ }] } {
32     return -1
33 }
34
35 # Test general offset printing, ctor/dtor printing, union, formatting.
36 gdb_test "ptype /o struct abc" \
37     [multi_line \
38 {/\* offset    |  size \*/  type = struct abc \{} \
39 {                         public:} \
40 {/\*    8      |     8 \*/    void \*field1;} \
41 {/\*   16:31   |     4 \*/    unsigned int field2 : 1;} \
42 {/\* XXX  7-bit hole   \*/} \
43 {/\* XXX  3-byte hole  \*/} \
44 {/\*   20      |     4 \*/    int field3;} \
45 {/\*   24      |     1 \*/    signed char field4;} \
46 {/\* XXX  7-byte hole  \*/} \
47 {/\*   32      |     8 \*/    uint64_t field5;} \
48 {/\*   40      |     8 \*/    union \{} \
49 {/\*                 8 \*/        void \*field6;} \
50 {/\*                 4 \*/        int field7;} \
51 {} \
52 {                               /\* total size \(bytes\):    8 \*/} \
53 {                           \} field8;} \
54 {/\*   48      |     4 \*/    my_int_type field9;} \
55 {} \
56 {                           /\* total size \(bytes\):   56 \*/} \
57 {                         \}}]
58
59 # Test "ptype /oTM".
60 gdb_test "ptype /oTM struct abc" \
61     [multi_line \
62 {/\* offset    |  size \*/  type = struct abc \{} \
63 {                         public:} \
64 {/\*    8      |     8 \*/    void \*field1;} \
65 {/\*   16:31   |     4 \*/    unsigned int field2 : 1;} \
66 {/\* XXX  7-bit hole   \*/} \
67 {/\* XXX  3-byte hole  \*/} \
68 {/\*   20      |     4 \*/    int field3;} \
69 {/\*   24      |     1 \*/    signed char field4;} \
70 {/\* XXX  7-byte hole  \*/} \
71 {/\*   32      |     8 \*/    uint64_t field5;} \
72 {/\*   40      |     8 \*/    union \{} \
73 {/\*                 8 \*/        void \*field6;} \
74 {/\*                 4 \*/        int field7;} \
75 {} \
76 {                               /\* total size \(bytes\):    8 \*/} \
77 {                           \} field8;} \
78 {/\*   48      |     4 \*/    my_int_type field9;} \
79 {} \
80 {                           abc\(void\);} \
81 {                           ~abc\(\);} \
82 {} \
83 {                           typedef int my_int_type;} \
84 {} \
85 {                           /\* total size \(bytes\):   56 \*/} \
86 {                         \}}]
87
88 # Test "ptype /TMo".  This should be the same as "ptype /o".
89 gdb_test "ptype /TMo struct abc" \
90     [multi_line \
91 {/\* offset    |  size \*/  type = struct abc \{} \
92 {                         public:} \
93 {/\*    8      |     8 \*/    void \*field1;} \
94 {/\*   16:31   |     4 \*/    unsigned int field2 : 1;} \
95 {/\* XXX  7-bit hole   \*/} \
96 {/\* XXX  3-byte hole  \*/} \
97 {/\*   20      |     4 \*/    int field3;} \
98 {/\*   24      |     1 \*/    signed char field4;} \
99 {/\* XXX  7-byte hole  \*/} \
100 {/\*   32      |     8 \*/    uint64_t field5;} \
101 {/\*   40      |     8 \*/    union \{} \
102 {/\*                 8 \*/        void \*field6;} \
103 {/\*                 4 \*/        int field7;} \
104 {} \
105 {                               /\* total size \(bytes\):    8 \*/} \
106 {                           \} field8;} \
107 {/\*   48      |     4 \*/    my_int_type field9;} \
108 {} \
109 {                           /\* total size \(bytes\):   56 \*/} \
110 {                         \}}]
111
112 # Test nested structs.
113 gdb_test "ptype /o struct pqr" \
114     [multi_line \
115 {/\* offset    |  size \*/  type = struct pqr \{} \
116 {/\*    0      |     4 \*/    int ff1;} \
117 {/\* XXX  4-byte hole  \*/} \
118 {/\*    8      |    40 \*/    struct xyz \{} \
119 {/\*    8      |     4 \*/        int f1;} \
120 {/\*   12      |     1 \*/        signed char f2;} \
121 {/\* XXX  3-byte hole  \*/} \
122 {/\*   16      |     8 \*/        void \*f3;} \
123 {/\*   24      |    24 \*/        struct tuv \{} \
124 {/\*   24      |     4 \*/            int a1;} \
125 {/\* XXX  4-byte hole  \*/} \
126 {/\*   32      |     8 \*/            signed char \*a2;} \
127 {/\*   40      |     4 \*/            int a3;} \
128 {} \
129 {                                   /\* total size \(bytes\):   24 \*/} \
130 {                               \} f4;} \
131 {} \
132 {                               /\* total size \(bytes\):   40 \*/} \
133 {                           \} ff2;} \
134 {/\* XXX 28-byte hole  \*/} \
135 {/\*   72      |     1 \*/    signed char ff3;} \
136 {} \
137 {                           /\* total size \(bytes\):   56 \*/} \
138 {                         \}}]
139
140 # Test that the offset is properly reset when we are printing a union
141 # and go inside two inner structs.
142 # This also tests a struct inside a struct inside a union.
143 gdb_test "ptype /o union qwe" \
144     [multi_line \
145 {/\* offset    |  size \*/  type = union qwe \{} \
146 {/\*                24 \*/    struct tuv \{} \
147 {/\*    0      |     4 \*/        int a1;} \
148 {/\* XXX  4-byte hole  \*/} \
149 {/\*    8      |     8 \*/        signed char \*a2;} \
150 {/\*   16      |     4 \*/        int a3;} \
151 {} \
152 {                               /\* total size \(bytes\):   24 \*/} \
153 {                           \} fff1;} \
154 {/\*                40 \*/    struct xyz \{} \
155 {/\*    0      |     4 \*/        int f1;} \
156 {/\*    4      |     1 \*/        signed char f2;} \
157 {/\* XXX  3-byte hole  \*/} \
158 {/\*    8      |     8 \*/        void \*f3;} \
159 {/\*   16      |    24 \*/        struct tuv \{} \
160 {/\*   16      |     4 \*/            int a1;} \
161 {/\* XXX  4-byte hole  \*/} \
162 {/\*   24      |     8 \*/            signed char \*a2;} \
163 {/\*   32      |     4 \*/            int a3;} \
164 {} \
165 {                                   /\* total size \(bytes\):   24 \*/} \
166 {                               \} f4;} \
167 {} \
168 {                               /\* total size \(bytes\):   40 \*/} \
169 {                           \} fff2;} \
170 {} \
171 {                           /\* total size \(bytes\):   40 \*/} \
172 {                         \}}]
173
174 # Test printing a struct that contains a union, and that also
175 # contains a struct.
176 gdb_test "ptype /o struct poi" \
177     [multi_line \
178 {/\* offset    |  size \*/  type = struct poi \{} \
179 {/\*    0      |     4 \*/    int f1;} \
180 {/\* XXX  4-byte hole  \*/} \
181 {/\*    8      |    40 \*/    union qwe \{} \
182 {/\*                24 \*/        struct tuv \{} \
183 {/\*    8      |     4 \*/            int a1;} \
184 {/\* XXX  4-byte hole  \*/} \
185 {/\*   16      |     8 \*/            signed char \*a2;} \
186 {/\*   24      |     4 \*/            int a3;} \
187 {} \
188 {                                   /\* total size \(bytes\):   24 \*/} \
189 {                               \} fff1;} \
190 {/\*                40 \*/        struct xyz \{} \
191 {/\*    8      |     4 \*/            int f1;} \
192 {/\*   12      |     1 \*/            signed char f2;} \
193 {/\* XXX  3-byte hole  \*/} \
194 {/\*   16      |     8 \*/            void \*f3;} \
195 {/\*   24      |    24 \*/            struct tuv \{} \
196 {/\*   24      |     4 \*/                int a1;} \
197 {/\* XXX  4-byte hole  \*/} \
198 {/\*   32      |     8 \*/                signed char \*a2;} \
199 {/\*   40      |     4 \*/                int a3;} \
200 {} \
201 {                                       /\* total size \(bytes\):   24 \*/} \
202 {                                   \} f4;} \
203 {} \
204 {                                   /\* total size \(bytes\):   40 \*/} \
205 {                               \} fff2;} \
206 {} \
207 {                               /\* total size \(bytes\):   40 \*/} \
208 {                           \} f2;} \
209 {/\*   72      |     2 \*/    uint16_t f3;} \
210 {/\* XXX  6-byte hole  \*/} \
211 {/\*   80      |    56 \*/    struct pqr \{} \
212 {/\*   80      |     4 \*/        int ff1;} \
213 {/\* XXX  4-byte hole  \*/} \
214 {/\*   88      |    40 \*/        struct xyz \{} \
215 {/\*   88      |     4 \*/            int f1;} \
216 {/\*   92      |     1 \*/            signed char f2;} \
217 {/\* XXX  3-byte hole  \*/} \
218 {/\*   96      |     8 \*/            void \*f3;} \
219 {/\*  104      |    24 \*/            struct tuv \{} \
220 {/\*  104      |     4 \*/                int a1;} \
221 {/\* XXX  4-byte hole  \*/} \
222 {/\*  112      |     8 \*/                signed char \*a2;} \
223 {/\*  120      |     4 \*/                int a3;} \
224 {} \
225 {                                       /\* total size \(bytes\):   24 \*/} \
226 {                                   \} f4;} \
227 {} \
228 {                                   /\* total size \(bytes\):   40 \*/} \
229 {                               \} ff2;} \
230 {/\*  152      |     1 \*/        signed char ff3;} \
231 {} \
232 {                               /\* total size \(bytes\):   56 \*/} \
233 {                           \} f4;} \
234 {} \
235 {                           /\* total size \(bytes\):  112 \*/} \
236 {                         \}}]
237
238 # Test printing a struct with several bitfields, laid out in various
239 # ways.
240 #
241 # Because dealing with bitfields and offsets is difficult, it can be
242 # tricky to confirm that the output of this command is accurate.  A
243 # nice way to do that is to use GDB's "x" command and print the actual
244 # memory layout of the struct.  In order to differentiate between
245 # bitfields and non-bitfield variables, one can assign "-1" to every
246 # bitfield in the struct.  An example of the output of "x" using
247 # "struct tyu" is:
248 #
249 #   (gdb) x/24xb &e
250 #   0x7fffffffd540: 0xff    0xff    0xff    0x1f    0x00    0x00    0x00    0x00
251 #   0x7fffffffd548: 0xff    0xff    0xff    0xff    0xff    0xff    0xff    0xff
252 #   0x7fffffffd550: 0xff    0x00    0x00    0x00    0x00    0x00    0x00    0x00
253 gdb_test "ptype /o struct tyu" \
254     [multi_line \
255 {/\* offset    |  size \*/  type = struct tyu \{} \
256 {/\*    0:31   |     4 \*/    int a1 : 1;} \
257 {/\*    0:28   |     4 \*/    int a2 : 3;} \
258 {/\*    0: 5   |     4 \*/    int a3 : 23;} \
259 {/\*    3: 3   |     1 \*/    signed char a4 : 2;} \
260 {/\* XXX  3-bit hole   \*/} \
261 {/\* XXX  4-byte hole  \*/} \
262 {/\*    8      |     8 \*/    int64_t a5;} \
263 {/\*   16:27   |     4 \*/    int a6 : 5;} \
264 {/\*   16:56   |     8 \*/    int64_t a7 : 3;} \
265 {} \
266 {                           /\* total size \(bytes\):   24 \*/} \
267 {                         \}}]
268
269 gdb_test "ptype /o struct asd" \
270     [multi_line \
271 {/\* offset    |  size \*/  type = struct asd \{} \
272 {/\*    0      |    32 \*/    struct asd::jkl \{} \
273 {/\*    0      |     8 \*/        signed char \*f1;} \
274 {/\*    8      |     8 \*/        union \{} \
275 {/\*                 8 \*/            void \*ff1;} \
276 {} \
277 {                                   /\* total size \(bytes\):    8 \*/} \
278 {                               \} f2;} \
279 {/\*   16      |     8 \*/        union \{} \
280 {/\*                 8 \*/            signed char \*ff2;} \
281 {} \
282 {                                   /\* total size \(bytes\):    8 \*/} \
283 {                               \} f3;} \
284 {/\*   24:27   |     4 \*/        int f4 : 5;} \
285 {/\*   24:26   |     4 \*/        unsigned int f5 : 1;} \
286 {/\* XXX  2-bit hole   \*/} \
287 {/\* XXX  1-byte hole  \*/} \
288 {/\*   26      |     2 \*/        short f6;} \
289 {} \
290 {                               /\* total size \(bytes\):   32 \*/} \
291 {                           \} f7;} \
292 {/\*   32      |     8 \*/    unsigned long f8;} \
293 {/\*   40      |     8 \*/    signed char \*f9;} \
294 {/\*   48:28   |     4 \*/    int f10 : 4;} \
295 {/\*   48:27   |     4 \*/    unsigned int f11 : 1;} \
296 {/\*   48:26   |     4 \*/    unsigned int f12 : 1;} \
297 {/\*   48:25   |     4 \*/    unsigned int f13 : 1;} \
298 {/\*   48:24   |     4 \*/    unsigned int f14 : 1;} \
299 {/\* XXX  7-byte hole  \*/} \
300 {/\*   56      |     8 \*/    void \*f15;} \
301 {/\*   64      |     8 \*/    void \*f16;} \
302 {} \
303 {                           /\* total size \(bytes\):   72 \*/} \
304 {                         \}}]
305
306 # Test that we don't print any header when issuing a "ptype /o" on a
307 # non-struct, non-union, non-class type.
308 gdb_test "ptype /o int" "int"
309 gdb_test "ptype /o uint8_t" "char"
310
311 # Test that the "whatis" command doesn't print anything related to the
312 # "offsets" feature, even when receiving the "/o" parameter.
313 set test "whatis /o asd"
314 gdb_test_multiple "$test" "$test" {
315    -re "^$test\r\ntype = asd\r\n$gdb_prompt $" {
316        pass $test
317    }
318 }