1/* Type handling functions. 2 Copyright (C) 2019-2022 Free Software Foundation, Inc. 3 4 This file is part of libctf. 5 6 libctf is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 This program is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 See the GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; see the file COPYING. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20#include <ctf-impl.h> 21#include <assert.h> 22#include <string.h> 23 24/* Determine whether a type is a parent or a child. */ 25 26int 27ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id) 28{ 29 return (LCTF_TYPE_ISPARENT (fp, id)); 30} 31 32int 33ctf_type_ischild (ctf_dict_t * fp, ctf_id_t id) 34{ 35 return (LCTF_TYPE_ISCHILD (fp, id)); 36} 37 38/* Expand a structure element into the passed-in ctf_lmember_t. */ 39 40static int 41ctf_struct_member (ctf_dict_t *fp, ctf_lmember_t *dst, const ctf_type_t *tp, 42 unsigned char *vlen, size_t vbytes, size_t n) 43{ 44 if (!ctf_assert (fp, n < LCTF_INFO_VLEN (fp, tp->ctt_info))) 45 return -1; /* errno is set for us. */ 46 47 /* Already large. */ 48 if (tp->ctt_size == CTF_LSIZE_SENT) 49 { 50 ctf_lmember_t *lmp = (ctf_lmember_t *) vlen; 51 52 if (!ctf_assert (fp, (n + 1) * sizeof (ctf_lmember_t) <= vbytes)) 53 return -1; /* errno is set for us. */ 54 55 memcpy (dst, &lmp[n], sizeof (ctf_lmember_t)); 56 } 57 else 58 { 59 ctf_member_t *mp = (ctf_member_t *) vlen; 60 dst->ctlm_name = mp[n].ctm_name; 61 dst->ctlm_type = mp[n].ctm_type; 62 dst->ctlm_offsetlo = mp[n].ctm_offset; 63 dst->ctlm_offsethi = 0; 64 } 65 return 0; 66} 67 68/* Iterate over the members of a STRUCT or UNION. We pass the name, member 69 type, and offset of each member to the specified callback function. */ 70 71int 72ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) 73{ 74 ctf_next_t *i = NULL; 75 ssize_t offset; 76 const char *name; 77 ctf_id_t membtype; 78 79 while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0) 80 { 81 int rc; 82 if ((rc = func (name, membtype, offset, arg)) != 0) 83 { 84 ctf_next_destroy (i); 85 return rc; 86 } 87 } 88 if (ctf_errno (fp) != ECTF_NEXT_END) 89 return -1; /* errno is set for us. */ 90 91 return 0; 92} 93 94/* Iterate over the members of a STRUCT or UNION, returning each member's 95 offset and optionally name and member type in turn. On end-of-iteration, 96 returns -1. If FLAGS is CTF_MN_RECURSE, recurse into unnamed members. */ 97 98ssize_t 99ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, 100 const char **name, ctf_id_t *membtype, int flags) 101{ 102 ctf_dict_t *ofp = fp; 103 uint32_t kind; 104 ssize_t offset; 105 uint32_t max_vlen; 106 ctf_next_t *i = *it; 107 108 if (!i) 109 { 110 const ctf_type_t *tp; 111 ctf_dtdef_t *dtd; 112 ssize_t size; 113 ssize_t increment; 114 115 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 116 return -1; /* errno is set for us. */ 117 118 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 119 return -1; /* errno is set for us. */ 120 121 if ((i = ctf_next_create ()) == NULL) 122 return ctf_set_errno (ofp, ENOMEM); 123 i->cu.ctn_fp = ofp; 124 i->ctn_tp = tp; 125 126 ctf_get_ctt_size (fp, tp, &size, &increment); 127 kind = LCTF_INFO_KIND (fp, tp->ctt_info); 128 129 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) 130 { 131 ctf_next_destroy (i); 132 return (ctf_set_errno (ofp, ECTF_NOTSOU)); 133 } 134 135 if ((dtd = ctf_dynamic_type (fp, type)) != NULL) 136 { 137 i->u.ctn_vlen = dtd->dtd_vlen; 138 i->ctn_size = dtd->dtd_vlen_alloc; 139 } 140 else 141 { 142 unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info); 143 144 i->u.ctn_vlen = (unsigned char *) tp + increment; 145 i->ctn_size = LCTF_VBYTES (fp, kind, size, vlen);; 146 } 147 i->ctn_iter_fun = (void (*) (void)) ctf_member_next; 148 i->ctn_n = 0; 149 *it = i; 150 } 151 152 if ((void (*) (void)) ctf_member_next != i->ctn_iter_fun) 153 return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN)); 154 155 if (ofp != i->cu.ctn_fp) 156 return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFP)); 157 158 /* Resolve to the native dict of this type. */ 159 if ((fp = ctf_get_dict (ofp, type)) == NULL) 160 return (ctf_set_errno (ofp, ECTF_NOPARENT)); 161 162 max_vlen = LCTF_INFO_VLEN (fp, i->ctn_tp->ctt_info); 163 164 /* When we hit an unnamed struct/union member, we set ctn_type to indicate 165 that we are inside one, then return the unnamed member: on the next call, 166 we must skip over top-level member iteration in favour of iteration within 167 the sub-struct until it later turns out that that iteration has ended. */ 168 169 retry: 170 if (!i->ctn_type) 171 { 172 ctf_lmember_t memb; 173 const char *membname; 174 175 if (i->ctn_n == max_vlen) 176 goto end_iter; 177 178 if (ctf_struct_member (fp, &memb, i->ctn_tp, i->u.ctn_vlen, i->ctn_size, 179 i->ctn_n) < 0) 180 return -1; /* errno is set for us. */ 181 182 membname = ctf_strptr (fp, memb.ctlm_name); 183 184 if (name) 185 *name = membname; 186 if (membtype) 187 *membtype = memb.ctlm_type; 188 offset = (unsigned long) CTF_LMEM_OFFSET (&memb); 189 190 if (membname[0] == 0 191 && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT 192 || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION)) 193 i->ctn_type = memb.ctlm_type; 194 i->ctn_n++; 195 196 /* The callers might want automatic recursive sub-struct traversal. */ 197 if (!(flags & CTF_MN_RECURSE)) 198 i->ctn_type = 0; 199 200 /* Sub-struct traversal starting? Take note of the offset of this member, 201 for later boosting of sub-struct members' offsets. */ 202 if (i->ctn_type) 203 i->ctn_increment = offset; 204 } 205 /* Traversing a sub-struct? Just return it, with the offset adjusted. */ 206 else 207 { 208 ssize_t ret = ctf_member_next (fp, i->ctn_type, &i->ctn_next, name, 209 membtype, flags); 210 211 if (ret >= 0) 212 return ret + i->ctn_increment; 213 214 if (ctf_errno (fp) != ECTF_NEXT_END) 215 { 216 ctf_next_destroy (i); 217 *it = NULL; 218 i->ctn_type = 0; 219 return ret; /* errno is set for us. */ 220 } 221 222 if (!ctf_assert (fp, (i->ctn_next == NULL))) 223 return -1; /* errno is set for us. */ 224 225 i->ctn_type = 0; 226 /* This sub-struct has ended: on to the next real member. */ 227 goto retry; 228 } 229 230 return offset; 231 232 end_iter: 233 ctf_next_destroy (i); 234 *it = NULL; 235 return ctf_set_errno (ofp, ECTF_NEXT_END); 236} 237 238/* Iterate over the members of an ENUM. We pass the string name and associated 239 integer value of each enum element to the specified callback function. */ 240 241int 242ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg) 243{ 244 ctf_next_t *i = NULL; 245 const char *name; 246 int val; 247 248 while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL) 249 { 250 int rc; 251 if ((rc = func (name, val, arg)) != 0) 252 { 253 ctf_next_destroy (i); 254 return rc; 255 } 256 } 257 if (ctf_errno (fp) != ECTF_NEXT_END) 258 return -1; /* errno is set for us. */ 259 260 return 0; 261} 262 263/* Iterate over the members of an enum TYPE, returning each enumerand's NAME or 264 NULL at end of iteration or error, and optionally passing back the 265 enumerand's integer VALue. */ 266 267const char * 268ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, 269 int *val) 270{ 271 ctf_dict_t *ofp = fp; 272 uint32_t kind; 273 const char *name; 274 ctf_next_t *i = *it; 275 276 if (!i) 277 { 278 const ctf_type_t *tp; 279 ctf_dtdef_t *dtd; 280 281 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR) 282 return NULL; /* errno is set for us. */ 283 284 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 285 return NULL; /* errno is set for us. */ 286 287 if ((i = ctf_next_create ()) == NULL) 288 { 289 ctf_set_errno (ofp, ENOMEM); 290 return NULL; 291 } 292 i->cu.ctn_fp = ofp; 293 294 (void) ctf_get_ctt_size (fp, tp, NULL, 295 &i->ctn_increment); 296 kind = LCTF_INFO_KIND (fp, tp->ctt_info); 297 298 if (kind != CTF_K_ENUM) 299 { 300 ctf_next_destroy (i); 301 ctf_set_errno (ofp, ECTF_NOTENUM); 302 return NULL; 303 } 304 305 dtd = ctf_dynamic_type (fp, type); 306 i->ctn_iter_fun = (void (*) (void)) ctf_enum_next; 307 i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info); 308 309 if (dtd == NULL) 310 i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp + 311 i->ctn_increment); 312 else 313 i->u.ctn_en = (const ctf_enum_t *) dtd->dtd_vlen; 314 315 *it = i; 316 } 317 318 if ((void (*) (void)) ctf_enum_next != i->ctn_iter_fun) 319 { 320 ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN); 321 return NULL; 322 } 323 324 if (ofp != i->cu.ctn_fp) 325 { 326 ctf_set_errno (ofp, ECTF_NEXT_WRONGFP); 327 return NULL; 328 } 329 330 /* Resolve to the native dict of this type. */ 331 if ((fp = ctf_get_dict (ofp, type)) == NULL) 332 { 333 ctf_set_errno (ofp, ECTF_NOPARENT); 334 return NULL; 335 } 336 337 if (i->ctn_n == 0) 338 goto end_iter; 339 340 name = ctf_strptr (fp, i->u.ctn_en->cte_name); 341 if (val) 342 *val = i->u.ctn_en->cte_value; 343 i->u.ctn_en++; 344 i->ctn_n--; 345 346 return name; 347 348 end_iter: 349 ctf_next_destroy (i); 350 *it = NULL; 351 ctf_set_errno (ofp, ECTF_NEXT_END); 352 return NULL; 353} 354 355/* Iterate over every root (user-visible) type in the given CTF dict. 356 We pass the type ID of each type to the specified callback function. 357 358 Does not traverse parent types: you have to do that explicitly. This is by 359 design, to avoid traversing them more than once if traversing many children 360 of a single parent. */ 361 362int 363ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg) 364{ 365 ctf_next_t *i = NULL; 366 ctf_id_t type; 367 368 while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR) 369 { 370 int rc; 371 if ((rc = func (type, arg)) != 0) 372 { 373 ctf_next_destroy (i); 374 return rc; 375 } 376 } 377 if (ctf_errno (fp) != ECTF_NEXT_END) 378 return -1; /* errno is set for us. */ 379 380 return 0; 381} 382 383/* Iterate over every type in the given CTF dict, user-visible or not. 384 We pass the type ID of each type to the specified callback function. 385 386 Does not traverse parent types: you have to do that explicitly. This is by 387 design, to avoid traversing them more than once if traversing many children 388 of a single parent. */ 389 390int 391ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg) 392{ 393 ctf_next_t *i = NULL; 394 ctf_id_t type; 395 int flag; 396 397 while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR) 398 { 399 int rc; 400 if ((rc = func (type, flag, arg)) != 0) 401 { 402 ctf_next_destroy (i); 403 return rc; 404 } 405 } 406 if (ctf_errno (fp) != ECTF_NEXT_END) 407 return -1; /* errno is set for us. */ 408 409 return 0; 410} 411 412/* Iterate over every type in the given CTF dict, optionally including 413 non-user-visible types, returning each type ID and hidden flag in turn. 414 Returns CTF_ERR on end of iteration or error. 415 416 Does not traverse parent types: you have to do that explicitly. This is by 417 design, to avoid traversing them more than once if traversing many children 418 of a single parent. */ 419 420ctf_id_t 421ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden) 422{ 423 ctf_next_t *i = *it; 424 425 if (!i) 426 { 427 if ((i = ctf_next_create ()) == NULL) 428 return ctf_set_errno (fp, ENOMEM); 429 430 i->cu.ctn_fp = fp; 431 i->ctn_type = 1; 432 i->ctn_iter_fun = (void (*) (void)) ctf_type_next; 433 *it = i; 434 } 435 436 if ((void (*) (void)) ctf_type_next != i->ctn_iter_fun) 437 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN)); 438 439 if (fp != i->cu.ctn_fp) 440 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP)); 441 442 while (i->ctn_type <= fp->ctf_typemax) 443 { 444 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, i->ctn_type); 445 446 if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info))) 447 { 448 i->ctn_type++; 449 continue; 450 } 451 452 if (flag) 453 *flag = LCTF_INFO_ISROOT (fp, tp->ctt_info); 454 return LCTF_INDEX_TO_TYPE (fp, i->ctn_type++, fp->ctf_flags & LCTF_CHILD); 455 } 456 ctf_next_destroy (i); 457 *it = NULL; 458 return ctf_set_errno (fp, ECTF_NEXT_END); 459} 460 461/* Iterate over every variable in the given CTF dict, in arbitrary order. 462 We pass the name of each variable to the specified callback function. */ 463 464int 465ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg) 466{ 467 ctf_next_t *i = NULL; 468 ctf_id_t type; 469 const char *name; 470 471 while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR) 472 { 473 int rc; 474 if ((rc = func (name, type, arg)) != 0) 475 { 476 ctf_next_destroy (i); 477 return rc; 478 } 479 } 480 if (ctf_errno (fp) != ECTF_NEXT_END) 481 return -1; /* errno is set for us. */ 482 483 return 0; 484} 485 486/* Iterate over every variable in the given CTF dict, in arbitrary order, 487 returning the name and type of each variable in turn. The name argument is 488 not optional. Returns CTF_ERR on end of iteration or error. */ 489 490ctf_id_t 491ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name) 492{ 493 ctf_next_t *i = *it; 494 495 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL)) 496 return (ctf_set_errno (fp, ECTF_NOPARENT)); 497 498 if (!i) 499 { 500 if ((i = ctf_next_create ()) == NULL) 501 return ctf_set_errno (fp, ENOMEM); 502 503 i->cu.ctn_fp = fp; 504 i->ctn_iter_fun = (void (*) (void)) ctf_variable_next; 505 if (fp->ctf_flags & LCTF_RDWR) 506 i->u.ctn_dvd = ctf_list_next (&fp->ctf_dvdefs); 507 *it = i; 508 } 509 510 if ((void (*) (void)) ctf_variable_next != i->ctn_iter_fun) 511 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN)); 512 513 if (fp != i->cu.ctn_fp) 514 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP)); 515 516 if (!(fp->ctf_flags & LCTF_RDWR)) 517 { 518 if (i->ctn_n >= fp->ctf_nvars) 519 goto end_iter; 520 521 *name = ctf_strptr (fp, fp->ctf_vars[i->ctn_n].ctv_name); 522 return fp->ctf_vars[i->ctn_n++].ctv_type; 523 } 524 else 525 { 526 ctf_id_t id; 527 528 if (i->u.ctn_dvd == NULL) 529 goto end_iter; 530 531 *name = i->u.ctn_dvd->dvd_name; 532 id = i->u.ctn_dvd->dvd_type; 533 i->u.ctn_dvd = ctf_list_next (i->u.ctn_dvd); 534 return id; 535 } 536 537 end_iter: 538 ctf_next_destroy (i); 539 *it = NULL; 540 return ctf_set_errno (fp, ECTF_NEXT_END); 541} 542 543/* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and 544 RESTRICT nodes until we reach a "base" type node. This is useful when 545 we want to follow a type ID to a node that has members or a size. To guard 546 against infinite loops, we implement simplified cycle detection and check 547 each link against itself, the previous node, and the topmost node. 548 549 Does not drill down through slices to their contained type. 550 551 Callers of this function must not presume that a type it returns must have a 552 valid ctt_size: forwards do not, and must be separately handled. */ 553 554ctf_id_t 555ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type) 556{ 557 ctf_id_t prev = type, otype = type; 558 ctf_dict_t *ofp = fp; 559 const ctf_type_t *tp; 560 561 if (type == 0) 562 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE)); 563 564 while ((tp = ctf_lookup_by_id (&fp, type)) != NULL) 565 { 566 switch (LCTF_INFO_KIND (fp, tp->ctt_info)) 567 { 568 case CTF_K_TYPEDEF: 569 case CTF_K_VOLATILE: 570 case CTF_K_CONST: 571 case CTF_K_RESTRICT: 572 if (tp->ctt_type == type || tp->ctt_type == otype 573 || tp->ctt_type == prev) 574 { 575 ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"), 576 otype); 577 return (ctf_set_errno (ofp, ECTF_CORRUPT)); 578 } 579 prev = type; 580 type = tp->ctt_type; 581 break; 582 case CTF_K_UNKNOWN: 583 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE)); 584 default: 585 return type; 586 } 587 if (type == 0) 588 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE)); 589 } 590 591 return CTF_ERR; /* errno is set for us. */ 592} 593 594/* Like ctf_type_resolve(), but traverse down through slices to their contained 595 type. */ 596 597ctf_id_t 598ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type) 599{ 600 const ctf_type_t *tp; 601 602 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 603 return -1; 604 605 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 606 return CTF_ERR; /* errno is set for us. */ 607 608 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE) 609 return ctf_type_reference (fp, type); 610 return type; 611} 612 613/* Return the native dict of a given type: if called on a child and the 614 type is in the parent, return the parent. Needed if you plan to access 615 the type directly, without using the API. */ 616ctf_dict_t * 617ctf_get_dict (ctf_dict_t *fp, ctf_id_t type) 618{ 619 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type)) 620 return fp->ctf_parent; 621 622 return fp; 623} 624 625/* Look up a name in the given name table, in the appropriate hash given the 626 kind of the identifier. The name is a raw, undecorated identifier. */ 627 628ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name) 629{ 630 return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name); 631} 632 633/* Look up a name in the given name table, in the appropriate hash given the 634 readability state of the dictionary. The name is a raw, undecorated 635 identifier. */ 636 637ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name) 638{ 639 ctf_id_t id; 640 641 if (fp->ctf_flags & LCTF_RDWR) 642 id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name); 643 else 644 id = ctf_hash_lookup_type (np->ctn_readonly, fp, name); 645 return id; 646} 647 648/* Lookup the given type ID and return its name as a new dynamically-allocated 649 string. */ 650 651char * 652ctf_type_aname (ctf_dict_t *fp, ctf_id_t type) 653{ 654 ctf_decl_t cd; 655 ctf_decl_node_t *cdp; 656 ctf_decl_prec_t prec, lp, rp; 657 int ptr, arr; 658 uint32_t k; 659 char *buf; 660 661 if (fp == NULL && type == CTF_ERR) 662 return NULL; /* Simplify caller code by permitting CTF_ERR. */ 663 664 ctf_decl_init (&cd); 665 ctf_decl_push (&cd, fp, type); 666 667 if (cd.cd_err != 0) 668 { 669 ctf_decl_fini (&cd); 670 ctf_set_errno (fp, cd.cd_err); 671 return NULL; 672 } 673 674 /* If the type graph's order conflicts with lexical precedence order 675 for pointers or arrays, then we need to surround the declarations at 676 the corresponding lexical precedence with parentheses. This can 677 result in either a parenthesized pointer (*) as in int (*)() or 678 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */ 679 680 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER; 681 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY; 682 683 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1; 684 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1; 685 686 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */ 687 688 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) 689 { 690 for (cdp = ctf_list_next (&cd.cd_nodes[prec]); 691 cdp != NULL; cdp = ctf_list_next (cdp)) 692 { 693 ctf_dict_t *rfp = fp; 694 const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type); 695 const char *name = ctf_strptr (rfp, tp->ctt_name); 696 697 if (k != CTF_K_POINTER && k != CTF_K_ARRAY) 698 ctf_decl_sprintf (&cd, " "); 699 700 if (lp == prec) 701 { 702 ctf_decl_sprintf (&cd, "("); 703 lp = -1; 704 } 705 706 switch (cdp->cd_kind) 707 { 708 case CTF_K_INTEGER: 709 case CTF_K_FLOAT: 710 case CTF_K_TYPEDEF: 711 /* Integers, floats, and typedefs must always be named types. */ 712 713 if (name[0] == '\0') 714 { 715 ctf_set_errno (fp, ECTF_CORRUPT); 716 ctf_decl_fini (&cd); 717 return NULL; 718 } 719 720 ctf_decl_sprintf (&cd, "%s", name); 721 break; 722 case CTF_K_POINTER: 723 ctf_decl_sprintf (&cd, "*"); 724 break; 725 case CTF_K_ARRAY: 726 ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n); 727 break; 728 case CTF_K_FUNCTION: 729 { 730 size_t i; 731 ctf_funcinfo_t fi; 732 ctf_id_t *argv = NULL; 733 734 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0) 735 goto err; /* errno is set for us. */ 736 737 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL) 738 { 739 ctf_set_errno (rfp, errno); 740 goto err; 741 } 742 743 if (ctf_func_type_args (rfp, cdp->cd_type, 744 fi.ctc_argc, argv) < 0) 745 goto err; /* errno is set for us. */ 746 747 ctf_decl_sprintf (&cd, "(*) ("); 748 for (i = 0; i < fi.ctc_argc; i++) 749 { 750 char *arg = ctf_type_aname (rfp, argv[i]); 751 752 if (arg == NULL) 753 goto err; /* errno is set for us. */ 754 ctf_decl_sprintf (&cd, "%s", arg); 755 free (arg); 756 757 if ((i < fi.ctc_argc - 1) 758 || (fi.ctc_flags & CTF_FUNC_VARARG)) 759 ctf_decl_sprintf (&cd, ", "); 760 } 761 762 if (fi.ctc_flags & CTF_FUNC_VARARG) 763 ctf_decl_sprintf (&cd, "..."); 764 ctf_decl_sprintf (&cd, ")"); 765 766 free (argv); 767 break; 768 769 err: 770 free (argv); 771 ctf_decl_fini (&cd); 772 return NULL; 773 } 774 break; 775 case CTF_K_STRUCT: 776 ctf_decl_sprintf (&cd, "struct %s", name); 777 break; 778 case CTF_K_UNION: 779 ctf_decl_sprintf (&cd, "union %s", name); 780 break; 781 case CTF_K_ENUM: 782 ctf_decl_sprintf (&cd, "enum %s", name); 783 break; 784 case CTF_K_FORWARD: 785 { 786 switch (ctf_type_kind_forwarded (fp, cdp->cd_type)) 787 { 788 case CTF_K_STRUCT: 789 ctf_decl_sprintf (&cd, "struct %s", name); 790 break; 791 case CTF_K_UNION: 792 ctf_decl_sprintf (&cd, "union %s", name); 793 break; 794 case CTF_K_ENUM: 795 ctf_decl_sprintf (&cd, "enum %s", name); 796 break; 797 default: 798 ctf_set_errno (fp, ECTF_CORRUPT); 799 ctf_decl_fini (&cd); 800 return NULL; 801 } 802 break; 803 } 804 case CTF_K_VOLATILE: 805 ctf_decl_sprintf (&cd, "volatile"); 806 break; 807 case CTF_K_CONST: 808 ctf_decl_sprintf (&cd, "const"); 809 break; 810 case CTF_K_RESTRICT: 811 ctf_decl_sprintf (&cd, "restrict"); 812 break; 813 case CTF_K_UNKNOWN: 814 if (name[0] == '\0') 815 ctf_decl_sprintf (&cd, _("(nonrepresentable type)")); 816 else 817 ctf_decl_sprintf (&cd, _("(nonrepresentable type %s)"), 818 name); 819 break; 820 } 821 822 k = cdp->cd_kind; 823 } 824 825 if (rp == prec) 826 ctf_decl_sprintf (&cd, ")"); 827 } 828 829 if (cd.cd_enomem) 830 (void) ctf_set_errno (fp, ENOMEM); 831 832 buf = ctf_decl_buf (&cd); 833 834 ctf_decl_fini (&cd); 835 return buf; 836} 837 838/* Lookup the given type ID and print a string name for it into buf. Return 839 the actual number of bytes (not including \0) needed to format the name. */ 840 841ssize_t 842ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len) 843{ 844 char *str = ctf_type_aname (fp, type); 845 size_t slen; 846 847 if (str == NULL) 848 return CTF_ERR; /* errno is set for us. */ 849 850 slen = strlen (str); 851 snprintf (buf, len, "%s", str); 852 free (str); 853 854 if (slen >= len) 855 (void) ctf_set_errno (fp, ECTF_NAMELEN); 856 857 return slen; 858} 859 860/* Lookup the given type ID and print a string name for it into buf. If buf 861 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */ 862 863char * 864ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len) 865{ 866 ssize_t rv = ctf_type_lname (fp, type, buf, len); 867 return (rv >= 0 && (size_t) rv < len ? buf : NULL); 868} 869 870/* Lookup the given type ID and return its raw, unadorned, undecorated name. 871 The name will live as long as its ctf_dict_t does. 872 873 The only decoration is that a NULL return always means an error: nameless 874 types return a null string. */ 875 876const char * 877ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type) 878{ 879 const ctf_type_t *tp; 880 881 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 882 return NULL; /* errno is set for us. */ 883 884 if (tp->ctt_name == 0) 885 return ""; 886 887 return ctf_strraw (fp, tp->ctt_name); 888} 889 890/* Lookup the given type ID and return its raw, unadorned, undecorated name as a 891 new dynamically-allocated string. */ 892 893char * 894ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type) 895{ 896 const char *name = ctf_type_name_raw (fp, type); 897 898 if (name != NULL) 899 return strdup (name); 900 901 return NULL; 902} 903 904/* Resolve the type down to a base type node, and then return the size 905 of the type storage in bytes. */ 906 907ssize_t 908ctf_type_size (ctf_dict_t *fp, ctf_id_t type) 909{ 910 ctf_dict_t *ofp = fp; 911 const ctf_type_t *tp; 912 ssize_t size; 913 ctf_arinfo_t ar; 914 915 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 916 return -1; /* errno is set for us. */ 917 918 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 919 return -1; /* errno is set for us. */ 920 921 switch (LCTF_INFO_KIND (fp, tp->ctt_info)) 922 { 923 case CTF_K_POINTER: 924 return fp->ctf_dmodel->ctd_pointer; 925 926 case CTF_K_FUNCTION: 927 return 0; /* Function size is only known by symtab. */ 928 929 case CTF_K_ENUM: 930 return fp->ctf_dmodel->ctd_int; 931 932 case CTF_K_ARRAY: 933 /* ctf_add_array() does not directly encode the element size, but 934 requires the user to multiply to determine the element size. 935 936 If ctf_get_ctt_size() returns nonzero, then use the recorded 937 size instead. */ 938 939 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0) 940 return size; 941 942 if (ctf_array_info (ofp, type, &ar) < 0 943 || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0) 944 return -1; /* errno is set for us. */ 945 946 return size * ar.ctr_nelems; 947 948 case CTF_K_FORWARD: 949 /* Forwards do not have a meaningful size. */ 950 return (ctf_set_errno (ofp, ECTF_INCOMPLETE)); 951 952 default: /* including slices of enums, etc */ 953 return (ctf_get_ctt_size (fp, tp, NULL, NULL)); 954 } 955} 956 957/* Resolve the type down to a base type node, and then return the alignment 958 needed for the type storage in bytes. 959 960 XXX may need arch-dependent attention. */ 961 962ssize_t 963ctf_type_align (ctf_dict_t *fp, ctf_id_t type) 964{ 965 const ctf_type_t *tp; 966 ctf_dict_t *ofp = fp; 967 int kind; 968 969 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 970 return -1; /* errno is set for us. */ 971 972 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 973 return -1; /* errno is set for us. */ 974 975 kind = LCTF_INFO_KIND (fp, tp->ctt_info); 976 switch (kind) 977 { 978 case CTF_K_POINTER: 979 case CTF_K_FUNCTION: 980 return fp->ctf_dmodel->ctd_pointer; 981 982 case CTF_K_ARRAY: 983 { 984 ctf_arinfo_t r; 985 if (ctf_array_info (ofp, type, &r) < 0) 986 return -1; /* errno is set for us. */ 987 return (ctf_type_align (ofp, r.ctr_contents)); 988 } 989 990 case CTF_K_STRUCT: 991 case CTF_K_UNION: 992 { 993 size_t align = 0; 994 ctf_dtdef_t *dtd; 995 unsigned char *vlen; 996 uint32_t i = 0, n = LCTF_INFO_VLEN (fp, tp->ctt_info); 997 ssize_t size, increment, vbytes; 998 999 ctf_get_ctt_size (fp, tp, &size, &increment); 1000 1001 if ((dtd = ctf_dynamic_type (fp, type)) != NULL) 1002 { 1003 vlen = dtd->dtd_vlen; 1004 vbytes = dtd->dtd_vlen_alloc; 1005 } 1006 else 1007 { 1008 vlen = (unsigned char *) tp + increment; 1009 vbytes = LCTF_VBYTES (fp, kind, size, n); 1010 } 1011 1012 if (kind == CTF_K_STRUCT) 1013 n = MIN (n, 1); /* Only use first member for structs. */ 1014 1015 for (; n != 0; n--, i++) 1016 { 1017 ctf_lmember_t memb; 1018 1019 if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0) 1020 return -1; /* errno is set for us. */ 1021 1022 ssize_t am = ctf_type_align (ofp, memb.ctlm_type); 1023 align = MAX (align, (size_t) am); 1024 } 1025 return align; 1026 } 1027 1028 case CTF_K_ENUM: 1029 return fp->ctf_dmodel->ctd_int; 1030 1031 case CTF_K_FORWARD: 1032 /* Forwards do not have a meaningful alignment. */ 1033 return (ctf_set_errno (ofp, ECTF_INCOMPLETE)); 1034 1035 default: /* including slices of enums, etc */ 1036 return (ctf_get_ctt_size (fp, tp, NULL, NULL)); 1037 } 1038} 1039 1040/* Return the kind (CTF_K_* constant) for the specified type ID. */ 1041 1042int 1043ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type) 1044{ 1045 const ctf_type_t *tp; 1046 1047 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1048 return -1; /* errno is set for us. */ 1049 1050 return (LCTF_INFO_KIND (fp, tp->ctt_info)); 1051} 1052 1053/* Return the kind (CTF_K_* constant) for the specified type ID. 1054 Slices are considered to be of the same kind as the type sliced. */ 1055 1056int 1057ctf_type_kind (ctf_dict_t *fp, ctf_id_t type) 1058{ 1059 int kind; 1060 1061 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0) 1062 return -1; 1063 1064 if (kind == CTF_K_SLICE) 1065 { 1066 if ((type = ctf_type_reference (fp, type)) == CTF_ERR) 1067 return -1; 1068 kind = ctf_type_kind_unsliced (fp, type); 1069 } 1070 1071 return kind; 1072} 1073 1074/* Return the kind of this type, except, for forwards, return the kind of thing 1075 this is a forward to. */ 1076int 1077ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type) 1078{ 1079 int kind; 1080 const ctf_type_t *tp; 1081 1082 if ((kind = ctf_type_kind (fp, type)) < 0) 1083 return -1; /* errno is set for us. */ 1084 1085 if (kind != CTF_K_FORWARD) 1086 return kind; 1087 1088 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1089 return -1; /* errno is set for us. */ 1090 1091 return tp->ctt_type; 1092} 1093 1094/* If the type is one that directly references another type (such as POINTER), 1095 then return the ID of the type to which it refers. */ 1096 1097ctf_id_t 1098ctf_type_reference (ctf_dict_t *fp, ctf_id_t type) 1099{ 1100 ctf_dict_t *ofp = fp; 1101 const ctf_type_t *tp; 1102 1103 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1104 return CTF_ERR; /* errno is set for us. */ 1105 1106 switch (LCTF_INFO_KIND (fp, tp->ctt_info)) 1107 { 1108 case CTF_K_POINTER: 1109 case CTF_K_TYPEDEF: 1110 case CTF_K_VOLATILE: 1111 case CTF_K_CONST: 1112 case CTF_K_RESTRICT: 1113 return tp->ctt_type; 1114 /* Slices store their type in an unusual place. */ 1115 case CTF_K_SLICE: 1116 { 1117 ctf_dtdef_t *dtd; 1118 const ctf_slice_t *sp; 1119 1120 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL) 1121 { 1122 ssize_t increment; 1123 1124 (void) ctf_get_ctt_size (fp, tp, NULL, &increment); 1125 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment); 1126 } 1127 else 1128 sp = (const ctf_slice_t *) dtd->dtd_vlen; 1129 1130 return sp->cts_type; 1131 } 1132 default: 1133 return (ctf_set_errno (ofp, ECTF_NOTREF)); 1134 } 1135} 1136 1137/* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a 1138 pointer to the given type, see if we can compute a pointer to the type 1139 resulting from resolving the type down to its base type and use that 1140 instead. This helps with cases where the CTF data includes "struct foo *" 1141 but not "foo_t *" and the user accesses "foo_t *" in the debugger. 1142 1143 XXX what about parent dicts? */ 1144 1145ctf_id_t 1146ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type) 1147{ 1148 ctf_dict_t *ofp = fp; 1149 ctf_id_t ntype; 1150 1151 if (ctf_lookup_by_id (&fp, type) == NULL) 1152 return CTF_ERR; /* errno is set for us. */ 1153 1154 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0) 1155 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD))); 1156 1157 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 1158 return (ctf_set_errno (ofp, ECTF_NOTYPE)); 1159 1160 if (ctf_lookup_by_id (&fp, type) == NULL) 1161 return (ctf_set_errno (ofp, ECTF_NOTYPE)); 1162 1163 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0) 1164 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD))); 1165 1166 return (ctf_set_errno (ofp, ECTF_NOTYPE)); 1167} 1168 1169/* Return the encoding for the specified INTEGER, FLOAT, or ENUM. */ 1170 1171int 1172ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep) 1173{ 1174 ctf_dict_t *ofp = fp; 1175 ctf_dtdef_t *dtd; 1176 const ctf_type_t *tp; 1177 ssize_t increment; 1178 const unsigned char *vlen; 1179 uint32_t data; 1180 1181 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1182 return -1; /* errno is set for us. */ 1183 1184 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL) 1185 vlen = dtd->dtd_vlen; 1186 else 1187 { 1188 ctf_get_ctt_size (fp, tp, NULL, &increment); 1189 vlen = (const unsigned char *) ((uintptr_t) tp + increment); 1190 } 1191 1192 switch (LCTF_INFO_KIND (fp, tp->ctt_info)) 1193 { 1194 case CTF_K_INTEGER: 1195 data = *(const uint32_t *) vlen; 1196 ep->cte_format = CTF_INT_ENCODING (data); 1197 ep->cte_offset = CTF_INT_OFFSET (data); 1198 ep->cte_bits = CTF_INT_BITS (data); 1199 break; 1200 case CTF_K_FLOAT: 1201 data = *(const uint32_t *) vlen; 1202 ep->cte_format = CTF_FP_ENCODING (data); 1203 ep->cte_offset = CTF_FP_OFFSET (data); 1204 ep->cte_bits = CTF_FP_BITS (data); 1205 break; 1206 case CTF_K_ENUM: 1207 /* v3 only: we must guess at the underlying integral format. */ 1208 ep->cte_format = CTF_INT_SIGNED; 1209 ep->cte_offset = 0; 1210 ep->cte_bits = 0; 1211 break; 1212 case CTF_K_SLICE: 1213 { 1214 const ctf_slice_t *slice; 1215 ctf_encoding_t underlying_en; 1216 ctf_id_t underlying; 1217 1218 slice = (ctf_slice_t *) vlen; 1219 underlying = ctf_type_resolve (fp, slice->cts_type); 1220 if (ctf_type_encoding (fp, underlying, &underlying_en) < 0) 1221 return -1; /* errno is set for us. */ 1222 1223 ep->cte_format = underlying_en.cte_format; 1224 ep->cte_offset = slice->cts_offset; 1225 ep->cte_bits = slice->cts_bits; 1226 break; 1227 } 1228 default: 1229 return (ctf_set_errno (ofp, ECTF_NOTINTFP)); 1230 } 1231 1232 return 0; 1233} 1234 1235int 1236ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp, 1237 ctf_id_t rtype) 1238{ 1239 int rval; 1240 1241 if (ltype < rtype) 1242 rval = -1; 1243 else if (ltype > rtype) 1244 rval = 1; 1245 else 1246 rval = 0; 1247 1248 if (lfp == rfp) 1249 return rval; 1250 1251 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL) 1252 lfp = lfp->ctf_parent; 1253 1254 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL) 1255 rfp = rfp->ctf_parent; 1256 1257 if (lfp < rfp) 1258 return -1; 1259 1260 if (lfp > rfp) 1261 return 1; 1262 1263 return rval; 1264} 1265 1266/* Return a boolean value indicating if two types are compatible. This function 1267 returns true if the two types are the same, or if they (or their ultimate 1268 base type) have the same encoding properties, or (for structs / unions / 1269 enums / forward declarations) if they have the same name and (for structs / 1270 unions) member count. */ 1271 1272int 1273ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype, 1274 ctf_dict_t *rfp, ctf_id_t rtype) 1275{ 1276 const ctf_type_t *ltp, *rtp; 1277 ctf_encoding_t le, re; 1278 ctf_arinfo_t la, ra; 1279 uint32_t lkind, rkind; 1280 int same_names = 0; 1281 1282 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0) 1283 return 1; 1284 1285 ltype = ctf_type_resolve (lfp, ltype); 1286 lkind = ctf_type_kind (lfp, ltype); 1287 1288 rtype = ctf_type_resolve (rfp, rtype); 1289 rkind = ctf_type_kind (rfp, rtype); 1290 1291 ltp = ctf_lookup_by_id (&lfp, ltype); 1292 rtp = ctf_lookup_by_id (&rfp, rtype); 1293 1294 if (ltp != NULL && rtp != NULL) 1295 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name), 1296 ctf_strptr (rfp, rtp->ctt_name)) == 0); 1297 1298 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) || 1299 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER))) 1300 return 1; 1301 1302 if (lkind != rkind) 1303 return 0; 1304 1305 switch (lkind) 1306 { 1307 case CTF_K_INTEGER: 1308 case CTF_K_FLOAT: 1309 memset (&le, 0, sizeof (le)); 1310 memset (&re, 0, sizeof (re)); 1311 return (ctf_type_encoding (lfp, ltype, &le) == 0 1312 && ctf_type_encoding (rfp, rtype, &re) == 0 1313 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0); 1314 case CTF_K_POINTER: 1315 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype), 1316 rfp, ctf_type_reference (rfp, rtype))); 1317 case CTF_K_ARRAY: 1318 return (ctf_array_info (lfp, ltype, &la) == 0 1319 && ctf_array_info (rfp, rtype, &ra) == 0 1320 && la.ctr_nelems == ra.ctr_nelems 1321 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents) 1322 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index)); 1323 case CTF_K_STRUCT: 1324 case CTF_K_UNION: 1325 return (same_names && (ctf_type_size (lfp, ltype) 1326 == ctf_type_size (rfp, rtype))); 1327 case CTF_K_ENUM: 1328 { 1329 int lencoded, rencoded; 1330 lencoded = ctf_type_encoding (lfp, ltype, &le); 1331 rencoded = ctf_type_encoding (rfp, rtype, &re); 1332 1333 if ((lencoded != rencoded) || 1334 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0)) 1335 return 0; 1336 } 1337 /* FALLTHRU */ 1338 case CTF_K_FORWARD: 1339 return same_names; /* No other checks required for these type kinds. */ 1340 default: 1341 return 0; /* Should not get here since we did a resolve. */ 1342 } 1343} 1344 1345/* Return the number of members in a STRUCT or UNION, or the number of 1346 enumerators in an ENUM. The count does not include unnamed sub-members. */ 1347 1348int 1349ctf_member_count (ctf_dict_t *fp, ctf_id_t type) 1350{ 1351 ctf_dict_t *ofp = fp; 1352 const ctf_type_t *tp; 1353 uint32_t kind; 1354 1355 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 1356 return -1; /* errno is set for us. */ 1357 1358 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1359 return -1; /* errno is set for us. */ 1360 1361 kind = LCTF_INFO_KIND (fp, tp->ctt_info); 1362 1363 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM) 1364 return (ctf_set_errno (ofp, ECTF_NOTSUE)); 1365 1366 return LCTF_INFO_VLEN (fp, tp->ctt_info); 1367} 1368 1369/* Return the type and offset for a given member of a STRUCT or UNION. */ 1370 1371int 1372ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name, 1373 ctf_membinfo_t *mip) 1374{ 1375 ctf_dict_t *ofp = fp; 1376 const ctf_type_t *tp; 1377 ctf_dtdef_t *dtd; 1378 unsigned char *vlen; 1379 ssize_t size, increment, vbytes; 1380 uint32_t kind, n, i = 0; 1381 1382 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 1383 return -1; /* errno is set for us. */ 1384 1385 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1386 return -1; /* errno is set for us. */ 1387 1388 ctf_get_ctt_size (fp, tp, &size, &increment); 1389 kind = LCTF_INFO_KIND (fp, tp->ctt_info); 1390 1391 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) 1392 return (ctf_set_errno (ofp, ECTF_NOTSOU)); 1393 1394 n = LCTF_INFO_VLEN (fp, tp->ctt_info); 1395 if ((dtd = ctf_dynamic_type (fp, type)) != NULL) 1396 { 1397 vlen = dtd->dtd_vlen; 1398 vbytes = dtd->dtd_vlen_alloc; 1399 } 1400 else 1401 { 1402 vlen = (unsigned char *) tp + increment; 1403 vbytes = LCTF_VBYTES (fp, kind, size, n); 1404 } 1405 1406 for (; n != 0; n--, i++) 1407 { 1408 ctf_lmember_t memb; 1409 const char *membname; 1410 1411 if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0) 1412 return -1; /* errno is set for us. */ 1413 1414 membname = ctf_strptr (fp, memb.ctlm_name); 1415 1416 if (membname[0] == 0 1417 && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT 1418 || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION) 1419 && (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0)) 1420 return 0; 1421 1422 if (strcmp (membname, name) == 0) 1423 { 1424 mip->ctm_type = memb.ctlm_type; 1425 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (&memb); 1426 return 0; 1427 } 1428 } 1429 1430 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM)); 1431} 1432 1433/* Return the array type, index, and size information for the specified ARRAY. */ 1434 1435int 1436ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp) 1437{ 1438 ctf_dict_t *ofp = fp; 1439 const ctf_type_t *tp; 1440 const ctf_array_t *ap; 1441 const ctf_dtdef_t *dtd; 1442 ssize_t increment; 1443 1444 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1445 return -1; /* errno is set for us. */ 1446 1447 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY) 1448 return (ctf_set_errno (ofp, ECTF_NOTARRAY)); 1449 1450 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL) 1451 ap = (const ctf_array_t *) dtd->dtd_vlen; 1452 else 1453 { 1454 ctf_get_ctt_size (fp, tp, NULL, &increment); 1455 ap = (const ctf_array_t *) ((uintptr_t) tp + increment); 1456 } 1457 arp->ctr_contents = ap->cta_contents; 1458 arp->ctr_index = ap->cta_index; 1459 arp->ctr_nelems = ap->cta_nelems; 1460 1461 return 0; 1462} 1463 1464/* Convert the specified value to the corresponding enum tag name, if a 1465 matching name can be found. Otherwise NULL is returned. */ 1466 1467const char * 1468ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value) 1469{ 1470 ctf_dict_t *ofp = fp; 1471 const ctf_type_t *tp; 1472 const ctf_enum_t *ep; 1473 const ctf_dtdef_t *dtd; 1474 ssize_t increment; 1475 uint32_t n; 1476 1477 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR) 1478 return NULL; /* errno is set for us. */ 1479 1480 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1481 return NULL; /* errno is set for us. */ 1482 1483 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM) 1484 { 1485 ctf_set_errno (ofp, ECTF_NOTENUM); 1486 return NULL; 1487 } 1488 1489 ctf_get_ctt_size (fp, tp, NULL, &increment); 1490 1491 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL) 1492 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment); 1493 else 1494 ep = (const ctf_enum_t *) dtd->dtd_vlen; 1495 1496 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) 1497 { 1498 if (ep->cte_value == value) 1499 return (ctf_strptr (fp, ep->cte_name)); 1500 } 1501 1502 ctf_set_errno (ofp, ECTF_NOENUMNAM); 1503 return NULL; 1504} 1505 1506/* Convert the specified enum tag name to the corresponding value, if a 1507 matching name can be found. Otherwise CTF_ERR is returned. */ 1508 1509int 1510ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int *valp) 1511{ 1512 ctf_dict_t *ofp = fp; 1513 const ctf_type_t *tp; 1514 const ctf_enum_t *ep; 1515 const ctf_dtdef_t *dtd; 1516 ssize_t increment; 1517 uint32_t n; 1518 1519 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR) 1520 return -1; /* errno is set for us. */ 1521 1522 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1523 return -1; /* errno is set for us. */ 1524 1525 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM) 1526 { 1527 (void) ctf_set_errno (ofp, ECTF_NOTENUM); 1528 return -1; 1529 } 1530 1531 ctf_get_ctt_size (fp, tp, NULL, &increment); 1532 1533 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL) 1534 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment); 1535 else 1536 ep = (const ctf_enum_t *) dtd->dtd_vlen; 1537 1538 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) 1539 { 1540 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0) 1541 { 1542 if (valp != NULL) 1543 *valp = ep->cte_value; 1544 return 0; 1545 } 1546 } 1547 1548 ctf_set_errno (ofp, ECTF_NOENUMNAM); 1549 return -1; 1550} 1551 1552/* Given a type ID relating to a function type, return info on return types and 1553 arg counts for that function. */ 1554 1555int 1556ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip) 1557{ 1558 const ctf_type_t *tp; 1559 uint32_t kind; 1560 const uint32_t *args; 1561 const ctf_dtdef_t *dtd; 1562 ssize_t size, increment; 1563 1564 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 1565 return -1; /* errno is set for us. */ 1566 1567 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1568 return -1; /* errno is set for us. */ 1569 1570 (void) ctf_get_ctt_size (fp, tp, &size, &increment); 1571 kind = LCTF_INFO_KIND (fp, tp->ctt_info); 1572 1573 if (kind != CTF_K_FUNCTION) 1574 return (ctf_set_errno (fp, ECTF_NOTFUNC)); 1575 1576 fip->ctc_return = tp->ctt_type; 1577 fip->ctc_flags = 0; 1578 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info); 1579 1580 if ((dtd = ctf_dynamic_type (fp, type)) == NULL) 1581 args = (uint32_t *) ((uintptr_t) tp + increment); 1582 else 1583 args = (uint32_t *) dtd->dtd_vlen; 1584 1585 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0) 1586 { 1587 fip->ctc_flags |= CTF_FUNC_VARARG; 1588 fip->ctc_argc--; 1589 } 1590 1591 return 0; 1592} 1593 1594/* Given a type ID relating to a function type, return the arguments for the 1595 function. */ 1596 1597int 1598ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv) 1599{ 1600 const ctf_type_t *tp; 1601 const uint32_t *args; 1602 const ctf_dtdef_t *dtd; 1603 ssize_t size, increment; 1604 ctf_funcinfo_t f; 1605 1606 if (ctf_func_type_info (fp, type, &f) < 0) 1607 return -1; /* errno is set for us. */ 1608 1609 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) 1610 return -1; /* errno is set for us. */ 1611 1612 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1613 return -1; /* errno is set for us. */ 1614 1615 (void) ctf_get_ctt_size (fp, tp, &size, &increment); 1616 1617 if ((dtd = ctf_dynamic_type (fp, type)) == NULL) 1618 args = (uint32_t *) ((uintptr_t) tp + increment); 1619 else 1620 args = (uint32_t *) dtd->dtd_vlen; 1621 1622 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--) 1623 *argv++ = *args++; 1624 1625 return 0; 1626} 1627 1628/* Recursively visit the members of any type. This function is used as the 1629 engine for ctf_type_visit, below. We resolve the input type, recursively 1630 invoke ourself for each type member if the type is a struct or union, and 1631 then invoke the callback function on the current type. If any callback 1632 returns non-zero, we abort and percolate the error code back up to the top. */ 1633 1634static int 1635ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, 1636 void *arg, const char *name, unsigned long offset, int depth) 1637{ 1638 ctf_id_t otype = type; 1639 const ctf_type_t *tp; 1640 const ctf_dtdef_t *dtd; 1641 unsigned char *vlen; 1642 ssize_t size, increment, vbytes; 1643 uint32_t kind, n, i = 0; 1644 int nonrepresentable = 0; 1645 int rc; 1646 1647 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) { 1648 if (ctf_errno (fp) != ECTF_NONREPRESENTABLE) 1649 return -1; /* errno is set for us. */ 1650 else 1651 nonrepresentable = 1; 1652 } 1653 1654 if (!nonrepresentable) 1655 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) 1656 return -1; /* errno is set for us. */ 1657 1658 if ((rc = func (name, otype, offset, depth, arg)) != 0) 1659 return rc; 1660 1661 if (!nonrepresentable) 1662 kind = LCTF_INFO_KIND (fp, tp->ctt_info); 1663 1664 if (nonrepresentable || (kind != CTF_K_STRUCT && kind != CTF_K_UNION)) 1665 return 0; 1666 1667 ctf_get_ctt_size (fp, tp, &size, &increment); 1668 1669 n = LCTF_INFO_VLEN (fp, tp->ctt_info); 1670 if ((dtd = ctf_dynamic_type (fp, type)) != NULL) 1671 { 1672 vlen = dtd->dtd_vlen; 1673 vbytes = dtd->dtd_vlen_alloc; 1674 } 1675 else 1676 { 1677 vlen = (unsigned char *) tp + increment; 1678 vbytes = LCTF_VBYTES (fp, kind, size, n); 1679 } 1680 1681 for (; n != 0; n--, i++) 1682 { 1683 ctf_lmember_t memb; 1684 1685 if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0) 1686 return -1; /* errno is set for us. */ 1687 1688 if ((rc = ctf_type_rvisit (fp, memb.ctlm_type, 1689 func, arg, ctf_strptr (fp, memb.ctlm_name), 1690 offset + (unsigned long) CTF_LMEM_OFFSET (&memb), 1691 depth + 1)) != 0) 1692 return rc; 1693 } 1694 1695 return 0; 1696} 1697 1698/* Recursively visit the members of any type. We pass the name, member 1699 type, and offset of each member to the specified callback function. */ 1700int 1701ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg) 1702{ 1703 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0)); 1704} 1705