Print this page
10823 should ignore DW_TAG_subprogram with DW_AT_declaration tags
10824 GCC7-derived CTF can double qualifiers on arrays
10825 ctfdump -c drops last type
10826 ctfdump -c goes off the rails with a missing parent
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Jason King <jason.king@joyent.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/test/util-tests/tests/ctf/check-sou.c
+++ new/usr/src/test/util-tests/tests/ctf/check-sou.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright (c) 2019, Joyent, Inc.
13 + * Copyright 2019, Joyent, Inc.
14 14 */
15 15
16 16 /*
17 17 * Check that we properly handle structures and unions.
18 18 */
19 19
20 20 #include "check-common.h"
21 21
22 22 static check_number_t check_bitfields[] = {
23 23 #ifdef TARGET_LP64
24 24 { "unsigned long:1", CTF_K_INTEGER, 0, 0, 1 },
25 25 { "unsigned long:2", CTF_K_INTEGER, 0, 0, 2 },
26 26 { "unsigned long:4", CTF_K_INTEGER, 0, 0, 4 },
27 27 { "unsigned long:5", CTF_K_INTEGER, 0, 0, 5 },
28 28 { "unsigned long:8", CTF_K_INTEGER, 0, 0, 8 },
29 29 { "unsigned long:16", CTF_K_INTEGER, 0, 0, 16 },
30 30 { "unsigned long:19", CTF_K_INTEGER, 0, 0, 19 },
31 31 { "unsigned long:32", CTF_K_INTEGER, 0, 0, 32 },
32 32 #else
33 33 { "unsigned long long:1", CTF_K_INTEGER, 0, 0, 1 },
34 34 { "unsigned long long:2", CTF_K_INTEGER, 0, 0, 2 },
35 35 { "unsigned long long:4", CTF_K_INTEGER, 0, 0, 4 },
36 36 { "unsigned long long:5", CTF_K_INTEGER, 0, 0, 5 },
37 37 { "unsigned long long:8", CTF_K_INTEGER, 0, 0, 8 },
38 38 { "unsigned long long:16", CTF_K_INTEGER, 0, 0, 16 },
39 39 { "unsigned long long:19", CTF_K_INTEGER, 0, 0, 19 },
40 40 { "unsigned long long:32", CTF_K_INTEGER, 0, 0, 32 },
41 41 #endif
42 42 { "unsigned short:1", CTF_K_INTEGER, 0, 0, 1 },
43 43 { "unsigned int:7", CTF_K_INTEGER, 0, 0, 7 },
44 44 { "unsigned int:32", CTF_K_INTEGER, 0, 0, 32 },
45 45 { "int:3", CTF_K_INTEGER, CTF_INT_SIGNED, 0, 3 },
46 46 { NULL }
47 47 };
48 48
49 49 static check_symbol_t check_syms[] = {
50 50 { "foo", "struct foo" },
51 51 { "head", "nlist_t" },
52 52 { "forward", "const forward_t" },
53 53 { "oot", "struct round_up" },
54 54 { "botw", "struct fixed_up" },
55 55 { "sophie", "struct mysterious_barrel" },
56 56 { "ayesha", "struct dusk_barrel" },
57 57 { "stats", "struct stats" },
58 58 { "ring", "struct fellowship" },
59 59 { "rings", "struct rings" },
60 60 { "nvme", "struct csts" },
61 61 { "games", "union jrpg" },
62 62 { "nier", "union nier" },
63 63 { "kh", "union kh" },
64 64 { "ct", "struct trigger" },
65 65 { "regress", "const union regress [9]" },
66 66 { NULL }
67 67 };
68 68
69 69 static check_member_t check_member_foo[] = {
70 70 { "a", "int", 0 },
71 71 { "b", "float", 4 * NBBY },
72 72 { "c", "const char *", 8 * NBBY },
73 73 { NULL }
74 74 };
75 75
76 76 static check_member_t check_member_node[] = {
77 77 { "prev", "struct node *", 0 },
78 78 #ifdef TARGET_LP64
79 79 { "next", "struct node *", 8 * NBBY },
80 80 #else
81 81 { "next", "struct node *", 4 * NBBY },
82 82 #endif
83 83 { NULL }
84 84 };
85 85
86 86 static check_member_t check_member_nlist[] = {
87 87 { "size", "size_t", 0 },
88 88 #ifdef TARGET_LP64
89 89 { "off", "size_t", 8 * NBBY },
90 90 { "head", "struct node", 16 * NBBY },
91 91 #else
92 92 { "off", "size_t", 4 * NBBY },
93 93 { "head", "struct node", 8 * NBBY },
94 94 #endif
95 95 { NULL }
96 96 };
97 97
98 98 static check_member_t check_member_forward[] = {
99 99 { "past", "void *", 0 },
100 100 #ifdef TARGET_LP64
101 101 { "present", "void *", 8 * NBBY },
102 102 { "future", "void *", 16 * NBBY },
103 103 #else
104 104 { "present", "void *", 4 * NBBY },
105 105 { "future", "void *", 8 * NBBY },
106 106 #endif
107 107 { NULL }
108 108 };
109 109
110 110 static check_member_t check_member_round_up[] = {
111 111 { "triforce", "uint8_t", 0 },
112 112 { "link", "uint32_t", 4 * NBBY },
113 113 { "zelda", "uint8_t", 8 * NBBY },
114 114 { "ganon", "uint8_t", 9 * NBBY },
115 115 { NULL }
116 116 };
117 117
118 118 static check_member_t check_member_fixed_up[] = {
119 119 { "triforce", "uint8_t", 0 },
120 120 { "link", "uint32_t", 1 * NBBY },
121 121 { "zelda", "uint8_t", 5 * NBBY },
122 122 { "ganon", "uint8_t", 6 * NBBY },
123 123 { NULL }
124 124 };
125 125
126 126 #ifdef TARGET_LP64
127 127 static check_member_t check_member_component[] = {
128 128 { "m", "enum material", 0 },
129 129 { "grade", "uint64_t", 8 * NBBY },
130 130 { "count", "uint64_t", 16 * NBBY },
131 131 { "locations", "const char *[4]", 24 * NBBY },
132 132 { NULL }
133 133 };
134 134
135 135 static check_member_t check_member_mysterious[] = {
136 136 { "name", "const char *", 0 },
137 137 { "capacity", "size_t", 8 * NBBY },
138 138 { "optional", "struct component [0]", 16 * NBBY },
139 139 { NULL }
140 140 };
141 141
142 142 static check_member_t check_member_dusk[] = {
143 143 { "name", "const char *", 0 },
144 144 { "opacity", "size_t", 8 * NBBY },
145 145 { "optional", "struct component [0]", 16 * NBBY },
146 146 { NULL }
147 147 };
148 148
149 149
150 150 static check_member_t check_member_stats[] = {
151 151 { "hp", "unsigned long:16", 0 },
152 152 { "mp", "unsigned long:16", 16 },
153 153 { "str", "unsigned long:8", 32 },
154 154 { "dex", "unsigned long:4", 40 },
155 155 { "con", "unsigned long:1", 44 },
156 156 { "inte", "unsigned long:2", 45 },
157 157 { "wis", "unsigned long:1", 47 },
158 158 { "cha", "unsigned long:4", 48 },
159 159 { "sanity", "unsigned long:1", 52 },
160 160 { "attack", "unsigned long:2", 53 },
161 161 { "mattack", "unsigned long:1", 55 },
162 162 { "defense", "unsigned long:8", 56 },
163 163 { "mdefense", "unsigned long:32", 64 },
164 164 { "evasion", "unsigned long:8", 96 },
165 165 { "crit", "unsigned long:5", 104 },
166 166 { "luck", "unsigned long:19", 109 },
167 167 { NULL }
168 168 };
169 169 #else
170 170 static check_member_t check_member_component[] = {
171 171 { "m", "enum material", 0 },
172 172 { "grade", "uint64_t", 4 * NBBY },
173 173 { "count", "uint64_t", 12 * NBBY },
174 174 { "locations", "const char *[4]", 20 * NBBY },
175 175 { NULL }
176 176 };
177 177
178 178 static check_member_t check_member_mysterious[] = {
179 179 { "name", "const char *", 0 },
180 180 { "capacity", "size_t", 4 * NBBY },
181 181 { "optional", "struct component [0]", 8 * NBBY },
182 182 { NULL }
183 183 };
184 184
185 185 static check_member_t check_member_dusk[] = {
186 186 { "name", "const char *", 0 },
187 187 { "opacity", "size_t", 4 * NBBY },
188 188 { "optional", "struct component [0]", 8 * NBBY },
189 189 { NULL }
190 190 };
191 191
192 192
193 193 static check_member_t check_member_stats[] = {
194 194 { "hp", "unsigned long long:16", 0 },
195 195 { "mp", "unsigned long long:16", 16 },
196 196 { "str", "unsigned long long:8", 32 },
197 197 { "dex", "unsigned long long:4", 40 },
198 198 { "con", "unsigned long long:1", 44 },
199 199 { "inte", "unsigned long long:2", 45 },
200 200 { "wis", "unsigned long long:1", 47 },
201 201 { "cha", "unsigned long long:4", 48 },
202 202 { "sanity", "unsigned long long:1", 52 },
203 203 { "attack", "unsigned long long:2", 53 },
204 204 { "mattack", "unsigned long long:1", 55 },
205 205 { "defense", "unsigned long long:8", 56 },
206 206 { "mdefense", "unsigned long long:32", 64 },
207 207 { "evasion", "unsigned long long:8", 96 },
208 208 { "crit", "unsigned long long:5", 104 },
209 209 { "luck", "unsigned long long:19", 109 },
210 210 { NULL }
211 211 };
212 212 #endif
213 213
214 214 static check_member_t check_member_fellowship[] = {
215 215 { "frodo", "unsigned short:1", 0 },
216 216 { "sam", "unsigned short:1", 1 },
217 217 { "merry", "unsigned short:1", 2 },
218 218 { "pippin", "unsigned short:1", 3 },
219 219 { "aragorn", "unsigned short:1", 4 },
220 220 { "boromir", "unsigned short:1", 5 },
221 221 { "legolas", "unsigned short:1", 6 },
222 222 { "gimli", "unsigned short:1", 7 },
223 223 { "gandalf", "unsigned short:1", 8 },
224 224 { NULL }
225 225 };
226 226
227 227 static check_member_t check_member_rings[] = {
228 228 { "elves", "unsigned int:3", 0 },
229 229 { "dwarves", "unsigned int:7", 3 },
230 230 { "men", "unsigned int:9", 10 },
231 231 { "one", "uint8_t", 3 * NBBY },
232 232 { "silmarils", "uint8_t [3]", 4 * NBBY },
233 233 { NULL }
234 234 };
235 235
236 236 static check_member_t check_member_csts[] = {
237 237 { "rdy", "unsigned int:7", 0 },
238 238 { "csts", "unsigned int:32", 7 },
239 239 { NULL }
240 240 };
241 241
242 242 static check_member_t check_member_jrpg[] = {
243 243 { "ff", "int", 0 },
244 244 { "atelier", "double [4]", 0 },
245 245 { "tales", "const char *", 0 },
246 246 { "chrono", "int (*)()", 0 },
247 247 { "xeno", "struct rings", 0 },
248 248 { NULL }
249 249 };
250 250
251 251 static check_member_t check_member_android[] = {
252 252 { "_2b", "unsigned int:16", 0 },
253 253 { "_9s", "unsigned int:16", 16 },
254 254 { NULL }
255 255 };
256 256
257 257 static check_member_t check_member_nier[] = {
258 258 { "automata", "uint32_t", 0 },
259 259 { "android", "struct android", 0 },
260 260 { NULL }
261 261 };
262 262
263 263 static check_member_t check_member_kh[] = {
264 264 { "sora", "int:3", 0 },
265 265 { "riku", "char:7", 0 },
266 266 { "kairi", "double", 0 },
267 267 { "namine", "complex double", 0 },
268 268 { NULL }
269 269 };
270 270
271 271 static check_member_t check_member_trigger[] = {
272 272 { "chrono", "uint8_t", 0 },
273 273 { "cross", "uint8_t", 8 },
274 274 /*
275 275 * This test has an anonymous union. Unfortunately, there's not a great
276 276 * way to distinguish between various anonymous unions in this form.
277 277 */
278 278 #ifdef TARGET_LP64
279 279 { "", "union ", 64 },
280 280 #else
281 281 { "", "union ", 32 },
282 282 #endif
283 283 { NULL }
284 284 };
285 285
286 286 static check_member_t check_member_regress[] = {
287 287 { "i", "unsigned int [3]", 0 },
288 288 { "e", "long double", 0 },
289 289 { NULL }
290 290 };
291 291
292 292 static check_member_test_t members[] = {
293 293 #ifdef TARGET_LP64
294 294 { "struct foo", CTF_K_STRUCT, 16, check_member_foo },
295 295 { "struct node", CTF_K_STRUCT, 16, check_member_node },
296 296 { "struct nlist", CTF_K_STRUCT, 32, check_member_nlist },
297 297 { "struct forward", CTF_K_STRUCT, 24, check_member_forward },
298 298 #else
299 299 { "struct foo", CTF_K_STRUCT, 12, check_member_foo },
300 300 { "struct node", CTF_K_STRUCT, 8, check_member_node },
301 301 { "struct nlist", CTF_K_STRUCT, 16, check_member_nlist },
302 302 { "struct forward", CTF_K_STRUCT, 12, check_member_forward },
303 303 #endif
304 304 { "struct round_up", CTF_K_STRUCT, 12, check_member_round_up },
305 305 { "struct fixed_up", CTF_K_STRUCT, 7, check_member_fixed_up },
306 306 #ifdef TARGET_LP64
307 307 { "struct component", CTF_K_STRUCT, 56, check_member_component },
308 308 { "struct mysterious_barrel", CTF_K_STRUCT, 16,
309 309 check_member_mysterious },
310 310 { "struct dusk_barrel", CTF_K_STRUCT, 16, check_member_dusk },
311 311 #else
312 312 { "struct component", CTF_K_STRUCT, 36, check_member_component },
313 313 { "struct mysterious_barrel", CTF_K_STRUCT, 8,
314 314 check_member_mysterious },
315 315 { "struct dusk_barrel", CTF_K_STRUCT, 8, check_member_dusk },
316 316 #endif
317 317 { "struct stats", CTF_K_STRUCT, 16, check_member_stats },
318 318 { "struct fellowship", CTF_K_STRUCT, 2, check_member_fellowship },
319 319 { "struct rings", CTF_K_STRUCT, 8, check_member_rings },
320 320 { "struct csts", CTF_K_STRUCT, 5, check_member_csts },
321 321 { "union jrpg", CTF_K_UNION, 32, check_member_jrpg },
322 322 { "struct android", CTF_K_STRUCT, 4, check_member_android },
323 323 { "union nier", CTF_K_UNION, 4, check_member_nier },
324 324 { "union kh", CTF_K_UNION, 16, check_member_kh },
325 325 #ifdef TARGET_LP64
326 326 { "struct trigger", CTF_K_STRUCT, 32, check_member_trigger },
327 327 { "union regress", CTF_K_UNION, 16, check_member_regress },
328 328 #else
329 329 { "struct trigger", CTF_K_STRUCT, 28, check_member_trigger },
330 330 { "union regress", CTF_K_UNION, 12, check_member_regress },
331 331 #endif
332 332 { NULL }
333 333 };
334 334
335 335 static check_descent_t check_descent_head[] = {
336 336 { "nlist_t", CTF_K_TYPEDEF },
337 337 { "struct nlist", CTF_K_STRUCT },
↓ open down ↓ |
314 lines elided |
↑ open up ↑ |
338 338 { NULL }
339 339 };
340 340
341 341 static check_descent_t check_descent_forward[] = {
342 342 { "const forward_t", CTF_K_CONST },
343 343 { "forward_t", CTF_K_TYPEDEF },
344 344 { "struct forward", CTF_K_STRUCT },
345 345 { NULL }
346 346 };
347 347
348 -static check_descent_t check_descent_regress[] = {
348 +static check_descent_test_t descents[] = {
349 + { "head", check_descent_head },
350 + { "forward", check_descent_forward },
351 + { NULL }
352 +};
353 +
354 +static check_descent_t check_descent_regress_gcc4[] = {
349 355 { "const union regress [9]", CTF_K_CONST },
350 356 { "union regress [9]", CTF_K_ARRAY, "union regress", 9 },
351 357 { "union regress", CTF_K_UNION },
352 358 { NULL }
353 359 };
354 360
355 -static check_descent_test_t descents[] = {
356 - { "head", check_descent_head },
357 - { "forward", check_descent_forward },
358 - { "regress", check_descent_regress },
361 +static check_descent_t check_descent_regress_gcc7[] = {
362 + { "const union regress [9]", CTF_K_ARRAY, "const union regress", 9 },
363 + { "const union regress", CTF_K_CONST },
364 + { "union regress", CTF_K_UNION },
359 365 { NULL }
360 366 };
361 367
368 +/*
369 + * See needed_array_qualifier(): applying this fix means the qualifier order is
370 + * different between GCC versions. Accept either form.
371 + */
372 +static check_descent_test_t alt_descents[] = {
373 + { "regress", check_descent_regress_gcc4 },
374 + { "regress", check_descent_regress_gcc7 },
375 + { NULL }
376 +};
377 +
362 378 int
363 379 main(int argc, char *argv[])
364 380 {
365 381 int i, ret = 0;
366 382
367 383 if (argc < 2) {
368 384 errx(EXIT_FAILURE, "missing test files");
369 385 }
370 386
371 387 for (i = 1; i < argc; i++) {
372 388 ctf_file_t *fp;
389 + int alt_ok = 0;
373 390 uint_t j;
374 391
375 392 if ((fp = ctf_open(argv[i], &ret)) == NULL) {
376 393 warnx("failed to open %s: %s", argv[i],
377 394 ctf_errmsg(ret));
378 395 ret = EXIT_FAILURE;
379 396 continue;
380 397 }
381 398
382 399 if (!ctftest_check_numbers(fp, check_bitfields))
383 400 ret = EXIT_FAILURE;
384 401 if (!ctftest_check_symbols(fp, check_syms))
385 402 ret = EXIT_FAILURE;
386 403 for (j = 0; descents[j].cdt_sym != NULL; j++) {
387 404 if (!ctftest_check_descent(descents[j].cdt_sym, fp,
388 - descents[j].cdt_tests)) {
405 + descents[j].cdt_tests, B_FALSE)) {
389 406 ret = EXIT_FAILURE;
390 407 }
391 408 }
392 409
410 + for (j = 0; alt_descents[j].cdt_sym != NULL; j++) {
411 + if (ctftest_check_descent(alt_descents[j].cdt_sym, fp,
412 + alt_descents[j].cdt_tests, B_TRUE)) {
413 + alt_ok = 1;
414 + break;
415 + }
416 + }
417 +
418 + if (!alt_ok) {
419 + warnx("all descents failed for %s",
420 + alt_descents[0].cdt_sym);
421 + ret = EXIT_FAILURE;
422 + }
423 +
393 424 for (j = 0; members[j].cmt_type != NULL; j++) {
394 425 if (!ctftest_check_members(members[j].cmt_type, fp,
395 426 members[j].cmt_kind, members[j].cmt_size,
396 427 members[j].cmt_members)) {
397 428 ret = EXIT_FAILURE;
398 429 }
399 430 }
400 431
401 432 ctf_close(fp);
402 433 }
403 434
404 435 return (ret);
405 436 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX