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, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 /*
  28  * Copyright 2018 Joyent, Inc.
  29  */
  30 
  31 #include <ctf_impl.h>
  32 #include <sys/debug.h>
  33 
  34 ssize_t
  35 ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
  36     ssize_t *incrementp)
  37 {
  38         ssize_t size, increment;
  39 
  40         if (fp->ctf_version > CTF_VERSION_1 &&
  41             tp->ctt_size == CTF_LSIZE_SENT) {
  42                 size = CTF_TYPE_LSIZE(tp);
  43                 increment = sizeof (ctf_type_t);
  44         } else {
  45                 size = tp->ctt_size;
  46                 increment = sizeof (ctf_stype_t);
  47         }
  48 
  49         if (sizep)
  50                 *sizep = size;
  51         if (incrementp)
  52                 *incrementp = increment;
  53 
  54         return (size);
  55 }
  56 
  57 /*
  58  * Iterate over the members of a STRUCT or UNION.  We pass the name, member
  59  * type, and offset of each member to the specified callback function.
  60  */
  61 int
  62 ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
  63 {
  64         ctf_file_t *ofp = fp;
  65         const ctf_type_t *tp;
  66         ssize_t size, increment;
  67         uint_t kind, n;
  68         int rc;
  69 
  70         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
  71                 return (CTF_ERR); /* errno is set for us */
  72 
  73         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
  74                 return (CTF_ERR); /* errno is set for us */
  75 
  76         (void) ctf_get_ctt_size(fp, tp, &size, &increment);
  77         kind = LCTF_INFO_KIND(fp, tp->ctt_info);
  78 
  79         if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
  80                 return (ctf_set_errno(ofp, ECTF_NOTSOU));
  81 
  82         if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
  83                 const ctf_member_t *mp = (const ctf_member_t *)
  84                     ((uintptr_t)tp + increment);
  85 
  86                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
  87                         const char *name = ctf_strptr(fp, mp->ctm_name);
  88                         if ((rc = func(name, mp->ctm_type, mp->ctm_offset,
  89                             arg)) != 0)
  90                                 return (rc);
  91                 }
  92 
  93         } else {
  94                 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
  95                     ((uintptr_t)tp + increment);
  96 
  97                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
  98                         const char *name = ctf_strptr(fp, lmp->ctlm_name);
  99                         if ((rc = func(name, lmp->ctlm_type,
 100                             (ulong_t)CTF_LMEM_OFFSET(lmp), arg)) != 0)
 101                                 return (rc);
 102                 }
 103         }
 104 
 105         return (0);
 106 }
 107 
 108 /*
 109  * Iterate over the members of an ENUM.  We pass the string name and associated
 110  * integer value of each enum element to the specified callback function.
 111  */
 112 int
 113 ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
 114 {
 115         ctf_file_t *ofp = fp;
 116         const ctf_type_t *tp;
 117         const ctf_enum_t *ep;
 118         ssize_t increment;
 119         uint_t n;
 120         int rc;
 121 
 122         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 123                 return (CTF_ERR); /* errno is set for us */
 124 
 125         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 126                 return (CTF_ERR); /* errno is set for us */
 127 
 128         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM)
 129                 return (ctf_set_errno(ofp, ECTF_NOTENUM));
 130 
 131         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
 132 
 133         ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
 134 
 135         for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
 136                 const char *name = ctf_strptr(fp, ep->cte_name);
 137                 if ((rc = func(name, ep->cte_value, arg)) != 0)
 138                         return (rc);
 139         }
 140 
 141         return (0);
 142 }
 143 
 144 /*
 145  * Iterate over every type in the given CTF container. If the user doesn't ask
 146  * for all types, then we only give them the user visible, aka root, types.  We
 147  * pass the type ID of each type to the specified callback function.
 148  */
 149 int
 150 ctf_type_iter(ctf_file_t *fp, boolean_t nonroot, ctf_type_f *func, void *arg)
 151 {
 152         ctf_id_t id, max = fp->ctf_typemax;
 153         int rc, child = (fp->ctf_flags & LCTF_CHILD);
 154 
 155         for (id = 1; id <= max; id++) {
 156                 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
 157                 if ((nonroot || CTF_INFO_ISROOT(tp->ctt_info)) &&
 158                     (rc = func(CTF_INDEX_TO_TYPE(id, child),
 159                     CTF_INFO_ISROOT(tp->ctt_info),  arg)) != 0)
 160                         return (rc);
 161         }
 162 
 163         return (0);
 164 }
 165 
 166 /*
 167  * Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
 168  * RESTRICT nodes until we reach a "base" type node.  This is useful when
 169  * we want to follow a type ID to a node that has members or a size.  To guard
 170  * against infinite loops, we implement simplified cycle detection and check
 171  * each link against itself, the previous node, and the topmost node.
 172  */
 173 ctf_id_t
 174 ctf_type_resolve(ctf_file_t *fp, ctf_id_t type)
 175 {
 176         ctf_id_t prev = type, otype = type;
 177         ctf_file_t *ofp = fp;
 178         const ctf_type_t *tp;
 179 
 180         while ((tp = ctf_lookup_by_id(&fp, type)) != NULL) {
 181                 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 182                 case CTF_K_TYPEDEF:
 183                 case CTF_K_VOLATILE:
 184                 case CTF_K_CONST:
 185                 case CTF_K_RESTRICT:
 186                         if (tp->ctt_type == type || tp->ctt_type == otype ||
 187                             tp->ctt_type == prev) {
 188                                 ctf_dprintf("type %ld cycle detected\n", otype);
 189                                 return (ctf_set_errno(ofp, ECTF_CORRUPT));
 190                         }
 191                         prev = type;
 192                         type = tp->ctt_type;
 193                         break;
 194                 default:
 195                         return (type);
 196                 }
 197         }
 198 
 199         return (CTF_ERR); /* errno is set for us */
 200 }
 201 
 202 /*
 203  * Format an integer type; if a vname is specified, we need to insert it prior
 204  * to any bitfield ":24" suffix.  This works out far simpler than figuring it
 205  * out from scratch.
 206  */
 207 static const char *
 208 ctf_format_int(ctf_decl_t *cd, const char *vname, const char *qname,
 209     const char *name)
 210 {
 211         const char *c;
 212 
 213         if (vname == NULL) {
 214                 if (qname != NULL)
 215                         ctf_decl_sprintf(cd, "%s`%s", qname, name);
 216                 else
 217                         ctf_decl_sprintf(cd, "%s", name);
 218                 return (NULL);
 219         }
 220 
 221         if ((c = strchr(name, ':')) == NULL) {
 222                 ctf_decl_sprintf(cd, "%s", name);
 223                 return (vname);
 224         }
 225 
 226         /* "unsigned int mybits:23" */
 227         ctf_decl_sprintf(cd, "%.*s %s%s", c - name, name, vname, c);
 228         return (NULL);
 229 }
 230 
 231 static void
 232 ctf_format_func(ctf_file_t *fp, ctf_decl_t *cd,
 233     const char *vname, ctf_id_t id, int want_func_args)
 234 {
 235         ctf_funcinfo_t fi;
 236         /* We'll presume zone_create() is a bad example. */
 237         ctf_id_t args[20];
 238 
 239         ctf_decl_sprintf(cd, "%s(", vname == NULL ? "" : vname);
 240 
 241         if (!want_func_args)
 242                 goto out;
 243 
 244         if (ctf_func_info_by_id(fp, id, &fi) != 0)
 245                 goto out;
 246 
 247         if (fi.ctc_argc > ARRAY_SIZE(args))
 248                 fi.ctc_argc = ARRAY_SIZE(args);
 249 
 250         if (fi.ctc_argc == 0) {
 251                 ctf_decl_sprintf(cd, "void");
 252                 goto out;
 253         }
 254 
 255         if (ctf_func_args_by_id(fp, id, fi.ctc_argc, args) != 0)
 256                 goto out;
 257 
 258         for (size_t i = 0; i < fi.ctc_argc; i++) {
 259                 char aname[512];
 260 
 261                 if (ctf_type_name(fp, args[i], aname, sizeof (aname)) == NULL)
 262                         (void) strlcpy(aname, "unknown_t", sizeof (aname));
 263 
 264                 ctf_decl_sprintf(cd, "%s%s", aname,
 265                     i + 1 == fi.ctc_argc ? "" : ", ");
 266         }
 267 
 268         if (fi.ctc_flags & CTF_FUNC_VARARG)
 269                 ctf_decl_sprintf(cd, "%s...", fi.ctc_argc == 0 ? "" : ", ");
 270 
 271 out:
 272         ctf_decl_sprintf(cd, ")");
 273 }
 274 
 275 /*
 276  * Lookup the given type ID and print a string name for it into buf.  Return the
 277  * actual number of bytes (not including \0) needed to format the name.
 278  *
 279  * "vname" is an optional variable name or similar, so array suffix formatting,
 280  * bitfields, and functions are C-correct.  (This is not perfect, as can be seen
 281  * in kiconv_ops_t.)
 282  */
 283 static ssize_t
 284 ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
 285     const char *vname, const char *qname)
 286 {
 287         int want_func_args = (vname != NULL);
 288         ctf_decl_t cd;
 289         ctf_decl_node_t *cdp;
 290         ctf_decl_prec_t prec, lp, rp;
 291         int ptr, arr;
 292         uint_t k;
 293 
 294         if (fp == NULL && type == CTF_ERR)
 295                 return (-1); /* simplify caller code by permitting CTF_ERR */
 296 
 297         ctf_decl_init(&cd, buf, len);
 298         ctf_decl_push(&cd, fp, type);
 299 
 300         if (cd.cd_err != 0) {
 301                 ctf_decl_fini(&cd);
 302                 return (ctf_set_errno(fp, cd.cd_err));
 303         }
 304 
 305         /*
 306          * If the type graph's order conflicts with lexical precedence order
 307          * for pointers or arrays, then we need to surround the declarations at
 308          * the corresponding lexical precedence with parentheses.  This can
 309          * result in either a parenthesized pointer (*) as in int (*)() or
 310          * int (*)[], or in a parenthesized pointer and array as in int (*[])().
 311          */
 312         ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
 313         arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
 314 
 315         rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
 316         lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
 317 
 318         k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
 319 
 320         for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
 321                 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
 322                     cdp != NULL; cdp = ctf_list_next(cdp)) {
 323 
 324                         ctf_file_t *rfp = fp;
 325                         const ctf_type_t *tp =
 326                             ctf_lookup_by_id(&rfp, cdp->cd_type);
 327                         const char *name = ctf_strptr(rfp, tp->ctt_name);
 328 
 329                         if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
 330                                 ctf_decl_sprintf(&cd, " ");
 331 
 332                         if (lp == prec) {
 333                                 ctf_decl_sprintf(&cd, "(");
 334                                 lp = -1;
 335                         }
 336 
 337                         switch (cdp->cd_kind) {
 338                         case CTF_K_INTEGER:
 339                                 vname = ctf_format_int(&cd, vname, qname, name);
 340                                 break;
 341                         case CTF_K_FLOAT:
 342                         case CTF_K_TYPEDEF:
 343                                 if (qname != NULL)
 344                                         ctf_decl_sprintf(&cd, "%s`", qname);
 345                                 ctf_decl_sprintf(&cd, "%s", name);
 346                                 break;
 347                         case CTF_K_POINTER:
 348                                 ctf_decl_sprintf(&cd, "*");
 349                                 break;
 350                         case CTF_K_ARRAY:
 351                                 ctf_decl_sprintf(&cd, "%s[%u]",
 352                                     vname != NULL ? vname : "", cdp->cd_n);
 353                                 vname = NULL;
 354                                 break;
 355                         case CTF_K_FUNCTION:
 356                                 ctf_format_func(fp, &cd, vname,
 357                                     cdp->cd_type, want_func_args);
 358                                 vname = NULL;
 359                                 break;
 360                         case CTF_K_STRUCT:
 361                         case CTF_K_FORWARD:
 362                                 ctf_decl_sprintf(&cd, "struct ");
 363                                 if (qname != NULL)
 364                                         ctf_decl_sprintf(&cd, "%s`", qname);
 365                                 ctf_decl_sprintf(&cd, "%s", name);
 366                                 break;
 367                         case CTF_K_UNION:
 368                                 ctf_decl_sprintf(&cd, "union ");
 369                                 if (qname != NULL)
 370                                         ctf_decl_sprintf(&cd, "%s`", qname);
 371                                 ctf_decl_sprintf(&cd, "%s", name);
 372                                 break;
 373                         case CTF_K_ENUM:
 374                                 ctf_decl_sprintf(&cd, "enum ");
 375                                 if (qname != NULL)
 376                                         ctf_decl_sprintf(&cd, "%s`", qname);
 377                                 ctf_decl_sprintf(&cd, "%s", name);
 378                                 break;
 379                         case CTF_K_VOLATILE:
 380                                 ctf_decl_sprintf(&cd, "volatile");
 381                                 break;
 382                         case CTF_K_CONST:
 383                                 ctf_decl_sprintf(&cd, "const");
 384                                 break;
 385                         case CTF_K_RESTRICT:
 386                                 ctf_decl_sprintf(&cd, "restrict");
 387                                 break;
 388                         }
 389 
 390                         k = cdp->cd_kind;
 391                 }
 392 
 393                 if (rp == prec) {
 394                         /*
 395                          * Peek ahead: if we're going to hit a function,
 396                          * we want to insert its name now before this closing
 397                          * bracket.
 398                          */
 399                         if (vname != NULL && prec < CTF_PREC_FUNCTION) {
 400                                 cdp = ctf_list_next(
 401                                     &cd.cd_nodes[CTF_PREC_FUNCTION]);
 402 
 403                                 if (cdp != NULL) {
 404                                         ctf_decl_sprintf(&cd, "%s", vname);
 405                                         vname = NULL;
 406                                 }
 407                         }
 408 
 409                         ctf_decl_sprintf(&cd, ")");
 410                 }
 411         }
 412 
 413         if (vname != NULL)
 414                 ctf_decl_sprintf(&cd, " %s", vname);
 415 
 416         if (cd.cd_len >= len)
 417                 (void) ctf_set_errno(fp, ECTF_NAMELEN);
 418 
 419         ctf_decl_fini(&cd);
 420         return (cd.cd_len);
 421 }
 422 
 423 ssize_t
 424 ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
 425 {
 426         return (ctf_type_qlname(fp, type, buf, len, NULL, NULL));
 427 }
 428 
 429 /*
 430  * Lookup the given type ID and print a string name for it into buf.  If buf
 431  * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
 432  */
 433 char *
 434 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
 435 {
 436         ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, NULL);
 437         return (rv >= 0 && rv < len ? buf : NULL);
 438 }
 439 
 440 char *
 441 ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
 442     const char *qname)
 443 {
 444         ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, qname);
 445         return (rv >= 0 && rv < len ? buf : NULL);
 446 }
 447 
 448 char *
 449 ctf_type_cname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
 450     const char *cname)
 451 {
 452         ssize_t rv = ctf_type_qlname(fp, type, buf, len, cname, NULL);
 453         return (rv >= 0 && rv < len ? buf : NULL);
 454 }
 455 
 456 /*
 457  * Resolve the type down to a base type node, and then return the size
 458  * of the type storage in bytes.
 459  */
 460 ssize_t
 461 ctf_type_size(ctf_file_t *fp, ctf_id_t type)
 462 {
 463         const ctf_type_t *tp;
 464         ssize_t size;
 465         ctf_arinfo_t ar;
 466 
 467         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 468                 return (-1); /* errno is set for us */
 469 
 470         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 471                 return (-1); /* errno is set for us */
 472 
 473         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 474         case CTF_K_POINTER:
 475                 return (fp->ctf_dmodel->ctd_pointer);
 476 
 477         case CTF_K_FUNCTION:
 478                 return (0); /* function size is only known by symtab */
 479 
 480         case CTF_K_FORWARD:
 481                 return (0);
 482 
 483         case CTF_K_ENUM:
 484                 return (fp->ctf_dmodel->ctd_int);
 485 
 486         case CTF_K_ARRAY:
 487                 /*
 488                  * Array size is not directly returned by stabs data.  Instead,
 489                  * it defines the element type and requires the user to perform
 490                  * the multiplication.  If ctf_get_ctt_size() returns zero, the
 491                  * current version of ctfconvert does not compute member sizes
 492                  * and we compute the size here on its behalf.
 493                  */
 494                 if ((size = ctf_get_ctt_size(fp, tp, NULL, NULL)) > 0)
 495                         return (size);
 496 
 497                 if (ctf_array_info(fp, type, &ar) == CTF_ERR ||
 498                     (size = ctf_type_size(fp, ar.ctr_contents)) == CTF_ERR)
 499                         return (-1); /* errno is set for us */
 500 
 501                 return (size * ar.ctr_nelems);
 502         case CTF_K_STRUCT:
 503         case CTF_K_UNION:
 504                 /*
 505                  * If we have a zero size, we may be in the process of adding a
 506                  * structure or union but having not called ctf_update() to deal
 507                  * with the circular dependencies in such structures and unions.
 508                  * To handle that case, if we get a size of zero from the ctt,
 509                  * we look up the dtdef and use its size instead.
 510                  */
 511                 size = ctf_get_ctt_size(fp, tp, NULL, NULL);
 512                 if (size == 0) {
 513                         ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
 514                         if (dtd != NULL)
 515                                 return (dtd->dtd_data.ctt_size);
 516                 }
 517                 return (size);
 518         default:
 519                 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
 520         }
 521 }
 522 
 523 /*
 524  * Resolve the type down to a base type node, and then return the alignment
 525  * needed for the type storage in bytes.
 526  */
 527 ssize_t
 528 ctf_type_align(ctf_file_t *fp, ctf_id_t type)
 529 {
 530         const ctf_type_t *tp;
 531         ctf_arinfo_t r;
 532 
 533         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 534                 return (-1); /* errno is set for us */
 535 
 536         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 537                 return (-1); /* errno is set for us */
 538 
 539         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 540         case CTF_K_POINTER:
 541         case CTF_K_FUNCTION:
 542                 return (fp->ctf_dmodel->ctd_pointer);
 543 
 544         case CTF_K_ARRAY:
 545                 if (ctf_array_info(fp, type, &r) == CTF_ERR)
 546                         return (-1); /* errno is set for us */
 547                 return (ctf_type_align(fp, r.ctr_contents));
 548 
 549         case CTF_K_STRUCT:
 550         case CTF_K_UNION: {
 551                 uint_t n = LCTF_INFO_VLEN(fp, tp->ctt_info);
 552                 ssize_t size, increment;
 553                 size_t align = 0;
 554                 const void *vmp;
 555 
 556                 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
 557                 vmp = (uchar_t *)tp + increment;
 558 
 559                 if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_STRUCT)
 560                         n = MIN(n, 1); /* only use first member for structs */
 561 
 562                 if (fp->ctf_version == CTF_VERSION_1 ||
 563                     size < CTF_LSTRUCT_THRESH) {
 564                         const ctf_member_t *mp = vmp;
 565                         for (; n != 0; n--, mp++) {
 566                                 ssize_t am = ctf_type_align(fp, mp->ctm_type);
 567                                 align = MAX(align, am);
 568                         }
 569                 } else {
 570                         const ctf_lmember_t *lmp = vmp;
 571                         for (; n != 0; n--, lmp++) {
 572                                 ssize_t am = ctf_type_align(fp, lmp->ctlm_type);
 573                                 align = MAX(align, am);
 574                         }
 575                 }
 576 
 577                 return (align);
 578         }
 579 
 580         case CTF_K_ENUM:
 581                 return (fp->ctf_dmodel->ctd_int);
 582 
 583         default:
 584                 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
 585         }
 586 }
 587 
 588 /*
 589  * Return the kind (CTF_K_* constant) for the specified type ID.
 590  */
 591 int
 592 ctf_type_kind(ctf_file_t *fp, ctf_id_t type)
 593 {
 594         const ctf_type_t *tp;
 595 
 596         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 597                 return (CTF_ERR); /* errno is set for us */
 598 
 599         return (LCTF_INFO_KIND(fp, tp->ctt_info));
 600 }
 601 
 602 /*
 603  * If the type is one that directly references another type (such as POINTER),
 604  * then return the ID of the type to which it refers.
 605  */
 606 ctf_id_t
 607 ctf_type_reference(ctf_file_t *fp, ctf_id_t type)
 608 {
 609         ctf_file_t *ofp = fp;
 610         const ctf_type_t *tp;
 611 
 612         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 613                 return (CTF_ERR); /* errno is set for us */
 614 
 615         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 616         case CTF_K_POINTER:
 617         case CTF_K_TYPEDEF:
 618         case CTF_K_VOLATILE:
 619         case CTF_K_CONST:
 620         case CTF_K_RESTRICT:
 621                 return (tp->ctt_type);
 622         default:
 623                 return (ctf_set_errno(ofp, ECTF_NOTREF));
 624         }
 625 }
 626 
 627 /*
 628  * Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
 629  * pointer to the given type, see if we can compute a pointer to the type
 630  * resulting from resolving the type down to its base type and use that
 631  * instead.  This helps with cases where the CTF data includes "struct foo *"
 632  * but not "foo_t *" and the user accesses "foo_t *" in the debugger.
 633  */
 634 ctf_id_t
 635 ctf_type_pointer(ctf_file_t *fp, ctf_id_t type)
 636 {
 637         ctf_file_t *ofp = fp;
 638         ctf_id_t ntype;
 639 
 640         if (ctf_lookup_by_id(&fp, type) == NULL)
 641                 return (CTF_ERR); /* errno is set for us */
 642 
 643         if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
 644                 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
 645 
 646         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 647                 return (ctf_set_errno(ofp, ECTF_NOTYPE));
 648 
 649         if (ctf_lookup_by_id(&fp, type) == NULL)
 650                 return (ctf_set_errno(ofp, ECTF_NOTYPE));
 651 
 652         if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
 653                 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
 654 
 655         return (ctf_set_errno(ofp, ECTF_NOTYPE));
 656 }
 657 
 658 /*
 659  * Return the encoding for the specified INTEGER or FLOAT.
 660  */
 661 int
 662 ctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
 663 {
 664         ctf_file_t *ofp = fp;
 665         const ctf_type_t *tp;
 666         ssize_t increment;
 667         uint_t data;
 668 
 669         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 670                 return (CTF_ERR); /* errno is set for us */
 671 
 672         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
 673 
 674         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 675         case CTF_K_INTEGER:
 676                 data = *(const uint_t *)((uintptr_t)tp + increment);
 677                 ep->cte_format = CTF_INT_ENCODING(data);
 678                 ep->cte_offset = CTF_INT_OFFSET(data);
 679                 ep->cte_bits = CTF_INT_BITS(data);
 680                 break;
 681         case CTF_K_FLOAT:
 682                 data = *(const uint_t *)((uintptr_t)tp + increment);
 683                 ep->cte_format = CTF_FP_ENCODING(data);
 684                 ep->cte_offset = CTF_FP_OFFSET(data);
 685                 ep->cte_bits = CTF_FP_BITS(data);
 686                 break;
 687         default:
 688                 return (ctf_set_errno(ofp, ECTF_NOTINTFP));
 689         }
 690 
 691         return (0);
 692 }
 693 
 694 int
 695 ctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype)
 696 {
 697         int rval;
 698 
 699         if (ltype < rtype)
 700                 rval = -1;
 701         else if (ltype > rtype)
 702                 rval = 1;
 703         else
 704                 rval = 0;
 705 
 706         if (lfp == rfp)
 707                 return (rval);
 708 
 709         if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL)
 710                 lfp = lfp->ctf_parent;
 711 
 712         if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL)
 713                 rfp = rfp->ctf_parent;
 714 
 715         if (lfp < rfp)
 716                 return (-1);
 717 
 718         if (lfp > rfp)
 719                 return (1);
 720 
 721         return (rval);
 722 }
 723 
 724 /*
 725  * Return a boolean value indicating if two types are compatible integers or
 726  * floating-pointer values.  This function returns true if the two types are
 727  * the same, or if they have the same ASCII name and encoding properties.
 728  * This function could be extended to test for compatibility for other kinds.
 729  */
 730 int
 731 ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
 732     ctf_file_t *rfp, ctf_id_t rtype)
 733 {
 734         const ctf_type_t *ltp, *rtp;
 735         ctf_encoding_t le, re;
 736         ctf_arinfo_t la, ra;
 737         uint_t lkind, rkind;
 738 
 739         if (ctf_type_cmp(lfp, ltype, rfp, rtype) == 0)
 740                 return (1);
 741 
 742         ltype = ctf_type_resolve(lfp, ltype);
 743         lkind = ctf_type_kind(lfp, ltype);
 744 
 745         rtype = ctf_type_resolve(rfp, rtype);
 746         rkind = ctf_type_kind(rfp, rtype);
 747 
 748         if (lkind != rkind ||
 749             (ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL ||
 750             (rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL ||
 751             strcmp(ctf_strptr(lfp, ltp->ctt_name),
 752             ctf_strptr(rfp, rtp->ctt_name)) != 0)
 753                 return (0);
 754 
 755         switch (lkind) {
 756         case CTF_K_INTEGER:
 757         case CTF_K_FLOAT:
 758                 return (ctf_type_encoding(lfp, ltype, &le) == 0 &&
 759                     ctf_type_encoding(rfp, rtype, &re) == 0 &&
 760                     bcmp(&le, &re, sizeof (ctf_encoding_t)) == 0);
 761         case CTF_K_POINTER:
 762                 return (ctf_type_compat(lfp, ctf_type_reference(lfp, ltype),
 763                     rfp, ctf_type_reference(rfp, rtype)));
 764         case CTF_K_ARRAY:
 765                 return (ctf_array_info(lfp, ltype, &la) == 0 &&
 766                     ctf_array_info(rfp, rtype, &ra) == 0 &&
 767                     la.ctr_nelems == ra.ctr_nelems && ctf_type_compat(
 768                     lfp, la.ctr_contents, rfp, ra.ctr_contents) &&
 769                     ctf_type_compat(lfp, la.ctr_index, rfp, ra.ctr_index));
 770         case CTF_K_STRUCT:
 771         case CTF_K_UNION:
 772                 return (ctf_type_size(lfp, ltype) == ctf_type_size(rfp, rtype));
 773         case CTF_K_ENUM:
 774         case CTF_K_FORWARD:
 775                 return (1); /* no other checks required for these type kinds */
 776         default:
 777                 return (0); /* should not get here since we did a resolve */
 778         }
 779 }
 780 
 781 /*
 782  * Return the type and offset for a given member of a STRUCT or UNION.
 783  */
 784 int
 785 ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
 786     ctf_membinfo_t *mip)
 787 {
 788         ctf_file_t *ofp = fp;
 789         const ctf_type_t *tp;
 790         ssize_t size, increment;
 791         uint_t kind, n;
 792 
 793         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 794                 return (CTF_ERR); /* errno is set for us */
 795 
 796         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 797                 return (CTF_ERR); /* errno is set for us */
 798 
 799         (void) ctf_get_ctt_size(fp, tp, &size, &increment);
 800         kind = LCTF_INFO_KIND(fp, tp->ctt_info);
 801 
 802         if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
 803                 return (ctf_set_errno(ofp, ECTF_NOTSOU));
 804 
 805         if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
 806                 const ctf_member_t *mp = (const ctf_member_t *)
 807                     ((uintptr_t)tp + increment);
 808 
 809                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
 810                         if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {
 811                                 mip->ctm_type = mp->ctm_type;
 812                                 mip->ctm_offset = mp->ctm_offset;
 813                                 return (0);
 814                         }
 815                 }
 816         } else {
 817                 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
 818                     ((uintptr_t)tp + increment);
 819 
 820                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
 821                         if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {
 822                                 mip->ctm_type = lmp->ctlm_type;
 823                                 mip->ctm_offset = (ulong_t)CTF_LMEM_OFFSET(lmp);
 824                                 return (0);
 825                         }
 826                 }
 827         }
 828 
 829         return (ctf_set_errno(ofp, ECTF_NOMEMBNAM));
 830 }
 831 
 832 /*
 833  * Return the array type, index, and size information for the specified ARRAY.
 834  */
 835 int
 836 ctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
 837 {
 838         ctf_file_t *ofp = fp;
 839         const ctf_type_t *tp;
 840         const ctf_array_t *ap;
 841         ssize_t increment;
 842 
 843         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 844                 return (CTF_ERR); /* errno is set for us */
 845 
 846         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY)
 847                 return (ctf_set_errno(ofp, ECTF_NOTARRAY));
 848 
 849         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
 850 
 851         ap = (const ctf_array_t *)((uintptr_t)tp + increment);
 852         arp->ctr_contents = ap->cta_contents;
 853         arp->ctr_index = ap->cta_index;
 854         arp->ctr_nelems = ap->cta_nelems;
 855 
 856         return (0);
 857 }
 858 
 859 /*
 860  * Convert the specified value to the corresponding enum member name, if a
 861  * matching name can be found.  Otherwise NULL is returned.
 862  */
 863 const char *
 864 ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
 865 {
 866         ctf_file_t *ofp = fp;
 867         const ctf_type_t *tp;
 868         const ctf_enum_t *ep;
 869         ssize_t increment;
 870         uint_t n;
 871 
 872         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 873                 return (NULL); /* errno is set for us */
 874 
 875         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 876                 return (NULL); /* errno is set for us */
 877 
 878         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
 879                 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
 880                 return (NULL);
 881         }
 882 
 883         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
 884 
 885         ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
 886 
 887         for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
 888                 if (ep->cte_value == value)
 889                         return (ctf_strptr(fp, ep->cte_name));
 890         }
 891 
 892         (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
 893         return (NULL);
 894 }
 895 
 896 /*
 897  * Convert the specified enum tag name to the corresponding value, if a
 898  * matching name can be found.  Otherwise CTF_ERR is returned.
 899  */
 900 int
 901 ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
 902 {
 903         ctf_file_t *ofp = fp;
 904         const ctf_type_t *tp;
 905         const ctf_enum_t *ep;
 906         ssize_t size, increment;
 907         uint_t n;
 908 
 909         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 910                 return (CTF_ERR); /* errno is set for us */
 911 
 912         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 913                 return (CTF_ERR); /* errno is set for us */
 914 
 915         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
 916                 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
 917                 return (CTF_ERR);
 918         }
 919 
 920         (void) ctf_get_ctt_size(fp, tp, &size, &increment);
 921 
 922         ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
 923 
 924         for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
 925                 if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) {
 926                         if (valp != NULL)
 927                                 *valp = ep->cte_value;
 928                         return (0);
 929                 }
 930         }
 931 
 932         (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
 933         return (CTF_ERR);
 934 }
 935 
 936 /*
 937  * Recursively visit the members of any type.  This function is used as the
 938  * engine for ctf_type_visit, below.  We resolve the input type, recursively
 939  * invoke ourself for each type member if the type is a struct or union, and
 940  * then invoke the callback function on the current type.  If any callback
 941  * returns non-zero, we abort and percolate the error code back up to the top.
 942  */
 943 static int
 944 ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,
 945     const char *name, ulong_t offset, int depth)
 946 {
 947         ctf_id_t otype = type;
 948         const ctf_type_t *tp;
 949         ssize_t size, increment;
 950         uint_t kind, n;
 951         int rc;
 952 
 953         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 954                 return (CTF_ERR); /* errno is set for us */
 955 
 956         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 957                 return (CTF_ERR); /* errno is set for us */
 958 
 959         if ((rc = func(name, otype, offset, depth, arg)) != 0)
 960                 return (rc);
 961 
 962         kind = LCTF_INFO_KIND(fp, tp->ctt_info);
 963 
 964         if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
 965                 return (0);
 966 
 967         (void) ctf_get_ctt_size(fp, tp, &size, &increment);
 968 
 969         if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
 970                 const ctf_member_t *mp = (const ctf_member_t *)
 971                     ((uintptr_t)tp + increment);
 972 
 973                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
 974                         if ((rc = ctf_type_rvisit(fp, mp->ctm_type,
 975                             func, arg, ctf_strptr(fp, mp->ctm_name),
 976                             offset + mp->ctm_offset, depth + 1)) != 0)
 977                                 return (rc);
 978                 }
 979 
 980         } else {
 981                 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
 982                     ((uintptr_t)tp + increment);
 983 
 984                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
 985                         if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type,
 986                             func, arg, ctf_strptr(fp, lmp->ctlm_name),
 987                             offset + (ulong_t)CTF_LMEM_OFFSET(lmp),
 988                             depth + 1)) != 0)
 989                                 return (rc);
 990                 }
 991         }
 992 
 993         return (0);
 994 }
 995 
 996 /*
 997  * Recursively visit the members of any type.  We pass the name, member
 998  * type, and offset of each member to the specified callback function.
 999  */
