1/* Symbol, variable and name lookup. 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 <elf.h> 22#include <string.h> 23#include <assert.h> 24 25/* Grow the pptrtab so that it is at least NEW_LEN long. */ 26static int 27grow_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. */ 46static int 47refresh_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 98static int 99isqualifier (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 134static ctf_id_t 135ctf_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_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 { 277 ctf_set_errno (fp, ENOMEM); 278 return CTF_ERR; 279 } 280 } 281 282 if ((type = ctf_lookup_by_rawhash (fp, lp->ctl_hash, 283 fp->ctf_tmp_typeslice)) == 0) 284 goto notype; 285 286 break; 287 } 288 } 289 290 if (lp->ctl_prefix == NULL) 291 goto notype; 292 } 293 294 if (*p != '\0' || type == 0) 295 return (ctf_set_errno (fp, ECTF_SYNTAX)); 296 297 return type; 298 299 notype: 300 ctf_set_errno (fp, ECTF_NOTYPE); 301 if (fp->ctf_parent != NULL) 302 { 303 /* Need to look up in the parent, from the child's perspective. 304 Make sure the pptrtab is up to date. */ 305 306 if (fp->ctf_pptrtab_typemax < fp->ctf_typemax) 307 { 308 if (refresh_pptrtab (fp, fp->ctf_parent) < 0) 309 return -1; /* errno is set for us. */ 310 } 311 312 if ((ptype = ctf_lookup_by_name_internal (fp->ctf_parent, fp, 313 name)) != CTF_ERR) 314 return ptype; 315 return (ctf_set_errno (fp, ctf_errno (fp->ctf_parent))); 316 } 317 318 return CTF_ERR; 319} 320 321ctf_id_t 322ctf_lookup_by_name (ctf_dict_t *fp, const char *name) 323{ 324 return ctf_lookup_by_name_internal (fp, NULL, name); 325} 326 327/* Return the pointer to the internal CTF type data corresponding to the 328 given type ID. If the ID is invalid, the function returns NULL. 329 This function is not exported outside of the library. */ 330 331const ctf_type_t * 332ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type) 333{ 334 ctf_dict_t *fp = *fpp; /* Caller passes in starting CTF dict. */ 335 ctf_id_t idx; 336 337 if ((fp = ctf_get_dict (fp, type)) == NULL) 338 { 339 (void) ctf_set_errno (*fpp, ECTF_NOPARENT); 340 return NULL; 341 } 342 343 /* If this dict is writable, check for a dynamic type. */ 344 345 if (fp->ctf_flags & LCTF_RDWR) 346 { 347 ctf_dtdef_t *dtd; 348 349 if ((dtd = ctf_dynamic_type (fp, type)) != NULL) 350 { 351 *fpp = fp; 352 return &dtd->dtd_data; 353 } 354 (void) ctf_set_errno (*fpp, ECTF_BADID); 355 return NULL; 356 } 357 358 /* Check for a type in the static portion. */ 359 360 idx = LCTF_TYPE_TO_INDEX (fp, type); 361 if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax) 362 { 363 *fpp = fp; /* Function returns ending CTF dict. */ 364 return (LCTF_INDEX_TO_TYPEPTR (fp, idx)); 365 } 366 367 (void) ctf_set_errno (*fpp, ECTF_BADID); 368 return NULL; 369} 370 371typedef struct ctf_lookup_idx_key 372{ 373 ctf_dict_t *clik_fp; 374 const char *clik_name; 375 uint32_t *clik_names; 376} ctf_lookup_idx_key_t; 377 378/* A bsearch function for variable names. */ 379 380static int 381ctf_lookup_var (const void *key_, const void *lookup_) 382{ 383 const ctf_lookup_idx_key_t *key = key_; 384 const ctf_varent_t *lookup = lookup_; 385 386 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name))); 387} 388 389/* Given a variable name, return the type of the variable with that name. */ 390 391ctf_id_t 392ctf_lookup_variable (ctf_dict_t *fp, const char *name) 393{ 394 ctf_varent_t *ent; 395 ctf_lookup_idx_key_t key = { fp, name, NULL }; 396 397 /* This array is sorted, so we can bsearch for it. */ 398 399 ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t), 400 ctf_lookup_var); 401 402 if (ent == NULL) 403 { 404 if (fp->ctf_parent != NULL) 405 return ctf_lookup_variable (fp->ctf_parent, name); 406 407 return (ctf_set_errno (fp, ECTF_NOTYPEDAT)); 408 } 409 410 return ent->ctv_type; 411} 412 413typedef struct ctf_symidx_sort_arg_cb 414{ 415 ctf_dict_t *fp; 416 uint32_t *names; 417} ctf_symidx_sort_arg_cb_t; 418 419static int 420sort_symidx_by_name (const void *one_, const void *two_, void *arg_) 421{ 422 const uint32_t *one = one_; 423 const uint32_t *two = two_; 424 ctf_symidx_sort_arg_cb_t *arg = arg_; 425 426 return (strcmp (ctf_strptr (arg->fp, arg->names[*one]), 427 ctf_strptr (arg->fp, arg->names[*two]))); 428} 429 430/* Sort a symbol index section by name. Takes a 1:1 mapping of names to the 431 corresponding symbol table. Returns a lexicographically sorted array of idx 432 indexes (and thus, of indexes into the corresponding func info / data object 433 section). */ 434 435static uint32_t * 436ctf_symidx_sort (ctf_dict_t *fp, uint32_t *idx, size_t *nidx, 437 size_t len) 438{ 439 uint32_t *sorted; 440 size_t i; 441 442 if ((sorted = malloc (len)) == NULL) 443 { 444 ctf_set_errno (fp, ENOMEM); 445 return NULL; 446 } 447 448 *nidx = len / sizeof (uint32_t); 449 for (i = 0; i < *nidx; i++) 450 sorted[i] = i; 451 452 if (!(fp->ctf_header->cth_flags & CTF_F_IDXSORTED)) 453 { 454 ctf_symidx_sort_arg_cb_t arg = { fp, idx }; 455 ctf_dprintf ("Index section unsorted: sorting."); 456 ctf_qsort_r (sorted, *nidx, sizeof (uint32_t), sort_symidx_by_name, &arg); 457 fp->ctf_header->cth_flags |= CTF_F_IDXSORTED; 458 } 459 460 return sorted; 461} 462 463/* Given a symbol index, return the name of that symbol from the table provided 464 by ctf_link_shuffle_syms, or failing that from the secondary string table, or 465 the null string. */ 466static const char * 467ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx) 468{ 469 const ctf_sect_t *sp = &fp->ctf_symtab; 470 ctf_link_sym_t sym; 471 int err; 472 473 if (fp->ctf_dynsymidx) 474 { 475 err = EINVAL; 476 if (symidx > fp->ctf_dynsymmax) 477 goto try_parent; 478 479 ctf_link_sym_t *symp = fp->ctf_dynsymidx[symidx]; 480 481 if (!symp) 482 goto try_parent; 483 484 return symp->st_name; 485 } 486 487 err = ECTF_NOSYMTAB; 488 if (sp->cts_data == NULL) 489 goto try_parent; 490 491 if (symidx >= fp->ctf_nsyms) 492 goto try_parent; 493 494 switch (sp->cts_entsize) 495 { 496 case sizeof (Elf64_Sym): 497 { 498 const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx; 499 ctf_elf64_to_link_sym (fp, &sym, symp, symidx); 500 } 501 break; 502 case sizeof (Elf32_Sym): 503 { 504 const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx; 505 ctf_elf32_to_link_sym (fp, &sym, symp, symidx); 506 } 507 break; 508 default: 509 ctf_set_errno (fp, ECTF_SYMTAB); 510 return _CTF_NULLSTR; 511 } 512 513 assert (!sym.st_nameidx_set); 514 515 return sym.st_name; 516 517 try_parent: 518 if (fp->ctf_parent) 519 { 520 const char *ret; 521 ret = ctf_lookup_symbol_name (fp->ctf_parent, symidx); 522 if (ret == NULL) 523 ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); 524 return ret; 525 } 526 else 527 { 528 ctf_set_errno (fp, err); 529 return _CTF_NULLSTR; 530 } 531} 532 533/* Given a symbol name, return the index of that symbol, or -1 on error or if 534 not found. */ 535static unsigned long 536ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname) 537{ 538 const ctf_sect_t *sp = &fp->ctf_symtab; 539 ctf_link_sym_t sym; 540 void *known_idx; 541 int err; 542 ctf_dict_t *cache = fp; 543 544 if (fp->ctf_dynsyms) 545 { 546 err = EINVAL; 547 548 ctf_link_sym_t *symp; 549 550 if ((symp = ctf_dynhash_lookup (fp->ctf_dynsyms, symname)) == NULL) 551 goto try_parent; 552 553 return symp->st_symidx; 554 } 555 556 err = ECTF_NOSYMTAB; 557 if (sp->cts_data == NULL) 558 goto try_parent; 559 560 /* First, try a hash lookup to see if we have already spotted this symbol 561 during a past iteration: create the hash first if need be. The lifespan 562 of the strings is equal to the lifespan of the cts_data, so we don't 563 need to strdup them. If this dict was opened as part of an archive, 564 and this archive has designed a crossdict_cache to cache results that 565 are the same across all dicts in an archive, use it. */ 566 567 if (fp->ctf_archive && fp->ctf_archive->ctfi_crossdict_cache) 568 cache = fp->ctf_archive->ctfi_crossdict_cache; 569 570 if (!cache->ctf_symhash) 571 if ((cache->ctf_symhash = ctf_dynhash_create (ctf_hash_string, 572 ctf_hash_eq_string, 573 NULL, NULL)) == NULL) 574 goto oom; 575 576 if (ctf_dynhash_lookup_kv (cache->ctf_symhash, symname, NULL, &known_idx)) 577 return (unsigned long) (uintptr_t) known_idx; 578 579 /* Hash lookup unsuccessful: linear search, populating the hashtab for later 580 lookups as we go. */ 581 582 for (; cache->ctf_symhash_latest < sp->cts_size / sp->cts_entsize; 583 cache->ctf_symhash_latest++) 584 { 585 switch (sp->cts_entsize) 586 { 587 case sizeof (Elf64_Sym): 588 { 589 Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data; 590 ctf_elf64_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest], 591 cache->ctf_symhash_latest); 592 if (!ctf_dynhash_lookup_kv (cache->ctf_symhash, sym.st_name, 593 NULL, NULL)) 594 if (ctf_dynhash_cinsert (cache->ctf_symhash, sym.st_name, 595 (const void *) (uintptr_t) 596 cache->ctf_symhash_latest) < 0) 597 goto oom; 598 if (strcmp (sym.st_name, symname) == 0) 599 return cache->ctf_symhash_latest++; 600 } 601 break; 602 case sizeof (Elf32_Sym): 603 { 604 Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data; 605 ctf_elf32_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest], 606 cache->ctf_symhash_latest); 607 if (!ctf_dynhash_lookup_kv (cache->ctf_symhash, sym.st_name, 608 NULL, NULL)) 609 if (ctf_dynhash_cinsert (cache->ctf_symhash, sym.st_name, 610 (const void *) (uintptr_t) 611 cache->ctf_symhash_latest) < 0) 612 goto oom; 613 if (strcmp (sym.st_name, symname) == 0) 614 return cache->ctf_symhash_latest++; 615 } 616 break; 617 default: 618 ctf_set_errno (fp, ECTF_SYMTAB); 619 return (unsigned long) -1; 620 } 621 } 622 623 /* Searched everything, still not found. */ 624 625 return (unsigned long) -1; 626 627 try_parent: 628 if (fp->ctf_parent) 629 return ctf_lookup_symbol_idx (fp->ctf_parent, symname); 630 else 631 { 632 ctf_set_errno (fp, err); 633 return (unsigned long) -1; 634 } 635oom: 636 ctf_set_errno (fp, ENOMEM); 637 ctf_err_warn (fp, 0, ENOMEM, _("cannot allocate memory for symbol " 638 "lookup hashtab")); 639 return (unsigned long) -1; 640 641} 642 643/* Iterate over all symbols with types: if FUNC, function symbols, otherwise, 644 data symbols. The name argument is not optional. The return order is 645 arbitrary, though is likely to be in symbol index or name order. You can 646 change the value of 'functions' in the middle of iteration over non-dynamic 647 dicts, but doing so on dynamic dicts will fail. (This is probably not very 648 useful, but there is no reason to prohibit it.) */ 649 650ctf_id_t 651ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name, 652 int functions) 653{ 654 ctf_id_t sym; 655 ctf_next_t *i = *it; 656 int err; 657 658 if (!i) 659 { 660 if ((i = ctf_next_create ()) == NULL) 661 return ctf_set_errno (fp, ENOMEM); 662 663 i->cu.ctn_fp = fp; 664 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next; 665 i->ctn_n = 0; 666 *it = i; 667 } 668 669 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun) 670 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN)); 671 672 if (fp != i->cu.ctn_fp) 673 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP)); 674 675 /* We intentionally use raw access, not ctf_lookup_by_symbol, to avoid 676 incurring additional sorting cost for unsorted symtypetabs coming from the 677 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and 678 finally because it's easier to work out what the name of each symbol is if 679 we do that. */ 680 681 if (fp->ctf_flags & LCTF_RDWR) 682 { 683 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash; 684 void *dyn_name = NULL, *dyn_value = NULL; 685 686 if (!dynh) 687 { 688 ctf_next_destroy (i); 689 return (ctf_set_errno (fp, ECTF_NEXT_END)); 690 } 691 692 err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value); 693 /* This covers errors and also end-of-iteration. */ 694 if (err != 0) 695 { 696 ctf_next_destroy (i); 697 *it = NULL; 698 return ctf_set_errno (fp, err); 699 } 700 701 *name = dyn_name; 702 sym = (ctf_id_t) (uintptr_t) dyn_value; 703 } 704 else if ((!functions && fp->ctf_objtidx_names) || 705 (functions && fp->ctf_funcidx_names)) 706 { 707 ctf_header_t *hp = fp->ctf_header; 708 uint32_t *idx = functions ? fp->ctf_funcidx_names : fp->ctf_objtidx_names; 709 uint32_t *tab; 710 size_t len; 711 712 if (functions) 713 { 714 len = (hp->cth_varoff - hp->cth_funcidxoff) / sizeof (uint32_t); 715 tab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff); 716 } 717 else 718 { 719 len = (hp->cth_funcidxoff - hp->cth_objtidxoff) / sizeof (uint32_t); 720 tab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff); 721 } 722 723 do 724 { 725 if (i->ctn_n >= len) 726 goto end; 727 728 *name = ctf_strptr (fp, idx[i->ctn_n]); 729 sym = tab[i->ctn_n++]; 730 } 731 while (sym == -1u || sym == 0); 732 } 733 else 734 { 735 /* Skip over pads in ctf_xslate, padding for typeless symbols in the 736 symtypetab itself, and symbols in the wrong table. */ 737 for (; i->ctn_n < fp->ctf_nsyms; i->ctn_n++) 738 { 739 ctf_header_t *hp = fp->ctf_header; 740 741 if (fp->ctf_sxlate[i->ctn_n] == -1u) 742 continue; 743 744 sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[i->ctn_n]); 745 746 if (sym == 0) 747 continue; 748 749 if (functions) 750 { 751 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_funcoff 752 && fp->ctf_sxlate[i->ctn_n] < hp->cth_objtidxoff) 753 break; 754 } 755 else 756 { 757 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_objtoff 758 && fp->ctf_sxlate[i->ctn_n] < hp->cth_funcoff) 759 break; 760 } 761 } 762 763 if (i->ctn_n >= fp->ctf_nsyms) 764 goto end; 765 766 *name = ctf_lookup_symbol_name (fp, i->ctn_n++); 767 } 768 769 return sym; 770 771 end: 772 ctf_next_destroy (i); 773 *it = NULL; 774 return (ctf_set_errno (fp, ECTF_NEXT_END)); 775} 776 777/* A bsearch function for function and object index names. */ 778 779static int 780ctf_lookup_idx_name (const void *key_, const void *idx_) 781{ 782 const ctf_lookup_idx_key_t *key = key_; 783 const uint32_t *idx = idx_; 784 785 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx]))); 786} 787 788/* Given a symbol name or (failing that) number, look up that symbol in the 789 function or object index table (which must exist). Return 0 if not found 790 there (or pad). */ 791 792static ctf_id_t 793ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx, 794 const char *symname, int is_function) 795{ 796 struct ctf_header *hp = fp->ctf_header; 797 uint32_t *symtypetab; 798 uint32_t *names; 799 uint32_t *sxlate; 800 size_t nidx; 801 802 if (symname == NULL) 803 symname = ctf_lookup_symbol_name (fp, symidx); 804 805 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in " 806 "indexed symtypetab\n", symidx, symname); 807 808 if (symname[0] == '\0') 809 return -1; /* errno is set for us. */ 810 811 if (is_function) 812 { 813 if (!fp->ctf_funcidx_sxlate) 814 { 815 if ((fp->ctf_funcidx_sxlate 816 = ctf_symidx_sort (fp, (uint32_t *) 817 (fp->ctf_buf + hp->cth_funcidxoff), 818 &fp->ctf_nfuncidx, 819 hp->cth_varoff - hp->cth_funcidxoff)) 820 == NULL) 821 { 822 ctf_err_warn (fp, 0, 0, _("cannot sort function symidx")); 823 return -1; /* errno is set for us. */ 824 } 825 } 826 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff); 827 sxlate = fp->ctf_funcidx_sxlate; 828 names = fp->ctf_funcidx_names; 829 nidx = fp->ctf_nfuncidx; 830 } 831 else 832 { 833 if (!fp->ctf_objtidx_sxlate) 834 { 835 if ((fp->ctf_objtidx_sxlate 836 = ctf_symidx_sort (fp, (uint32_t *) 837 (fp->ctf_buf + hp->cth_objtidxoff), 838 &fp->ctf_nobjtidx, 839 hp->cth_funcidxoff - hp->cth_objtidxoff)) 840 == NULL) 841 { 842 ctf_err_warn (fp, 0, 0, _("cannot sort object symidx")); 843 return -1; /* errno is set for us. */ 844 } 845 } 846 847 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff); 848 sxlate = fp->ctf_objtidx_sxlate; 849 names = fp->ctf_objtidx_names; 850 nidx = fp->ctf_nobjtidx; 851 } 852 853 ctf_lookup_idx_key_t key = { fp, symname, names }; 854 uint32_t *idx; 855 856 idx = bsearch (&key, sxlate, nidx, sizeof (uint32_t), ctf_lookup_idx_name); 857 858 if (!idx) 859 { 860 ctf_dprintf ("%s not found in idx\n", symname); 861 return 0; 862 } 863 864 /* Should be impossible, but be paranoid. */ 865 if ((idx - sxlate) > (ptrdiff_t) nidx) 866 return (ctf_set_errno (fp, ECTF_CORRUPT)); 867 868 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname, 869 symtypetab[*idx]); 870 return symtypetab[*idx]; 871} 872 873/* Given a symbol name or (if NULL) symbol index, return the type of the 874 function or data object described by the corresponding entry in the symbol 875 table. We can only return symbols in read-only dicts and in dicts for which 876 ctf_link_shuffle_syms has been called to assign symbol indexes to symbol 877 names. */ 878 879static ctf_id_t 880ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx, 881 const char *symname) 882{ 883 const ctf_sect_t *sp = &fp->ctf_symtab; 884 ctf_id_t type = 0; 885 int err = 0; 886 887 /* Shuffled dynsymidx present? Use that. */ 888 if (fp->ctf_dynsymidx) 889 { 890 const ctf_link_sym_t *sym; 891 892 if (symname) 893 ctf_dprintf ("Looking up type of object with symname %s in " 894 "writable dict symtypetab\n", symname); 895 else 896 ctf_dprintf ("Looking up type of object with symtab idx %lx in " 897 "writable dict symtypetab\n", symidx); 898 899 /* The dict must be dynamic. */ 900 if (!ctf_assert (fp, fp->ctf_flags & LCTF_RDWR)) 901 return CTF_ERR; 902 903 /* No name? Need to look it up. */ 904 if (!symname) 905 { 906 err = EINVAL; 907 if (symidx > fp->ctf_dynsymmax) 908 goto try_parent; 909 910 sym = fp->ctf_dynsymidx[symidx]; 911 err = ECTF_NOTYPEDAT; 912 if (!sym || (sym->st_shndx != STT_OBJECT && sym->st_shndx != STT_FUNC)) 913 goto try_parent; 914 915 if (!ctf_assert (fp, !sym->st_nameidx_set)) 916 return CTF_ERR; 917 symname = sym->st_name; 918 } 919 920 if (fp->ctf_objthash == NULL 921 || ((type = (ctf_id_t) (uintptr_t) 922 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0)) 923 { 924 if (fp->ctf_funchash == NULL 925 || ((type = (ctf_id_t) (uintptr_t) 926 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0)) 927 goto try_parent; 928 } 929 930 return type; 931 } 932 933 /* Lookup by name in a dynamic dict: just do it directly. */ 934 if (symname && fp->ctf_flags & LCTF_RDWR) 935 { 936 if (fp->ctf_objthash == NULL 937 || ((type = (ctf_id_t) (uintptr_t) 938 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0)) 939 { 940 if (fp->ctf_funchash == NULL 941 || ((type = (ctf_id_t) (uintptr_t) 942 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0)) 943 goto try_parent; 944 } 945 return type; 946 } 947 948 err = ECTF_NOSYMTAB; 949 if (sp->cts_data == NULL) 950 goto try_parent; 951 952 /* This covers both out-of-range lookups and a dynamic dict which hasn't been 953 shuffled yet. */ 954 err = EINVAL; 955 if (symname == NULL && symidx >= fp->ctf_nsyms) 956 goto try_parent; 957 958 if (fp->ctf_objtidx_names) 959 { 960 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR) 961 return CTF_ERR; /* errno is set for us. */ 962 } 963 if (type == 0 && fp->ctf_funcidx_names) 964 { 965 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR) 966 return CTF_ERR; /* errno is set for us. */ 967 } 968 if (type != 0) 969 return type; 970 971 err = ECTF_NOTYPEDAT; 972 if (fp->ctf_objtidx_names && fp->ctf_funcidx_names) 973 goto try_parent; 974 975 /* Table must be nonindexed. */ 976 977 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx); 978 979 if (symname != NULL) 980 if ((symidx = ctf_lookup_symbol_idx (fp, symname)) == (unsigned long) -1) 981 goto try_parent; 982 983 if (fp->ctf_sxlate[symidx] == -1u) 984 goto try_parent; 985 986 type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]); 987 988 if (type == 0) 989 goto try_parent; 990 991 return type; 992 try_parent: 993 if (fp->ctf_parent) 994 { 995 ctf_id_t ret = ctf_lookup_by_sym_or_name (fp->ctf_parent, symidx, 996 symname); 997 if (ret == CTF_ERR) 998 ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); 999 return ret; 1000 } 1001 else 1002 return (ctf_set_errno (fp, err)); 1003} 1004 1005/* Given a symbol table index, return the type of the function or data object 1006 described by the corresponding entry in the symbol table. */ 1007ctf_id_t 1008ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx) 1009{ 1010 return ctf_lookup_by_sym_or_name (fp, symidx, NULL); 1011} 1012 1013/* Given a symbol name, return the type of the function or data object described 1014 by the corresponding entry in the symbol table. */ 1015ctf_id_t 1016ctf_lookup_by_symbol_name (ctf_dict_t *fp, const char *symname) 1017{ 1018 return ctf_lookup_by_sym_or_name (fp, 0, symname); 1019} 1020 1021/* Given a symbol table index, return the info for the function described 1022 by the corresponding entry in the symbol table, which may be a function 1023 symbol or may be a data symbol that happens to be a function pointer. */ 1024 1025int 1026ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip) 1027{ 1028 ctf_id_t type; 1029 1030 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR) 1031 return -1; /* errno is set for us. */ 1032 1033 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION) 1034 return (ctf_set_errno (fp, ECTF_NOTFUNC)); 1035 1036 return ctf_func_type_info (fp, type, fip); 1037} 1038 1039/* Given a symbol table index, return the arguments for the function described 1040 by the corresponding entry in the symbol table. */ 1041 1042int 1043ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc, 1044 ctf_id_t *argv) 1045{ 1046 ctf_id_t type; 1047 1048 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR) 1049 return -1; /* errno is set for us. */ 1050 1051 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION) 1052 return (ctf_set_errno (fp, ECTF_NOTFUNC)); 1053 1054 return ctf_func_type_args (fp, type, argc, argv); 1055} 1056