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