1000 int
1001 ctf_type_visit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1002 {
1003         return (ctf_type_rvisit(fp, type, func, arg, "", 0, 0));
1004 }
1005 
1006 int
1007 ctf_func_info_by_id(ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1008 {
1009         ctf_file_t *ofp = fp;
1010         const ctf_type_t *tp;
1011         const ushort_t *dp;
1012         int nargs;
1013         ssize_t increment;
1014 
1015         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
1016                 return (CTF_ERR); /* errno is set for us */
1017 
1018         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_FUNCTION)
1019                 return (ctf_set_errno(ofp, ECTF_NOTFUNC));
1020 
1021         fip->ctc_return = tp->ctt_type;
1022         nargs = LCTF_INFO_VLEN(fp, tp->ctt_info);
1023         fip->ctc_argc = nargs;
1024         fip->ctc_flags = 0;
1025 
1026         /* dp should now point to the first argument */
1027         if (nargs != 0) {
1028                 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
1029                 dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1030                     fp->ctf_txlate[CTF_TYPE_TO_INDEX(type)] + increment);
1031                 if (dp[nargs - 1] == 0) {
1032                         fip->ctc_flags |= CTF_FUNC_VARARG;
1033                         fip->ctc_argc--;
1034                 }
1035         }
1036 
1037         return (0);
1038 }
1039 
1040 int
1041 ctf_func_args_by_id(ctf_file_t *fp, ctf_id_t type, uint_t argc, ctf_id_t *argv)
1042 {
1043         ctf_file_t *ofp = fp;
1044         const ctf_type_t *tp;
1045         const ushort_t *dp;
1046         int nargs;
1047         ssize_t increment;
1048 
1049         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
1050                 return (CTF_ERR); /* errno is set for us */
1051 
1052         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_FUNCTION)
1053                 return (ctf_set_errno(ofp, ECTF_NOTFUNC));
1054 
1055         nargs = LCTF_INFO_VLEN(fp, tp->ctt_info);
1056         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
1057         dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1058             fp->ctf_txlate[CTF_TYPE_TO_INDEX(type)] +
1059             increment);
1060         if (nargs != 0 && dp[nargs - 1] == 0)
1061                 nargs--;
1062 
1063         for (nargs = MIN(argc, nargs); nargs != 0; nargs--)
1064                 *argv++ = *dp++;
1065 
1066         return (0);
1067 }
1068 
1069 int
1070 ctf_object_iter(ctf_file_t *fp, ctf_object_f *func, void *arg)
1071 {
1072         int i, ret;
1073         ctf_id_t id;
1074         uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1075         uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1076 
1077         if (fp->ctf_symtab.cts_data == NULL)
1078                 return (ctf_set_errno(fp, ECTF_NOSYMTAB));
1079 
1080         for (i = 0; i < fp->ctf_nsyms; i++) {
1081                 char *name;
1082                 if (fp->ctf_sxlate[i] == -1u)
1083                         continue;
1084                 id = *(ushort_t *)((uintptr_t)fp->ctf_buf +
1085                     fp->ctf_sxlate[i]);
1086 
1087                 /*
1088                  * Validate whether or not we're looking at a data object as
1089                  * oposed to a function.
1090                  */
1091                 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1092                         const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
1093                         if (ELF32_ST_TYPE(symp->st_info) != STT_OBJECT)
1094                                 continue;
1095                         if (fp->ctf_strtab.cts_data != NULL &&
1096                             symp->st_name != 0)
1097                                 name = (char *)(strbase + symp->st_name);
1098                         else
1099                                 name = NULL;
1100                 } else {
1101                         const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
1102                         if (ELF64_ST_TYPE(symp->st_info) != STT_OBJECT)
1103                                 continue;
1104                         if (fp->ctf_strtab.cts_data != NULL &&
1105                             symp->st_name != 0)
1106                                 name = (char *)(strbase + symp->st_name);
1107                         else
1108                                 name = NULL;
1109                 }
1110 
1111                 if ((ret = func(name, id, i, arg)) != 0)
1112                         return (ret);
1113         }
1114 
1115         return (0);
1116 }
1117 
1118 int
1119 ctf_function_iter(ctf_file_t *fp, ctf_function_f *func, void *arg)
1120 {
1121         int i, ret;
1122         uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1123         uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1124 
1125         if (fp->ctf_symtab.cts_data == NULL)
1126                 return (ctf_set_errno(fp, ECTF_NOSYMTAB));
1127 
1128         for (i = 0; i < fp->ctf_nsyms; i++) {
1129                 char *name;
1130                 ushort_t info, *dp;
1131                 ctf_funcinfo_t fi;
1132                 if (fp->ctf_sxlate[i] == -1u)
1133                         continue;
1134 
1135                 dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1136                     fp->ctf_sxlate[i]);
1137                 info = *dp;
1138                 if (info == 0)
1139                         continue;
1140 
1141                 /*
1142                  * This may be a function or it may be a data object. We have to
1143                  * consult the symbol table to be certain. Functions are encoded
1144                  * with their info, data objects with their actual type.
1145                  */
1146                 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1147                         const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
1148                         if (ELF32_ST_TYPE(symp->st_info) != STT_FUNC)
1149                                 continue;
1150                         if (fp->ctf_strtab.cts_data != NULL)
1151                                 name = (char *)(strbase + symp->st_name);
1152                         else
1153                                 name = NULL;
1154                 } else {
1155                         const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
1156                         if (ELF64_ST_TYPE(symp->st_info) != STT_FUNC)
1157                                 continue;
1158                         if (fp->ctf_strtab.cts_data != NULL)
1159                                 name = (char *)(strbase + symp->st_name);
1160                         else
1161                                 name = NULL;
1162                 }
1163 
1164                 if (LCTF_INFO_KIND(fp, info) != CTF_K_FUNCTION)
1165                         continue;
1166                 dp++;
1167                 fi.ctc_return = *dp;
1168                 dp++;
1169                 fi.ctc_argc = LCTF_INFO_VLEN(fp, info);
1170                 fi.ctc_flags = 0;
1171 
1172                 if (fi.ctc_argc != 0 && dp[fi.ctc_argc - 1] == 0) {
1173                         fi.ctc_flags |= CTF_FUNC_VARARG;
1174                         fi.ctc_argc--;
1175                 }
1176 
1177                 if ((ret = func(name, i, &fi, arg)) != 0)
1178                         return (ret);
1179 
1180         }
1181 
1182         return (0);
1183 }
1184 
1185 char *
1186 ctf_symbol_name(ctf_file_t *fp, ulong_t idx, char *buf, size_t len)
1187 {
1188         const char *name;
1189         uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1190         uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1191 
1192         if (fp->ctf_symtab.cts_data == NULL) {
1193                 (void) ctf_set_errno(fp, ECTF_NOSYMTAB);
1194                 return (NULL);
1195         }
1196 
1197         if (fp->ctf_strtab.cts_data == NULL) {
1198                 (void) ctf_set_errno(fp, ECTF_STRTAB);
1199                 return (NULL);
1200         }
1201 
1202         if (idx > fp->ctf_nsyms) {
1203                 (void) ctf_set_errno(fp, ECTF_NOTDATA);
1204                 return (NULL);
1205         }
1206 
1207         if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1208                 const Elf32_Sym *symp = (Elf32_Sym *)symbase + idx;
1209                 if (ELF32_ST_TYPE(symp->st_info) != STT_OBJECT &&
1210                     ELF32_ST_TYPE(symp->st_info) != STT_FUNC) {
1211                         (void) ctf_set_errno(fp, ECTF_NOTDATA);
1212                         return (NULL);
1213                 }
1214                 if (symp->st_name == 0) {
1215                         (void) ctf_set_errno(fp, ENOENT);
1216                         return (NULL);
1217                 }
1218                 name = (const char *)(strbase + symp->st_name);
1219         } else {
1220                 const Elf64_Sym *symp = (Elf64_Sym *)symbase + idx;
1221                 if (ELF64_ST_TYPE(symp->st_info) != STT_FUNC &&
1222                     ELF64_ST_TYPE(symp->st_info) != STT_OBJECT) {
1223                         (void) ctf_set_errno(fp, ECTF_NOTDATA);
1224                         return (NULL);
1225                 }
1226                 if (symp->st_name == 0) {
1227                         (void) ctf_set_errno(fp, ENOENT);
1228                         return (NULL);
1229                 }
1230                 name = (const char *)(strbase + symp->st_name);
1231         }
1232 
1233         (void) strlcpy(buf, name, len);
1234 
1235         return (buf);
1236 }
1237 
1238 int
1239 ctf_string_iter(ctf_file_t *fp, ctf_string_f *func, void *arg)
1240 {
1241         int rc;
1242         const char *strp = fp->ctf_str[CTF_STRTAB_0].cts_strs;
1243         size_t strl = fp->ctf_str[CTF_STRTAB_0].cts_len;
1244 
1245         while (strl > 0) {
1246                 size_t len;
1247 
1248                 if ((rc = func(strp, arg)) != 0)
1249                         return (rc);
1250 
1251                 len = strlen(strp) + 1;
1252                 strl -= len;
1253                 strp += len;
1254         }
1255 
1256         return (0);
1257 }
1258 
1259 /*
1260  * fp isn't strictly necessary at the moment. However, if we ever rev the file
1261  * format, the valid values for kind will change.
1262  */
1263 const char *
1264 ctf_kind_name(ctf_file_t *fp, int kind)
1265 {
1266         switch (kind) {
1267         case CTF_K_INTEGER:
1268                 return ("integer");
1269         case CTF_K_FLOAT:
1270                 return ("float");
1271         case CTF_K_POINTER:
1272                 return ("pointer");
1273         case CTF_K_ARRAY:
1274                 return ("array");
1275         case CTF_K_FUNCTION:
1276                 return ("function");
1277         case CTF_K_STRUCT:
1278                 return ("struct");
1279         case CTF_K_UNION:
1280                 return ("union");
1281         case CTF_K_ENUM:
1282                 return ("enum");
1283         case CTF_K_FORWARD:
1284                 return ("forward");
1285         case CTF_K_TYPEDEF:
1286                 return ("typedef");
1287         case CTF_K_VOLATILE:
1288                 return ("volatile");
1289         case CTF_K_CONST:
1290                 return ("const");
1291         case CTF_K_RESTRICT:
1292                 return ("restrict");
1293         case CTF_K_UNKNOWN:
1294         default:
1295                 return ("unknown");
1296         }
1297 }
1298 
1299 ctf_id_t
1300 ctf_max_id(ctf_file_t *fp)
1301 {
1302         int child = (fp->ctf_flags & LCTF_CHILD);
1303         return (fp->ctf_typemax + (child ? CTF_CHILD_START : 0));
1304 }
1305 
1306 ulong_t
1307 ctf_nr_syms(ctf_file_t *fp)
1308 {
1309         return (fp->ctf_nsyms);
1310 }