LoongArch: implement count_{leading,trailing}_zeros
[binutils-gdb.git] / libctf / ctf-lookup.c
blobc65849118cbdbf91da47a490f00cef9f6f015549
1 /* Symbol, variable and name lookup.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
4 This file is part of libctf.
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.
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.
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/>. */
20 #include <ctf-impl.h>
21 #include <elf.h>
22 #include <string.h>
23 #include <assert.h>
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)
29 uint32_t *new_pptrtab;
31 if ((new_pptrtab = realloc (fp->ctf_pptrtab, sizeof (uint32_t)
32 * new_len)) == NULL)
33 return (ctf_set_errno (fp, ENOMEM));
35 fp->ctf_pptrtab = new_pptrtab;
37 memset (fp->ctf_pptrtab + fp->ctf_pptrtab_len, 0,
38 sizeof (uint32_t) * (new_len - fp->ctf_pptrtab_len));
40 fp->ctf_pptrtab_len = new_len;
41 return 0;
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)
49 uint32_t i;
50 for (i = fp->ctf_pptrtab_typemax; i <= fp->ctf_typemax; i++)
52 ctf_id_t type = LCTF_INDEX_TO_TYPE (fp, i, 1);
53 ctf_id_t reffed_type;
55 if (ctf_type_kind (fp, type) != CTF_K_POINTER)
56 continue;
58 reffed_type = ctf_type_reference (fp, type);
60 if (LCTF_TYPE_ISPARENT (fp, reffed_type))
62 uint32_t idx = LCTF_TYPE_TO_INDEX (fp, reffed_type);
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)
69 if (idx >= fp->ctf_pptrtab_len
70 && grow_pptrtab (fp, pfp->ctf_ptrtab_len) < 0)
71 return -1; /* errno is set for us. */
73 fp->ctf_pptrtab[idx] = i;
78 fp->ctf_pptrtab_typemax = fp->ctf_typemax;
80 return 0;
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:
88 R.J. Cichelli, "Minimal Perfect Hash Functions Made Simple",
89 Communications of the ACM, Volume 23, Issue 1, January 1980, pp. 17-19.
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().
96 TODO: just use gperf. */
98 static int
99 isqualifier (const char *s, size_t len)
101 static const struct qual
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}
113 int h = s[len - 1] + (int) len - 105;
114 const struct qual *qp;
116 if (h < 0 || (size_t) h >= sizeof (qhash) / sizeof (qhash[0]))
117 return 0;
119 qp = &qhash[h];
121 return ((size_t) len == qp->q_len &&
122 strncmp (qp->q_name, s, qp->q_len) == 0);
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. */
134 static ctf_id_t
135 ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
136 const char *name)
138 static const char delimiters[] = " \t\n\r\v\f*";
140 const ctf_lookup_t *lp;
141 const char *p, *q, *end;
142 ctf_id_t type = 0;
143 ctf_id_t ntype, ptype;
145 if (name == NULL)
146 return (ctf_set_errno (fp, EINVAL));
148 for (p = name, end = name + strlen (name); *p != '\0'; p = q)
150 while (isspace ((int) *p))
151 p++; /* Skip leading whitespace. */
153 if (p == end)
154 break;
156 if ((q = strpbrk (p + 1, delimiters)) == NULL)
157 q = end; /* Compare until end. */
159 if (*p == '*')
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.
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.) */
175 uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type);
176 int in_child = 0;
178 ntype = CTF_ERR;
179 if (child && idx < child->ctf_pptrtab_len)
181 ntype = child->ctf_pptrtab[idx];
182 if (ntype)
183 in_child = 1;
184 else
185 ntype = CTF_ERR;
188 if (ntype == CTF_ERR)
190 ntype = fp->ctf_ptrtab[idx];
191 if (ntype == 0)
192 ntype = CTF_ERR;
195 /* Try resolving to its base type and check again. */
196 if (ntype == CTF_ERR)
198 if (child)
199 ntype = ctf_type_resolve_unsliced (child, type);
200 else
201 ntype = ctf_type_resolve_unsliced (fp, type);
203 if (ntype == CTF_ERR)
204 goto notype;
206 idx = LCTF_TYPE_TO_INDEX (fp, ntype);
208 ntype = CTF_ERR;
209 if (child && idx < child->ctf_pptrtab_len)
211 ntype = child->ctf_pptrtab[idx];
212 if (ntype)
213 in_child = 1;
214 else
215 ntype = CTF_ERR;
218 if (ntype == CTF_ERR)
220 ntype = fp->ctf_ptrtab[idx];
221 if (ntype == 0)
222 ntype = CTF_ERR;
224 if (ntype == CTF_ERR)
225 goto notype;
228 type = LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)
229 || in_child);
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)
236 fp = child;
237 child = NULL;
240 q = p + 1;
241 continue;
244 if (isqualifier (p, (size_t) (q - p)))
245 continue; /* Skip qualifier keyword. */
247 for (lp = fp->ctf_lookups; lp->ctl_prefix != NULL; lp++)
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)
254 for (p += lp->ctl_len; isspace ((int) *p); p++)
255 continue; /* Skip prefix and next whitespace. */
257 if ((q = strchr (p, '*')) == NULL)
258 q = end; /* Compare until end. */
260 while (isspace ((int) q[-1]))
261 q--; /* Exclude trailing whitespace. */
263 /* Expand and/or allocate storage for a slice of the name, then
264 copy it in. */
266 if (fp->ctf_tmp_typeslicelen >= (size_t) (q - p) + 1)
268 memcpy (fp->ctf_tmp_typeslice, p, (size_t) (q - p));
269 fp->ctf_tmp_typeslice[(size_t) (q - p)] = '\0';
271 else
273 free (fp->ctf_tmp_typeslice);
274 fp->ctf_tmp_typeslice = xstrndup (p, (size_t) (q - p));
275 if (fp->ctf_tmp_typeslice == NULL)
277 ctf_set_errno (fp, ENOMEM);
278 return CTF_ERR;
282 if ((type = ctf_lookup_by_rawhash (fp, lp->ctl_hash,
283 fp->ctf_tmp_typeslice)) == 0)
284 goto notype;
286 break;
290 if (lp->ctl_prefix == NULL)
291 goto notype;
294 if (*p != '\0' || type == 0)
295 return (ctf_set_errno (fp, ECTF_SYNTAX));
297 return type;
299 notype:
300 ctf_set_errno (fp, ECTF_NOTYPE);
301 if (fp->ctf_parent != NULL)
303 /* Need to look up in the parent, from the child's perspective.
304 Make sure the pptrtab is up to date. */
306 if (fp->ctf_pptrtab_typemax < fp->ctf_typemax)
308 if (refresh_pptrtab (fp, fp->ctf_parent) < 0)
309 return -1; /* errno is set for us. */
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)));
318 return CTF_ERR;
321 ctf_id_t
322 ctf_lookup_by_name (ctf_dict_t *fp, const char *name)
324 return ctf_lookup_by_name_internal (fp, NULL, name);
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. */
331 const ctf_type_t *
332 ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type)
334 ctf_dict_t *fp = *fpp; /* Caller passes in starting CTF dict. */
335 ctf_id_t idx;
337 if ((fp = ctf_get_dict (fp, type)) == NULL)
339 (void) ctf_set_errno (*fpp, ECTF_NOPARENT);
340 return NULL;
343 /* If this dict is writable, check for a dynamic type. */
345 if (fp->ctf_flags & LCTF_RDWR)
347 ctf_dtdef_t *dtd;
349 if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
351 *fpp = fp;
352 return &dtd->dtd_data;
354 (void) ctf_set_errno (*fpp, ECTF_BADID);
355 return NULL;
358 /* Check for a type in the static portion. */
360 idx = LCTF_TYPE_TO_INDEX (fp, type);
361 if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax)
363 *fpp = fp; /* Function returns ending CTF dict. */
364 return (LCTF_INDEX_TO_TYPEPTR (fp, idx));
367 (void) ctf_set_errno (*fpp, ECTF_BADID);
368 return NULL;
371 typedef struct ctf_lookup_idx_key
373 ctf_dict_t *clik_fp;
374 const char *clik_name;
375 uint32_t *clik_names;
376 } ctf_lookup_idx_key_t;
378 /* A bsearch function for variable names. */
380 static int
381 ctf_lookup_var (const void *key_, const void *lookup_)
383 const ctf_lookup_idx_key_t *key = key_;
384 const ctf_varent_t *lookup = lookup_;
386 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name)));
389 /* Given a variable name, return the type of the variable with that name. */
391 ctf_id_t
392 ctf_lookup_variable (ctf_dict_t *fp, const char *name)
394 ctf_varent_t *ent;
395 ctf_lookup_idx_key_t key = { fp, name, NULL };
397 /* This array is sorted, so we can bsearch for it. */
399 ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t),
400 ctf_lookup_var);
402 if (ent == NULL)
404 if (fp->ctf_parent != NULL)
406 ctf_id_t ptype;
408 if ((ptype = ctf_lookup_variable (fp->ctf_parent, name)) != CTF_ERR)
409 return ptype;
410 return (ctf_set_errno (fp, ctf_errno (fp->ctf_parent)));
413 return (ctf_set_errno (fp, ECTF_NOTYPEDAT));
416 return ent->ctv_type;
419 typedef struct ctf_symidx_sort_arg_cb
421 ctf_dict_t *fp;
422 uint32_t *names;
423 } ctf_symidx_sort_arg_cb_t;
425 static int
426 sort_symidx_by_name (const void *one_, const void *two_, void *arg_)
428 const uint32_t *one = one_;
429 const uint32_t *two = two_;
430 ctf_symidx_sort_arg_cb_t *arg = arg_;
432 return (strcmp (ctf_strptr (arg->fp, arg->names[*one]),
433 ctf_strptr (arg->fp, arg->names[*two])));
436 /* Sort a symbol index section by name. Takes a 1:1 mapping of names to the
437 corresponding symbol table. Returns a lexicographically sorted array of idx
438 indexes (and thus, of indexes into the corresponding func info / data object
439 section). */
441 static uint32_t *
442 ctf_symidx_sort (ctf_dict_t *fp, uint32_t *idx, size_t *nidx,
443 size_t len)
445 uint32_t *sorted;
446 size_t i;
448 if ((sorted = malloc (len)) == NULL)
450 ctf_set_errno (fp, ENOMEM);
451 return NULL;
454 *nidx = len / sizeof (uint32_t);
455 for (i = 0; i < *nidx; i++)
456 sorted[i] = i;
458 if (!(fp->ctf_header->cth_flags & CTF_F_IDXSORTED))
460 ctf_symidx_sort_arg_cb_t arg = { fp, idx };
461 ctf_dprintf ("Index section unsorted: sorting.");
462 ctf_qsort_r (sorted, *nidx, sizeof (uint32_t), sort_symidx_by_name, &arg);
463 fp->ctf_header->cth_flags |= CTF_F_IDXSORTED;
466 return sorted;
469 /* Given a symbol index, return the name of that symbol from the table provided
470 by ctf_link_shuffle_syms, or failing that from the secondary string table, or
471 the null string. */
472 static const char *
473 ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx)
475 const ctf_sect_t *sp = &fp->ctf_symtab;
476 ctf_link_sym_t sym;
477 int err;
479 if (fp->ctf_dynsymidx)
481 err = EINVAL;
482 if (symidx > fp->ctf_dynsymmax)
483 goto try_parent;
485 ctf_link_sym_t *symp = fp->ctf_dynsymidx[symidx];
487 if (!symp)
488 goto try_parent;
490 return symp->st_name;
493 err = ECTF_NOSYMTAB;
494 if (sp->cts_data == NULL)
495 goto try_parent;
497 if (symidx >= fp->ctf_nsyms)
498 goto try_parent;
500 switch (sp->cts_entsize)
502 case sizeof (Elf64_Sym):
504 const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx;
505 ctf_elf64_to_link_sym (fp, &sym, symp, symidx);
507 break;
508 case sizeof (Elf32_Sym):
510 const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx;
511 ctf_elf32_to_link_sym (fp, &sym, symp, symidx);
513 break;
514 default:
515 ctf_set_errno (fp, ECTF_SYMTAB);
516 return _CTF_NULLSTR;
519 assert (!sym.st_nameidx_set);
521 return sym.st_name;
523 try_parent:
524 if (fp->ctf_parent)
526 const char *ret;
527 ret = ctf_lookup_symbol_name (fp->ctf_parent, symidx);
528 if (ret == NULL)
529 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
530 return ret;
532 else
534 ctf_set_errno (fp, err);
535 return _CTF_NULLSTR;
539 /* Given a symbol name, return the index of that symbol, or -1 on error or if
540 not found. */
541 static unsigned long
542 ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname)
544 const ctf_sect_t *sp = &fp->ctf_symtab;
545 ctf_link_sym_t sym;
546 void *known_idx;
547 int err;
548 ctf_dict_t *cache = fp;
550 if (fp->ctf_dynsyms)
552 err = EINVAL;
554 ctf_link_sym_t *symp;
556 if ((symp = ctf_dynhash_lookup (fp->ctf_dynsyms, symname)) == NULL)
557 goto try_parent;
559 return symp->st_symidx;
562 err = ECTF_NOSYMTAB;
563 if (sp->cts_data == NULL)
564 goto try_parent;
566 /* First, try a hash lookup to see if we have already spotted this symbol
567 during a past iteration: create the hash first if need be. The lifespan
568 of the strings is equal to the lifespan of the cts_data, so we don't
569 need to strdup them. If this dict was opened as part of an archive,
570 and this archive has designed a crossdict_cache to cache results that
571 are the same across all dicts in an archive, use it. */
573 if (fp->ctf_archive && fp->ctf_archive->ctfi_crossdict_cache)
574 cache = fp->ctf_archive->ctfi_crossdict_cache;
576 if (!cache->ctf_symhash)
577 if ((cache->ctf_symhash = ctf_dynhash_create (ctf_hash_string,
578 ctf_hash_eq_string,
579 NULL, NULL)) == NULL)
580 goto oom;
582 if (ctf_dynhash_lookup_kv (cache->ctf_symhash, symname, NULL, &known_idx))
583 return (unsigned long) (uintptr_t) known_idx;
585 /* Hash lookup unsuccessful: linear search, populating the hashtab for later
586 lookups as we go. */
588 for (; cache->ctf_symhash_latest < sp->cts_size / sp->cts_entsize;
589 cache->ctf_symhash_latest++)
591 switch (sp->cts_entsize)
593 case sizeof (Elf64_Sym):
595 Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data;
596 ctf_elf64_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest],
597 cache->ctf_symhash_latest);
598 if (!ctf_dynhash_lookup_kv (cache->ctf_symhash, sym.st_name,
599 NULL, NULL))
600 if (ctf_dynhash_cinsert (cache->ctf_symhash, sym.st_name,
601 (const void *) (uintptr_t)
602 cache->ctf_symhash_latest) < 0)
603 goto oom;
604 if (strcmp (sym.st_name, symname) == 0)
605 return cache->ctf_symhash_latest++;
607 break;
608 case sizeof (Elf32_Sym):
610 Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data;
611 ctf_elf32_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest],
612 cache->ctf_symhash_latest);
613 if (!ctf_dynhash_lookup_kv (cache->ctf_symhash, sym.st_name,
614 NULL, NULL))
615 if (ctf_dynhash_cinsert (cache->ctf_symhash, sym.st_name,
616 (const void *) (uintptr_t)
617 cache->ctf_symhash_latest) < 0)
618 goto oom;
619 if (strcmp (sym.st_name, symname) == 0)
620 return cache->ctf_symhash_latest++;
622 break;
623 default:
624 ctf_set_errno (fp, ECTF_SYMTAB);
625 return (unsigned long) -1;
629 /* Searched everything, still not found. */
631 return (unsigned long) -1;
633 try_parent:
634 if (fp->ctf_parent)
636 unsigned long psym;
638 if ((psym = ctf_lookup_symbol_idx (fp->ctf_parent, symname))
639 != (unsigned long) -1)
640 return psym;
642 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
643 return (unsigned long) -1;
645 else
647 ctf_set_errno (fp, err);
648 return (unsigned long) -1;
650 oom:
651 ctf_set_errno (fp, ENOMEM);
652 ctf_err_warn (fp, 0, ENOMEM, _("cannot allocate memory for symbol "
653 "lookup hashtab"));
654 return (unsigned long) -1;
658 /* Iterate over all symbols with types: if FUNC, function symbols, otherwise,
659 data symbols. The name argument is not optional. The return order is
660 arbitrary, though is likely to be in symbol index or name order. You can
661 change the value of 'functions' in the middle of iteration over non-dynamic
662 dicts, but doing so on dynamic dicts will fail. (This is probably not very
663 useful, but there is no reason to prohibit it.) */
665 ctf_id_t
666 ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name,
667 int functions)
669 ctf_id_t sym = CTF_ERR;
670 ctf_next_t *i = *it;
671 int err;
673 if (!i)
675 if ((i = ctf_next_create ()) == NULL)
676 return ctf_set_errno (fp, ENOMEM);
678 i->cu.ctn_fp = fp;
679 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next;
680 i->ctn_n = 0;
681 *it = i;
684 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun)
685 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
687 if (fp != i->cu.ctn_fp)
688 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
690 /* We intentionally use raw access, not ctf_lookup_by_symbol, to avoid
691 incurring additional sorting cost for unsorted symtypetabs coming from the
692 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and
693 finally because it's easier to work out what the name of each symbol is if
694 we do that. */
696 if (fp->ctf_flags & LCTF_RDWR)
698 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash;
699 void *dyn_name = NULL, *dyn_value = NULL;
701 if (!dynh)
703 ctf_next_destroy (i);
704 return (ctf_set_errno (fp, ECTF_NEXT_END));
707 err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value);
708 /* This covers errors and also end-of-iteration. */
709 if (err != 0)
711 ctf_next_destroy (i);
712 *it = NULL;
713 return ctf_set_errno (fp, err);
716 *name = dyn_name;
717 sym = (ctf_id_t) (uintptr_t) dyn_value;
719 else if ((!functions && fp->ctf_objtidx_names) ||
720 (functions && fp->ctf_funcidx_names))
722 ctf_header_t *hp = fp->ctf_header;
723 uint32_t *idx = functions ? fp->ctf_funcidx_names : fp->ctf_objtidx_names;
724 uint32_t *tab;
725 size_t len;
727 if (functions)
729 len = (hp->cth_varoff - hp->cth_funcidxoff) / sizeof (uint32_t);
730 tab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
732 else
734 len = (hp->cth_funcidxoff - hp->cth_objtidxoff) / sizeof (uint32_t);
735 tab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
740 if (i->ctn_n >= len)
741 goto end;
743 *name = ctf_strptr (fp, idx[i->ctn_n]);
744 sym = tab[i->ctn_n++];
746 while (sym == -1u || sym == 0);
748 else
750 /* Skip over pads in ctf_xslate, padding for typeless symbols in the
751 symtypetab itself, and symbols in the wrong table. */
752 for (; i->ctn_n < fp->ctf_nsyms; i->ctn_n++)
754 ctf_header_t *hp = fp->ctf_header;
756 if (fp->ctf_sxlate[i->ctn_n] == -1u)
757 continue;
759 sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[i->ctn_n]);
761 if (sym == 0)
762 continue;
764 if (functions)
766 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_funcoff
767 && fp->ctf_sxlate[i->ctn_n] < hp->cth_objtidxoff)
768 break;
770 else
772 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_objtoff
773 && fp->ctf_sxlate[i->ctn_n] < hp->cth_funcoff)
774 break;
778 if (i->ctn_n >= fp->ctf_nsyms)
779 goto end;
781 *name = ctf_lookup_symbol_name (fp, i->ctn_n++);
784 return sym;
786 end:
787 ctf_next_destroy (i);
788 *it = NULL;
789 return (ctf_set_errno (fp, ECTF_NEXT_END));
792 /* A bsearch function for function and object index names. */
794 static int
795 ctf_lookup_idx_name (const void *key_, const void *idx_)
797 const ctf_lookup_idx_key_t *key = key_;
798 const uint32_t *idx = idx_;
800 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx])));
803 /* Given a symbol name or (failing that) number, look up that symbol in the
804 function or object index table (which must exist). Return 0 if not found
805 there (or pad). */
807 static ctf_id_t
808 ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx,
809 const char *symname, int is_function)
811 struct ctf_header *hp = fp->ctf_header;
812 uint32_t *symtypetab;
813 uint32_t *names;
814 uint32_t *sxlate;
815 size_t nidx;
817 if (symname == NULL)
818 symname = ctf_lookup_symbol_name (fp, symidx);
820 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in "
821 "indexed symtypetab\n", symidx, symname);
823 if (symname[0] == '\0')
824 return -1; /* errno is set for us. */
826 if (is_function)
828 if (!fp->ctf_funcidx_sxlate)
830 if ((fp->ctf_funcidx_sxlate
831 = ctf_symidx_sort (fp, (uint32_t *)
832 (fp->ctf_buf + hp->cth_funcidxoff),
833 &fp->ctf_nfuncidx,
834 hp->cth_varoff - hp->cth_funcidxoff))
835 == NULL)
837 ctf_err_warn (fp, 0, 0, _("cannot sort function symidx"));
838 return -1; /* errno is set for us. */
841 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
842 sxlate = fp->ctf_funcidx_sxlate;
843 names = fp->ctf_funcidx_names;
844 nidx = fp->ctf_nfuncidx;
846 else
848 if (!fp->ctf_objtidx_sxlate)
850 if ((fp->ctf_objtidx_sxlate
851 = ctf_symidx_sort (fp, (uint32_t *)
852 (fp->ctf_buf + hp->cth_objtidxoff),
853 &fp->ctf_nobjtidx,
854 hp->cth_funcidxoff - hp->cth_objtidxoff))
855 == NULL)
857 ctf_err_warn (fp, 0, 0, _("cannot sort object symidx"));
858 return -1; /* errno is set for us. */
862 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
863 sxlate = fp->ctf_objtidx_sxlate;
864 names = fp->ctf_objtidx_names;
865 nidx = fp->ctf_nobjtidx;
868 ctf_lookup_idx_key_t key = { fp, symname, names };
869 uint32_t *idx;
871 idx = bsearch (&key, sxlate, nidx, sizeof (uint32_t), ctf_lookup_idx_name);
873 if (!idx)
875 ctf_dprintf ("%s not found in idx\n", symname);
876 return 0;
879 /* Should be impossible, but be paranoid. */
880 if ((idx - sxlate) > (ptrdiff_t) nidx)
881 return (ctf_set_errno (fp, ECTF_CORRUPT));
883 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname,
884 symtypetab[*idx]);
885 return symtypetab[*idx];
888 /* Given a symbol name or (if NULL) symbol index, return the type of the
889 function or data object described by the corresponding entry in the symbol
890 table. We can only return symbols in read-only dicts and in dicts for which
891 ctf_link_shuffle_syms has been called to assign symbol indexes to symbol
892 names. */
894 static ctf_id_t
895 ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx,
896 const char *symname)
898 const ctf_sect_t *sp = &fp->ctf_symtab;
899 ctf_id_t type = 0;
900 int err = 0;
902 /* Shuffled dynsymidx present? Use that. */
903 if (fp->ctf_dynsymidx)
905 const ctf_link_sym_t *sym;
907 if (symname)
908 ctf_dprintf ("Looking up type of object with symname %s in "
909 "writable dict symtypetab\n", symname);
910 else
911 ctf_dprintf ("Looking up type of object with symtab idx %lx in "
912 "writable dict symtypetab\n", symidx);
914 /* The dict must be dynamic. */
915 if (!ctf_assert (fp, fp->ctf_flags & LCTF_RDWR))
916 return CTF_ERR;
918 /* No name? Need to look it up. */
919 if (!symname)
921 err = EINVAL;
922 if (symidx > fp->ctf_dynsymmax)
923 goto try_parent;
925 sym = fp->ctf_dynsymidx[symidx];
926 err = ECTF_NOTYPEDAT;
927 if (!sym || (sym->st_shndx != STT_OBJECT && sym->st_shndx != STT_FUNC))
928 goto try_parent;
930 if (!ctf_assert (fp, !sym->st_nameidx_set))
931 return CTF_ERR;
932 symname = sym->st_name;
935 if (fp->ctf_objthash == NULL
936 || ((type = (ctf_id_t) (uintptr_t)
937 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0))
939 if (fp->ctf_funchash == NULL
940 || ((type = (ctf_id_t) (uintptr_t)
941 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0))
942 goto try_parent;
945 return type;
948 /* Lookup by name in a dynamic dict: just do it directly. */
949 if (symname && fp->ctf_flags & LCTF_RDWR)
951 if (fp->ctf_objthash == NULL
952 || ((type = (ctf_id_t) (uintptr_t)
953 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0))
955 if (fp->ctf_funchash == NULL
956 || ((type = (ctf_id_t) (uintptr_t)
957 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0))
958 goto try_parent;
960 return type;
963 err = ECTF_NOSYMTAB;
964 if (sp->cts_data == NULL)
965 goto try_parent;
967 /* This covers both out-of-range lookups and a dynamic dict which hasn't been
968 shuffled yet. */
969 err = EINVAL;
970 if (symname == NULL && symidx >= fp->ctf_nsyms)
971 goto try_parent;
973 if (fp->ctf_objtidx_names)
975 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR)
976 return CTF_ERR; /* errno is set for us. */
978 if (type == 0 && fp->ctf_funcidx_names)
980 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR)
981 return CTF_ERR; /* errno is set for us. */
983 if (type != 0)
984 return type;
986 err = ECTF_NOTYPEDAT;
987 if (fp->ctf_objtidx_names && fp->ctf_funcidx_names)
988 goto try_parent;
990 /* Table must be nonindexed. */
992 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx);
994 if (symname != NULL)
995 if ((symidx = ctf_lookup_symbol_idx (fp, symname)) == (unsigned long) -1)
996 goto try_parent;
998 if (fp->ctf_sxlate[symidx] == -1u)
999 goto try_parent;
1001 type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]);
1003 if (type == 0)
1004 goto try_parent;
1006 return type;
1007 try_parent:
1008 if (fp->ctf_parent)
1010 ctf_id_t ret = ctf_lookup_by_sym_or_name (fp->ctf_parent, symidx,
1011 symname);
1012 if (ret == CTF_ERR)
1013 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
1014 return ret;
1016 else
1017 return (ctf_set_errno (fp, err));
1020 /* Given a symbol table index, return the type of the function or data object
1021 described by the corresponding entry in the symbol table. */
1022 ctf_id_t
1023 ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx)
1025 return ctf_lookup_by_sym_or_name (fp, symidx, NULL);
1028 /* Given a symbol name, return the type of the function or data object described
1029 by the corresponding entry in the symbol table. */
1030 ctf_id_t
1031 ctf_lookup_by_symbol_name (ctf_dict_t *fp, const char *symname)
1033 return ctf_lookup_by_sym_or_name (fp, 0, symname);
1036 /* Given a symbol table index, return the info for the function described
1037 by the corresponding entry in the symbol table, which may be a function
1038 symbol or may be a data symbol that happens to be a function pointer. */
1041 ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip)
1043 ctf_id_t type;
1045 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1046 return -1; /* errno is set for us. */
1048 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1049 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1051 return ctf_func_type_info (fp, type, fip);
1054 /* Given a symbol table index, return the arguments for the function described
1055 by the corresponding entry in the symbol table. */
1058 ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc,
1059 ctf_id_t *argv)
1061 ctf_id_t type;
1063 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1064 return -1; /* errno is set for us. */
1066 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1067 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1069 return ctf_func_type_args (fp, type, argc, argv);