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_id_t) (uintptr_t) 280 ctf_dynhash_lookup (lp->ctl_hash, 281 fp->ctf_tmp_typeslice)) == 0) 282 goto notype; 283 284 break; 285 } 286 } 287 288 if (lp->ctl_prefix == NULL) 289 goto notype; 290 } 291 292 if (*p != '\0' || type == 0) 293 return (ctf_set_typed_errno (fp, ECTF_SYNTAX)); 294 295 return type; 296 297 notype: 298 ctf_set_errno (fp, ECTF_NOTYPE); 299 if (fp->ctf_parent != NULL) 300 { 301 /* Need to look up in the parent, from the child's perspective. 302 Make sure the pptrtab is up to date. */ 303 304 if (fp->ctf_pptrtab_typemax < fp->ctf_typemax) 305 { 306 if (refresh_pptrtab (fp, fp->ctf_parent) < 0) 307 return CTF_ERR; /* errno is set for us. */ 308 } 309 310 if ((ptype = ctf_lookup_by_name_internal (fp->ctf_parent, fp, 311 name)) != CTF_ERR) 312 return ptype; 313 return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent))); 314 } 315 316 return CTF_ERR; 317 } 318 319 ctf_id_t 320 ctf_lookup_by_name (ctf_dict_t *fp, const char *name) 321 { 322 return ctf_lookup_by_name_internal (fp, NULL, name); 323 } 324 325 /* Return the pointer to the internal CTF type data corresponding to the 326 given type ID. If the ID is invalid, the function returns NULL. 327 This function is not exported outside of the library. */ 328 329 const ctf_type_t * 330 ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type) 331 { 332 ctf_dict_t *fp = *fpp; 333 ctf_id_t idx; 334 335 if ((fp = ctf_get_dict (fp, type)) == NULL) 336 { 337 (void) ctf_set_errno (*fpp, ECTF_NOPARENT); 338 return NULL; 339 } 340 341 idx = LCTF_TYPE_TO_INDEX (fp, type); 342 if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax) 343 { 344 *fpp = fp; /* Possibly the parent CTF dict. */ 345 return (LCTF_INDEX_TO_TYPEPTR (fp, idx)); 346 } 347 348 (void) ctf_set_errno (*fpp, ECTF_BADID); 349 return NULL; 350 } 351 352 typedef struct ctf_lookup_idx_key 353 { 354 ctf_dict_t *clik_fp; 355 const char *clik_name; 356 uint32_t *clik_names; 357 } ctf_lookup_idx_key_t; 358 359 /* A bsearch function for variable names. */ 360 361 static int 362 ctf_lookup_var (const void *key_, const void *lookup_) 363 { 364 const ctf_lookup_idx_key_t *key = key_; 365 const ctf_varent_t *lookup = lookup_; 366 367 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name))); 368 } 369 370 /* Given a variable name, return the type of the variable with that name. 371 Look only in this dict, not in the parent. */ 372 373 ctf_id_t 374 ctf_lookup_variable_here (ctf_dict_t *fp, const char *name) 375 { 376 ctf_dvdef_t *dvd = ctf_dvd_lookup (fp, name); 377 ctf_varent_t *ent; 378 ctf_lookup_idx_key_t key = { fp, name, NULL }; 379 380 if (dvd != NULL) 381 return dvd->dvd_type; 382 383 /* This array is sorted, so we can bsearch for it. */ 384 385 ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t), 386 ctf_lookup_var); 387 388 if (ent == NULL) 389 return (ctf_set_typed_errno (fp, ECTF_NOTYPEDAT)); 390 391 return ent->ctv_type; 392 } 393 394 /* As above, but look in the parent too. */ 395 396 ctf_id_t 397 ctf_lookup_variable (ctf_dict_t *fp, const char *name) 398 { 399 ctf_id_t type; 400 401 if ((type = ctf_lookup_variable_here (fp, name)) == CTF_ERR) 402 { 403 if (ctf_errno (fp) == ECTF_NOTYPEDAT && fp->ctf_parent != NULL) 404 { 405 if ((type = ctf_lookup_variable_here (fp->ctf_parent, name)) != CTF_ERR) 406 return type; 407 return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent))); 408 } 409 410 return -1; /* errno is set for us. */ 411 } 412 413 return 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.\n"); 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_ext_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. If is_function is >= 0, return only function or data object 538 symbols, respectively. */ 539 static unsigned long 540 ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname, int try_parent, 541 int is_function) 542 { 543 const ctf_sect_t *sp = &fp->ctf_ext_symtab; 544 ctf_link_sym_t sym; 545 void *known_idx; 546 int err; 547 ctf_dict_t *cache = fp; 548 549 if (fp->ctf_dynsyms) 550 { 551 err = EINVAL; 552 553 ctf_link_sym_t *symp; 554 555 if (((symp = ctf_dynhash_lookup (fp->ctf_dynsyms, symname)) == NULL) 556 || (symp->st_type != STT_OBJECT && is_function == 0) 557 || (symp->st_type != STT_FUNC && is_function == 1)) 558 goto try_parent; 559 560 return symp->st_symidx; 561 } 562 563 err = ECTF_NOSYMTAB; 564 if (sp->cts_data == NULL) 565 goto try_parent; 566 567 /* First, try a hash lookup to see if we have already spotted this symbol 568 during a past iteration: create the hash first if need be. The 569 lifespan of the strings is equal to the lifespan of the cts_data, so we 570 don't need to strdup them. If this dict was opened as part of an 571 archive, and this archive has a crossdict_cache to cache results that 572 are the same across all dicts in an archive, use it. */ 573 574 if (fp->ctf_archive && fp->ctf_archive->ctfi_crossdict_cache) 575 cache = fp->ctf_archive->ctfi_crossdict_cache; 576 577 if (!cache->ctf_symhash_func) 578 if ((cache->ctf_symhash_func = ctf_dynhash_create (ctf_hash_string, 579 ctf_hash_eq_string, 580 NULL, NULL)) == NULL) 581 goto oom; 582 583 if (!cache->ctf_symhash_objt) 584 if ((cache->ctf_symhash_objt = ctf_dynhash_create (ctf_hash_string, 585 ctf_hash_eq_string, 586 NULL, NULL)) == NULL) 587 goto oom; 588 589 if (is_function != 0 && 590 ctf_dynhash_lookup_kv (cache->ctf_symhash_func, symname, NULL, &known_idx)) 591 return (unsigned long) (uintptr_t) known_idx; 592 593 if (is_function != 1 && 594 ctf_dynhash_lookup_kv (cache->ctf_symhash_objt, symname, NULL, &known_idx)) 595 return (unsigned long) (uintptr_t) known_idx; 596 597 /* Hash lookup unsuccessful: linear search, populating the hashtab for later 598 lookups as we go. */ 599 600 for (; cache->ctf_symhash_latest < sp->cts_size / sp->cts_entsize; 601 cache->ctf_symhash_latest++) 602 { 603 ctf_dynhash_t *h; 604 605 switch (sp->cts_entsize) 606 { 607 case sizeof (Elf64_Sym): 608 { 609 Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data; 610 611 ctf_elf64_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest], 612 cache->ctf_symhash_latest); 613 } 614 break; 615 case sizeof (Elf32_Sym): 616 { 617 Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data; 618 ctf_elf32_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest], 619 cache->ctf_symhash_latest); 620 break; 621 } 622 default: 623 ctf_set_errno (fp, ECTF_SYMTAB); 624 return (unsigned long) -1; 625 } 626 627 if (sym.st_type == STT_FUNC) 628 h = cache->ctf_symhash_func; 629 else if (sym.st_type == STT_OBJECT) 630 h = cache->ctf_symhash_objt; 631 else 632 continue; /* Not of interest. */ 633 634 if (!ctf_dynhash_lookup_kv (h, sym.st_name, 635 NULL, NULL)) 636 if (ctf_dynhash_cinsert (h, sym.st_name, 637 (const void *) (uintptr_t) 638 cache->ctf_symhash_latest) < 0) 639 goto oom; 640 if (strcmp (sym.st_name, symname) == 0) 641 return cache->ctf_symhash_latest++; 642 } 643 644 /* Searched everything, still not found. */ 645 646 return (unsigned long) -1; 647 648 try_parent: 649 if (fp->ctf_parent && try_parent) 650 { 651 unsigned long psym; 652 653 if ((psym = ctf_lookup_symbol_idx (fp->ctf_parent, symname, try_parent, 654 is_function)) 655 != (unsigned long) -1) 656 return psym; 657 658 ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); 659 return (unsigned long) -1; 660 } 661 else 662 { 663 ctf_set_errno (fp, err); 664 return (unsigned long) -1; 665 } 666 oom: 667 ctf_set_errno (fp, ENOMEM); 668 ctf_err_warn (fp, 0, 0, _("cannot allocate memory for symbol " 669 "lookup hashtab")); 670 return (unsigned long) -1; 671 672 } 673 674 ctf_id_t 675 ctf_symbol_next_static (ctf_dict_t *fp, ctf_next_t **it, const char **name, 676 int functions); 677 678 /* Iterate over all symbols with types: if FUNC, function symbols, 679 otherwise, data symbols. The name argument is not optional. The return 680 order is arbitrary, though is likely to be in symbol index or name order. 681 Changing the value of 'functions' in the middle of iteration has 682 unpredictable effects (probably skipping symbols, etc) and is not 683 recommended. Adding symbols while iteration is underway may also lead 684 to other symbols being skipped. */ 685 686 ctf_id_t 687 ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name, 688 int functions) 689 { 690 ctf_id_t sym = CTF_ERR; 691 ctf_next_t *i = *it; 692 int err; 693 694 if (!i) 695 { 696 if ((i = ctf_next_create ()) == NULL) 697 return ctf_set_typed_errno (fp, ENOMEM); 698 699 i->cu.ctn_fp = fp; 700 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next; 701 i->ctn_n = 0; 702 *it = i; 703 } 704 705 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun) 706 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN)); 707 708 if (fp != i->cu.ctn_fp) 709 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP)); 710 711 /* Check the dynamic set of names first, to allow previously-written names 712 to be replaced with dynamic ones (there is still no way to remove them, 713 though). 714 715 We intentionally use raw access, not ctf_lookup_by_symbol, to avoid 716 incurring additional sorting cost for unsorted symtypetabs coming from the 717 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and 718 finally because it's easier to work out what the name of each symbol is if 719 we do that. */ 720 721 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash; 722 void *dyn_name = NULL, *dyn_value = NULL; 723 size_t dyn_els = dynh ? ctf_dynhash_elements (dynh) : 0; 724 725 if (i->ctn_n < dyn_els) 726 { 727 err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value); 728 729 /* This covers errors and also end-of-iteration. */ 730 if (err != 0) 731 { 732 ctf_next_destroy (i); 733 *it = NULL; 734 return ctf_set_typed_errno (fp, err); 735 } 736 737 *name = dyn_name; 738 sym = (ctf_id_t) (uintptr_t) dyn_value; 739 i->ctn_n++; 740 741 return sym; 742 } 743 744 return ctf_symbol_next_static (fp, it, name, functions); 745 } 746 747 /* ctf_symbol_next, but only for static symbols. Mostly an internal 748 implementation detail of ctf_symbol_next, but also used to simplify 749 serialization. */ 750 ctf_id_t 751 ctf_symbol_next_static (ctf_dict_t *fp, ctf_next_t **it, const char **name, 752 int functions) 753 { 754 ctf_id_t sym = CTF_ERR; 755 ctf_next_t *i = *it; 756 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash; 757 size_t dyn_els = dynh ? ctf_dynhash_elements (dynh) : 0; 758 759 /* Only relevant for direct internal-to-library calls, not via 760 ctf_symbol_next (but important then). */ 761 762 if (!i) 763 { 764 if ((i = ctf_next_create ()) == NULL) 765 return ctf_set_typed_errno (fp, ENOMEM); 766 767 i->cu.ctn_fp = fp; 768 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next; 769 i->ctn_n = dyn_els; 770 *it = i; 771 } 772 773 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun) 774 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN)); 775 776 if (fp != i->cu.ctn_fp) 777 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP)); 778 779 /* TODO-v4: Indexed after non-indexed portions? */ 780 781 if ((!functions && fp->ctf_objtidx_names) || 782 (functions && fp->ctf_funcidx_names)) 783 { 784 ctf_header_t *hp = fp->ctf_header; 785 uint32_t *idx = functions ? fp->ctf_funcidx_names : fp->ctf_objtidx_names; 786 uint32_t *tab; 787 size_t len; 788 789 if (functions) 790 { 791 len = (hp->cth_varoff - hp->cth_funcidxoff) / sizeof (uint32_t); 792 tab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff); 793 } 794 else 795 { 796 len = (hp->cth_funcidxoff - hp->cth_objtidxoff) / sizeof (uint32_t); 797 tab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff); 798 } 799 800 do 801 { 802 if (i->ctn_n - dyn_els >= len) 803 goto end; 804 805 *name = ctf_strptr (fp, idx[i->ctn_n - dyn_els]); 806 sym = tab[i->ctn_n - dyn_els]; 807 i->ctn_n++; 808 } 809 while (sym == -1u || sym == 0); 810 } 811 else 812 { 813 /* Skip over pads in ctf_sxlate, padding for typeless symbols in the 814 symtypetab itself, and symbols in the wrong table. */ 815 for (; i->ctn_n - dyn_els < fp->ctf_nsyms; i->ctn_n++) 816 { 817 ctf_header_t *hp = fp->ctf_header; 818 size_t n = i->ctn_n - dyn_els; 819 820 if (fp->ctf_sxlate[n] == -1u) 821 continue; 822 823 sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[n]); 824 825 if (sym == 0) 826 continue; 827 828 if (functions) 829 { 830 if (fp->ctf_sxlate[n] >= hp->cth_funcoff 831 && fp->ctf_sxlate[n] < hp->cth_objtidxoff) 832 break; 833 } 834 else 835 { 836 if (fp->ctf_sxlate[n] >= hp->cth_objtoff 837 && fp->ctf_sxlate[n] < hp->cth_funcoff) 838 break; 839 } 840 } 841 842 if (i->ctn_n - dyn_els >= fp->ctf_nsyms) 843 goto end; 844 845 *name = ctf_lookup_symbol_name (fp, i->ctn_n - dyn_els); 846 i->ctn_n++; 847 } 848 849 return sym; 850 851 end: 852 ctf_next_destroy (i); 853 *it = NULL; 854 return (ctf_set_typed_errno (fp, ECTF_NEXT_END)); 855 } 856 857 /* A bsearch function for function and object index names. */ 858 859 static int 860 ctf_lookup_idx_name (const void *key_, const void *idx_) 861 { 862 const ctf_lookup_idx_key_t *key = key_; 863 const uint32_t *idx = idx_; 864 865 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx]))); 866 } 867 868 /* Given a symbol name or (failing that) number, look up that symbol in the 869 function or object index table (which must exist). Return 0 if not found 870 there (or pad). */ 871 872 static ctf_id_t 873 ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx, 874 const char *symname, int is_function) 875 { 876 struct ctf_header *hp = fp->ctf_header; 877 uint32_t *symtypetab; 878 uint32_t *names; 879 uint32_t *sxlate; 880 size_t nidx; 881 882 if (symname == NULL) 883 symname = ctf_lookup_symbol_name (fp, symidx); 884 885 /* Dynamic dict with no static portion: just return. */ 886 if (!hp) 887 { 888 ctf_dprintf ("%s not found in idx: dict is dynamic\n", symname); 889 return 0; 890 } 891 892 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in " 893 "indexed symtypetab\n", symidx, symname); 894 895 if (symname[0] == '\0') 896 return CTF_ERR; /* errno is set for us. */ 897 898 if (is_function) 899 { 900 if (!fp->ctf_funcidx_sxlate) 901 { 902 if ((fp->ctf_funcidx_sxlate 903 = ctf_symidx_sort (fp, (uint32_t *) 904 (fp->ctf_buf + hp->cth_funcidxoff), 905 &fp->ctf_nfuncidx, 906 hp->cth_varoff - hp->cth_funcidxoff)) 907 == NULL) 908 { 909 ctf_err_warn (fp, 0, 0, _("cannot sort function symidx")); 910 return CTF_ERR; /* errno is set for us. */ 911 } 912 } 913 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff); 914 sxlate = fp->ctf_funcidx_sxlate; 915 names = fp->ctf_funcidx_names; 916 nidx = fp->ctf_nfuncidx; 917 } 918 else 919 { 920 if (!fp->ctf_objtidx_sxlate) 921 { 922 if ((fp->ctf_objtidx_sxlate 923 = ctf_symidx_sort (fp, (uint32_t *) 924 (fp->ctf_buf + hp->cth_objtidxoff), 925 &fp->ctf_nobjtidx, 926 hp->cth_funcidxoff - hp->cth_objtidxoff)) 927 == NULL) 928 { 929 ctf_err_warn (fp, 0, 0, _("cannot sort object symidx")); 930 return CTF_ERR; /* errno is set for us. */ 931 } 932 } 933 934 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff); 935 sxlate = fp->ctf_objtidx_sxlate; 936 names = fp->ctf_objtidx_names; 937 nidx = fp->ctf_nobjtidx; 938 } 939 940 ctf_lookup_idx_key_t key = { fp, symname, names }; 941 uint32_t *idx; 942 943 idx = bsearch (&key, sxlate, nidx, sizeof (uint32_t), ctf_lookup_idx_name); 944 945 if (!idx) 946 { 947 ctf_dprintf ("%s not found in idx\n", symname); 948 return 0; 949 } 950 951 /* Should be impossible, but be paranoid. */ 952 if ((idx - sxlate) > (ptrdiff_t) nidx) 953 return (ctf_set_typed_errno (fp, ECTF_CORRUPT)); 954 955 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname, 956 symtypetab[*idx]); 957 return symtypetab[*idx]; 958 } 959 960 /* Given a symbol name or (if NULL) symbol index, return the type of the 961 function or data object described by the corresponding entry in the symbol 962 table. We can only return symbols in read-only dicts and in dicts for which 963 ctf_link_shuffle_syms has been called to assign symbol indexes to symbol 964 names. 965 966 If try_parent is false, do not check the parent dict too. 967 968 If is_function is > -1, only look for data objects or functions in 969 particular. */ 970 971 ctf_id_t 972 ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx, 973 const char *symname, int try_parent, 974 int is_function) 975 { 976 const ctf_sect_t *sp = &fp->ctf_ext_symtab; 977 ctf_id_t type = 0; 978 int err = 0; 979 980 /* Shuffled dynsymidx present? Use that. For now, the dynsymidx and 981 shuffled-symbol lookup only support dynamically-added symbols, because 982 this interface is meant for use by linkers, and linkers are only going 983 to report symbols against newly-created, freshly-ctf_link'ed dicts: so 984 there will be no static component in any case. */ 985 if (fp->ctf_dynsymidx) 986 { 987 const ctf_link_sym_t *sym; 988 989 if (symname) 990 ctf_dprintf ("Looking up type of object with symname %s in " 991 "writable dict symtypetab\n", symname); 992 else 993 ctf_dprintf ("Looking up type of object with symtab idx %lx in " 994 "writable dict symtypetab\n", symidx); 995 996 /* No name? Need to look it up. */ 997 if (!symname) 998 { 999 err = EINVAL; 1000 if (symidx > fp->ctf_dynsymmax) 1001 goto try_parent; 1002 1003 sym = fp->ctf_dynsymidx[symidx]; 1004 err = ECTF_NOTYPEDAT; 1005 if (!sym || (sym->st_type != STT_OBJECT && sym->st_type != STT_FUNC) 1006 || (sym->st_type != STT_OBJECT && is_function == 0) 1007 || (sym->st_type != STT_FUNC && is_function == 1)) 1008 goto try_parent; 1009 1010 if (!ctf_assert (fp, !sym->st_nameidx_set)) 1011 return CTF_ERR; 1012 symname = sym->st_name; 1013 } 1014 1015 if (fp->ctf_objthash == NULL 1016 || is_function == 1 1017 || (type = (ctf_id_t) (uintptr_t) 1018 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0) 1019 { 1020 if (fp->ctf_funchash == NULL 1021 || is_function == 0 1022 || (type = (ctf_id_t) (uintptr_t) 1023 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0) 1024 goto try_parent; 1025 } 1026 1027 return type; 1028 } 1029 1030 /* Dict not shuffled: look for a dynamic sym first, and look it up 1031 directly. */ 1032 if (symname) 1033 { 1034 if (fp->ctf_objthash != NULL 1035 && is_function != 1 1036 && ((type = (ctf_id_t) (uintptr_t) 1037 ctf_dynhash_lookup (fp->ctf_objthash, symname)) != 0)) 1038 return type; 1039 1040 if (fp->ctf_funchash != NULL 1041 && is_function != 0 1042 && ((type = (ctf_id_t) (uintptr_t) 1043 ctf_dynhash_lookup (fp->ctf_funchash, symname)) != 0)) 1044 return type; 1045 } 1046 1047 err = ECTF_NOSYMTAB; 1048 if (sp->cts_data == NULL && symname == NULL && 1049 ((is_function && !fp->ctf_funcidx_names) || 1050 (!is_function && !fp->ctf_objtidx_names))) 1051 goto try_parent; 1052 1053 /* This covers both out-of-range lookups by index and a dynamic dict which 1054 hasn't been shuffled yet. */ 1055 err = EINVAL; 1056 if (symname == NULL && symidx >= fp->ctf_nsyms) 1057 goto try_parent; 1058 1059 /* Try an indexed lookup. */ 1060 1061 if (fp->ctf_objtidx_names && is_function != 1) 1062 { 1063 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR) 1064 return CTF_ERR; /* errno is set for us. */ 1065 } 1066 if (type == 0 && fp->ctf_funcidx_names && is_function != 0) 1067 { 1068 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR) 1069 return CTF_ERR; /* errno is set for us. */ 1070 } 1071 if (type != 0) 1072 return type; 1073 1074 /* Indexed but no symbol found -> not present, try the parent. */ 1075 err = ECTF_NOTYPEDAT; 1076 if (fp->ctf_objtidx_names && fp->ctf_funcidx_names) 1077 goto try_parent; 1078 1079 /* Table must be nonindexed. */ 1080 1081 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx); 1082 1083 if (symname != NULL) 1084 if ((symidx = ctf_lookup_symbol_idx (fp, symname, try_parent, is_function)) 1085 == (unsigned long) -1) 1086 goto try_parent; 1087 1088 if (fp->ctf_sxlate[symidx] == -1u) 1089 goto try_parent; 1090 1091 type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]); 1092 1093 if (type == 0) 1094 goto try_parent; 1095 1096 return type; 1097 1098 try_parent: 1099 if (!try_parent) 1100 return ctf_set_errno (fp, err); 1101 1102 if (fp->ctf_parent) 1103 { 1104 ctf_id_t ret = ctf_lookup_by_sym_or_name (fp->ctf_parent, symidx, 1105 symname, try_parent, 1106 is_function); 1107 if (ret == CTF_ERR) 1108 ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); 1109 return ret; 1110 } 1111 else 1112 return (ctf_set_typed_errno (fp, err)); 1113 } 1114 1115 /* Given a symbol table index, return the type of the function or data object 1116 described by the corresponding entry in the symbol table. */ 1117 ctf_id_t 1118 ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx) 1119 { 1120 return ctf_lookup_by_sym_or_name (fp, symidx, NULL, 1, -1); 1121 } 1122 1123 /* Given a symbol name, return the type of the function or data object described 1124 by the corresponding entry in the symbol table. */ 1125 ctf_id_t 1126 ctf_lookup_by_symbol_name (ctf_dict_t *fp, const char *symname) 1127 { 1128 return ctf_lookup_by_sym_or_name (fp, 0, symname, 1, -1); 1129 } 1130 1131 /* Given a symbol table index, return the info for the function described 1132 by the corresponding entry in the symbol table, which may be a function 1133 symbol or may be a data symbol that happens to be a function pointer. */ 1134 1135 int 1136 ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip) 1137 { 1138 ctf_id_t type; 1139 1140 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR) 1141 return -1; /* errno is set for us. */ 1142 1143 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION) 1144 return (ctf_set_errno (fp, ECTF_NOTFUNC)); 1145 1146 return ctf_func_type_info (fp, type, fip); 1147 } 1148 1149 /* Given a symbol table index, return the arguments for the function described 1150 by the corresponding entry in the symbol table. */ 1151 1152 int 1153 ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc, 1154 ctf_id_t *argv) 1155 { 1156 ctf_id_t type; 1157 1158 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR) 1159 return -1; /* errno is set for us. */ 1160 1161 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION) 1162 return (ctf_set_errno (fp, ECTF_NOTFUNC)); 1163 1164 return ctf_func_type_args (fp, type, argc, argv); 1165 } 1166