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>
   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