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  * Verify that we can properly handle forward declarations.
  18  *
  19  * In test-forward.c barp is declared as a union, not a struct. However, today
  20  * the CTF tooling does not contain enough information to know whether a forward
  21  * declaration was for a struct or a union, only that it was a forward.
  22  * Therefore, the type printing information assumes at the moment that the type
  23  * is a struct. In a future revision of the CTF type data, we should encode this
  24  * information in the equivalent of ctt_info so we can properly distinguish
  25  * between these.
  26  */
  27 
  28 #include "check-common.h"
  29 
  30 static check_symbol_t check_syms[] = {
  31         { "forward", "struct forward" },
  32         { "foop", "struct foo *" },
  33         { "barp", "struct bar *" },
  34         { "bazp", "enum baz *" },
  35         { NULL }
  36 };
  37 
  38 static check_member_t check_member_forward[] = {
  39 #ifdef  TARGET_LP64
  40         { "prev", "struct foo *", 0 },
  41         { "next", "struct foo *", 8 * NBBY },
  42         { "data", "struct bar *", 16 * NBBY },
  43         { "tag", "enum baz *", 24 * NBBY },
  44 #else
  45         { "prev", "struct foo *", 0 },
  46         { "next", "struct foo *", 4 * NBBY },
  47         { "data", "struct bar *", 8 * NBBY },
  48         { "tag", "enum baz *", 12 * NBBY },
  49 #endif
  50         { NULL }
  51 };
  52 
  53 
  54 static check_member_test_t members[] = {
  55 #ifdef  TARGET_LP64
  56         { "struct forward", CTF_K_STRUCT, 32, check_member_forward },
  57 #else
  58         { "struct forward", CTF_K_STRUCT, 16, check_member_forward },
  59 #endif
  60         { NULL }
  61 };
  62 
  63 static check_descent_t check_descent_foo[] = {
  64         { "struct foo *", CTF_K_POINTER },
  65         { "struct foo", CTF_K_FORWARD },
  66         { NULL }
  67 };
  68 
  69 static check_descent_t check_descent_bar[] = {
  70         { "struct bar *", CTF_K_POINTER },
  71         { "struct bar", CTF_K_FORWARD },
  72         { NULL }
  73 };
  74 
  75 static check_descent_t check_descent_baz[] = {
  76         { "enum baz *", CTF_K_POINTER },
  77         { "enum baz", CTF_K_ENUM },
  78         { NULL }
  79 };
  80 
  81 static check_descent_test_t descents[] = {
  82         { "foop", check_descent_foo },
  83         { "barp", check_descent_bar },
  84         { "bazp", check_descent_baz },
  85         { NULL }
  86 };
  87 int
  88 main(int argc, char *argv[])
  89 {
  90         int i, ret = 0;
  91 
  92         if (argc < 2) {
  93                 errx(EXIT_FAILURE, "missing test files");
  94         }
  95 
  96         for (i = 1; i < argc; i++) {
  97                 ctf_file_t *fp;
  98                 uint_t j;
  99 
 100                 if ((fp = ctf_open(argv[i], &ret)) == NULL) {
 101                         warnx("failed to open %s: %s", argv[i],
 102                             ctf_errmsg(ret));
 103                         ret = EXIT_FAILURE;
 104                         continue;
 105                 }
 106 
 107                 if (!ctftest_check_symbols(fp, check_syms))
 108                         ret = EXIT_FAILURE;
 109 
 110                 for (j = 0; descents[j].cdt_sym != NULL; j++) {
 111                         if (!ctftest_check_descent(descents[j].cdt_sym, fp,
 112                             descents[j].cdt_tests)) {
 113                                 ret = EXIT_FAILURE;
 114                         }
 115                 }
 116 
 117 
 118                 for (j = 0; members[j].cmt_type != NULL; j++) {
 119                         if (!ctftest_check_members(members[j].cmt_type, fp,
 120                             members[j].cmt_kind, members[j].cmt_size,
 121                             members[j].cmt_members)) {
 122                                 ret = EXIT_FAILURE;
 123                         }
 124                 }
 125 
 126                 ctf_close(fp);
 127         }
 128 
 129         return (ret);
 130 }