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