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 2020 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 (ctf_get_ctt_size(fp, tp, NULL, NULL));
 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         default:
 582                 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
 583         }
 584 }
 585 
 586 /*
 587  * Return the kind (CTF_K_* constant) for the specified type ID.
 588  */
 589 int
 590 ctf_type_kind(ctf_file_t *fp, ctf_id_t type)
 591 {
 592         const ctf_type_t *tp;
 593 
 594         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 595                 return (CTF_ERR); /* errno is set for us */
 596 
 597         return (LCTF_INFO_KIND(fp, tp->ctt_info));
 598 }
 599 
 600 /*
 601  * If the type is one that directly references another type (such as POINTER),
 602  * then return the ID of the type to which it refers.
 603  */
 604 ctf_id_t
 605 ctf_type_reference(ctf_file_t *fp, ctf_id_t type)
 606 {
 607         ctf_file_t *ofp = fp;
 608         const ctf_type_t *tp;
 609 
 610         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 611                 return (CTF_ERR); /* errno is set for us */
 612 
 613         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 614         case CTF_K_POINTER:
 615         case CTF_K_TYPEDEF:
 616         case CTF_K_VOLATILE:
 617         case CTF_K_CONST:
 618         case CTF_K_RESTRICT:
 619                 return (tp->ctt_type);
 620         default:
 621                 return (ctf_set_errno(ofp, ECTF_NOTREF));
 622         }
 623 }
 624 
 625 /*
 626  * Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
 627  * pointer to the given type, see if we can compute a pointer to the type
 628  * resulting from resolving the type down to its base type and use that
 629  * instead.  This helps with cases where the CTF data includes "struct foo *"
 630  * but not "foo_t *" and the user accesses "foo_t *" in the debugger.
 631  */
 632 ctf_id_t
 633 ctf_type_pointer(ctf_file_t *fp, ctf_id_t type)
 634 {
 635         ctf_file_t *ofp = fp;
 636         ctf_id_t ntype;
 637 
 638         if (ctf_lookup_by_id(&fp, type) == NULL)
 639                 return (CTF_ERR); /* errno is set for us */
 640 
 641         if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
 642                 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
 643 
 644         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 645                 return (ctf_set_errno(ofp, ECTF_NOTYPE));
 646 
 647         if (ctf_lookup_by_id(&fp, type) == NULL)
 648                 return (ctf_set_errno(ofp, ECTF_NOTYPE));
 649 
 650         if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
 651                 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
 652 
 653         return (ctf_set_errno(ofp, ECTF_NOTYPE));
 654 }
 655 
 656 /*
 657  * Return the encoding for the specified INTEGER or FLOAT.
 658  */
 659 int
 660 ctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
 661 {
 662         ctf_file_t *ofp = fp;
 663         const ctf_type_t *tp;
 664         ssize_t increment;
 665         uint_t data;
 666 
 667         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 668                 return (CTF_ERR); /* errno is set for us */
 669 
 670         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
 671 
 672         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 673         case CTF_K_INTEGER:
 674                 data = *(const uint_t *)((uintptr_t)tp + increment);
 675                 ep->cte_format = CTF_INT_ENCODING(data);
 676                 ep->cte_offset = CTF_INT_OFFSET(data);
 677                 ep->cte_bits = CTF_INT_BITS(data);
 678                 break;
 679         case CTF_K_FLOAT:
 680                 data = *(const uint_t *)((uintptr_t)tp + increment);
 681                 ep->cte_format = CTF_FP_ENCODING(data);
 682                 ep->cte_offset = CTF_FP_OFFSET(data);
 683                 ep->cte_bits = CTF_FP_BITS(data);
 684                 break;
 685         default:
 686                 return (ctf_set_errno(ofp, ECTF_NOTINTFP));
 687         }
 688 
 689         return (0);
 690 }
 691 
 692 int
 693 ctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype)
 694 {
 695         int rval;
 696 
 697         if (ltype < rtype)
 698                 rval = -1;
 699         else if (ltype > rtype)
 700                 rval = 1;
 701         else
 702                 rval = 0;
 703 
 704         if (lfp == rfp)
 705                 return (rval);
 706 
 707         if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL)
 708                 lfp = lfp->ctf_parent;
 709 
 710         if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL)
 711                 rfp = rfp->ctf_parent;
 712 
 713         if (lfp < rfp)
 714                 return (-1);
 715 
 716         if (lfp > rfp)
 717                 return (1);
 718 
 719         return (rval);
 720 }
 721 
 722 /*
 723  * Return a boolean value indicating if two types are compatible integers or
 724  * floating-pointer values.  This function returns true if the two types are
 725  * the same, or if they have the same ASCII name and encoding properties.
 726  * This function could be extended to test for compatibility for other kinds.
 727  */
 728 int
 729 ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
 730     ctf_file_t *rfp, ctf_id_t rtype)
 731 {
 732         const ctf_type_t *ltp, *rtp;
 733         ctf_encoding_t le, re;
 734         ctf_arinfo_t la, ra;
 735         uint_t lkind, rkind;
 736 
 737         if (ctf_type_cmp(lfp, ltype, rfp, rtype) == 0)
 738                 return (1);
 739 
 740         ltype = ctf_type_resolve(lfp, ltype);
 741         lkind = ctf_type_kind(lfp, ltype);
 742 
 743         rtype = ctf_type_resolve(rfp, rtype);
 744         rkind = ctf_type_kind(rfp, rtype);
 745 
 746         if (lkind != rkind ||
 747             (ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL ||
 748             (rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL ||
 749             strcmp(ctf_strptr(lfp, ltp->ctt_name),
 750             ctf_strptr(rfp, rtp->ctt_name)) != 0)
 751                 return (0);
 752 
 753         switch (lkind) {
 754         case CTF_K_INTEGER:
 755         case CTF_K_FLOAT:
 756                 return (ctf_type_encoding(lfp, ltype, &le) == 0 &&
 757                     ctf_type_encoding(rfp, rtype, &re) == 0 &&
 758                     bcmp(&le, &re, sizeof (ctf_encoding_t)) == 0);
 759         case CTF_K_POINTER:
 760                 return (ctf_type_compat(lfp, ctf_type_reference(lfp, ltype),
 761                     rfp, ctf_type_reference(rfp, rtype)));
 762         case CTF_K_ARRAY:
 763                 return (ctf_array_info(lfp, ltype, &la) == 0 &&
 764                     ctf_array_info(rfp, rtype, &ra) == 0 &&
 765                     la.ctr_nelems == ra.ctr_nelems && ctf_type_compat(
 766                     lfp, la.ctr_contents, rfp, ra.ctr_contents) &&
 767                     ctf_type_compat(lfp, la.ctr_index, rfp, ra.ctr_index));
 768         case CTF_K_STRUCT:
 769         case CTF_K_UNION:
 770                 return (ctf_type_size(lfp, ltype) == ctf_type_size(rfp, rtype));
 771         case CTF_K_ENUM:
 772         case CTF_K_FORWARD:
 773                 return (1); /* no other checks required for these type kinds */
 774         default:
 775                 return (0); /* should not get here since we did a resolve */
 776         }
 777 }
 778 
 779 /*
 780  * Return the type and offset for a given member of a STRUCT or UNION.
 781  */
 782 int
 783 ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
 784     ctf_membinfo_t *mip)
 785 {
 786         ctf_file_t *ofp = fp;
 787         const ctf_type_t *tp;
 788         ssize_t size, increment;
 789         uint_t kind, n;
 790 
 791         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 792                 return (CTF_ERR); /* errno is set for us */
 793 
 794         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 795                 return (CTF_ERR); /* errno is set for us */
 796 
 797         (void) ctf_get_ctt_size(fp, tp, &size, &increment);
 798         kind = LCTF_INFO_KIND(fp, tp->ctt_info);
 799 
 800         if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
 801                 return (ctf_set_errno(ofp, ECTF_NOTSOU));
 802 
 803         if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
 804                 const ctf_member_t *mp = (const ctf_member_t *)
 805                     ((uintptr_t)tp + increment);
 806 
 807                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
 808                         if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {
 809                                 mip->ctm_type = mp->ctm_type;
 810                                 mip->ctm_offset = mp->ctm_offset;
 811                                 return (0);
 812                         }
 813                 }
 814         } else {
 815                 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
 816                     ((uintptr_t)tp + increment);
 817 
 818                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
 819                         if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {
 820                                 mip->ctm_type = lmp->ctlm_type;
 821                                 mip->ctm_offset = (ulong_t)CTF_LMEM_OFFSET(lmp);
 822                                 return (0);
 823                         }
 824                 }
 825         }
 826 
 827         return (ctf_set_errno(ofp, ECTF_NOMEMBNAM));
 828 }
 829 
 830 /*
 831  * Return the array type, index, and size information for the specified ARRAY.
 832  */
 833 int
 834 ctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
 835 {
 836         ctf_file_t *ofp = fp;
 837         const ctf_type_t *tp;
 838         const ctf_array_t *ap;
 839         ssize_t increment;
 840 
 841         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 842                 return (CTF_ERR); /* errno is set for us */
 843 
 844         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY)
 845                 return (ctf_set_errno(ofp, ECTF_NOTARRAY));
 846 
 847         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
 848 
 849         ap = (const ctf_array_t *)((uintptr_t)tp + increment);
 850         arp->ctr_contents = ap->cta_contents;
 851         arp->ctr_index = ap->cta_index;
 852         arp->ctr_nelems = ap->cta_nelems;
 853 
 854         return (0);
 855 }
 856 
 857 /*
 858  * Convert the specified value to the corresponding enum member name, if a
 859  * matching name can be found.  Otherwise NULL is returned.
 860  */
 861 const char *
 862 ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
 863 {
 864         ctf_file_t *ofp = fp;
 865         const ctf_type_t *tp;
 866         const ctf_enum_t *ep;
 867         ssize_t increment;
 868         uint_t n;
 869 
 870         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 871                 return (NULL); /* errno is set for us */
 872 
 873         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 874                 return (NULL); /* errno is set for us */
 875 
 876         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
 877                 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
 878                 return (NULL);
 879         }
 880 
 881         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
 882 
 883         ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
 884 
 885         for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
 886                 if (ep->cte_value == value)
 887                         return (ctf_strptr(fp, ep->cte_name));
 888         }
 889 
 890         (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
 891         return (NULL);
 892 }
 893 
 894 /*
 895  * Convert the specified enum tag name to the corresponding value, if a
 896  * matching name can be found.  Otherwise CTF_ERR is returned.
 897  */
 898 int
 899 ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
 900 {
 901         ctf_file_t *ofp = fp;
 902         const ctf_type_t *tp;
 903         const ctf_enum_t *ep;
 904         ssize_t size, increment;
 905         uint_t n;
 906 
 907         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 908                 return (CTF_ERR); /* errno is set for us */
 909 
 910         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 911                 return (CTF_ERR); /* errno is set for us */
 912 
 913         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
 914                 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
 915                 return (CTF_ERR);
 916         }
 917 
 918         (void) ctf_get_ctt_size(fp, tp, &size, &increment);
 919 
 920         ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
 921 
 922         for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
 923                 if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) {
 924                         if (valp != NULL)
 925                                 *valp = ep->cte_value;
 926                         return (0);
 927                 }
 928         }
 929 
 930         (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
 931         return (CTF_ERR);
 932 }
 933 
 934 /*
 935  * Recursively visit the members of any type.  This function is used as the
 936  * engine for ctf_type_visit, below.  We resolve the input type, recursively
 937  * invoke ourself for each type member if the type is a struct or union, and
 938  * then invoke the callback function on the current type.  If any callback
 939  * returns non-zero, we abort and percolate the error code back up to the top.
 940  */
 941 static int
 942 ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,
 943     const char *name, ulong_t offset, int depth)
 944 {
 945         ctf_id_t otype = type;
 946         const ctf_type_t *tp;
 947         ssize_t size, increment;
 948         uint_t kind, n;
 949         int rc;
 950 
 951         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 952                 return (CTF_ERR); /* errno is set for us */
 953 
 954         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 955                 return (CTF_ERR); /* errno is set for us */
 956 
 957         if ((rc = func(name, otype, offset, depth, arg)) != 0)
 958                 return (rc);
 959 
 960         kind = LCTF_INFO_KIND(fp, tp->ctt_info);
 961 
 962         if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
 963                 return (0);
 964 
 965         (void) ctf_get_ctt_size(fp, tp, &size, &increment);
 966 
 967         if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
 968                 const ctf_member_t *mp = (const ctf_member_t *)
 969                     ((uintptr_t)tp + increment);
 970 
 971                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
 972                         if ((rc = ctf_type_rvisit(fp, mp->ctm_type,
 973                             func, arg, ctf_strptr(fp, mp->ctm_name),
 974                             offset + mp->ctm_offset, depth + 1)) != 0)
 975                                 return (rc);
 976                 }
 977 
 978         } else {
 979                 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
 980                     ((uintptr_t)tp + increment);
 981 
 982                 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
 983                         if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type,
 984                             func, arg, ctf_strptr(fp, lmp->ctlm_name),
 985                             offset + (ulong_t)CTF_LMEM_OFFSET(lmp),
 986                             depth + 1)) != 0)
 987                                 return (rc);
 988                 }
 989         }
 990 
 991         return (0);
 992 }
 993 
 994 /*
 995  * Recursively visit the members of any type.  We pass the name, member
 996  * type, and offset of each member to the specified callback function.
 997  */
 998 int
 999 ctf_type_visit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1000 {
1001         return (ctf_type_rvisit(fp, type, func, arg, "", 0, 0));
1002 }
1003 
1004 int
1005 ctf_func_info_by_id(ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1006 {
1007         ctf_file_t *ofp = fp;
1008         const ctf_type_t *tp;
1009         const ushort_t *dp;
1010         int nargs;
1011         ssize_t increment;
1012 
1013         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
1014                 return (CTF_ERR); /* errno is set for us */
1015 
1016         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_FUNCTION)
1017                 return (ctf_set_errno(ofp, ECTF_NOTFUNC));
1018 
1019         fip->ctc_return = tp->ctt_type;
1020         nargs = LCTF_INFO_VLEN(fp, tp->ctt_info);
1021         fip->ctc_argc = nargs;
1022         fip->ctc_flags = 0;
1023 
1024         /* dp should now point to the first argument */
1025         if (nargs != 0) {
1026                 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
1027                 dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1028                     fp->ctf_txlate[CTF_TYPE_TO_INDEX(type)] + increment);
1029                 if (dp[nargs - 1] == 0) {
1030                         fip->ctc_flags |= CTF_FUNC_VARARG;
1031                         fip->ctc_argc--;
1032                 }
1033         }
1034 
1035         return (0);
1036 }
1037 
1038 int
1039 ctf_func_args_by_id(ctf_file_t *fp, ctf_id_t type, uint_t argc, ctf_id_t *argv)
1040 {
1041         ctf_file_t *ofp = fp;
1042         const ctf_type_t *tp;
1043         const ushort_t *dp;
1044         int nargs;
1045         ssize_t increment;
1046 
1047         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
1048                 return (CTF_ERR); /* errno is set for us */
1049 
1050         if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_FUNCTION)
1051                 return (ctf_set_errno(ofp, ECTF_NOTFUNC));
1052 
1053         nargs = LCTF_INFO_VLEN(fp, tp->ctt_info);
1054         (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
1055         dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1056             fp->ctf_txlate[CTF_TYPE_TO_INDEX(type)] +
1057             increment);
1058         if (nargs != 0 && dp[nargs - 1] == 0)
1059                 nargs--;
1060 
1061         for (nargs = MIN(argc, nargs); nargs != 0; nargs--)
1062                 *argv++ = *dp++;
1063 
1064         return (0);
1065 }
1066 
1067 int
1068 ctf_object_iter(ctf_file_t *fp, ctf_object_f *func, void *arg)
1069 {
1070         int i, ret;
1071         ctf_id_t id;
1072         uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1073         uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1074 
1075         if (fp->ctf_symtab.cts_data == NULL)
1076                 return (ctf_set_errno(fp, ECTF_NOSYMTAB));
1077 
1078         for (i = 0; i < fp->ctf_nsyms; i++) {
1079                 char *name;
1080                 if (fp->ctf_sxlate[i] == -1u)
1081                         continue;
1082                 id = *(ushort_t *)((uintptr_t)fp->ctf_buf +
1083                     fp->ctf_sxlate[i]);
1084 
1085                 /*
1086                  * Validate whether or not we're looking at a data object as
1087                  * oposed to a function.
1088                  */
1089                 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1090                         const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
1091                         if (ELF32_ST_TYPE(symp->st_info) != STT_OBJECT)
1092                                 continue;
1093                         if (fp->ctf_strtab.cts_data != NULL &&
1094                             symp->st_name != 0)
1095                                 name = (char *)(strbase + symp->st_name);
1096                         else
1097                                 name = NULL;
1098                 } else {
1099                         const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
1100                         if (ELF64_ST_TYPE(symp->st_info) != STT_OBJECT)
1101                                 continue;
1102                         if (fp->ctf_strtab.cts_data != NULL &&
1103                             symp->st_name != 0)
1104                                 name = (char *)(strbase + symp->st_name);
1105                         else
1106                                 name = NULL;
1107                 }
1108 
1109                 if ((ret = func(name, id, i, arg)) != 0)
1110                         return (ret);
1111         }
1112 
1113         return (0);
1114 }
1115 
1116 int
1117 ctf_function_iter(ctf_file_t *fp, ctf_function_f *func, void *arg)
1118 {
1119         int i, ret;
1120         uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1121         uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1122 
1123         if (fp->ctf_symtab.cts_data == NULL)
1124                 return (ctf_set_errno(fp, ECTF_NOSYMTAB));
1125 
1126         for (i = 0; i < fp->ctf_nsyms; i++) {
1127                 char *name;
1128                 ushort_t info, *dp;
1129                 ctf_funcinfo_t fi;
1130                 if (fp->ctf_sxlate[i] == -1u)
1131                         continue;
1132 
1133                 dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1134                     fp->ctf_sxlate[i]);
1135                 info = *dp;
1136                 if (info == 0)
1137                         continue;
1138 
1139                 /*
1140                  * This may be a function or it may be a data object. We have to
1141                  * consult the symbol table to be certain. Functions are encoded
1142                  * with their info, data objects with their actual type.
1143                  */
1144                 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1145                         const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
1146                         if (ELF32_ST_TYPE(symp->st_info) != STT_FUNC)
1147                                 continue;
1148                         if (fp->ctf_strtab.cts_data != NULL)
1149                                 name = (char *)(strbase + symp->st_name);
1150                         else
1151                                 name = NULL;
1152                 } else {
1153                         const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
1154                         if (ELF64_ST_TYPE(symp->st_info) != STT_FUNC)
1155                                 continue;
1156                         if (fp->ctf_strtab.cts_data != NULL)
1157                                 name = (char *)(strbase + symp->st_name);
1158                         else
1159                                 name = NULL;
1160                 }
1161 
1162                 if (LCTF_INFO_KIND(fp, info) != CTF_K_FUNCTION)
1163                         continue;
1164                 dp++;
1165                 fi.ctc_return = *dp;
1166                 dp++;
1167                 fi.ctc_argc = LCTF_INFO_VLEN(fp, info);
1168                 fi.ctc_flags = 0;
1169 
1170                 if (fi.ctc_argc != 0 && dp[fi.ctc_argc - 1] == 0) {
1171                         fi.ctc_flags |= CTF_FUNC_VARARG;
1172                         fi.ctc_argc--;
1173                 }
1174 
1175                 if ((ret = func(name, i, &fi, arg)) != 0)
1176                         return (ret);
1177 
1178         }
1179 
1180         return (0);
1181 }
1182 
1183 char *
1184 ctf_symbol_name(ctf_file_t *fp, ulong_t idx, char *buf, size_t len)
1185 {
1186         const char *name;
1187         uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1188         uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1189 
1190         if (fp->ctf_symtab.cts_data == NULL) {
1191                 (void) ctf_set_errno(fp, ECTF_NOSYMTAB);
1192                 return (NULL);
1193         }
1194 
1195         if (fp->ctf_strtab.cts_data == NULL) {
1196                 (void) ctf_set_errno(fp, ECTF_STRTAB);
1197                 return (NULL);
1198         }
1199 
1200         if (idx > fp->ctf_nsyms) {
1201                 (void) ctf_set_errno(fp, ECTF_NOTDATA);
1202                 return (NULL);
1203         }
1204 
1205         if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1206                 const Elf32_Sym *symp = (Elf32_Sym *)symbase + idx;
1207                 if (ELF32_ST_TYPE(symp->st_info) != STT_OBJECT &&
1208                     ELF32_ST_TYPE(symp->st_info) != STT_FUNC) {
1209                         (void) ctf_set_errno(fp, ECTF_NOTDATA);
1210                         return (NULL);
1211                 }
1212                 if (symp->st_name == 0) {
1213                         (void) ctf_set_errno(fp, ENOENT);
1214                         return (NULL);
1215                 }
1216                 name = (const char *)(strbase + symp->st_name);
1217         } else {
1218                 const Elf64_Sym *symp = (Elf64_Sym *)symbase + idx;
1219                 if (ELF64_ST_TYPE(symp->st_info) != STT_FUNC &&
1220                     ELF64_ST_TYPE(symp->st_info) != STT_OBJECT) {
1221                         (void) ctf_set_errno(fp, ECTF_NOTDATA);
1222                         return (NULL);
1223                 }
1224                 if (symp->st_name == 0) {
1225                         (void) ctf_set_errno(fp, ENOENT);
1226                         return (NULL);
1227                 }
1228                 name = (const char *)(strbase + symp->st_name);
1229         }
1230 
1231         (void) strlcpy(buf, name, len);
1232 
1233         return (buf);
1234 }
1235 
1236 int
1237 ctf_string_iter(ctf_file_t *fp, ctf_string_f *func, void *arg)
1238 {
1239         int rc;
1240         const char *strp = fp->ctf_str[CTF_STRTAB_0].cts_strs;
1241         size_t strl = fp->ctf_str[CTF_STRTAB_0].cts_len;
1242 
1243         while (strl > 0) {
1244                 size_t len;
1245 
1246                 if ((rc = func(strp, arg)) != 0)
1247                         return (rc);
1248 
1249                 len = strlen(strp) + 1;
1250                 strl -= len;
1251                 strp += len;
1252         }
1253 
1254         return (0);
1255 }
1256 
1257 /*
1258  * fp isn't strictly necessary at the moment. However, if we ever rev the file
1259  * format, the valid values for kind will change.
1260  */
1261 const char *
1262 ctf_kind_name(ctf_file_t *fp, int kind)
1263 {
1264         switch (kind) {
1265         case CTF_K_INTEGER:
1266                 return ("integer");
1267         case CTF_K_FLOAT:
1268                 return ("float");
1269         case CTF_K_POINTER:
1270                 return ("pointer");
1271         case CTF_K_ARRAY:
1272                 return ("array");
1273         case CTF_K_FUNCTION:
1274                 return ("function");
1275         case CTF_K_STRUCT:
1276                 return ("struct");
1277         case CTF_K_UNION:
1278                 return ("union");
1279         case CTF_K_ENUM:
1280                 return ("enum");
1281         case CTF_K_FORWARD:
1282                 return ("forward");
1283         case CTF_K_TYPEDEF:
1284                 return ("typedef");
1285         case CTF_K_VOLATILE:
1286                 return ("volatile");
1287         case CTF_K_CONST:
1288                 return ("const");
1289         case CTF_K_RESTRICT:
1290                 return ("restrict");
1291         case CTF_K_UNKNOWN:
1292         default:
1293                 return ("unknown");
1294         }
1295 }
1296 
1297 ctf_id_t
1298 ctf_max_id(ctf_file_t *fp)
1299 {
1300         int child = (fp->ctf_flags & LCTF_CHILD);
1301         return (fp->ctf_typemax + (child ? CTF_CHILD_START : 0));
1302 }
1303 
1304 ulong_t
1305 ctf_nr_syms(ctf_file_t *fp)
1306 {
1307         return (fp->ctf_nsyms);
1308 }