1 /* Symbol, variable and name lookup. 2 Copyright (C) 2019-2024 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 <elf.h> 22 #include <string.h> 23 #include <assert.h> 24 25 /* Grow the pptrtab so that it is at least NEW_LEN long. */ 26 static int 27 grow_pptrtab (ctf_dict_t *fp, size_t new_len) 28 { 29 uint32_t *new_pptrtab; 30 31 if ((new_pptrtab = realloc (fp->ctf_pptrtab, sizeof (uint32_t) 32 * new_len)) == NULL) 33 return (ctf_set_errno (fp, ENOMEM)); 34 35 fp->ctf_pptrtab = new_pptrtab; 36 37 memset (fp->ctf_pptrtab + fp->ctf_pptrtab_len, 0, 38 sizeof (uint32_t) * (new_len - fp->ctf_pptrtab_len)); 39 40 fp->ctf_pptrtab_len = new_len; 41 return 0; 42 } 43 44 /* Update entries in the pptrtab that relate to types newly added in the 45 child. */ 46 static int 47 refresh_pptrtab (ctf_dict_t *fp, ctf_dict_t *pfp) 48 { 49 uint32_t i; 50 for (i = fp->ctf_pptrtab_typemax; i <= fp->ctf_typemax; i++) 51 { 52 ctf_id_t type = LCTF_INDEX_TO_TYPE (fp, i, 1); 53 ctf_id_t reffed_type; 54 55 if (ctf_type_kind (fp, type) != CTF_K_POINTER) 56 continue; 57 58 reffed_type = ctf_type_reference (fp, type); 59 60 if (LCTF_TYPE_ISPARENT (fp, reffed_type)) 61 { 62 uint32_t idx = LCTF_TYPE_TO_INDEX (fp, reffed_type); 63 64 /* Guard against references to invalid types. No need to consider 65 the CTF dict corrupt in this case: this pointer just can't be a 66 pointer to any type we know about. */ 67 if (idx <= pfp->ctf_typemax) 68 { 69 if (idx >= fp->ctf_pptrtab_len 70 && grow_pptrtab (fp, pfp->ctf_ptrtab_len) < 0) 71 return -1; /* errno is set for us. */ 72 73 fp->ctf_pptrtab[idx] = i; 74 } 75 } 76 } 77 78 fp->ctf_pptrtab_typemax = fp->ctf_typemax; 79 80 return 0; 81 } 82 83 /* Compare the given input string and length against a table of known C storage 84 qualifier keywords. We just ignore these in ctf_lookup_by_name, below. To 85 do this quickly, we use a pre-computed Perfect Hash Function similar to the 86 technique originally described in the classic paper: 87 88 R.J. Cichelli, "Minimal Perfect Hash Functions Made Simple", 89 Communications of the ACM, Volume 23, Issue 1, January 1980, pp. 17-19. 90 91 For an input string S of length N, we use hash H = S[N - 1] + N - 105, which 92 for the current set of qualifiers yields a unique H in the range [0 .. 20]. 93 The hash can be modified when the keyword set changes as necessary. We also 94 store the length of each keyword and check it prior to the final strcmp(). 95 96 TODO: just use gperf. */ 97 98 static int 99 isqualifier (const char *s, size_t len) 100 { 101 static const struct qual 102 { 103 const char *q_name; 104 size_t q_len; 105 } qhash[] = { 106 {"static", 6}, {"", 0}, {"", 0}, {"", 0}, 107 {"volatile", 8}, {"", 0}, {"", 0}, {"", 0}, {"", 0}, 108 {"", 0}, {"auto", 4}, {"extern", 6}, {"", 0}, {"", 0}, 109 {"", 0}, {"", 0}, {"const", 5}, {"register", 8}, 110 {"", 0}, {"restrict", 8}, {"_Restrict", 9} 111 }; 112 113 int h = s[len - 1] + (int) len - 105; 114 const struct qual *qp; 115 116 if (h < 0 || (size_t) h >= sizeof (qhash) / sizeof (qhash[0])) 117 return 0; 118 119 qp = &qhash[h]; 120 121 return ((size_t) len == qp->q_len && 122 strncmp (qp->q_name, s, qp->q_len) == 0); 123 } 124 125 /* Attempt to convert the given C type name into the corresponding CTF type ID. 126 It is not possible to do complete and proper conversion of type names 127 without implementing a more full-fledged parser, which is necessary to 128 handle things like types that are function pointers to functions that 129 have arguments that are function pointers, and fun stuff like that. 130 Instead, this function implements a very simple conversion algorithm that 131 finds the things that we actually care about: structs, unions, enums, 132 integers, floats, typedefs, and pointers to any of these named types. */ 133 134 static ctf_id_t 135 ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child, 136 const char *name) 137 { 138 static const char delimiters[] = " \t\n\r\v\f*"; 139 140 const ctf_lookup_t *lp; 141 const char *p, *q, *end; 142 ctf_id_t type = 0; 143 ctf_id_t ntype, ptype; 144 145 if (name == NULL) 146 return (ctf_set_typed_errno (fp, EINVAL)); 147 148 for (p = name, end = name + strlen (name); *p != '\0'; p = q) 149 { 150 while (isspace ((int) *p)) 151 p++; /* Skip leading whitespace. */ 152 153 if (p == end) 154 break; 155 156 if ((q = strpbrk (p + 1, delimiters)) == NULL) 157 q = end; /* Compare until end. */ 158 159 if (*p == '*') 160 { 161 /* Find a pointer to type by looking in child->ctf_pptrtab (if child 162 is set) and fp->ctf_ptrtab. If we can't find a pointer to the 163 given type, see if we can compute a pointer to the type resulting 164 from resolving the type down to its base type and use that instead. 165 This helps with cases where the CTF data includes "struct foo *" 166 but not "foo_t *" and the user tries to access "foo_t *" in the 167 debugger. 168 169 There is extra complexity here because uninitialized elements in 170 the pptrtab and ptrtab are set to zero, but zero (as the type ID 171 meaning the unimplemented type) is a valid return type from 172 ctf_lookup_by_name. (Pointers to types are never of type 0, so 173 this is unambiguous, just fiddly to deal with.) */ 174 175 uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type); 176 int in_child = 0; 177 178 ntype = CTF_ERR; 179 if (child && idx < child->ctf_pptrtab_len) 180 { 181 ntype = child->ctf_pptrtab[idx]; 182 if (ntype) 183 in_child = 1; 184 else 185 ntype = CTF_ERR; 186 } 187 188 if (ntype == CTF_ERR) 189 { 190 ntype = fp->ctf_ptrtab[idx]; 191 if (ntype == 0) 192 ntype = CTF_ERR; 193 } 194 195 /* Try resolving to its base type and check again. */ 196 if (ntype == CTF_ERR) 197 { 198 if (child) 199 ntype = ctf_type_resolve_unsliced (child, type); 200 else 201 ntype = ctf_type_resolve_unsliced (fp, type); 202 203 if (ntype == CTF_ERR) 204 goto notype; 205 206 idx = LCTF_TYPE_TO_INDEX (fp, ntype); 207 208 ntype = CTF_ERR; 209 if (child && idx < child->ctf_pptrtab_len) 210 { 211 ntype = child->ctf_pptrtab[idx]; 212 if (ntype) 213 in_child = 1; 214 else 215 ntype = CTF_ERR; 216 } 217 218 if (ntype == CTF_ERR) 219 { 220 ntype = fp->ctf_ptrtab[idx]; 221 if (ntype == 0) 222 ntype = CTF_ERR; 223 } 224 if (ntype == CTF_ERR) 225 goto notype; 226 } 227 228 type = LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD) 229 || in_child); 230 231 /* We are looking up a type in the parent, but the pointed-to type is 232 in the child. Switch to looking in the child: if we need to go 233 back into the parent, we can recurse again. */ 234 if (in_child) 235 { 236 fp = child; 237 child = NULL; 238 } 239 240 q = p + 1; 241 continue; 242 } 243 244 if (isqualifier (p, (size_t) (q - p))) 245 continue; /* Skip qualifier keyword. */ 246 247 for (lp = fp->ctf_lookups; lp->ctl_prefix != NULL; lp++) 248 { 249 /* TODO: This is not MT-safe. */ 250 if ((lp->ctl_prefix[0] == '\0' || 251 strncmp (p, lp->ctl_prefix, (size_t) (q - p)) == 0) && 252 (size_t) (q - p) >= lp->ctl_len) 253 { 254 for (p += lp->ctl_len; isspace ((int) *p); p++) 255 continue; /* Skip prefix and next whitespace. */ 256 257 if ((q = strchr (p, '*')) == NULL) 258 q = end; /* Compare until end. */ 259 260 while (isspace ((int) q[-1])) 261 q--; /* Exclude trailing whitespace. */ 262 263 /* Expand and/or allocate storage for a slice of the name, then 264 copy it in. */ 265 266 if (fp->ctf_tmp_typeslicelen >= (size_t) (q - p) + 1) 267 { 268 memcpy (fp->ctf_tmp_typeslice, p, (size_t) (q - p)); 269 fp->ctf_tmp_typeslice[(size_t) (q - p)] = '\0'; 270 } 271 else 272 { 273 free (fp->ctf_tmp_typeslice); 274 fp->ctf_tmp_typeslice = xstrndup (p, (size_t) (q - p)); 275 if (fp->ctf_tmp_typeslice == NULL) 276 return ctf_set_typed_errno (fp, ENOMEM); 277 } 278 279 if ((type = ctf_lookup_by_rawhash (fp, lp->ctl_hash, 280 fp->ctf_tmp_typeslice)) == 0) 281 goto notype; 282 283 break; 284 } 285 } 286 287 if (lp->ctl_prefix == NULL) 288 goto notype; 289 } 290 291 if (*p != '\0' || type == 0) 292 return (ctf_set_typed_errno (fp, ECTF_SYNTAX)); 293 294 return type; 295 296 notype: 297 ctf_set_errno (fp, ECTF_NOTYPE); 298 if (fp->ctf_parent != NULL) 299 { 300 /* Need to look up in the parent, from the child's perspective. 301 Make sure the pptrtab is up to date. */ 302 303 if (fp->ctf_pptrtab_typemax < fp->ctf_typemax) 304 { 305 if (refresh_pptrtab (fp, fp->ctf_parent) < 0) 306 return CTF_ERR; /* errno is set for us. */ 307 } 308 309 if ((ptype = ctf_lookup_by_name_internal (fp->ctf_parent, fp, 310 name)) != CTF_ERR) 311 return ptype; 312 return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent))); 313 } 314 315 return CTF_ERR; 316 } 317 318 ctf_id_t 319 ctf_lookup_by_name (ctf_dict_t *fp, const char *name) 320 { 321 return ctf_lookup_by_name_internal (fp, NULL, name); 322 } 323 324 /* Return the pointer to the internal CTF type data corresponding to the 325 given type ID. If the ID is invalid, the function returns NULL. 326 This function is not exported outside of the library. */ 327 328 const ctf_type_t * 329 ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type) 330 { 331 ctf_dict_t *fp = *fpp; /* Caller passes in starting CTF dict. */ 332 ctf_id_t idx; 333 334 if ((fp = ctf_get_dict (fp, type)) == NULL) 335 { 336 (void) ctf_set_errno (*fpp, ECTF_NOPARENT); 337 return NULL; 338 } 339 340 /* If this dict is writable, check for a dynamic type. */ 341 342 if (fp->ctf_flags & LCTF_RDWR) 343 { 344 ctf_dtdef_t *dtd; 345 346 if ((dtd = ctf_dynamic_type (fp, type)) != NULL) 347 { 348 *fpp = fp; 349 return &dtd->dtd_data; 350 } 351 (void) ctf_set_errno (*fpp, ECTF_BADID); 352 return NULL; 353 } 354 355 /* Check for a type in the static portion. */ 356 357 idx = LCTF_TYPE_TO_INDEX (fp, type); 358 if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax) 359 { 360 *fpp = fp; /* Function returns ending CTF dict. */ 361 return (LCTF_INDEX_TO_TYPEPTR (fp, idx)); 362 } 363 364 (void) ctf_set_errno (*fpp, ECTF_BADID); 365 return NULL; 366 } 367 368 typedef struct ctf_lookup_idx_key 369 { 370 ctf_dict_t *clik_fp; 371 const char *clik_name; 372 uint32_t *clik_names; 373 } ctf_lookup_idx_key_t; 374 375 /* A bsearch function for variable names. */ 376 377 static int 378 ctf_lookup_var (const void *key_, const void *lookup_) 379 { 380 const ctf_lookup_idx_key_t *key = key_; 381 const ctf_varent_t *lookup = lookup_; 382 383 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name))); 384 } 385 386 /* Given a variable name, return the type of the variable with that name. */ 387 388 ctf_id_t 389 ctf_lookup_variable (ctf_dict_t *fp, const char *name) 390 { 391 ctf_varent_t *ent; 392 ctf_lookup_idx_key_t key = { fp, name, NULL }; 393 394 /* This array is sorted, so we can bsearch for it. */ 395 396 ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t), 397 ctf_lookup_var); 398 399 if (ent == NULL) 400 { 401 if (fp->ctf_parent != NULL) 402 { 403 ctf_id_t ptype; 404 405 if ((ptype = ctf_lookup_variable (fp->ctf_parent, name)) != CTF_ERR) 406 return ptype; 407 return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent))); 408 } 409 410 return (ctf_set_typed_errno (fp, ECTF_NOTYPEDAT)); 411 } 412 413 return ent->ctv_type; 414 } 415 416 typedef struct ctf_symidx_sort_arg_cb 417 { 418 ctf_dict_t *fp; 419 uint32_t *names; 420 } ctf_symidx_sort_arg_cb_t; 421 422 static int 423 sort_symidx_by_name (const void *one_, const void *two_, void *arg_) 424 { 425 const uint32_t *one = one_; 426 const uint32_t *two = two_; 427 ctf_symidx_sort_arg_cb_t *arg = arg_; 428 429 return (strcmp (ctf_strptr (arg->fp, arg->names[*one]), 430 ctf_strptr (arg->fp, arg->names[*two]))); 431 } 432 433 /* Sort a symbol index section by name. Takes a 1:1 mapping of names to the 434 corresponding symbol table. Returns a lexicographically sorted array of idx 435 indexes (and thus, of indexes into the corresponding func info / data object 436 section). */ 437 438 static uint32_t * 439 ctf_symidx_sort (ctf_dict_t *fp, uint32_t *idx, size_t *nidx, 440 size_t len) 441 { 442 uint32_t *sorted; 443 size_t i; 444 445 if ((sorted = malloc (len)) == NULL) 446 { 447 ctf_set_errno (fp, ENOMEM); 448 return NULL; 449 } 450 451 *nidx = len / sizeof (uint32_t); 452 for (i = 0; i < *nidx; i++) 453 sorted[i] = i; 454 455 if (!(fp->ctf_header->cth_flags & CTF_F_IDXSORTED)) 456 { 457 ctf_symidx_sort_arg_cb_t arg = { fp, idx }; 458 ctf_dprintf ("Index section unsorted: sorting."); 459 ctf_qsort_r (sorted, *nidx, sizeof (uint32_t), sort_symidx_by_name, &arg); 460 fp->ctf_header->cth_flags |= CTF_F_IDXSORTED; 461 } 462 463 return sorted; 464 } 465 466 /* Given a symbol index, return the name of that symbol from the table provided 467 by ctf_link_shuffle_syms, or failing that from the secondary string table, or 468 the null string. */ 469 static const char * 470 ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx) 471 { 472 const ctf_sect_t *sp = &fp->ctf_symtab; 473 ctf_link_sym_t sym; 474 int err; 475 476 if (fp->ctf_dynsymidx) 477 { 478 err = EINVAL; 479 if (symidx > fp->ctf_dynsymmax) 480 goto try_parent; 481 482 ctf_link_sym_t *symp = fp->ctf_dynsymidx[symidx]; 483 484 if (!symp) 485 goto try_parent; 486 487 return symp->st_name; 488 } 489 490 err = ECTF_NOSYMTAB; 491 if (sp->cts_data == NULL) 492 goto try_parent; 493 494 if (symidx >= fp->ctf_nsyms) 495 goto try_parent; 496 497 switch (sp->cts_entsize) 498 { 499 case sizeof (Elf64_Sym): 500 { 501 const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx; 502 ctf_elf64_to_link_sym (fp, &sym, symp, symidx); 503 } 504 break; 505 case sizeof (Elf32_Sym): 506 { 507 const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx; 508 ctf_elf32_to_link_sym (fp, &sym, symp, symidx); 509 } 510 break; 511 default: 512 ctf_set_errno (fp, ECTF_SYMTAB); 513 return _CTF_NULLSTR; 514 } 515 516 assert (!sym.st_nameidx_set); 517 518 return sym.st_name; 519 520 try_parent: 521 if (fp->ctf_parent) 522 { 523 const char *ret; 524 ret = ctf_lookup_symbol_name (fp->ctf_parent, symidx); 525 if (ret == NULL) 526 ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); 527 return ret; 528 } 529 else 530 { 531 ctf_set_errno (fp, err); 532 return _CTF_NULLSTR; 533 } 534 } 535 536 /* Given a symbol name, return the index of that symbol, or -1 on error or if 537 not found. */ 538 static unsigned long 539 ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname) 540 { 541 const ctf_sect_t *sp = &fp->ctf_symtab; 542 ctf_link_sym_t sym; 543 void *known_idx; 544 int err; 545 ctf_dict_t *cache = fp; 546 547 if (fp->ctf_dynsyms) 548 { 549 err = EINVAL; 550 551 ctf_link_sym_t *symp; 552 553 if ((symp = ctf_dynhash_lookup (fp->ctf_dynsyms, symname)) == NULL) 554 goto try_parent; 555 556 return symp->st_symidx; 557 } 558 559 err = ECTF_NOSYMTAB; 560 if (sp->cts_data == NULL) 561 goto try_parent; 562 563 /* First, try a hash lookup to see if we have already spotted this symbol 564 during a past iteration: create the hash first if need be. The lifespan 565 of the strings is equal to the lifespan of the cts_data, so we don't 566 need to strdup them. If this dict was opened as part of an archive, 567 and this archive has designed a crossdict_cache to cache results that 568 are the same across all dicts in an archive, use it. */ 569 570 if (fp->ctf_archive && fp->ctf_archive->ctfi_crossdict_cache) 571 cache = fp->ctf_archive->ctfi_crossdict_cache; 572 573 if (!cache->ctf_symhash) 574 if ((cache->ctf_symhash = ctf_dynhash_create (ctf_hash_string, 575 ctf_hash_eq_string, 576 NULL, NULL)) == NULL) 577 goto oom; 578 579 if (ctf_dynhash_lookup_kv (cache->ctf_symhash, symname, NULL, &known_idx)) 580 return (unsigned long) (uintptr_t) known_idx; 581 582 /* Hash lookup unsuccessful: linear search, populating the hashtab for later 583 lookups as we go. */ 584 585 for (; cache->ctf_symhash_latest < sp->cts_size / sp->cts_entsize; 586 cache->ctf_symhash_latest++) 587 { 588 switch (sp->cts_entsize) 589 { 590 case sizeof (Elf64_Sym): 591 { 592 Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data; 593 ctf_elf64_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest], 594 cache->ctf_symhash_latest); 595 if (!ctf_dynhash_lookup_kv (cache->ctf_symhash, sym.st_name, 596 NULL, NULL)) 597 if (ctf_dynhash_cinsert (cache->ctf_symhash, sym.st_name, 598 (const void *) (uintptr_t) 599 cache->ctf_symhash_latest) < 0) 600 goto oom; 601 if (strcmp (sym.st_name, symname) == 0) 602 return cache->ctf_symhash_latest++; 603 } 604 break; 605 case sizeof (Elf32_Sym): 606 { 607 Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data; 608 ctf_elf32_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest], 609 cache->ctf_symhash_latest); 610 if (!ctf_dynhash_lookup_kv (cache->ctf_symhash, sym.st_name, 611 NULL, NULL)) 612 if (ctf_dynhash_cinsert (cache->ctf_symhash, sym.st_name, 613 (const void *) (uintptr_t) 614 cache->ctf_symhash_latest) < 0) 615 goto oom; 616 if (strcmp (sym.st_name, symname) == 0) 617 return cache->ctf_symhash_latest++; 618 } 619 break; 620 default: 621 ctf_set_errno (fp, ECTF_SYMTAB); 622 return (unsigned long) -1; 623 } 624 } 625 626 /* Searched everything, still not found. */ 627 628 return (unsigned long) -1; 629 630 try_parent: 631 if (fp->ctf_parent) 632 { 633 unsigned long psym; 634 635 if ((psym = ctf_lookup_symbol_idx (fp->ctf_parent, symname)) 636 != (unsigned long) -1) 637 return psym; 638 639 ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); 640 return (unsigned long) -1; 641 } 642 else 643 { 644 ctf_set_errno (fp, err); 645 return (unsigned long) -1; 646 } 647 oom: 648 ctf_set_errno (fp, ENOMEM); 649 ctf_err_warn (fp, 0, ENOMEM, _("cannot allocate memory for symbol " 650 "lookup hashtab")); 651 return (unsigned long) -1; 652 653 } 654 655 /* Iterate over all symbols with types: if FUNC, function symbols, otherwise, 656 data symbols. The name argument is not optional. The return order is 657 arbitrary, though is likely to be in symbol index or name order. You can 658 change the value of 'functions' in the middle of iteration over non-dynamic 659 dicts, but doing so on dynamic dicts will fail. (This is probably not very 660 useful, but there is no reason to prohibit it.) */ 661 662 ctf_id_t 663 ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name, 664 int functions) 665 { 666 ctf_id_t sym = CTF_ERR; 667 ctf_next_t *i = *it; 668 int err; 669 670 if (!i) 671 { 672 if ((i = ctf_next_create ()) == NULL) 673 return ctf_set_typed_errno (fp, ENOMEM); 674 675 i->cu.ctn_fp = fp; 676 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next; 677 i->ctn_n = 0; 678 *it = i; 679 } 680 681 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun) 682 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN)); 683 684 if (fp != i->cu.ctn_fp) 685 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP)); 686 687 /* We intentionally use raw access, not ctf_lookup_by_symbol, to avoid 688 incurring additional sorting cost for unsorted symtypetabs coming from the 689 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and 690 finally because it's easier to work out what the name of each symbol is if 691 we do that. */ 692 693 if (fp->ctf_flags & LCTF_RDWR) 694 { 695 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash; 696 void *dyn_name = NULL, *dyn_value = NULL; 697 698 if (!dynh) 699 { 700 ctf_next_destroy (i); 701 return (ctf_set_typed_errno (fp, ECTF_NEXT_END)); 702 } 703 704 err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value); 705 /* This covers errors and also end-of-iteration. */ 706 if (err != 0) 707 { 708 ctf_next_destroy (i); 709 *it = NULL; 710 return ctf_set_typed_errno (fp, err); 711 } 712 713 *name = dyn_name; 714 sym = (ctf_id_t) (uintptr_t) dyn_value; 715 } 716 else if ((!functions && fp->ctf_objtidx_names) || 717 (functions && fp->ctf_funcidx_names)) 718 { 719 ctf_header_t *hp = fp->ctf_header; 720 uint32_t *idx = functions ? fp->ctf_funcidx_names : fp->ctf_objtidx_names; 721 uint32_t *tab; 722 size_t len; 723 724 if (functions) 725 { 726 len = (hp->cth_varoff - hp->cth_funcidxoff) / sizeof (uint32_t); 727 tab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff); 728 } 729 else 730 { 731 len = (hp->cth_funcidxoff - hp->cth_objtidxoff) / sizeof (uint32_t); 732 tab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff); 733 } 734 735 do 736 { 737 if (i->ctn_n >= len) 738 goto end; 739 740 *name = ctf_strptr (fp, idx[i->ctn_n]); 741 sym = tab[i->ctn_n++]; 742 } 743 while (sym == -1u || sym == 0); 744 } 745 else 746 { 747 /* Skip over pads in ctf_xslate, padding for typeless symbols in the 748 symtypetab itself, and symbols in the wrong table. */ 749 for (; i->ctn_n < fp->ctf_nsyms; i->ctn_n++) 750 { 751 ctf_header_t *hp = fp->ctf_header; 752 753 if (fp->ctf_sxlate[i->ctn_n] == -1u) 754 continue; 755 756 sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[i->ctn_n]); 757 758 if (sym == 0) 759 continue; 760 761 if (functions) 762 { 763 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_funcoff 764 && fp->ctf_sxlate[i->ctn_n] < hp->cth_objtidxoff) 765 break; 766 } 767 else 768 { 769 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_objtoff 770 && fp->ctf_sxlate[i->ctn_n] < hp->cth_funcoff) 771 break; 772 } 773 } 774 775 if (i->ctn_n >= fp->ctf_nsyms) 776 goto end; 777 778 *name = ctf_lookup_symbol_name (fp, i->ctn_n++); 779 } 780 781 return sym; 782 783 end: 784 ctf_next_destroy (i); 785 *it = NULL; 786 return (ctf_set_typed_errno (fp, ECTF_NEXT_END)); 787 } 788 789 /* A bsearch function for function and object index names. */ 790 791 static int 792 ctf_lookup_idx_name (const void *key_, const void *idx_) 793 { 794 const ctf_lookup_idx_key_t *key = key_; 795 const uint32_t *idx = idx_; 796 797 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx]))); 798 } 799 800 /* Given a symbol name or (failing that) number, look up that symbol in the 801 function or object index table (which must exist). Return 0 if not found 802 there (or pad). */ 803 804 static ctf_id_t 805 ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx, 806 const char *symname, int is_function) 807 { 808 struct ctf_header *hp = fp->ctf_header; 809 uint32_t *symtypetab; 810 uint32_t *names; 811 uint32_t *sxlate; 812 size_t nidx; 813 814 if (symname == NULL) 815 symname = ctf_lookup_symbol_name (fp, symidx); 816 817 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in " 818 "indexed symtypetab\n", symidx, symname); 819 820 if (symname[0] == '\0') 821 return CTF_ERR; /* errno is set for us. */ 822 823 if (is_function) 824 { 825 if (!fp->ctf_funcidx_sxlate) 826 { 827 if ((fp->ctf_funcidx_sxlate 828 = ctf_symidx_sort (fp, (uint32_t *) 829 (fp->ctf_buf + hp->cth_funcidxoff), 830 &fp->ctf_nfuncidx, 831 hp->cth_varoff - hp->cth_funcidxoff)) 832 == NULL) 833 { 834 ctf_err_warn (fp, 0, 0, _("cannot sort function symidx")); 835 return CTF_ERR; /* errno is set for us. */ 836 } 837 } 838 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff); 839 sxlate = fp->ctf_funcidx_sxlate; 840 names = fp->ctf_funcidx_names; 841 nidx = fp->ctf_nfuncidx; 842 } 843 else 844 { 845 if (!fp->ctf_objtidx_sxlate) 846 { 847 if ((fp->ctf_objtidx_sxlate 848 = ctf_symidx_sort (fp, (uint32_t *) 849 (fp->ctf_buf + hp->cth_objtidxoff), 850 &fp->ctf_nobjtidx, 851 hp->cth_funcidxoff - hp->cth_objtidxoff)) 852 == NULL) 853 { 854 ctf_err_warn (fp, 0, 0, _("cannot sort object symidx")); 855 return CTF_ERR; /* errno is set for us. */ 856 } 857 } 858 859 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff); 860 sxlate = fp->ctf_objtidx_sxlate; 861 names = fp->ctf_objtidx_names; 862 nidx = fp->ctf_nobjtidx; 863 } 864 865 ctf_lookup_idx_key_t key = { fp, symname, names }; 866 uint32_t *idx; 867 868 idx = bsearch (&key, sxlate, nidx, sizeof (uint32_t), ctf_lookup_idx_name); 869 870 if (!idx) 871 { 872 ctf_dprintf ("%s not found in idx\n", symname); 873 return 0; 874 } 875 876 /* Should be impossible, but be paranoid. */ 877 if ((idx - sxlate) > (ptrdiff_t) nidx) 878 return (ctf_set_typed_errno (fp, ECTF_CORRUPT)); 879 880 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname, 881 symtypetab[*idx]); 882 return symtypetab[*idx]; 883 } 884 885 /* Given a symbol name or (if NULL) symbol index, return the type of the 886 function or data object described by the corresponding entry in the symbol 887 table. We can only return symbols in read-only dicts and in dicts for which 888 ctf_link_shuffle_syms has been called to assign symbol indexes to symbol 889 names. */ 890 891 static ctf_id_t 892 ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx, 893 const char *symname) 894 { 895 const ctf_sect_t *sp = &fp->ctf_symtab; 896 ctf_id_t type = 0; 897 int err = 0; 898 899 /* Shuffled dynsymidx present? Use that. */ 900 if (fp->ctf_dynsymidx) 901 { 902 const ctf_link_sym_t *sym; 903 904 if (symname) 905 ctf_dprintf ("Looking up type of object with symname %s in " 906 "writable dict symtypetab\n", symname); 907 else 908 ctf_dprintf ("Looking up type of object with symtab idx %lx in " 909 "writable dict symtypetab\n", symidx); 910 911 /* The dict must be dynamic. */ 912 if (!ctf_assert (fp, fp->ctf_flags & LCTF_RDWR)) 913 return CTF_ERR; 914 915 /* No name? Need to look it up. */ 916 if (!symname) 917 { 918 err = EINVAL; 919 if (symidx > fp->ctf_dynsymmax) 920 goto try_parent; 921 922 sym = fp->ctf_dynsymidx[symidx]; 923 err = ECTF_NOTYPEDAT; 924 if (!sym || (sym->st_shndx != STT_OBJECT && sym->st_shndx != STT_FUNC)) 925 goto try_parent; 926 927 if (!ctf_assert (fp, !sym->st_nameidx_set)) 928 return CTF_ERR; 929 symname = sym->st_name; 930 } 931 932 if (fp->ctf_objthash == NULL 933 || ((type = (ctf_id_t) (uintptr_t) 934 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0)) 935 { 936 if (fp->ctf_funchash == NULL 937 || ((type = (ctf_id_t) (uintptr_t) 938 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0)) 939 goto try_parent; 940 } 941 942 return type; 943 } 944 945 /* Lookup by name in a dynamic dict: just do it directly. */ 946 if (symname && fp->ctf_flags & LCTF_RDWR) 947 { 948 if (fp->ctf_objthash == NULL 949 || ((type = (ctf_id_t) (uintptr_t) 950 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0)) 951 { 952 if (fp->ctf_funchash == NULL 953 || ((type = (ctf_id_t) (uintptr_t) 954 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0)) 955 goto try_parent; 956 } 957 return type; 958 } 959 960 err = ECTF_NOSYMTAB; 961 if (sp->cts_data == NULL) 962 goto try_parent; 963 964 /* This covers both out-of-range lookups and a dynamic dict which hasn't been 965 shuffled yet. */ 966 err = EINVAL; 967 if (symname == NULL && symidx >= fp->ctf_nsyms) 968 goto try_parent; 969 970 if (fp->ctf_objtidx_names) 971 { 972 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR) 973 return CTF_ERR; /* errno is set for us. */ 974 } 975 if (type == 0 && fp->ctf_funcidx_names) 976 { 977 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR) 978 return CTF_ERR; /* errno is set for us. */ 979 } 980 if (type != 0) 981 return type; 982 983 err = ECTF_NOTYPEDAT; 984 if (fp->ctf_objtidx_names && fp->ctf_funcidx_names) 985 goto try_parent; 986 987 /* Table must be nonindexed. */ 988 989 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx); 990 991 if (symname != NULL) 992 if ((symidx = ctf_lookup_symbol_idx (fp, symname)) == (unsigned long) -1) 993 goto try_parent; 994 995 if (fp->ctf_sxlate[symidx] == -1u) 996 goto try_parent; 997 998 type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]); 999 1000 if (type == 0) 1001 goto try_parent; 1002 1003 return type; 1004 try_parent: 1005 if (fp->ctf_parent) 1006 { 1007 ctf_id_t ret = ctf_lookup_by_sym_or_name (fp->ctf_parent, symidx, 1008 symname); 1009 if (ret == CTF_ERR) 1010 ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); 1011 return ret; 1012 } 1013 else 1014 return (ctf_set_typed_errno (fp, err)); 1015 } 1016 1017 /* Given a symbol table index, return the type of the function or data object 1018 described by the corresponding entry in the symbol table. */ 1019 ctf_id_t 1020 ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx) 1021 { 1022 return ctf_lookup_by_sym_or_name (fp, symidx, NULL); 1023 } 1024 1025 /* Given a symbol name, return the type of the function or data object described 1026 by the corresponding entry in the symbol table. */ 1027 ctf_id_t 1028 ctf_lookup_by_symbol_name (ctf_dict_t *fp, const char *symname) 1029 { 1030 return ctf_lookup_by_sym_or_name (fp, 0, symname); 1031 } 1032 1033 /* Given a symbol table index, return the info for the function described 1034 by the corresponding entry in the symbol table, which may be a function 1035 symbol or may be a data symbol that happens to be a function pointer. */ 1036 1037 int 1038 ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip) 1039 { 1040 ctf_id_t type; 1041 1042 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR) 1043 return -1; /* errno is set for us. */ 1044 1045 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION) 1046 return (ctf_set_errno (fp, ECTF_NOTFUNC)); 1047 1048 return ctf_func_type_info (fp, type, fip); 1049 } 1050 1051 /* Given a symbol table index, return the arguments for the function described 1052 by the corresponding entry in the symbol table. */ 1053 1054 int 1055 ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc, 1056 ctf_id_t *argv) 1057 { 1058 ctf_id_t type; 1059 1060 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR) 1061 return -1; /* errno is set for us. */ 1062 1063 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION) 1064 return (ctf_set_errno (fp, ECTF_NOTFUNC)); 1065 1066 return ctf_func_type_args (fp, type, argc, argv); 1067 } 1068