1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright (c) 2013, 2016 by Delphix. All rights reserved.
  27  * Copyright (c) 2018, Joyent, Inc.
  28  */
  29 
  30 #include <mdb/mdb_ctf.h>
  31 #include <mdb/mdb_ctf_impl.h>
  32 #include <mdb/mdb_err.h>
  33 #include <mdb/mdb_modapi.h>
  34 #include <mdb/mdb_string.h>
  35 #include <mdb/mdb.h>
  36 #include <mdb/mdb_debug.h>
  37 
  38 #include <libctf.h>
  39 #include <string.h>
  40 #include <limits.h>
  41 
  42 typedef struct tnarg {
  43         mdb_tgt_t *tn_tgt;              /* target to use for lookup */
  44         const char *tn_name;            /* query string to lookup */
  45         ctf_file_t *tn_fp;              /* CTF container from match */
  46         ctf_id_t tn_id;                 /* CTF type ID from match */
  47 } tnarg_t;
  48 
  49 typedef struct type_iter {
  50         mdb_ctf_type_f *ti_cb;
  51         void *ti_arg;
  52         ctf_file_t *ti_fp;
  53 } type_iter_t;
  54 
  55 typedef struct member_iter {
  56         mdb_ctf_member_f *mi_cb;
  57         void *mi_arg;
  58         ctf_file_t *mi_fp;
  59 } member_iter_t;
  60 
  61 typedef struct type_visit {
  62         mdb_ctf_visit_f *tv_cb;
  63         void            *tv_arg;
  64         ctf_file_t      *tv_fp;
  65         ulong_t         tv_base_offset; /* used when recursing from type_cb() */
  66         int             tv_base_depth;  /* used when recursing from type_cb() */
  67         int             tv_min_depth;
  68 } type_visit_t;
  69 
  70 typedef struct mbr_info {
  71         const char *mbr_member;
  72         ulong_t *mbr_offp;
  73         mdb_ctf_id_t *mbr_typep;
  74 } mbr_info_t;
  75 
  76 typedef struct synth_intrinsic {
  77         const char *syn_name;
  78         ctf_encoding_t syn_enc;
  79         uint_t syn_kind;
  80 } synth_intrinsic_t;
  81 
  82 typedef struct synth_typedef {
  83         const char *syt_src;
  84         const char *syt_targ;
  85 } synth_typedef_t;
  86 
  87 /*
  88  * As part of our support for synthetic types via ::typedef, we define a core
  89  * set of types.
  90  */
  91 static const synth_intrinsic_t synth_builtins32[] = {
  92 { "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
  93 { "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
  94 { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
  95 { "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
  96 { "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
  97 { "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
  98 { "long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
  99 { "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
 100 { "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
 101 { "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
 102 { "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
 103 { "signed long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
 104 { "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
 105 { "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
 106 { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
 107 { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
 108 { "unsigned long", { 0, 0, 32 }, CTF_K_INTEGER },
 109 { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
 110 { "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
 111 { "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
 112 { "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
 113 { "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
 114 { "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
 115 { "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
 116 { "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
 117 { "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
 118 { "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
 119 { "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
 120 { NULL, { 0, 0, 0}, 0 }
 121 };
 122 
 123 static const synth_intrinsic_t synth_builtins64[] = {
 124 { "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
 125 { "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
 126 { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
 127 { "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
 128 { "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
 129 { "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
 130 { "long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
 131 { "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
 132 { "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
 133 { "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
 134 { "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
 135 { "signed long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
 136 { "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
 137 { "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
 138 { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
 139 { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
 140 { "unsigned long", { 0, 0, 64 }, CTF_K_INTEGER },
 141 { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
 142 { "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
 143 { "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
 144 { "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
 145 { "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
 146 { "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
 147 { "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
 148 { "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
 149 { "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
 150 { "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
 151 { "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
 152 { NULL, { 0, 0, 0 }, 0 }
 153 };
 154 
 155 static const synth_typedef_t synth_typedefs32[] = {
 156 { "char", "int8_t" },
 157 { "short", "int16_t" },
 158 { "int", "int32_t" },
 159 { "long long", "int64_t" },
 160 { "int", "intptr_t" },
 161 { "unsigned char", "uint8_t" },
 162 { "unsigned short", "uint16_t" },
 163 { "unsigned", "uint32_t" },
 164 { "unsigned long long", "uint64_t" },
 165 { "unsigned char", "uchar_t" },
 166 { "unsigned short", "ushort_t" },
 167 { "unsigned", "uint_t" },
 168 { "unsigned long", "ulong_t" },
 169 { "unsigned long long", "u_longlong_t" },
 170 { "int", "ptrdiff_t" },
 171 { "unsigned", "uintptr_t" },
 172 { NULL, NULL }
 173 };
 174 
 175 static const synth_typedef_t synth_typedefs64[] = {
 176 { "char", "int8_t" },
 177 { "short", "int16_t" },
 178 { "int", "int32_t" },
 179 { "long", "int64_t" },
 180 { "long", "intptr_t" },
 181 { "unsigned char", "uint8_t" },
 182 { "unsigned short", "uint16_t" },
 183 { "unsigned", "uint32_t" },
 184 { "unsigned long", "uint64_t" },
 185 { "unsigned char", "uchar_t" },
 186 { "unsigned short", "ushort_t" },
 187 { "unsigned", "uint_t" },
 188 { "unsigned long", "ulong_t" },
 189 { "unsigned long long", "u_longlong_t" },
 190 { "long", "ptrdiff_t" },
 191 { "unsigned long", "uintptr_t" },
 192 { NULL, NULL }
 193 };
 194 
 195 static void
 196 set_ctf_id(mdb_ctf_id_t *p, ctf_file_t *fp, ctf_id_t id)
 197 {
 198         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
 199 
 200         mcip->mci_fp = fp;
 201         mcip->mci_id = id;
 202 }
 203 
 204 /*
 205  * Callback function for mdb_tgt_object_iter used from name_to_type, below,
 206  * to search the CTF namespace of each object file for a particular name.
 207  */
 208 /*ARGSUSED*/
 209 static int
 210 obj_lookup(void *data, const mdb_map_t *mp, const char *name)
 211 {
 212         tnarg_t *tnp = data;
 213         ctf_file_t *fp;
 214         ctf_id_t id;
 215 
 216         if ((fp = mdb_tgt_name_to_ctf(tnp->tn_tgt, name)) != NULL &&
 217             (id = ctf_lookup_by_name(fp, tnp->tn_name)) != CTF_ERR) {
 218                 tnp->tn_fp = fp;
 219                 tnp->tn_id = id;
 220 
 221                 /*
 222                  * We may have found a forward declaration.  If we did, we'll
 223                  * note the ID and file pointer, but we'll keep searching in
 224                  * an attempt to find the real thing.  If we found something
 225                  * real (i.e. not a forward), we stop the iteration.
 226                  */
 227                 return (ctf_type_kind(fp, id) == CTF_K_FORWARD ? 0 : -1);
 228         }
 229 
 230         return (0);
 231 }
 232 
 233 /*
 234  * Convert a string type name with an optional leading object specifier into
 235  * the corresponding CTF file container and type ID.  If an error occurs, we
 236  * print an appropriate message and return NULL.
 237  */
 238 static ctf_file_t *
 239 name_to_type(mdb_tgt_t *t, const char *cname, ctf_id_t *idp)
 240 {
 241         const char *object = MDB_TGT_OBJ_EXEC;
 242         ctf_file_t *fp = NULL;
 243         ctf_id_t id;
 244         tnarg_t arg;
 245         char *p, *s;
 246         char buf[MDB_SYM_NAMLEN];
 247         char *name = &buf[0];
 248 
 249         (void) mdb_snprintf(buf, sizeof (buf), "%s", cname);
 250 
 251         if ((p = strrsplit(name, '`')) != NULL) {
 252                 /*
 253                  * We need to shuffle things around a little to support
 254                  * type names of the form "struct module`name".
 255                  */
 256                 if ((s = strsplit(name, ' ')) != NULL) {
 257                         bcopy(cname + (s - name), name, (p - s) - 1);
 258                         name[(p - s) - 1] = '\0';
 259                         bcopy(cname, name + (p - s), s - name);
 260                         p = name + (p - s);
 261                 }
 262                 if (*name != '\0')
 263                         object = name;
 264                 name = p;
 265         }
 266 
 267         /*
 268          * Attempt to look up the name in the primary object file.  If this
 269          * fails and the name was unscoped, search all remaining object files.
 270          * Finally, search the synthetic types.
 271          */
 272         if (((fp = mdb_tgt_name_to_ctf(t, object)) == NULL ||
 273             (id = ctf_lookup_by_name(fp, name)) == CTF_ERR ||
 274             ctf_type_kind(fp, id) == CTF_K_FORWARD) &&
 275             object == MDB_TGT_OBJ_EXEC) {
 276 
 277                 arg.tn_tgt = t;
 278                 arg.tn_name = name;
 279                 arg.tn_fp = NULL;
 280                 arg.tn_id = CTF_ERR;
 281 
 282                 (void) mdb_tgt_object_iter(t, obj_lookup, &arg);
 283 
 284                 if (arg.tn_id != CTF_ERR) {
 285                         fp = arg.tn_fp;
 286                         id = arg.tn_id;
 287                 } else if (mdb.m_synth != NULL) {
 288                         if ((id = ctf_lookup_by_name(mdb.m_synth,
 289                             name)) != CTF_ERR)
 290                                 fp = mdb.m_synth;
 291                 }
 292         }
 293 
 294         if (fp == NULL)
 295                 return (NULL); /* errno is set for us */
 296 
 297         if (id == CTF_ERR) {
 298                 (void) set_errno(ctf_to_errno(ctf_errno(fp)));
 299                 return (NULL);
 300         }
 301 
 302         *idp = id;
 303         return (fp);
 304 }
 305 
 306 /*
 307  * Check to see if there is ctf data in the given object. This is useful
 308  * so that we don't enter some loop where every call to lookup fails.
 309  */
 310 int
 311 mdb_ctf_enabled_by_object(const char *object)
 312 {
 313         mdb_tgt_t *t = mdb.m_target;
 314 
 315         return (mdb_tgt_name_to_ctf(t, object) != NULL);
 316 }
 317 
 318 int
 319 mdb_ctf_lookup_by_name(const char *name, mdb_ctf_id_t *p)
 320 {
 321         ctf_file_t *fp = NULL;
 322         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
 323         mdb_tgt_t *t = mdb.m_target;
 324 
 325         if (mcip == NULL)
 326                 return (set_errno(EINVAL));
 327 
 328         if ((fp = name_to_type(t, name, &mcip->mci_id)) == NULL) {
 329                 mdb_ctf_type_invalidate(p);
 330                 return (-1); /* errno is set for us */
 331         }
 332 
 333         mcip->mci_fp = fp;
 334 
 335         return (0);
 336 }
 337 
 338 int
 339 mdb_ctf_lookup_by_symbol(const GElf_Sym *symp, const mdb_syminfo_t *sip,
 340     mdb_ctf_id_t *p)
 341 {
 342         ctf_file_t *fp = NULL;
 343         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
 344         mdb_tgt_t *t = mdb.m_target;
 345 
 346         if (mcip == NULL)
 347                 return (set_errno(EINVAL));
 348 
 349         if (symp == NULL || sip == NULL) {
 350                 mdb_ctf_type_invalidate(p);
 351                 return (set_errno(EINVAL));
 352         }
 353 
 354         if ((fp = mdb_tgt_addr_to_ctf(t, symp->st_value)) == NULL) {
 355                 mdb_ctf_type_invalidate(p);
 356                 return (-1); /* errno is set for us */
 357         }
 358 
 359         if ((mcip->mci_id = ctf_lookup_by_symbol(fp, sip->sym_id)) == CTF_ERR) {
 360                 mdb_ctf_type_invalidate(p);
 361                 return (set_errno(ctf_to_errno(ctf_errno(fp))));
 362         }
 363 
 364         mcip->mci_fp = fp;
 365 
 366         return (0);
 367 }
 368 
 369 int
 370 mdb_ctf_lookup_by_addr(uintptr_t addr, mdb_ctf_id_t *p)
 371 {
 372         GElf_Sym sym;
 373         mdb_syminfo_t si;
 374         char name[MDB_SYM_NAMLEN];
 375         const mdb_map_t *mp;
 376         mdb_tgt_t *t = mdb.m_target;
 377         const char *obj, *c;
 378 
 379         if (p == NULL)
 380                 return (set_errno(EINVAL));
 381 
 382         if (mdb_tgt_lookup_by_addr(t, addr, MDB_TGT_SYM_EXACT, name,
 383             sizeof (name), NULL, NULL) == -1) {
 384                 mdb_ctf_type_invalidate(p);
 385                 return (-1); /* errno is set for us */
 386         }
 387 
 388         if ((c = strrsplit(name, '`')) != NULL) {
 389                 obj = name;
 390         } else {
 391                 if ((mp = mdb_tgt_addr_to_map(t, addr)) == NULL) {
 392                         mdb_ctf_type_invalidate(p);
 393                         return (-1); /* errno is set for us */
 394                 }
 395 
 396                 obj = mp->map_name;
 397                 c = name;
 398         }
 399 
 400         if (mdb_tgt_lookup_by_name(t, obj, c, &sym, &si) == -1) {
 401                 mdb_ctf_type_invalidate(p);
 402                 return (-1); /* errno is set for us */
 403         }
 404 
 405         return (mdb_ctf_lookup_by_symbol(&sym, &si, p));
 406 }
 407 
 408 int
 409 mdb_ctf_module_lookup(const char *name, mdb_ctf_id_t *p)
 410 {
 411         ctf_file_t *fp;
 412         ctf_id_t id;
 413         mdb_module_t *mod;
 414 
 415         if ((mod = mdb_get_module()) == NULL)
 416                 return (set_errno(EMDB_CTX));
 417 
 418         if ((fp = mod->mod_ctfp) == NULL)
 419                 return (set_errno(EMDB_NOCTF));
 420 
 421         if ((id = ctf_lookup_by_name(fp, name)) == CTF_ERR)
 422                 return (set_errno(ctf_to_errno(ctf_errno(fp))));
 423 
 424         set_ctf_id(p, fp, id);
 425 
 426         return (0);
 427 }
 428 
 429 /*ARGSUSED*/
 430 int
 431 mdb_ctf_func_info(const GElf_Sym *symp, const mdb_syminfo_t *sip,
 432     mdb_ctf_funcinfo_t *mfp)
 433 {
 434         ctf_file_t *fp = NULL;
 435         ctf_funcinfo_t f;
 436         mdb_tgt_t *t = mdb.m_target;
 437         char name[MDB_SYM_NAMLEN];
 438         const mdb_map_t *mp;
 439         mdb_syminfo_t si;
 440         int err;
 441 
 442         if (symp == NULL || mfp == NULL)
 443                 return (set_errno(EINVAL));
 444 
 445         /*
 446          * In case the input symbol came from a merged or private symbol table,
 447          * re-lookup the address as a symbol, and then perform a fully scoped
 448          * lookup of that symbol name to get the mdb_syminfo_t for its CTF.
 449          */
 450         if ((fp = mdb_tgt_addr_to_ctf(t, symp->st_value)) == NULL ||
 451             (mp = mdb_tgt_addr_to_map(t, symp->st_value)) == NULL ||
 452             mdb_tgt_lookup_by_addr(t, symp->st_value, MDB_TGT_SYM_FUZZY,
 453             name, sizeof (name), NULL, NULL) != 0)
 454                 return (-1); /* errno is set for us */
 455 
 456         if (strchr(name, '`') != NULL)
 457                 err = mdb_tgt_lookup_by_scope(t, name, NULL, &si);
 458         else
 459                 err = mdb_tgt_lookup_by_name(t, mp->map_name, name, NULL, &si);
 460 
 461         if (err != 0)
 462                 return (-1); /* errno is set for us */
 463 
 464         if (ctf_func_info(fp, si.sym_id, &f) == CTF_ERR)
 465                 return (set_errno(ctf_to_errno(ctf_errno(fp))));
 466 
 467         set_ctf_id(&mfp->mtf_return, fp, f.ctc_return);
 468         mfp->mtf_argc = f.ctc_argc;
 469         mfp->mtf_flags = f.ctc_flags;
 470         mfp->mtf_symidx = si.sym_id;
 471 
 472         return (0);
 473 }
 474 
 475 int
 476 mdb_ctf_func_args(const mdb_ctf_funcinfo_t *funcp, uint_t len,
 477     mdb_ctf_id_t *argv)
 478 {
 479         ctf_file_t *fp;
 480         ctf_id_t cargv[32];
 481         int i;
 482 
 483         if (len > (sizeof (cargv) / sizeof (cargv[0])))
 484                 return (set_errno(EINVAL));
 485 
 486         if (funcp == NULL || argv == NULL)
 487                 return (set_errno(EINVAL));
 488 
 489         fp = mdb_ctf_type_file(funcp->mtf_return);
 490 
 491         if (ctf_func_args(fp, funcp->mtf_symidx, len, cargv) == CTF_ERR)
 492                 return (set_errno(ctf_to_errno(ctf_errno(fp))));
 493 
 494         for (i = MIN(len, funcp->mtf_argc) - 1; i >= 0; i--) {
 495                 set_ctf_id(&argv[i], fp, cargv[i]);
 496         }
 497 
 498         return (0);
 499 }
 500 
 501 void
 502 mdb_ctf_type_invalidate(mdb_ctf_id_t *idp)
 503 {
 504         set_ctf_id(idp, NULL, CTF_ERR);
 505 }
 506 
 507 int
 508 mdb_ctf_type_valid(mdb_ctf_id_t id)
 509 {
 510         return (((mdb_ctf_impl_t *)&id)->mci_id != CTF_ERR);
 511 }
 512 
 513 int
 514 mdb_ctf_type_cmp(mdb_ctf_id_t aid, mdb_ctf_id_t bid)
 515 {
 516         mdb_ctf_impl_t *aidp = (mdb_ctf_impl_t *)&aid;
 517         mdb_ctf_impl_t *bidp = (mdb_ctf_impl_t *)&bid;
 518 
 519         return (ctf_type_cmp(aidp->mci_fp, aidp->mci_id,
 520             bidp->mci_fp, bidp->mci_id));
 521 }
 522 
 523 int
 524 mdb_ctf_type_resolve(mdb_ctf_id_t mid, mdb_ctf_id_t *outp)
 525 {
 526         ctf_id_t id;
 527         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&mid;
 528 
 529         if ((id = ctf_type_resolve(idp->mci_fp, idp->mci_id)) == CTF_ERR) {
 530                 if (outp)
 531                         mdb_ctf_type_invalidate(outp);
 532                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 533         }
 534 
 535         if (ctf_type_kind(idp->mci_fp, id) == CTF_K_FORWARD) {
 536                 char name[MDB_SYM_NAMLEN];
 537                 mdb_ctf_id_t lookup_id;
 538 
 539                 if (ctf_type_name(idp->mci_fp, id, name, sizeof (name)) !=
 540                     NULL &&
 541                     mdb_ctf_lookup_by_name(name, &lookup_id) == 0 &&
 542                     outp != NULL) {
 543                         *outp = lookup_id;
 544                         return (0);
 545                 }
 546         }
 547 
 548         if (outp != NULL)
 549                 set_ctf_id(outp, idp->mci_fp, id);
 550 
 551         return (0);
 552 }
 553 
 554 char *
 555 mdb_ctf_type_name(mdb_ctf_id_t id, char *buf, size_t len)
 556 {
 557         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 558         char *ret;
 559 
 560         if (!mdb_ctf_type_valid(id)) {
 561                 (void) set_errno(EINVAL);
 562                 return (NULL);
 563         }
 564 
 565         ret = ctf_type_name(idp->mci_fp, idp->mci_id, buf, len);
 566         if (ret == NULL)
 567                 (void) set_errno(ctf_to_errno(ctf_errno(idp->mci_fp)));
 568 
 569         return (ret);
 570 }
 571 
 572 ssize_t
 573 mdb_ctf_type_size(mdb_ctf_id_t id)
 574 {
 575         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 576         ssize_t ret;
 577 
 578         /* resolve the type in case there's a forward declaration */
 579         if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
 580                 return (ret);
 581 
 582         if ((ret = ctf_type_size(idp->mci_fp, idp->mci_id)) == CTF_ERR)
 583                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 584 
 585         return (ret);
 586 }
 587 
 588 int
 589 mdb_ctf_type_kind(mdb_ctf_id_t id)
 590 {
 591         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 592         int ret;
 593 
 594         if ((ret = ctf_type_kind(idp->mci_fp, idp->mci_id)) == CTF_ERR)
 595                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 596 
 597         return (ret);
 598 }
 599 
 600 int
 601 mdb_ctf_type_reference(mdb_ctf_id_t mid, mdb_ctf_id_t *outp)
 602 {
 603         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&mid;
 604         ctf_id_t id;
 605 
 606         if ((id = ctf_type_reference(idp->mci_fp, idp->mci_id)) == CTF_ERR) {
 607                 if (outp)
 608                         mdb_ctf_type_invalidate(outp);
 609                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 610         }
 611 
 612         if (outp != NULL)
 613                 set_ctf_id(outp, idp->mci_fp, id);
 614 
 615         return (0);
 616 }
 617 
 618 
 619 int
 620 mdb_ctf_type_encoding(mdb_ctf_id_t id, ctf_encoding_t *ep)
 621 {
 622         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 623 
 624         if (ctf_type_encoding(idp->mci_fp, idp->mci_id, ep) == CTF_ERR)
 625                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 626 
 627         return (0);
 628 }
 629 
 630 /*
 631  * callback proxy for mdb_ctf_type_visit
 632  */
 633 static int
 634 type_cb(const char *name, ctf_id_t type, ulong_t off, int depth, void *arg)
 635 {
 636         type_visit_t *tvp = arg;
 637         mdb_ctf_id_t id;
 638         mdb_ctf_id_t base;
 639         mdb_ctf_impl_t *basep = (mdb_ctf_impl_t *)&base;
 640 
 641         int ret;
 642 
 643         if (depth < tvp->tv_min_depth)
 644                 return (0);
 645 
 646         off += tvp->tv_base_offset;
 647         depth += tvp->tv_base_depth;
 648 
 649         set_ctf_id(&id, tvp->tv_fp, type);
 650 
 651         (void) mdb_ctf_type_resolve(id, &base);
 652         if ((ret = tvp->tv_cb(name, id, base, off, depth, tvp->tv_arg)) != 0)
 653                 return (ret);
 654 
 655         /*
 656          * If the type resolves to a type in a different file, we must have
 657          * followed a forward declaration.  We need to recurse into the
 658          * new type.
 659          */
 660         if (basep->mci_fp != tvp->tv_fp && mdb_ctf_type_valid(base)) {
 661                 type_visit_t tv;
 662 
 663                 tv.tv_cb = tvp->tv_cb;
 664                 tv.tv_arg = tvp->tv_arg;
 665                 tv.tv_fp = basep->mci_fp;
 666 
 667                 tv.tv_base_offset = off;
 668                 tv.tv_base_depth = depth;
 669                 tv.tv_min_depth = 1;    /* depth = 0 has already been done */
 670 
 671                 ret = ctf_type_visit(basep->mci_fp, basep->mci_id,
 672                     type_cb, &tv);
 673         }
 674         return (ret);
 675 }
 676 
 677 int
 678 mdb_ctf_type_visit(mdb_ctf_id_t id, mdb_ctf_visit_f *func, void *arg)
 679 {
 680         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 681         type_visit_t tv;
 682         int ret;
 683 
 684         tv.tv_cb = func;
 685         tv.tv_arg = arg;
 686         tv.tv_fp = idp->mci_fp;
 687         tv.tv_base_offset = 0;
 688         tv.tv_base_depth = 0;
 689         tv.tv_min_depth = 0;
 690 
 691         ret = ctf_type_visit(idp->mci_fp, idp->mci_id, type_cb, &tv);
 692 
 693         if (ret == CTF_ERR)
 694                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 695 
 696         return (ret);
 697 }
 698 
 699 int
 700 mdb_ctf_array_info(mdb_ctf_id_t id, mdb_ctf_arinfo_t *arp)
 701 {
 702         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 703         ctf_arinfo_t car;
 704 
 705         if (ctf_array_info(idp->mci_fp, idp->mci_id, &car) == CTF_ERR)
 706                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 707 
 708         set_ctf_id(&arp->mta_contents, idp->mci_fp, car.ctr_contents);
 709         set_ctf_id(&arp->mta_index, idp->mci_fp, car.ctr_index);
 710 
 711         arp->mta_nelems = car.ctr_nelems;
 712 
 713         return (0);
 714 }
 715 
 716 const char *
 717 mdb_ctf_enum_name(mdb_ctf_id_t id, int value)
 718 {
 719         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 720         const char *ret;
 721 
 722         /* resolve the type in case there's a forward declaration */
 723         if (mdb_ctf_type_resolve(id, &id) != 0)
 724                 return (NULL);
 725 
 726         if ((ret = ctf_enum_name(idp->mci_fp, idp->mci_id, value)) == NULL)
 727                 (void) set_errno(ctf_to_errno(ctf_errno(idp->mci_fp)));
 728 
 729         return (ret);
 730 }
 731 
 732 /*
 733  * callback proxy for mdb_ctf_member_iter
 734  */
 735 static int
 736 member_iter_cb(const char *name, ctf_id_t type, ulong_t off, void *data)
 737 {
 738         member_iter_t *mip = data;
 739         mdb_ctf_id_t id;
 740 
 741         set_ctf_id(&id, mip->mi_fp, type);
 742 
 743         return (mip->mi_cb(name, id, off, mip->mi_arg));
 744 }
 745 
 746 int
 747 mdb_ctf_member_iter(mdb_ctf_id_t id, mdb_ctf_member_f *cb, void *data)
 748 {
 749         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 750         member_iter_t mi;
 751         int ret;
 752 
 753         /* resolve the type in case there's a forward declaration */
 754         if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
 755                 return (ret);
 756 
 757         mi.mi_cb = cb;
 758         mi.mi_arg = data;
 759         mi.mi_fp = idp->mci_fp;
 760 
 761         ret = ctf_member_iter(idp->mci_fp, idp->mci_id, member_iter_cb, &mi);
 762 
 763         if (ret == CTF_ERR)
 764                 return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
 765 
 766         return (ret);
 767 }
 768 
 769 int
 770 mdb_ctf_enum_iter(mdb_ctf_id_t id, mdb_ctf_enum_f *cb, void *data)
 771 {
 772         mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
 773         int ret;
 774 
 775         /* resolve the type in case there's a forward declaration */
 776         if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
 777                 return (ret);
 778 
 779         return (ctf_enum_iter(idp->mci_fp, idp->mci_id, cb, data));
 780 }
 781 
 782 /*
 783  * callback proxy for mdb_ctf_type_iter
 784  */
 785 /* ARGSUSED */
 786 static int
 787 type_iter_cb(ctf_id_t type, boolean_t root, void *data)
 788 {
 789         type_iter_t *tip = data;
 790         mdb_ctf_id_t id;
 791 
 792         set_ctf_id(&id, tip->ti_fp, type);
 793 
 794         return (tip->ti_cb(id, tip->ti_arg));
 795 }
 796 
 797 int
 798 mdb_ctf_type_iter(const char *object, mdb_ctf_type_f *cb, void *data)
 799 {
 800         ctf_file_t *fp;
 801         mdb_tgt_t *t = mdb.m_target;
 802         int ret;
 803         type_iter_t ti;
 804 
 805         if (object == MDB_CTF_SYNTHETIC_ITER)
 806                 fp = mdb.m_synth;
 807         else
 808                 fp = mdb_tgt_name_to_ctf(t, object);
 809 
 810         if (fp == NULL)
 811                 return (-1);
 812 
 813         ti.ti_cb = cb;
 814         ti.ti_arg = data;
 815         ti.ti_fp = fp;
 816 
 817         if ((ret = ctf_type_iter(fp, B_FALSE, type_iter_cb, &ti)) == CTF_ERR)
 818                 return (set_errno(ctf_to_errno(ctf_errno(fp))));
 819 
 820         return (ret);
 821 }
 822 
 823 /* utility functions */
 824 
 825 ctf_id_t
 826 mdb_ctf_type_id(mdb_ctf_id_t id)
 827 {
 828         return (((mdb_ctf_impl_t *)&id)->mci_id);
 829 }
 830 
 831 ctf_file_t *
 832 mdb_ctf_type_file(mdb_ctf_id_t id)
 833 {
 834         return (((mdb_ctf_impl_t *)&id)->mci_fp);
 835 }
 836 
 837 static int
 838 member_info_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data)
 839 {
 840         mbr_info_t *mbrp = data;
 841 
 842         if (strcmp(name, mbrp->mbr_member) == 0) {
 843                 if (mbrp->mbr_offp != NULL)
 844                         *(mbrp->mbr_offp) = off;
 845                 if (mbrp->mbr_typep != NULL)
 846                         *(mbrp->mbr_typep) = id;
 847 
 848                 return (1);
 849         }
 850 
 851         return (0);
 852 }
 853 
 854 int
 855 mdb_ctf_member_info(mdb_ctf_id_t id, const char *member, ulong_t *offp,
 856     mdb_ctf_id_t *typep)
 857 {
 858         mbr_info_t mbr;
 859         int rc;
 860 
 861         mbr.mbr_member = member;
 862         mbr.mbr_offp = offp;
 863         mbr.mbr_typep = typep;
 864 
 865         rc = mdb_ctf_member_iter(id, member_info_cb, &mbr);
 866 
 867         /* couldn't get member list */
 868         if (rc == -1)
 869                 return (-1); /* errno is set for us */
 870 
 871         /* not a member */
 872         if (rc == 0)
 873                 return (set_errno(EMDB_CTFNOMEMB));
 874 
 875         return (0);
 876 }
 877 
 878 /*
 879  * Returns offset in _bits_ in *retp.
 880  */
 881 int
 882 mdb_ctf_offsetof(mdb_ctf_id_t id, const char *member, ulong_t *retp)
 883 {
 884         return (mdb_ctf_member_info(id, member, retp, NULL));
 885 }
 886 
 887 /*
 888  * Returns offset in _bytes_, or -1 on failure.
 889  */
 890 int
 891 mdb_ctf_offsetof_by_name(const char *type, const char *member)
 892 {
 893         mdb_ctf_id_t id;
 894         ulong_t off;
 895 
 896         if (mdb_ctf_lookup_by_name(type, &id) == -1) {
 897                 mdb_warn("couldn't find type %s", type);
 898                 return (-1);
 899         }
 900 
 901         if (mdb_ctf_offsetof(id, member, &off) == -1) {
 902                 mdb_warn("couldn't find member %s of type %s", member, type);
 903                 return (-1);
 904         }
 905         if (off % 8 != 0) {
 906                 mdb_warn("member %s of type %s is an unsupported bitfield\n",
 907                     member, type);
 908                 return (-1);
 909         }
 910         off /= 8;
 911 
 912         return (off);
 913 }
 914 
 915 ssize_t
 916 mdb_ctf_sizeof_by_name(const char *type)
 917 {
 918         mdb_ctf_id_t id;
 919         ssize_t size;
 920 
 921         if (mdb_ctf_lookup_by_name(type, &id) == -1) {
 922                 mdb_warn("couldn't find type %s", type);
 923                 return (-1);
 924         }
 925 
 926         if ((size = mdb_ctf_type_size(id)) == -1) {
 927                 mdb_warn("couldn't determine type size of %s", type);
 928                 return (-1);
 929         }
 930 
 931         return (size);
 932 }
 933 
 934 /*ARGSUSED*/
 935 static int
 936 num_members_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data)
 937 {
 938         int *count = data;
 939         *count = *count + 1;
 940         return (0);
 941 }
 942 
 943 int
 944 mdb_ctf_num_members(mdb_ctf_id_t id)
 945 {
 946         int count = 0;
 947 
 948         if (mdb_ctf_member_iter(id, num_members_cb, &count) != 0)
 949                 return (-1); /* errno is set for us */
 950 
 951         return (count);
 952 }
 953 
 954 typedef struct mbr_contains {
 955         char **mbc_bufp;
 956         size_t *mbc_lenp;
 957         ulong_t *mbc_offp;
 958         mdb_ctf_id_t *mbc_idp;
 959         ssize_t mbc_total;
 960 } mbr_contains_t;
 961 
 962 static int
 963 offset_to_name_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data)
 964 {
 965         mbr_contains_t *mbc = data;
 966         ulong_t size;
 967         ctf_encoding_t e;
 968         size_t n;
 969 
 970         if (*mbc->mbc_offp < off)
 971                 return (0);
 972 
 973         if (mdb_ctf_type_encoding(id, &e) == -1)
 974                 size = mdb_ctf_type_size(id) * NBBY;
 975         else
 976                 size = e.cte_bits;
 977 
 978         if (off + size <= *mbc->mbc_offp)
 979                 return (0);
 980 
 981         n = mdb_snprintf(*mbc->mbc_bufp, *mbc->mbc_lenp, "%s", name);
 982         mbc->mbc_total += n;
 983         if (n > *mbc->mbc_lenp)
 984                 n = *mbc->mbc_lenp;
 985 
 986         *mbc->mbc_lenp -= n;
 987         *mbc->mbc_bufp += n;
 988 
 989         *mbc->mbc_offp -= off;
 990         *mbc->mbc_idp = id;
 991 
 992         return (1);
 993 }
 994 
 995 ssize_t
 996 mdb_ctf_offset_to_name(mdb_ctf_id_t id, ulong_t off, char *buf, size_t len,
 997     int dot, mdb_ctf_id_t *midp, ulong_t *moffp)
 998 {
 999         size_t size;
1000         size_t n;
1001         mbr_contains_t mbc;
1002 
1003         if (!mdb_ctf_type_valid(id))
1004                 return (set_errno(EINVAL));
1005 
1006         /*
1007          * Quick sanity check to make sure the given offset is within
1008          * this scope of this type.
1009          */
1010         if (mdb_ctf_type_size(id) * NBBY <= off)
1011                 return (set_errno(EINVAL));
1012 
1013         mbc.mbc_bufp = &buf;
1014         mbc.mbc_lenp = &len;
1015         mbc.mbc_offp = &off;
1016         mbc.mbc_idp = &id;
1017         mbc.mbc_total = 0;
1018 
1019         *buf = '\0';
1020 
1021         for (;;) {
1022                 /*
1023                  * Check for an exact match.
1024                  */
1025                 if (off == 0)
1026                         break;
1027 
1028                 (void) mdb_ctf_type_resolve(id, &id);
1029 
1030                 /*
1031                  * Find the member that contains this offset.
1032                  */
1033                 switch (mdb_ctf_type_kind(id)) {
1034                 case CTF_K_ARRAY: {
1035                         mdb_ctf_arinfo_t ar;
1036                         uint_t index;
1037 
1038                         (void) mdb_ctf_array_info(id, &ar);
1039                         size = mdb_ctf_type_size(ar.mta_contents) * NBBY;
1040                         index = off / size;
1041 
1042                         id = ar.mta_contents;
1043                         off %= size;
1044 
1045                         n = mdb_snprintf(buf, len, "[%u]", index);
1046                         mbc.mbc_total += n;
1047                         if (n > len)
1048                                 n = len;
1049 
1050                         buf += n;
1051                         len -= n;
1052                         break;
1053                 }
1054 
1055                 case CTF_K_STRUCT: {
1056                         int ret;
1057 
1058                         /*
1059                          * Find the member that contains this offset
1060                          * and continue.
1061                          */
1062 
1063                         if (dot) {
1064                                 mbc.mbc_total++;
1065                                 if (len != 0) {
1066                                         *buf++ = '.';
1067                                         *buf = '\0';
1068                                         len--;
1069                                 }
1070                         }
1071 
1072                         ret = mdb_ctf_member_iter(id, offset_to_name_cb, &mbc);
1073                         if (ret == -1)
1074                                 return (-1); /* errno is set for us */
1075 
1076                         /*
1077                          * If we did not find a member containing this offset
1078                          * (due to holes in the structure), return EINVAL.
1079                          */
1080                         if (ret == 0)
1081                                 return (set_errno(EINVAL));
1082 
1083                         break;
1084                 }
1085 
1086                 case CTF_K_UNION:
1087                         /*
1088                          * Treat unions like atomic entities since we can't
1089                          * do more than guess which member of the union
1090                          * might be the intended one.
1091                          */
1092                         goto done;
1093 
1094                 case CTF_K_INTEGER:
1095                 case CTF_K_FLOAT:
1096                 case CTF_K_POINTER:
1097                 case CTF_K_ENUM:
1098                         goto done;
1099 
1100                 default:
1101                         return (set_errno(EINVAL));
1102                 }
1103 
1104                 dot = 1;
1105         }
1106 done:
1107         if (midp != NULL)
1108                 *midp = id;
1109         if (moffp != NULL)
1110                 *moffp = off;
1111 
1112         return (mbc.mbc_total);
1113 }
1114 
1115 static void
1116 mdb_ctf_warn(uint_t flags, const char *format, ...)
1117 {
1118         va_list alist;
1119 
1120         if (flags & MDB_CTF_VREAD_QUIET)
1121                 return;
1122 
1123         va_start(alist, format);
1124         vwarn(format, alist);
1125         va_end(alist);
1126 }
1127 
1128 /*
1129  * Check if two types are structurally the same rather than logically
1130  * the same. That is to say that two types are equal if they have the
1131  * same logical structure rather than having the same ids in CTF-land.
1132  */
1133 static int type_equals(mdb_ctf_id_t, mdb_ctf_id_t);
1134 
1135 static int
1136 type_equals_cb(const char *name, mdb_ctf_id_t amem, ulong_t aoff, void *data)
1137 {
1138         mdb_ctf_id_t b = *(mdb_ctf_id_t *)data;
1139         ulong_t boff;
1140         mdb_ctf_id_t bmem;
1141 
1142         /*
1143          * Look up the corresponding member in the other composite type.
1144          */
1145         if (mdb_ctf_member_info(b, name, &boff, &bmem) != 0)
1146                 return (1);
1147 
1148         /*
1149          * We don't allow members to be shuffled around.
1150          */
1151         if (aoff != boff)
1152                 return (1);
1153 
1154         return (type_equals(amem, bmem) ? 0 : 1);
1155 }
1156 
1157 static int
1158 type_equals(mdb_ctf_id_t a, mdb_ctf_id_t b)
1159 {
1160         size_t asz, bsz;
1161         int akind, bkind;
1162         mdb_ctf_arinfo_t aar, bar;
1163 
1164         /*
1165          * Resolve both types down to their fundamental types, and make
1166          * sure their sizes and kinds match.
1167          */
1168         if (mdb_ctf_type_resolve(a, &a) != 0 ||
1169             mdb_ctf_type_resolve(b, &b) != 0 ||
1170             (asz = mdb_ctf_type_size(a)) == -1UL ||
1171             (bsz = mdb_ctf_type_size(b)) == -1UL ||
1172             (akind = mdb_ctf_type_kind(a)) == -1 ||
1173             (bkind = mdb_ctf_type_kind(b)) == -1 ||
1174             asz != bsz || akind != bkind) {
1175                 return (0);
1176         }
1177 
1178         switch (akind) {
1179         case CTF_K_INTEGER:
1180         case CTF_K_FLOAT:
1181         case CTF_K_POINTER:
1182                 /*
1183                  * For pointers we could be a little stricter and require
1184                  * both pointers to reference types which look vaguely
1185                  * similar (for example, we could insist that the two types
1186                  * have the same name). However, all we really care about
1187                  * here is that the structure of the two types are the same,
1188                  * and, in that regard, one pointer is as good as another.
1189                  */
1190                 return (1);
1191 
1192         case CTF_K_UNION:
1193         case CTF_K_STRUCT:
1194                 /*
1195                  * The test for the number of members is only strictly
1196                  * necessary for unions since we'll find other problems with
1197                  * structs. However, the extra check will do no harm.
1198                  */
1199                 return (mdb_ctf_num_members(a) == mdb_ctf_num_members(b) &&
1200                     mdb_ctf_member_iter(a, type_equals_cb, &b) == 0);
1201 
1202         case CTF_K_ARRAY:
1203                 return (mdb_ctf_array_info(a, &aar) == 0 &&
1204                     mdb_ctf_array_info(b, &bar) == 0 &&
1205                     aar.mta_nelems == bar.mta_nelems &&
1206                     type_equals(aar.mta_index, bar.mta_index) &&
1207                     type_equals(aar.mta_contents, bar.mta_contents));
1208         }
1209 
1210         return (0);
1211 }
1212 
1213 
1214 typedef struct member {
1215         char            *m_modbuf;
1216         char            *m_tgtbuf;
1217         const char      *m_tgtname;
1218         mdb_ctf_id_t    m_tgtid;
1219         uint_t          m_flags;
1220 } member_t;
1221 
1222 static int vread_helper(mdb_ctf_id_t, char *, mdb_ctf_id_t, char *,
1223     const char *, uint_t);
1224 
1225 static int
1226 member_cb(const char *name, mdb_ctf_id_t modmid, ulong_t modoff, void *data)
1227 {
1228         member_t *mp = data;
1229         char *modbuf = mp->m_modbuf;
1230         mdb_ctf_id_t tgtmid;
1231         char *tgtbuf = mp->m_tgtbuf;
1232         ulong_t tgtoff;
1233         char tgtname[128];
1234 
1235         (void) mdb_snprintf(tgtname, sizeof (tgtname),
1236             "member %s of type %s", name, mp->m_tgtname);
1237 
1238         if (mdb_ctf_member_info(mp->m_tgtid, name, &tgtoff, &tgtmid) != 0) {
1239                 if (mp->m_flags & MDB_CTF_VREAD_IGNORE_ABSENT)
1240                         return (0);
1241                 mdb_ctf_warn(mp->m_flags, "could not find %s\n", tgtname);
1242                 return (set_errno(EMDB_CTFNOMEMB));
1243         }
1244 
1245         return (vread_helper(modmid, modbuf + modoff / NBBY,
1246             tgtmid, tgtbuf + tgtoff / NBBY, tgtname, mp->m_flags));
1247 }
1248 
1249 typedef struct enum_value {
1250         int             *ev_modbuf;
1251         const char      *ev_name;
1252 } enum_value_t;
1253 
1254 static int
1255 enum_cb(const char *name, int value, void *data)
1256 {
1257         enum_value_t *ev = data;
1258 
1259         if (strcmp(name, ev->ev_name) == 0) {
1260                 *ev->ev_modbuf = value;
1261                 return (1);
1262         }
1263         return (0);
1264 }
1265 
1266 static int
1267 vread_helper(mdb_ctf_id_t modid, char *modbuf,
1268     mdb_ctf_id_t tgtid, char *tgtbuf, const char *tgtname, uint_t flags)
1269 {
1270         size_t modsz, tgtsz;
1271         int modkind, tgtkind, mod_members;
1272         member_t mbr;
1273         enum_value_t ev;
1274         int ret;
1275         mdb_ctf_arinfo_t tar, mar;
1276         int i;
1277         char typename[128];
1278         char mdbtypename[128];
1279         ctf_encoding_t tgt_encoding, mod_encoding;
1280         boolean_t signed_int = B_FALSE;
1281 
1282         if (mdb_ctf_type_name(tgtid, typename, sizeof (typename)) == NULL) {
1283                 (void) mdb_snprintf(typename, sizeof (typename),
1284                     "#%ul", mdb_ctf_type_id(tgtid));
1285         }
1286         if (mdb_ctf_type_name(modid,
1287             mdbtypename, sizeof (mdbtypename)) == NULL) {
1288                 (void) mdb_snprintf(mdbtypename, sizeof (mdbtypename),
1289                     "#%ul", mdb_ctf_type_id(modid));
1290         }
1291 
1292         if (tgtname == NULL)
1293                 tgtname = "";
1294 
1295         /*
1296          * Resolve the types to their canonical form.
1297          */
1298         (void) mdb_ctf_type_resolve(modid, &modid);
1299         (void) mdb_ctf_type_resolve(tgtid, &tgtid);
1300 
1301         if ((modkind = mdb_ctf_type_kind(modid)) == -1) {
1302                 mdb_ctf_warn(flags,
1303                     "couldn't determine type kind of mdb module type %s\n",
1304                     mdbtypename);
1305                 return (-1); /* errno is set for us */
1306         }
1307         if ((tgtkind = mdb_ctf_type_kind(tgtid)) == -1) {
1308                 mdb_ctf_warn(flags,
1309                     "couldn't determine type kind of %s\n", typename);
1310                 return (-1); /* errno is set for us */
1311         }
1312 
1313         if ((modsz = mdb_ctf_type_size(modid)) == -1UL) {
1314                 mdb_ctf_warn(flags, "couldn't determine type size of "
1315                     "mdb module type %s\n", mdbtypename);
1316                 return (-1); /* errno is set for us */
1317         }
1318         if ((tgtsz = mdb_ctf_type_size(tgtid)) == -1UL) {
1319                 mdb_ctf_warn(flags, "couldn't determine size of %s (%s)\n",
1320                     typename, tgtname);
1321                 return (-1); /* errno is set for us */
1322         }
1323 
1324         if (tgtkind == CTF_K_POINTER && modkind == CTF_K_INTEGER &&
1325             strcmp(mdbtypename, "uintptr_t") == 0) {
1326                 /* allow them to convert a pointer to a uintptr_t */
1327                 ASSERT(modsz == tgtsz);
1328         } else if (tgtkind != modkind) {
1329                 mdb_ctf_warn(flags, "unexpected kind for type %s (%s)\n",
1330                     typename, tgtname);
1331                 return (set_errno(EMDB_INCOMPAT));
1332         }
1333 
1334         switch (tgtkind) {
1335         case CTF_K_INTEGER:
1336         case CTF_K_FLOAT:
1337                 /*
1338                  * Must determine if the target and module types have the same
1339                  * encoding before we can copy them.
1340                  */
1341                 if (mdb_ctf_type_encoding(tgtid, &tgt_encoding) != 0) {
1342                         mdb_ctf_warn(flags,
1343                             "couldn't determine encoding of type %s (%s)\n",
1344                             typename, tgtname);
1345                         return (-1); /* errno is set for us */
1346                 }
1347                 if (mdb_ctf_type_encoding(modid, &mod_encoding) != 0) {
1348                         mdb_ctf_warn(flags, "couldn't determine encoding of "
1349                             "mdb module type %s\n", mdbtypename);
1350                         return (-1); /* errno is set for us */
1351                 }
1352 
1353                 if (modkind == CTF_K_INTEGER) {
1354                         if ((tgt_encoding.cte_format & CTF_INT_SIGNED) !=
1355                             (mod_encoding.cte_format & CTF_INT_SIGNED)) {
1356                                 mdb_ctf_warn(flags,
1357                                     "signedness mismatch between type "
1358                                     "%s (%s) and mdb module type %s\n",
1359                                     typename, tgtname, mdbtypename);
1360                                 return (set_errno(EMDB_INCOMPAT));
1361                         }
1362                         signed_int =
1363                             ((tgt_encoding.cte_format & CTF_INT_SIGNED) != 0);
1364                 } else if (tgt_encoding.cte_format != mod_encoding.cte_format) {
1365                         mdb_ctf_warn(flags,
1366                             "encoding mismatch (%#x != %#x) between type "
1367                             "%s (%s) and mdb module type %s\n",
1368                             tgt_encoding.cte_format, mod_encoding.cte_format,
1369                             typename, tgtname, mdbtypename);
1370                         return (set_errno(EMDB_INCOMPAT));
1371                 }
1372                 /* FALLTHROUGH */
1373         case CTF_K_POINTER:
1374                 /*
1375                  * If the sizes don't match we need to be tricky to make
1376                  * sure that the caller gets the correct data.
1377                  */
1378                 if (modsz < tgtsz) {
1379                         mdb_ctf_warn(flags, "size of type %s (%s) is too "
1380                             "large for mdb module type %s\n",
1381                             typename, tgtname, mdbtypename);
1382                         return (set_errno(EMDB_INCOMPAT));
1383                 } else if (modsz > tgtsz) {
1384                         /* BEGIN CSTYLED */
1385                         /*
1386                          * Fill modbuf with 1's for sign extension if target
1387                          * buf is a signed integer and its value is negative.
1388                          *
1389                          *   S = sign bit (in most-significant byte)
1390                          *
1391                          *      BIG ENDIAN DATA
1392                          *    +--------+--------+--------+--------+
1393                          *    |S       |        |        |        |
1394                          *    +--------+--------+--------+--------+
1395                          *     0        1  ...            sz-1     sz
1396                          *
1397                          *      LITTLE ENDIAN DATA
1398                          *    +--------+--------+--------+--------+
1399                          *    |        |        |        |S       |
1400                          *    +--------+--------+--------+--------+
1401                          *     0        1  ...            sz-1     sz
1402                          */
1403                         /* END CSTYLED */
1404 #ifdef _BIG_ENDIAN
1405                         if (signed_int && (tgtbuf[0] & 0x80) != 0)
1406 #else
1407                         if (signed_int && (tgtbuf[tgtsz - 1] & 0x80) != 0)
1408 #endif
1409                                 (void) memset(modbuf, 0xFF, modsz);
1410                         else
1411                                 bzero(modbuf, modsz);
1412 #ifdef _BIG_ENDIAN
1413                         bcopy(tgtbuf, modbuf + modsz - tgtsz, tgtsz);
1414 #else
1415                         bcopy(tgtbuf, modbuf, tgtsz);
1416 #endif
1417                 } else {
1418                         bcopy(tgtbuf, modbuf, modsz);
1419                 }
1420 
1421                 return (0);
1422 
1423         case CTF_K_ENUM:
1424                 if (modsz != tgtsz || modsz != sizeof (int)) {
1425                         mdb_ctf_warn(flags, "unexpected size of type %s (%s)\n",
1426                             typename, tgtname);
1427                         return (set_errno(EMDB_INCOMPAT));
1428                 }
1429 
1430                 /*
1431                  * Default to the same value as in the target.
1432                  */
1433                 bcopy(tgtbuf, modbuf, sizeof (int));
1434 
1435                 /* LINTED */
1436                 i = *(int *)tgtbuf;
1437 
1438                 /* LINTED */
1439                 ev.ev_modbuf = (int *)modbuf;
1440                 ev.ev_name = mdb_ctf_enum_name(tgtid, i);
1441                 if (ev.ev_name == NULL) {
1442                         mdb_ctf_warn(flags,
1443                             "unexpected value %u of enum type %s (%s)\n",
1444                             i, typename, tgtname);
1445                         return (set_errno(EMDB_INCOMPAT));
1446                 }
1447 
1448                 ret = mdb_ctf_enum_iter(modid, enum_cb, &ev);
1449                 if (ret == 0) {
1450                         /* value not found */
1451                         mdb_ctf_warn(flags,
1452                             "unexpected value %s (%u) of enum type %s (%s)\n",
1453                             ev.ev_name, i, typename, tgtname);
1454                         return (set_errno(EMDB_INCOMPAT));
1455                 } else if (ret == 1) {
1456                         /* value found */
1457                         return (0);
1458                 } else if (ret == -1) {
1459                         mdb_ctf_warn(flags, "could not iterate enum %s (%s)\n",
1460                             typename, tgtname);
1461                 }
1462                 return (ret);
1463 
1464         case CTF_K_STRUCT:
1465                 mbr.m_modbuf = modbuf;
1466                 mbr.m_tgtbuf = tgtbuf;
1467                 mbr.m_tgtid = tgtid;
1468                 mbr.m_flags = flags;
1469                 mbr.m_tgtname = typename;
1470 
1471                 return (mdb_ctf_member_iter(modid, member_cb, &mbr));
1472 
1473         case CTF_K_UNION:
1474                 mbr.m_modbuf = modbuf;
1475                 mbr.m_tgtbuf = tgtbuf;
1476                 mbr.m_tgtid = tgtid;
1477                 mbr.m_flags = flags;
1478                 mbr.m_tgtname = typename;
1479 
1480                 /*
1481                  * Not all target union members need to be present in the
1482                  * mdb type. If there is only a single union member in the
1483                  * mdb type, its actual type does not need to match with
1484                  * its target's type. On the other hand, if more than one
1485                  * union members are specified in the mdb type, their types
1486                  * must match with the types of their relevant union members
1487                  * of the target union.
1488                  */
1489                 mod_members = mdb_ctf_num_members(modid);
1490                 if (mod_members == 1) {
1491                         return (mdb_ctf_member_iter(modid, member_cb, &mbr));
1492                 } else if (mod_members > 1) {
1493                         if (mdb_ctf_member_iter(modid, type_equals_cb,
1494                             &tgtid)) {
1495                                 mdb_ctf_warn(flags,
1496                                     "inexact match for union %s (%s)\n",
1497                                     typename, tgtname);
1498                                 return (set_errno(EMDB_INCOMPAT));
1499                         }
1500 
1501                         /*
1502                          * From the check above we know that the members
1503                          * which are present in the mdb type are equal to
1504                          * the types in the target. Thus, the member_cb
1505                          * callback below will not move anything around and
1506                          * it is equivalent to:
1507                          *
1508                          * bcopy(tgtbuf, modbuf, MAX(module member's sizes))
1509                          */
1510                         return (mdb_ctf_member_iter(modid, member_cb, &mbr));
1511                 } else {
1512                         /*
1513                          * We either got 0 or -1. In any case that number
1514                          * should be returned right away. For the error
1515                          * case of -1, errno has been set for us.
1516                          */
1517                         return (mod_members);
1518                 }
1519 
1520         case CTF_K_ARRAY:
1521                 if (mdb_ctf_array_info(tgtid, &tar) != 0) {
1522                         mdb_ctf_warn(flags,
1523                             "couldn't get array info for %s (%s)\n",
1524                             typename, tgtname);
1525                         return (-1); /* errno is set for us */
1526                 }
1527                 if (mdb_ctf_array_info(modid, &mar) != 0) {
1528                         mdb_ctf_warn(flags,
1529                             "couldn't get array info for mdb module type %s\n",
1530                             mdbtypename);
1531                         return (-1); /* errno is set for us */
1532                 }
1533 
1534                 if (tar.mta_nelems != mar.mta_nelems) {
1535                         mdb_ctf_warn(flags,
1536                             "unexpected array size (%u) for type %s (%s)\n",
1537                             tar.mta_nelems, typename, tgtname);
1538                         return (set_errno(EMDB_INCOMPAT));
1539                 }
1540 
1541                 if ((modsz = mdb_ctf_type_size(mar.mta_contents)) == -1UL) {
1542                         mdb_ctf_warn(flags, "couldn't determine type size of "
1543                             "mdb module type %s\n", mdbtypename);
1544                         return (-1); /* errno is set for us */
1545                 }
1546                 if ((tgtsz = mdb_ctf_type_size(tar.mta_contents)) == -1UL) {
1547                         mdb_ctf_warn(flags,
1548                             "couldn't determine size of %s (%s)\n",
1549                             typename, tgtname);
1550                         return (-1); /* errno is set for us */
1551                 }
1552 
1553                 for (i = 0; i < tar.mta_nelems; i++) {
1554                         ret = vread_helper(mar.mta_contents, modbuf + i * modsz,
1555                             tar.mta_contents, tgtbuf + i * tgtsz,
1556                             tgtname, flags);
1557 
1558                         if (ret != 0)
1559                                 return (ret);
1560                 }
1561 
1562                 return (0);
1563         }
1564 
1565         mdb_ctf_warn(flags, "unsupported kind %d for type %s (%s)\n",
1566             modkind, typename, tgtname);
1567         return (set_errno(EMDB_INCOMPAT));
1568 }
1569 
1570 /*
1571  * Like mdb_vread(), mdb_ctf_vread() is used to read from the target's
1572  * virtual address space.  However, mdb_ctf_vread() can be used to safely
1573  * read a complex type (e.g. a struct) from the target, even if MDB was compiled
1574  * against a different definition of that type (e.g. when debugging a crash
1575  * dump from an older release).
1576  *
1577  * Callers can achieve this by defining their own type which corresponds to the
1578  * type in the target, but contains only the members that the caller requires.
1579  * Using the CTF type information embedded in the target, mdb_ctf_vread will
1580  * find the required members in the target and fill in the caller's structure.
1581  * The members are located by name, and their types are verified to be
1582  * compatible.
1583  *
1584  * By convention, the caller will declare a type with the name "mdb_<type>",
1585  * where <type> is the name of the type in the target (e.g. mdb_zio_t).  This
1586  * type will contain the members that the caller is interested in.  For example:
1587  *
1588  * typedef struct mdb_zio {
1589  *         enum zio_type io_type;
1590  *         uintptr_t io_waiter;
1591  *         struct {
1592  *                 struct {
1593  *                         uintptr_t list_next;
1594  *                 } list_head;
1595  *         } io_parent_list;
1596  *         int io_error;
1597  * } mdb_zio_t;
1598  *
1599  * mdb_zio_t zio;
1600  * error = mdb_ctf_vread(&zio, "zio_t", "mdb_zio_t", zio_target_addr, 0);
1601  *
1602  * If a given MDB module has different dcmds or walkers that need to read
1603  * different members from the same struct, then different "mdb_" types
1604  * should be declared for each caller.  By convention, these types should
1605  * be named "mdb_<dcmd or walker>_<type>", e.g. mdb_findstack_kthread_t
1606  * for ::findstack.  If the MDB module is compiled from several source files,
1607  * one must be especially careful to not define different types with the
1608  * same name in different source files, because the compiler can not detect
1609  * this error.
1610  *
1611  * Enums will also be translated by name, so the mdb module will receive
1612  * the enum value it expects even if the target has renumbered the enum.
1613  * Warning: it will therefore only work with enums are only used to store
1614  * legitimate enum values (not several values or-ed together).
1615  *
1616  * Flags values:
1617  *
1618  * MDB_CTF_VREAD_QUIET: keep quiet about failures
1619  * MDB_CTF_VREAD_IGNORE_ABSENT: ignore any member that couldn't be found in the
1620  * target struct; be careful not to use an uninitialized result.
1621  */
1622 int
1623 mdb_ctf_vread(void *modbuf, const char *target_typename,
1624     const char *mdb_typename, uintptr_t addr, uint_t flags)
1625 {
1626         ctf_file_t *mfp;
1627         ctf_id_t mid;
1628         void *tgtbuf;
1629         size_t size;
1630         mdb_ctf_id_t tgtid;
1631         mdb_ctf_id_t modid;
1632         mdb_module_t *mod;
1633         int ret;
1634 
1635         if ((mod = mdb_get_module()) == NULL || (mfp = mod->mod_ctfp) == NULL) {
1636                 mdb_ctf_warn(flags, "no ctf data found for mdb module %s\n",
1637                     mod->mod_name);
1638                 return (set_errno(EMDB_NOCTF));
1639         }
1640 
1641         if ((mid = ctf_lookup_by_name(mfp, mdb_typename)) == CTF_ERR) {
1642                 mdb_ctf_warn(flags, "couldn't find ctf data for "
1643                     "type %s in mdb module %s\n",
1644                     mdb_typename, mod->mod_name);
1645                 return (set_errno(ctf_to_errno(ctf_errno(mfp))));
1646         }
1647 
1648         set_ctf_id(&modid, mfp, mid);
1649 
1650         if (mdb_ctf_lookup_by_name(target_typename, &tgtid) != 0) {
1651                 mdb_ctf_warn(flags,
1652                     "couldn't find type %s in target's ctf data\n",
1653                     target_typename);
1654                 return (set_errno(EMDB_NOCTF));
1655         }
1656 
1657         /*
1658          * Read the data out of the target's address space.
1659          */
1660         if ((size = mdb_ctf_type_size(tgtid)) == -1UL) {
1661                 mdb_ctf_warn(flags, "couldn't determine size of type %s\n",
1662                     target_typename);
1663                 return (-1); /* errno is set for us */
1664         }
1665 
1666         tgtbuf = mdb_alloc(size, UM_SLEEP);
1667 
1668         if (mdb_vread(tgtbuf, size, addr) < 0) {
1669                 mdb_ctf_warn(flags, "couldn't read %s from %p\n",
1670                     target_typename, addr);
1671                 mdb_free(tgtbuf, size);
1672                 return (-1); /* errno is set for us */
1673         }
1674 
1675         ret = vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags);
1676 
1677         mdb_free(tgtbuf, size);
1678 
1679         return (ret);
1680 }
1681 
1682 /*
1683  * Note: mdb_ctf_readsym() doesn't take separate parameters for the name
1684  * of the target's type vs the mdb module's type.  Use with complicated
1685  * types (e.g. structs) may result in unnecessary failure if a member of
1686  * the struct has been changed in the target, but is not actually needed
1687  * by the mdb module.  Use mdb_lookup_by_name() + mdb_ctf_vread() to
1688  * avoid this problem.
1689  */
1690 int
1691 mdb_ctf_readsym(void *buf, const char *typename, const char *name, uint_t flags)
1692 {
1693         GElf_Sym sym;
1694 
1695         if (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY, name, &sym) != 0) {
1696                 mdb_ctf_warn(flags, "couldn't find symbol %s\n", name);
1697                 return (-1); /* errno is set for us */
1698         }
1699 
1700         return (mdb_ctf_vread(buf, typename, typename, sym.st_value, flags));
1701 }
1702 
1703 ctf_file_t *
1704 mdb_ctf_bufopen(const void *ctf_va, size_t ctf_size, const void *sym_va,
1705     Shdr *symhdr, const void *str_va, Shdr *strhdr, int *errp)
1706 {
1707         ctf_sect_t ctdata, symtab, strtab;
1708 
1709         ctdata.cts_name = ".SUNW_ctf";
1710         ctdata.cts_type = SHT_PROGBITS;
1711         ctdata.cts_flags = 0;
1712         ctdata.cts_data = ctf_va;
1713         ctdata.cts_size = ctf_size;
1714         ctdata.cts_entsize = 1;
1715         ctdata.cts_offset = 0;
1716 
1717         symtab.cts_name = ".symtab";
1718         symtab.cts_type = symhdr->sh_type;
1719         symtab.cts_flags = symhdr->sh_flags;
1720         symtab.cts_data = sym_va;
1721         symtab.cts_size = symhdr->sh_size;
1722         symtab.cts_entsize = symhdr->sh_entsize;
1723         symtab.cts_offset = symhdr->sh_offset;
1724 
1725         strtab.cts_name = ".strtab";
1726         strtab.cts_type = strhdr->sh_type;
1727         strtab.cts_flags = strhdr->sh_flags;
1728         strtab.cts_data = str_va;
1729         strtab.cts_size = strhdr->sh_size;
1730         strtab.cts_entsize = strhdr->sh_entsize;
1731         strtab.cts_offset = strhdr->sh_offset;
1732 
1733         return (ctf_bufopen(&ctdata, &symtab, &strtab, errp));
1734 }
1735 
1736 int
1737 mdb_ctf_synthetics_init(void)
1738 {
1739         int err;
1740 
1741         if ((mdb.m_synth = ctf_create(&err)) == NULL)
1742                 return (set_errno(ctf_to_errno(err)));
1743 
1744         return (0);
1745 }
1746 
1747 void
1748 mdb_ctf_synthetics_fini(void)
1749 {
1750         if (mdb.m_synth == NULL)
1751                 return;
1752 
1753         ctf_close(mdb.m_synth);
1754         mdb.m_synth = NULL;
1755 }
1756 
1757 int
1758 mdb_ctf_synthetics_create_base(int kind)
1759 {
1760         const synth_intrinsic_t *synp;
1761         const synth_typedef_t *sytp;
1762         int err;
1763         ctf_id_t id;
1764         ctf_file_t *cp = mdb.m_synth;
1765 
1766         if (mdb.m_synth == NULL) {
1767                 mdb_printf("synthetic types disabled: ctf create failed\n");
1768                 return (1);
1769         }
1770 
1771         switch (kind) {
1772         case SYNTHETIC_ILP32:
1773                 synp = synth_builtins32;
1774                 sytp = synth_typedefs32;
1775                 break;
1776         case SYNTHETIC_LP64:
1777                 synp = synth_builtins64;
1778                 sytp = synth_typedefs64;
1779                 break;
1780         default:
1781                 mdb_dprintf(MDB_DBG_CTF, "invalid type of intrinsic: %d\n",
1782                     kind);
1783                 return (1);
1784         }
1785 
1786         err = 0;
1787         for (; synp->syn_name != NULL; synp++) {
1788                 if (synp->syn_kind == CTF_K_INTEGER) {
1789                         err = ctf_add_integer(cp, CTF_ADD_ROOT, synp->syn_name,
1790                             &synp->syn_enc);
1791                 } else {
1792                         err = ctf_add_float(cp, CTF_ADD_ROOT, synp->syn_name,
1793                             &synp->syn_enc);
1794                 }
1795 
1796                 if (err == CTF_ERR) {
1797                         mdb_dprintf(MDB_DBG_CTF, "couldn't add synthetic "
1798                             "type: %s\n", synp->syn_name);
1799                         goto discard;
1800                 }
1801         }
1802 
1803         if (ctf_update(cp) == CTF_ERR) {
1804                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n");
1805                 goto discard;
1806         }
1807 
1808         for (; sytp->syt_src != NULL; sytp++) {
1809                 id = ctf_lookup_by_name(cp, sytp->syt_src);
1810                 if (id == CTF_ERR) {
1811                         mdb_dprintf(MDB_DBG_CTF, "cailed to lookup %s: %s\n",
1812                             sytp->syt_src, ctf_errmsg(ctf_errno(cp)));
1813                         goto discard;
1814                 }
1815                 if (ctf_add_typedef(cp, CTF_ADD_ROOT, sytp->syt_targ, id) ==
1816                     CTF_ERR) {
1817                         mdb_dprintf(MDB_DBG_CTF, "couldn't add typedef %s "
1818                             "%s: %s\n", sytp->syt_targ, sytp->syt_src,
1819                             ctf_errmsg(ctf_errno(cp)));
1820                         goto discard;
1821                 }
1822         }
1823 
1824         if (ctf_update(cp) == CTF_ERR) {
1825                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n");
1826                 goto discard;
1827         }
1828 
1829         return (0);
1830 
1831 discard:
1832         err = set_errno(ctf_to_errno(ctf_errno(cp)));
1833         (void) ctf_discard(cp);
1834         return (err);
1835 }
1836 
1837 int
1838 mdb_ctf_synthetics_reset(void)
1839 {
1840         mdb_ctf_synthetics_fini();
1841         return (mdb_ctf_synthetics_init());
1842 }
1843 
1844 int
1845 mdb_ctf_add_typedef(const char *name, const mdb_ctf_id_t *p, mdb_ctf_id_t *new)
1846 {
1847         ctf_id_t rid;
1848         mdb_ctf_id_t tid;
1849         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
1850 
1851         if (mdb.m_synth == NULL) {
1852                 mdb_printf("synthetic types disabled: ctf create failed\n");
1853                 return (1);
1854         }
1855 
1856         if (mdb_ctf_lookup_by_name(name, &tid) == 0) {
1857                 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type "
1858                     "with that name already exists\n", name);
1859                 return (set_errno(EEXIST));
1860         }
1861 
1862         rid = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
1863         if (rid == CTF_ERR) {
1864                 mdb_dprintf(MDB_DBG_CTF, "failed to add reference type: %s\n",
1865                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1866                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1867         }
1868         rid = ctf_add_typedef(mdb.m_synth, CTF_ADD_ROOT, name, rid);
1869         if (rid == CTF_ERR) {
1870                 mdb_dprintf(MDB_DBG_CTF, "failed to add typedef: %s",
1871                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1872                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1873         }
1874 
1875         if (ctf_update(mdb.m_synth) == CTF_ERR) {
1876                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1877                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1878                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1879         }
1880 
1881         if (new != NULL)
1882                 set_ctf_id(new, mdb.m_synth, rid);
1883 
1884         return (0);
1885 }
1886 
1887 int
1888 mdb_ctf_add_struct(const char *name, mdb_ctf_id_t *rid)
1889 {
1890         mdb_ctf_id_t tid;
1891         ctf_id_t id;
1892 
1893         if (mdb.m_synth == NULL) {
1894                 mdb_printf("synthetic types disabled: ctf create failed\n");
1895                 return (1);
1896         }
1897 
1898         if (name != NULL && mdb_ctf_lookup_by_name(name, &tid) == 0) {
1899                 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type "
1900                     "with that name already exists\n", name);
1901                 return (set_errno(EEXIST));
1902         }
1903 
1904         if ((id = ctf_add_struct(mdb.m_synth, CTF_ADD_ROOT, name)) ==
1905             CTF_ERR) {
1906                 mdb_dprintf(MDB_DBG_CTF, "failed to add struct: %s\n",
1907                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1908                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1909         }
1910 
1911         if (ctf_update(mdb.m_synth) == CTF_ERR) {
1912                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1913                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1914                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1915         }
1916 
1917         if (rid != NULL)
1918                 set_ctf_id(rid, mdb.m_synth, id);
1919 
1920         return (0);
1921 }
1922 
1923 int
1924 mdb_ctf_add_union(const char *name, mdb_ctf_id_t *rid)
1925 {
1926         mdb_ctf_id_t tid;
1927         ctf_id_t id;
1928 
1929         if (mdb.m_synth == NULL) {
1930                 mdb_printf("synthetic types disabled: ctf create failed\n");
1931                 return (1);
1932         }
1933 
1934         if (name != NULL && mdb_ctf_lookup_by_name(name, &tid) == 0) {
1935                 mdb_dprintf(MDB_DBG_CTF, "failed to add type %s: a type "
1936                     "with that name already exists\n", name);
1937                 return (set_errno(EEXIST));
1938         }
1939 
1940         if ((id = ctf_add_union(mdb.m_synth, CTF_ADD_ROOT, name)) ==
1941             CTF_ERR) {
1942                 mdb_dprintf(MDB_DBG_CTF, "failed to add union: %s\n",
1943                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1944                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1945         }
1946 
1947         if (ctf_update(mdb.m_synth) == CTF_ERR) {
1948                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1949                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1950                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1951         }
1952 
1953         if (rid != NULL)
1954                 set_ctf_id(rid, mdb.m_synth, id);
1955 
1956         return (0);
1957 }
1958 
1959 int
1960 mdb_ctf_add_member(const mdb_ctf_id_t *p, const char *name,
1961     const mdb_ctf_id_t *mtype, mdb_ctf_id_t *rid)
1962 {
1963         ctf_id_t id, mtid;
1964         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
1965         mdb_ctf_impl_t *mcim = (mdb_ctf_impl_t *)mtype;
1966 
1967         if (mdb.m_synth == NULL) {
1968                 mdb_printf("synthetic types disabled: ctf create failed\n");
1969                 return (DCMD_ERR);
1970         }
1971 
1972         if (mcip->mci_fp != mdb.m_synth) {
1973                 mdb_dprintf(MDB_DBG_CTF, "requested to add member to a type "
1974                     "that wasn't created from a synthetic\n");
1975                 return (set_errno(EINVAL));
1976         }
1977 
1978         mtid = ctf_add_type(mdb.m_synth, mcim->mci_fp, mcim->mci_id);
1979         if (mtid == CTF_ERR) {
1980                 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n",
1981                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1982                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1983         }
1984 
1985         if (ctf_update(mdb.m_synth) == CTF_ERR) {
1986                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
1987                     ctf_errmsg(ctf_errno(mdb.m_synth)));
1988                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1989         }
1990 
1991         id = ctf_add_member(mdb.m_synth, mcip->mci_id, name, mtid, ULONG_MAX);
1992         if (id == CTF_ERR) {
1993                 mdb_dprintf(MDB_DBG_CTF, "failed to add member %s: %s\n",
1994                     name, ctf_errmsg(ctf_errno(mdb.m_synth)));
1995                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
1996         }
1997 
1998         if (ctf_update(mdb.m_synth) == CTF_ERR) {
1999                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2000                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2001                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2002         }
2003 
2004         if (rid != NULL)
2005                 set_ctf_id(rid, mdb.m_synth, id);
2006 
2007         return (0);
2008 }
2009 
2010 int
2011 mdb_ctf_add_array(const mdb_ctf_arinfo_t *marp, mdb_ctf_id_t *rid)
2012 {
2013         mdb_ctf_impl_t *mcip;
2014         ctf_arinfo_t car;
2015         ctf_id_t id;
2016 
2017         if (mdb.m_synth == NULL) {
2018                 mdb_printf("synthetic types disabled: ctf create failed\n");
2019                 return (1);
2020         }
2021 
2022         car.ctr_nelems = marp->mta_nelems;
2023 
2024         mcip = (mdb_ctf_impl_t *)&marp->mta_contents;
2025         id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
2026         if (id == CTF_ERR) {
2027                 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n",
2028                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2029                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2030         }
2031         car.ctr_contents = id;
2032 
2033         mcip = (mdb_ctf_impl_t *)&marp->mta_index;
2034         id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
2035         if (id == CTF_ERR) {
2036                 mdb_dprintf(MDB_DBG_CTF, "failed to add member type: %s\n",
2037                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2038                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2039         }
2040         car.ctr_index = id;
2041 
2042         if (ctf_update(mdb.m_synth) == CTF_ERR) {
2043                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2044                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2045                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2046         }
2047 
2048         id = ctf_add_array(mdb.m_synth, CTF_ADD_ROOT, &car);
2049         if (id == CTF_ERR) {
2050                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2051                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2052                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2053         }
2054 
2055         if (ctf_update(mdb.m_synth) == CTF_ERR) {
2056                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2057                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2058                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2059         }
2060 
2061         if (rid != NULL)
2062                 set_ctf_id(rid, mdb.m_synth, id);
2063 
2064         return (0);
2065 }
2066 
2067 int
2068 mdb_ctf_add_pointer(const mdb_ctf_id_t *p, mdb_ctf_id_t *rid)
2069 {
2070         ctf_id_t id;
2071         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
2072 
2073         if (mdb.m_synth == NULL) {
2074                 mdb_printf("synthetic types disabled: ctf create failed\n");
2075                 return (1);
2076         }
2077 
2078         id = ctf_add_type(mdb.m_synth, mcip->mci_fp, mcip->mci_id);
2079         if (id == CTF_ERR) {
2080                 mdb_dprintf(MDB_DBG_CTF, "failed to add pointer type: %s\n",
2081                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2082                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2083         }
2084 
2085         if (ctf_update(mdb.m_synth) == CTF_ERR) {
2086                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2087                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2088                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2089         }
2090 
2091 
2092         id = ctf_add_pointer(mdb.m_synth, CTF_ADD_ROOT, NULL, id);
2093         if (id == CTF_ERR) {
2094                 mdb_dprintf(MDB_DBG_CTF, "failed to add pointer: %s\n",
2095                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2096                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2097         }
2098 
2099         if (ctf_update(mdb.m_synth) == CTF_ERR) {
2100                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2101                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2102                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2103         }
2104 
2105 
2106         if (rid != NULL)
2107                 set_ctf_id(rid, mdb.m_synth, id);
2108 
2109         return (0);
2110 }
2111 
2112 int
2113 mdb_ctf_type_delete(const mdb_ctf_id_t *id)
2114 {
2115         int ret;
2116 
2117         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)id;
2118 
2119         if (mcip->mci_fp != mdb.m_synth) {
2120                 mdb_warn("bad ctf_file_t, expected synth container\n");
2121                 return (1);
2122         }
2123 
2124         ret = ctf_delete_type(mcip->mci_fp, mcip->mci_id);
2125         if (ret != 0) {
2126                 mdb_dprintf(MDB_DBG_CTF, "failed to delete synthetic type: %s",
2127                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2128                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2129         }
2130 
2131         if (ctf_update(mdb.m_synth) == CTF_ERR) {
2132                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types: %s",
2133                     ctf_errmsg(ctf_errno(mdb.m_synth)));
2134                 return (set_errno(ctf_to_errno(ctf_errno(mdb.m_synth))));
2135         }
2136 
2137         return (0);
2138 }
2139 
2140 /* ARGSUSED */
2141 static int
2142 mdb_ctf_synthetics_file_cb(mdb_ctf_id_t id, void *arg)
2143 {
2144         ctf_file_t *targ = arg;
2145         mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)&id;
2146 
2147         if (ctf_add_type(targ, mcip->mci_fp, mcip->mci_id) == CTF_ERR) {
2148                 mdb_dprintf(MDB_DBG_CTF, "failed to add type %d: %s\n",
2149                     mcip->mci_id, ctf_errmsg(ctf_errno(mcip->mci_fp)));
2150                 return (set_errno(ctf_to_errno(ctf_errno(mcip->mci_fp))));
2151         }
2152 
2153         return (0);
2154 }
2155 
2156 int
2157 mdb_ctf_synthetics_from_file(const char *file)
2158 {
2159         ctf_file_t *fp, *syn = mdb.m_synth;
2160         int ret;
2161         type_iter_t ti;
2162 
2163         if (syn == NULL) {
2164                 mdb_warn("synthetic types disabled: ctf create failed\n");
2165                 return (1);
2166         }
2167 
2168         if ((fp = mdb_ctf_open(file, &ret)) == NULL) {
2169                 mdb_warn("failed to parse ctf data in %s: %s\n", file,
2170                     ctf_errmsg(ret));
2171                 return (1);
2172         }
2173 
2174         ret = DCMD_OK;
2175         ti.ti_fp = fp;
2176         ti.ti_arg = syn;
2177         ti.ti_cb = mdb_ctf_synthetics_file_cb;
2178         if (ctf_type_iter(fp, B_FALSE, type_iter_cb, &ti) == CTF_ERR) {
2179                 ret = set_errno(ctf_to_errno(ctf_errno(fp)));
2180                 mdb_warn("failed to add types");
2181                 goto cleanup;
2182         }
2183 
2184         if (ctf_update(syn) == CTF_ERR) {
2185                 mdb_dprintf(MDB_DBG_CTF, "failed to update synthetic types\n");
2186                 ret = set_errno(ctf_to_errno(ctf_errno(fp)));
2187         }
2188 
2189 cleanup:
2190         ctf_close(fp);
2191         if (ret != 0)
2192                 (void) ctf_discard(syn);
2193         return (ret);
2194 }
2195 
2196 int
2197 mdb_ctf_synthetics_to_file(const char *file)
2198 {
2199         int err;
2200         ctf_file_t *fp = mdb.m_synth;
2201 
2202         if (fp == NULL) {
2203                 mdb_warn("synthetic types are disabled, not writing "
2204                     "anything\n");
2205                 return (DCMD_ERR);
2206         }
2207 
2208         err = mdb_ctf_write(file, fp);
2209         if (err != 0) {
2210                 if (err == CTF_ERR)
2211                         (void) set_errno(ctf_to_errno(ctf_errno(fp)));
2212                 else
2213                         (void) set_errno(err);
2214                 err = DCMD_ERR;
2215         } else {
2216                 err = DCMD_OK;
2217         }
2218 
2219         return (err);
2220 }