1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright (c) 2019, Joyent, Inc.
14 */
15
16 /*
17 * Collection of common utilities for CTF testing.
18 */
19
20 #include <strings.h>
21 #include <libctf.h>
22 #include "check-common.h"
23
24 typedef struct ctftests_lookup_cb {
25 ctf_file_t *clc_fp;
26 ctf_id_t clc_id;
27 const char *clc_name;
28 } ctftests_lookup_cb_t;
29
30 typedef struct ctftest_member_cb {
31 ctf_file_t *cmc_fp;
32 const check_member_t *cmc_members;
33 const char *cmc_name;
231
232 return (0);
233 }
234
235 boolean_t
236 ctftest_check_symbols(ctf_file_t *fp, const check_symbol_t *tests)
237 {
238 ctftest_symbol_cb_t cb;
239
240 cb.csc_fp = fp;
241 cb.csc_ret = B_TRUE;
242 cb.csc_tests = tests;
243 if (ctf_object_iter(fp, ctftest_check_symbol_cb, &cb) != 0)
244 return (B_FALSE);
245 return (cb.csc_ret);
246 }
247
248
249 boolean_t
250 ctftest_check_descent(const char *symbol, ctf_file_t *fp,
251 const check_descent_t *tests)
252 {
253 ctf_id_t base;
254 uint_t layer = 0;
255
256 /*
257 * First, find the initial type of the symbol.
258 */
259 base = ctftest_lookup_symbol(fp, symbol);
260 if (base == CTF_ERR) {
261 warnx("failed to lookup type for symbol %s", symbol);
262 return (B_FALSE);
263 }
264
265 while (tests->cd_tname != NULL) {
266 ctf_id_t tid;
267 int kind;
268 ctf_arinfo_t ari;
269
270 if (base == CTF_ERR) {
271 warnx("encountered non-reference type at layer %u "
272 "while still expecting type %s for symbol %s",
273 layer, tests->cd_tname, symbol);
274 return (B_FALSE);
275 }
276
277 tid = ctftest_lookup_type(fp, tests->cd_tname);
278 if (tid == CTF_ERR) {
279 warnx("failed to lookup type %s", tests->cd_tname);
280 return (B_FALSE);
281 }
282
283 if (tid != base) {
284 warnx("type mismatch at layer %u: found id %u, but "
285 "expecting type id %u for type %s, symbol %s",
286 layer, base, tid, tests->cd_tname, symbol);
287 return (B_FALSE);
288 }
289
290 kind = ctf_type_kind(fp, base);
291 if (kind != tests->cd_kind) {
292 warnx("type kind mismatch at layer %u: found kind %u, "
293 "but expected kind %u for %s, symbol %s", layer,
294 kind, tests->cd_kind, tests->cd_tname, symbol);
295 return (B_FALSE);
296 }
297
298 switch (kind) {
299 case CTF_K_ARRAY:
300 if (ctf_array_info(fp, base, &ari) == CTF_ERR) {
301 warnx("failed to lookup array info at layer "
302 "%u for type %s, symbol %s: %s", base,
303 tests->cd_tname, symbol,
304 ctf_errmsg(ctf_errno(fp)));
305 return (B_FALSE);
306 }
307
308 if (tests->cd_nents != ari.ctr_nelems) {
309 warnx("array element mismatch at layer %u "
310 "for type %s, symbol %s: found %u, "
311 "expected %u", layer, tests->cd_tname,
312 symbol, ari.ctr_nelems, tests->cd_nents);
313 return (B_FALSE);
314 }
315
316 tid = ctftest_lookup_type(fp, tests->cd_contents);
317 if (tid == CTF_ERR) {
318 warnx("failed to look up type %s",
319 tests->cd_contents);
320 return (B_FALSE);
321 }
322
323 if (ari.ctr_contents != tid) {
324 warnx("array contents mismatch at layer %u "
325 "for type %s, symbol %s: found %u, "
326 "expected %s/%u", layer, tests->cd_tname,
327 symbol, ari.ctr_contents,
328 tests->cd_contents, tid);
329
330 return (B_FALSE);
331 }
332 base = ari.ctr_contents;
333 break;
334 default:
335 base = ctf_type_reference(fp, base);
336 break;
337 }
338
339 tests++;
340 layer++;
341 }
342
343 if (base != CTF_ERR) {
344 warnx("found additional type %u in chain, but expected no more",
345 base);
346 return (B_FALSE);
347 }
348
349 return (B_TRUE);
350 }
351
352 int
353 ctftest_check_enum_count(const char *name, int value, void *arg)
354 {
355 uint_t *u = arg;
356 *u = *u + 1;
357 return (0);
358 }
359
360 int
361 ctftest_check_enum_value(const char *name, int value, void *arg)
362 {
363 uint_t i;
364 const check_enum_t *enums = arg;
365
| 1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2019, Joyent, Inc.
14 */
15
16 /*
17 * Collection of common utilities for CTF testing.
18 */
19
20 #include <strings.h>
21 #include <libctf.h>
22 #include "check-common.h"
23
24 typedef struct ctftests_lookup_cb {
25 ctf_file_t *clc_fp;
26 ctf_id_t clc_id;
27 const char *clc_name;
28 } ctftests_lookup_cb_t;
29
30 typedef struct ctftest_member_cb {
31 ctf_file_t *cmc_fp;
32 const check_member_t *cmc_members;
33 const char *cmc_name;
231
232 return (0);
233 }
234
235 boolean_t
236 ctftest_check_symbols(ctf_file_t *fp, const check_symbol_t *tests)
237 {
238 ctftest_symbol_cb_t cb;
239
240 cb.csc_fp = fp;
241 cb.csc_ret = B_TRUE;
242 cb.csc_tests = tests;
243 if (ctf_object_iter(fp, ctftest_check_symbol_cb, &cb) != 0)
244 return (B_FALSE);
245 return (cb.csc_ret);
246 }
247
248
249 boolean_t
250 ctftest_check_descent(const char *symbol, ctf_file_t *fp,
251 const check_descent_t *tests, boolean_t quiet)
252 {
253 ctf_id_t base;
254 uint_t layer = 0;
255
256 /*
257 * First, find the initial type of the symbol.
258 */
259 base = ctftest_lookup_symbol(fp, symbol);
260 if (base == CTF_ERR) {
261 warnx("failed to lookup type for symbol %s", symbol);
262 return (B_FALSE);
263 }
264
265 while (tests->cd_tname != NULL) {
266 ctf_id_t tid;
267 int kind;
268 ctf_arinfo_t ari;
269
270 if (base == CTF_ERR) {
271 if (!quiet) {
272 warnx("encountered non-reference type at layer "
273 "%u while still expecting type %s for "
274 "symbol %s", layer,
275 tests->cd_tname, symbol);
276 }
277 return (B_FALSE);
278 }
279
280 tid = ctftest_lookup_type(fp, tests->cd_tname);
281 if (tid == CTF_ERR) {
282 if (!quiet) {
283 warnx("failed to lookup type %s",
284 tests->cd_tname);
285 }
286 return (B_FALSE);
287 }
288
289 if (tid != base) {
290 if (!quiet) {
291 warnx("type mismatch at layer %u: found id %u, "
292 "but expecting type id %u for type %s, "
293 "symbol %s", layer, base, tid,
294 tests->cd_tname, symbol);
295 }
296 return (B_FALSE);
297 }
298
299 kind = ctf_type_kind(fp, base);
300 if (kind != tests->cd_kind) {
301 if (!quiet) {
302 warnx("type kind mismatch at layer %u: found "
303 "kind %u, but expected kind %u for %s, "
304 "symbol %s", layer, kind, tests->cd_kind,
305 tests->cd_tname, symbol);
306 }
307 return (B_FALSE);
308 }
309
310 switch (kind) {
311 case CTF_K_ARRAY:
312 if (ctf_array_info(fp, base, &ari) == CTF_ERR) {
313 if (!quiet) {
314 warnx("failed to lookup array info at "
315 "layer %u for type %s, symbol "
316 "%s: %s", base, tests->cd_tname,
317 symbol, ctf_errmsg(ctf_errno(fp)));
318 }
319 return (B_FALSE);
320 }
321
322 if (tests->cd_nents != ari.ctr_nelems) {
323 if (!quiet) {
324 warnx("array element mismatch at layer "
325 "%u for type %s, symbol %s: found "
326 "%u, expected %u", layer,
327 tests->cd_tname, symbol,
328 ari.ctr_nelems, tests->cd_nents);
329 }
330 return (B_FALSE);
331 }
332
333 tid = ctftest_lookup_type(fp, tests->cd_contents);
334 if (tid == CTF_ERR) {
335 if (!quiet) {
336 warnx("failed to look up type %s",
337 tests->cd_contents);
338 }
339 return (B_FALSE);
340 }
341
342 if (ari.ctr_contents != tid) {
343 if (!quiet) {
344 warnx("array contents mismatch at "
345 "layer %u for type %s, symbol %s: "
346 "found %u, expected %s/%u", layer,
347 tests->cd_tname, symbol,
348 ari.ctr_contents,
349 tests->cd_contents, tid);
350 }
351 return (B_FALSE);
352 }
353 base = ari.ctr_contents;
354 break;
355 default:
356 base = ctf_type_reference(fp, base);
357 break;
358 }
359
360 tests++;
361 layer++;
362 }
363
364 if (base != CTF_ERR) {
365 if (!quiet) {
366 warnx("found additional type %u in chain, "
367 "but expected no more", base);
368 }
369 return (B_FALSE);
370 }
371
372 return (B_TRUE);
373 }
374
375 int
376 ctftest_check_enum_count(const char *name, int value, void *arg)
377 {
378 uint_t *u = arg;
379 *u = *u + 1;
380 return (0);
381 }
382
383 int
384 ctftest_check_enum_value(const char *name, int value, void *arg)
385 {
386 uint_t i;
387 const check_enum_t *enums = arg;
388
|