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  * Check that we properly understand reference types and can walk through them
  18  * as well as generate them.
  19  */
  20 
  21 #include "check-common.h"
  22 
  23 static check_number_t check_base[] = {
  24         { "char", CTF_K_INTEGER, CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 },
  25         { "int", CTF_K_INTEGER, CTF_INT_SIGNED, 0, 32 },
  26         { "float", CTF_K_FLOAT, CTF_FP_SINGLE, 0, 32 },
  27         { NULL }
  28 };
  29 
  30 static check_symbol_t check_syms[] = {
  31         { "a", "int" },
  32         { "aa", "test_int_t" },
  33         { "b", "const short" },
  34         { "c", "volatile float" },
  35         { "d", "int *" },
  36         { "dd", "int **" },
  37         { "ddd", "int ***" },
  38         { "e", "test_int_t *" },
  39         { "ce", "const test_int_t *" },
  40         { "ve", "volatile test_int_t *" },
  41         { "cve", "const volatile test_int_t *" },
  42         { "f", "int *const *" },
  43         { "g", "const char *const" },
  44         { NULL },
  45 };
  46 
  47 static check_descent_t check_descent_aa[] = {
  48         { "test_int_t", CTF_K_TYPEDEF },
  49         { "int", CTF_K_INTEGER },
  50         { NULL }
  51 };
  52 
  53 static check_descent_t check_descent_b[] = {
  54         { "const short", CTF_K_CONST },
  55         { "short", CTF_K_INTEGER },
  56         { NULL }
  57 };
  58 
  59 static check_descent_t check_descent_c[] = {
  60         { "volatile float", CTF_K_VOLATILE },
  61         { "float", CTF_K_FLOAT },
  62         { NULL }
  63 };
  64 
  65 static check_descent_t check_descent_d[] = {
  66         { "int *", CTF_K_POINTER },
  67         { "int", CTF_K_INTEGER },
  68         { NULL }
  69 };
  70 
  71 static check_descent_t check_descent_dd[] = {
  72         { "int **", CTF_K_POINTER },
  73         { "int *", CTF_K_POINTER },
  74         { "int", CTF_K_INTEGER },
  75         { NULL }
  76 };
  77 
  78 static check_descent_t check_descent_ddd[] = {
  79         { "int ***", CTF_K_POINTER },
  80         { "int **", CTF_K_POINTER },
  81         { "int *", CTF_K_POINTER },
  82         { "int", CTF_K_INTEGER },
  83         { NULL }
  84 };
  85 
  86 static check_descent_t check_descent_e[] = {
  87         { "test_int_t *", CTF_K_POINTER },
  88         { "test_int_t", CTF_K_TYPEDEF },
  89         { "int", CTF_K_INTEGER },
  90         { NULL },
  91 };
  92 
  93 static check_descent_t check_descent_ce[] = {
  94         { "const test_int_t *", CTF_K_POINTER },
  95         { "const test_int_t", CTF_K_CONST },
  96         { "test_int_t", CTF_K_TYPEDEF },
  97         { "int", CTF_K_INTEGER },
  98         { NULL },
  99 };
 100 
 101 static check_descent_t check_descent_ve[] = {
 102         { "volatile test_int_t *", CTF_K_POINTER},
 103         { "volatile test_int_t", CTF_K_VOLATILE },
 104         { "test_int_t", CTF_K_TYPEDEF },
 105         { "int", CTF_K_INTEGER },
 106         { NULL }
 107 };
 108 
 109 static check_descent_t check_descent_cve[] = {
 110         { "const volatile test_int_t *", CTF_K_POINTER },
 111         { "const volatile test_int_t", CTF_K_CONST },
 112         { "volatile test_int_t", CTF_K_VOLATILE },
 113         { "test_int_t", CTF_K_TYPEDEF },
 114         { "int", CTF_K_INTEGER },
 115         { NULL }
 116 };
 117 
 118 static check_descent_t check_descent_f[] = {
 119         { "int *const *", CTF_K_POINTER },
 120         { "int *const", CTF_K_CONST },
 121         { "int *", CTF_K_POINTER },
 122         { "int", CTF_K_INTEGER },
 123         { NULL }
 124 };
 125 
 126 static check_descent_t check_descent_g[] = {
 127         { "const char *const", CTF_K_CONST },
 128         { "const char *", CTF_K_POINTER },
 129         { "const char", CTF_K_CONST },
 130         { "char", CTF_K_INTEGER },
 131         { NULL }
 132 };
 133 
 134 static check_descent_t check_descent_cvh[] = {
 135         { "const volatile foo_t *", CTF_K_POINTER },
 136         { "const volatile foo_t", CTF_K_CONST },
 137         { "volatile foo_t", CTF_K_VOLATILE },
 138         { "foo_t", CTF_K_TYPEDEF },
 139         { "int *const *", CTF_K_POINTER },
 140         { "int *const", CTF_K_CONST },
 141         { "int *", CTF_K_POINTER },
 142         { "int", CTF_K_INTEGER },
 143         { NULL }
 144 };
 145 
 146 static check_descent_test_t descents[] = {
 147         { "aa", check_descent_aa },
 148         { "b", check_descent_b },
 149         { "c", check_descent_c },
 150         { "d", check_descent_d },
 151         { "dd", check_descent_dd },
 152         { "ddd", check_descent_ddd },
 153         { "e", check_descent_e },
 154         { "ce", check_descent_ce },
 155         { "ve", check_descent_ve },
 156         { "cve", check_descent_cve },
 157         { "f", check_descent_f },
 158         { "g", check_descent_g },
 159         { "cvh", check_descent_cvh },
 160         { NULL }
 161 };
 162 
 163 int
 164 main(int argc, char *argv[])
 165 {
 166         int i, ret = 0;
 167 
 168         if (argc < 2) {
 169                 errx(EXIT_FAILURE, "missing test files");
 170         }
 171 
 172         for (i = 1; i < argc; i++) {
 173                 ctf_file_t *fp;
 174                 uint_t d;
 175 
 176                 if ((fp = ctf_open(argv[i], &ret)) == NULL) {
 177                         warnx("failed to open %s: %s", argv[i],
 178                             ctf_errmsg(ret));
 179                         ret = EXIT_FAILURE;
 180                         continue;
 181                 }
 182 
 183                 if (!ctftest_check_numbers(fp, check_base))
 184                         ret = EXIT_FAILURE;
 185                 if (!ctftest_check_symbols(fp, check_syms))
 186                         ret = EXIT_FAILURE;
 187                 for (d = 0; descents[d].cdt_sym != NULL; d++) {
 188                         if (!ctftest_check_descent(descents[d].cdt_sym, fp,
 189                             descents[d].cdt_tests)) {
 190                                 ret = EXIT_FAILURE;
 191                         }
 192                 }
 193                 ctf_close(fp);
 194         }
 195 
 196         return (ret);
 197 }