Updated translations for the bfd, binutils, gas, ld and opcodes directories
[binutils-gdb.git] / libctf / ctf-lookup.c
blob8accb2ed99e52935e576dbe48e4a99beb5cacead
1 /* Symbol, variable and name lookup.
2 Copyright (C) 2019-2024 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_typed_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)
276 return ctf_set_typed_errno (fp, ENOMEM);
279 if ((type = (ctf_id_t) (uintptr_t)
280 ctf_dynhash_lookup (lp->ctl_hash,
281 fp->ctf_tmp_typeslice)) == 0)
282 goto notype;
284 break;
288 if (lp->ctl_prefix == NULL)
289 goto notype;
292 if (*p != '\0' || type == 0)
293 return (ctf_set_typed_errno (fp, ECTF_SYNTAX));
295 return type;
297 notype:
298 ctf_set_errno (fp, ECTF_NOTYPE);
299 if (fp->ctf_parent != NULL)
301 /* Need to look up in the parent, from the child's perspective.
302 Make sure the pptrtab is up to date. */
304 if (fp->ctf_pptrtab_typemax < fp->ctf_typemax)
306 if (refresh_pptrtab (fp, fp->ctf_parent) < 0)
307 return CTF_ERR; /* errno is set for us. */
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)));
316 return CTF_ERR;
319 ctf_id_t
320 ctf_lookup_by_name (ctf_dict_t *fp, const char *name)
322 return ctf_lookup_by_name_internal (fp, NULL, name);
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. */
329 const ctf_type_t *
330 ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type)
332 ctf_dict_t *fp = *fpp;
333 ctf_id_t idx;
335 if ((fp = ctf_get_dict (fp, type)) == NULL)
337 (void) ctf_set_errno (*fpp, ECTF_NOPARENT);
338 return NULL;
341 idx = LCTF_TYPE_TO_INDEX (fp, type);
342 if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax)
344 *fpp = fp; /* Possibly the parent CTF dict. */
345 return (LCTF_INDEX_TO_TYPEPTR (fp, idx));
348 (void) ctf_set_errno (*fpp, ECTF_BADID);
349 return NULL;
352 typedef struct ctf_lookup_idx_key
354 ctf_dict_t *clik_fp;
355 const char *clik_name;
356 uint32_t *clik_names;
357 } ctf_lookup_idx_key_t;
359 /* A bsearch function for variable names. */
361 static int
362 ctf_lookup_var (const void *key_, const void *lookup_)
364 const ctf_lookup_idx_key_t *key = key_;
365 const ctf_varent_t *lookup = lookup_;
367 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name)));
370 /* Given a variable name, return the type of the variable with that name.
371 Look only in this dict, not in the parent. */
373 ctf_id_t
374 ctf_lookup_variable_here (ctf_dict_t *fp, const char *name)
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 };
380 if (dvd != NULL)
381 return dvd->dvd_type;
383 /* This array is sorted, so we can bsearch for it. */
385 ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t),
386 ctf_lookup_var);
388 if (ent == NULL)
389 return (ctf_set_typed_errno (fp, ECTF_NOTYPEDAT));
391 return ent->ctv_type;
394 /* As above, but look in the parent too. */
396 ctf_id_t
397 ctf_lookup_variable (ctf_dict_t *fp, const char *name)
399 ctf_id_t type;
401 if ((type = ctf_lookup_variable_here (fp, name)) == CTF_ERR)
403 if (ctf_errno (fp) == ECTF_NOTYPEDAT && fp->ctf_parent != NULL)
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)));
410 return -1; /* errno is set for us. */
413 return type;
416 /* Look up a single enumerator by enumeration constant name. Returns the ID of
417 the enum it is contained within and optionally its value. Error out with
418 ECTF_DUPLICATE if multiple exist (which can happen in some older dicts). See
419 ctf_lookup_enumerator_next in that case. Enumeration constants in non-root
420 types are not returned, but constants in parents are, if not overridden by
421 an enum in the child.. */
423 ctf_id_t
424 ctf_lookup_enumerator (ctf_dict_t *fp, const char *name, int64_t *enum_value)
426 ctf_id_t type;
427 int enum_int_value;
429 if (ctf_dynset_lookup (fp->ctf_conflicting_enums, name))
430 return (ctf_set_typed_errno (fp, ECTF_DUPLICATE));
432 /* CTF_K_UNKNOWN suffices for things like enumeration constants that aren't
433 actually types at all (ending up in the global name table). */
434 type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name);
435 /* Nonexistent type? It may be in the parent. */
436 if (type == 0 && fp->ctf_parent)
438 if ((type = ctf_lookup_enumerator (fp->ctf_parent, name, enum_value)) == 0)
439 return ctf_set_typed_errno (fp, ECTF_NOENUMNAM);
440 return type;
443 /* Nothing more to do if this type didn't exist or we don't have to look up
444 the enum value. */
445 if (type == 0)
446 return ctf_set_typed_errno (fp, ECTF_NOENUMNAM);
448 if (enum_value == NULL)
449 return type;
451 if (ctf_enum_value (fp, type, name, &enum_int_value) < 0)
452 return CTF_ERR;
453 *enum_value = enum_int_value;
455 return type;
458 /* Return all enumeration constants with a given name in a given dict, similar
459 to ctf_lookup_enumerator above but capable of returning multiple values.
460 Enumerators in parent dictionaries are not returned: enumerators in
461 hidden types *are* returned. */
463 ctf_id_t
464 ctf_lookup_enumerator_next (ctf_dict_t *fp, const char *name,
465 ctf_next_t **it, int64_t *val)
467 ctf_next_t *i = *it;
468 int found = 0;
470 /* We use ctf_type_next() to iterate across all types, but then traverse each
471 enumerator found by hand: traversing enumerators is very easy, and it would
472 probably be more confusing to use two nested iterators than to do it this
473 way. We use ctn_next to work over enums, then ctn_en and ctn_n to work
474 over enumerators within each enum. */
475 if (!i)
477 if ((i = ctf_next_create ()) == NULL)
478 return ctf_set_typed_errno (fp, ENOMEM);
480 i->cu.ctn_fp = fp;
481 i->ctn_iter_fun = (void (*) (void)) ctf_lookup_enumerator_next;
482 i->ctn_increment = 0;
483 i->ctn_tp = NULL;
484 i->u.ctn_en = NULL;
485 i->ctn_n = 0;
486 *it = i;
489 if ((void (*) (void)) ctf_lookup_enumerator_next != i->ctn_iter_fun)
490 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN));
492 if (fp != i->cu.ctn_fp)
493 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP));
497 const char *this_name;
499 /* At end of enum? Traverse to next one, if any are left. */
501 if (i->u.ctn_en == NULL || i->ctn_n == 0)
503 const ctf_type_t *tp;
504 ctf_dtdef_t *dtd;
507 i->ctn_type = ctf_type_next (i->cu.ctn_fp, &i->ctn_next, NULL, 1);
508 while (i->ctn_type != CTF_ERR
509 && ctf_type_kind_unsliced (i->cu.ctn_fp, i->ctn_type)
510 != CTF_K_ENUM);
512 if (i->ctn_type == CTF_ERR)
514 /* Conveniently, when the iterator over all types is done, so is the
515 iteration as a whole: so we can just pass all errors from the
516 internal iterator straight back out.. */
517 ctf_next_destroy (i);
518 *it = NULL;
519 return CTF_ERR; /* errno is set for us. */
522 if ((tp = ctf_lookup_by_id (&fp, i->ctn_type)) == NULL)
523 return CTF_ERR; /* errno is set for us. */
524 i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
526 dtd = ctf_dynamic_type (fp, i->ctn_type);
528 if (dtd == NULL)
530 (void) ctf_get_ctt_size (fp, tp, NULL, &i->ctn_increment);
531 i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp +
532 i->ctn_increment);
534 else
535 i->u.ctn_en = (const ctf_enum_t *) dtd->dtd_vlen;
538 this_name = ctf_strptr (fp, i->u.ctn_en->cte_name);
540 i->ctn_n--;
542 if (strcmp (name, this_name) == 0)
544 if (val)
545 *val = i->u.ctn_en->cte_value;
546 found = 1;
548 /* Constant found in this enum: try the next one. (Constant names
549 cannot be duplicated within a given enum.) */
551 i->ctn_n = 0;
554 i->u.ctn_en++;
556 while (!found);
558 return i->ctn_type;
561 typedef struct ctf_symidx_sort_arg_cb
563 ctf_dict_t *fp;
564 uint32_t *names;
565 } ctf_symidx_sort_arg_cb_t;
567 static int
568 sort_symidx_by_name (const void *one_, const void *two_, void *arg_)
570 const uint32_t *one = one_;
571 const uint32_t *two = two_;
572 ctf_symidx_sort_arg_cb_t *arg = arg_;
574 return (strcmp (ctf_strptr (arg->fp, arg->names[*one]),
575 ctf_strptr (arg->fp, arg->names[*two])));
578 /* Sort a symbol index section by name. Takes a 1:1 mapping of names to the
579 corresponding symbol table. Returns a lexicographically sorted array of idx
580 indexes (and thus, of indexes into the corresponding func info / data object
581 section). */
583 static uint32_t *
584 ctf_symidx_sort (ctf_dict_t *fp, uint32_t *idx, size_t *nidx,
585 size_t len)
587 uint32_t *sorted;
588 size_t i;
590 if ((sorted = malloc (len)) == NULL)
592 ctf_set_errno (fp, ENOMEM);
593 return NULL;
596 *nidx = len / sizeof (uint32_t);
597 for (i = 0; i < *nidx; i++)
598 sorted[i] = i;
600 if (!(fp->ctf_header->cth_flags & CTF_F_IDXSORTED))
602 ctf_symidx_sort_arg_cb_t arg = { fp, idx };
603 ctf_dprintf ("Index section unsorted: sorting.\n");
604 ctf_qsort_r (sorted, *nidx, sizeof (uint32_t), sort_symidx_by_name, &arg);
605 fp->ctf_header->cth_flags |= CTF_F_IDXSORTED;
608 return sorted;
611 /* Given a symbol index, return the name of that symbol from the table provided
612 by ctf_link_shuffle_syms, or failing that from the secondary string table, or
613 the null string. */
614 static const char *
615 ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx)
617 const ctf_sect_t *sp = &fp->ctf_ext_symtab;
618 ctf_link_sym_t sym;
619 int err;
621 if (fp->ctf_dynsymidx)
623 err = EINVAL;
624 if (symidx > fp->ctf_dynsymmax)
625 goto try_parent;
627 ctf_link_sym_t *symp = fp->ctf_dynsymidx[symidx];
629 if (!symp)
630 goto try_parent;
632 return symp->st_name;
635 err = ECTF_NOSYMTAB;
636 if (sp->cts_data == NULL)
637 goto try_parent;
639 if (symidx >= fp->ctf_nsyms)
640 goto try_parent;
642 switch (sp->cts_entsize)
644 case sizeof (Elf64_Sym):
646 const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx;
647 ctf_elf64_to_link_sym (fp, &sym, symp, symidx);
649 break;
650 case sizeof (Elf32_Sym):
652 const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx;
653 ctf_elf32_to_link_sym (fp, &sym, symp, symidx);
655 break;
656 default:
657 ctf_set_errno (fp, ECTF_SYMTAB);
658 return _CTF_NULLSTR;
661 assert (!sym.st_nameidx_set);
663 return sym.st_name;
665 try_parent:
666 if (fp->ctf_parent)
668 const char *ret;
669 ret = ctf_lookup_symbol_name (fp->ctf_parent, symidx);
670 if (ret == NULL)
671 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
672 return ret;
674 else
676 ctf_set_errno (fp, err);
677 return _CTF_NULLSTR;
681 /* Given a symbol name, return the index of that symbol, or -1 on error or if
682 not found. If is_function is >= 0, return only function or data object
683 symbols, respectively. */
684 static unsigned long
685 ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname, int try_parent,
686 int is_function)
688 const ctf_sect_t *sp = &fp->ctf_ext_symtab;
689 ctf_link_sym_t sym;
690 void *known_idx;
691 int err;
692 ctf_dict_t *cache = fp;
694 if (fp->ctf_dynsyms)
696 err = EINVAL;
698 ctf_link_sym_t *symp;
700 if (((symp = ctf_dynhash_lookup (fp->ctf_dynsyms, symname)) == NULL)
701 || (symp->st_type != STT_OBJECT && is_function == 0)
702 || (symp->st_type != STT_FUNC && is_function == 1))
703 goto try_parent;
705 return symp->st_symidx;
708 err = ECTF_NOSYMTAB;
709 if (sp->cts_data == NULL)
710 goto try_parent;
712 /* First, try a hash lookup to see if we have already spotted this symbol
713 during a past iteration: create the hash first if need be. The
714 lifespan of the strings is equal to the lifespan of the cts_data, so we
715 don't need to strdup them. If this dict was opened as part of an
716 archive, and this archive has a crossdict_cache to cache results that
717 are the same across all dicts in an archive, use it. */
719 if (fp->ctf_archive && fp->ctf_archive->ctfi_crossdict_cache)
720 cache = fp->ctf_archive->ctfi_crossdict_cache;
722 if (!cache->ctf_symhash_func)
723 if ((cache->ctf_symhash_func = ctf_dynhash_create (ctf_hash_string,
724 ctf_hash_eq_string,
725 NULL, NULL)) == NULL)
726 goto oom;
728 if (!cache->ctf_symhash_objt)
729 if ((cache->ctf_symhash_objt = ctf_dynhash_create (ctf_hash_string,
730 ctf_hash_eq_string,
731 NULL, NULL)) == NULL)
732 goto oom;
734 if (is_function != 0 &&
735 ctf_dynhash_lookup_kv (cache->ctf_symhash_func, symname, NULL, &known_idx))
736 return (unsigned long) (uintptr_t) known_idx;
738 if (is_function != 1 &&
739 ctf_dynhash_lookup_kv (cache->ctf_symhash_objt, symname, NULL, &known_idx))
740 return (unsigned long) (uintptr_t) known_idx;
742 /* Hash lookup unsuccessful: linear search, populating the hashtab for later
743 lookups as we go. */
745 for (; cache->ctf_symhash_latest < sp->cts_size / sp->cts_entsize;
746 cache->ctf_symhash_latest++)
748 ctf_dynhash_t *h;
750 switch (sp->cts_entsize)
752 case sizeof (Elf64_Sym):
754 Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data;
756 ctf_elf64_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest],
757 cache->ctf_symhash_latest);
759 break;
760 case sizeof (Elf32_Sym):
762 Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data;
763 ctf_elf32_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest],
764 cache->ctf_symhash_latest);
765 break;
767 default:
768 ctf_set_errno (fp, ECTF_SYMTAB);
769 return (unsigned long) -1;
772 if (sym.st_type == STT_FUNC)
773 h = cache->ctf_symhash_func;
774 else if (sym.st_type == STT_OBJECT)
775 h = cache->ctf_symhash_objt;
776 else
777 continue; /* Not of interest. */
779 if (!ctf_dynhash_lookup_kv (h, sym.st_name,
780 NULL, NULL))
781 if (ctf_dynhash_cinsert (h, sym.st_name,
782 (const void *) (uintptr_t)
783 cache->ctf_symhash_latest) < 0)
784 goto oom;
785 if (strcmp (sym.st_name, symname) == 0)
786 return cache->ctf_symhash_latest++;
789 /* Searched everything, still not found. */
791 return (unsigned long) -1;
793 try_parent:
794 if (fp->ctf_parent && try_parent)
796 unsigned long psym;
798 if ((psym = ctf_lookup_symbol_idx (fp->ctf_parent, symname, try_parent,
799 is_function))
800 != (unsigned long) -1)
801 return psym;
803 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
804 return (unsigned long) -1;
806 else
808 ctf_set_errno (fp, err);
809 return (unsigned long) -1;
811 oom:
812 ctf_set_errno (fp, ENOMEM);
813 ctf_err_warn (fp, 0, 0, _("cannot allocate memory for symbol "
814 "lookup hashtab"));
815 return (unsigned long) -1;
819 ctf_id_t
820 ctf_symbol_next_static (ctf_dict_t *fp, ctf_next_t **it, const char **name,
821 int functions);
823 /* Iterate over all symbols with types: if FUNC, function symbols,
824 otherwise, data symbols. The name argument is not optional. The return
825 order is arbitrary, though is likely to be in symbol index or name order.
826 Changing the value of 'functions' in the middle of iteration has
827 unpredictable effects (probably skipping symbols, etc) and is not
828 recommended. Adding symbols while iteration is underway may also lead
829 to other symbols being skipped. */
831 ctf_id_t
832 ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name,
833 int functions)
835 ctf_id_t sym = CTF_ERR;
836 ctf_next_t *i = *it;
837 int err;
839 if (!i)
841 if ((i = ctf_next_create ()) == NULL)
842 return ctf_set_typed_errno (fp, ENOMEM);
844 i->cu.ctn_fp = fp;
845 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next;
846 i->ctn_n = 0;
847 *it = i;
850 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun)
851 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN));
853 if (fp != i->cu.ctn_fp)
854 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP));
856 /* Check the dynamic set of names first, to allow previously-written names
857 to be replaced with dynamic ones (there is still no way to remove them,
858 though).
860 We intentionally use raw access, not ctf_lookup_by_symbol, to avoid
861 incurring additional sorting cost for unsorted symtypetabs coming from the
862 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and
863 finally because it's easier to work out what the name of each symbol is if
864 we do that. */
866 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash;
867 void *dyn_name = NULL, *dyn_value = NULL;
868 size_t dyn_els = dynh ? ctf_dynhash_elements (dynh) : 0;
870 if (i->ctn_n < dyn_els)
872 err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value);
874 /* This covers errors and also end-of-iteration. */
875 if (err != 0)
877 ctf_next_destroy (i);
878 *it = NULL;
879 return ctf_set_typed_errno (fp, err);
882 *name = dyn_name;
883 sym = (ctf_id_t) (uintptr_t) dyn_value;
884 i->ctn_n++;
886 return sym;
889 return ctf_symbol_next_static (fp, it, name, functions);
892 /* ctf_symbol_next, but only for static symbols. Mostly an internal
893 implementation detail of ctf_symbol_next, but also used to simplify
894 serialization. */
895 ctf_id_t
896 ctf_symbol_next_static (ctf_dict_t *fp, ctf_next_t **it, const char **name,
897 int functions)
899 ctf_id_t sym = CTF_ERR;
900 ctf_next_t *i = *it;
901 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash;
902 size_t dyn_els = dynh ? ctf_dynhash_elements (dynh) : 0;
904 /* Only relevant for direct internal-to-library calls, not via
905 ctf_symbol_next (but important then). */
907 if (!i)
909 if ((i = ctf_next_create ()) == NULL)
910 return ctf_set_typed_errno (fp, ENOMEM);
912 i->cu.ctn_fp = fp;
913 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next;
914 i->ctn_n = dyn_els;
915 *it = i;
918 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun)
919 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN));
921 if (fp != i->cu.ctn_fp)
922 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP));
924 /* TODO-v4: Indexed after non-indexed portions? */
926 if ((!functions && fp->ctf_objtidx_names) ||
927 (functions && fp->ctf_funcidx_names))
929 ctf_header_t *hp = fp->ctf_header;
930 uint32_t *idx = functions ? fp->ctf_funcidx_names : fp->ctf_objtidx_names;
931 uint32_t *tab;
932 size_t len;
934 if (functions)
936 len = (hp->cth_varoff - hp->cth_funcidxoff) / sizeof (uint32_t);
937 tab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
939 else
941 len = (hp->cth_funcidxoff - hp->cth_objtidxoff) / sizeof (uint32_t);
942 tab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
947 if (i->ctn_n - dyn_els >= len)
948 goto end;
950 *name = ctf_strptr (fp, idx[i->ctn_n - dyn_els]);
951 sym = tab[i->ctn_n - dyn_els];
952 i->ctn_n++;
954 while (sym == -1u || sym == 0);
956 else
958 /* Skip over pads in ctf_sxlate, padding for typeless symbols in the
959 symtypetab itself, and symbols in the wrong table. */
960 for (; i->ctn_n - dyn_els < fp->ctf_nsyms; i->ctn_n++)
962 ctf_header_t *hp = fp->ctf_header;
963 size_t n = i->ctn_n - dyn_els;
965 if (fp->ctf_sxlate[n] == -1u)
966 continue;
968 sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[n]);
970 if (sym == 0)
971 continue;
973 if (functions)
975 if (fp->ctf_sxlate[n] >= hp->cth_funcoff
976 && fp->ctf_sxlate[n] < hp->cth_objtidxoff)
977 break;
979 else
981 if (fp->ctf_sxlate[n] >= hp->cth_objtoff
982 && fp->ctf_sxlate[n] < hp->cth_funcoff)
983 break;
987 if (i->ctn_n - dyn_els >= fp->ctf_nsyms)
988 goto end;
990 *name = ctf_lookup_symbol_name (fp, i->ctn_n - dyn_els);
991 i->ctn_n++;
994 return sym;
996 end:
997 ctf_next_destroy (i);
998 *it = NULL;
999 return (ctf_set_typed_errno (fp, ECTF_NEXT_END));
1002 /* A bsearch function for function and object index names. */
1004 static int
1005 ctf_lookup_idx_name (const void *key_, const void *idx_)
1007 const ctf_lookup_idx_key_t *key = key_;
1008 const uint32_t *idx = idx_;
1010 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx])));
1013 /* Given a symbol name or (failing that) number, look up that symbol in the
1014 function or object index table (which must exist). Return 0 if not found
1015 there (or pad). */
1017 static ctf_id_t
1018 ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx,
1019 const char *symname, int is_function)
1021 struct ctf_header *hp = fp->ctf_header;
1022 uint32_t *symtypetab;
1023 uint32_t *names;
1024 uint32_t *sxlate;
1025 size_t nidx;
1027 if (symname == NULL)
1028 symname = ctf_lookup_symbol_name (fp, symidx);
1030 /* Dynamic dict with no static portion: just return. */
1031 if (!hp)
1033 ctf_dprintf ("%s not found in idx: dict is dynamic\n", symname);
1034 return 0;
1037 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in "
1038 "indexed symtypetab\n", symidx, symname);
1040 if (symname[0] == '\0')
1041 return CTF_ERR; /* errno is set for us. */
1043 if (is_function)
1045 if (!fp->ctf_funcidx_sxlate)
1047 if ((fp->ctf_funcidx_sxlate
1048 = ctf_symidx_sort (fp, (uint32_t *)
1049 (fp->ctf_buf + hp->cth_funcidxoff),
1050 &fp->ctf_nfuncidx,
1051 hp->cth_varoff - hp->cth_funcidxoff))
1052 == NULL)
1054 ctf_err_warn (fp, 0, 0, _("cannot sort function symidx"));
1055 return CTF_ERR; /* errno is set for us. */
1058 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
1059 sxlate = fp->ctf_funcidx_sxlate;
1060 names = fp->ctf_funcidx_names;
1061 nidx = fp->ctf_nfuncidx;
1063 else
1065 if (!fp->ctf_objtidx_sxlate)
1067 if ((fp->ctf_objtidx_sxlate
1068 = ctf_symidx_sort (fp, (uint32_t *)
1069 (fp->ctf_buf + hp->cth_objtidxoff),
1070 &fp->ctf_nobjtidx,
1071 hp->cth_funcidxoff - hp->cth_objtidxoff))
1072 == NULL)
1074 ctf_err_warn (fp, 0, 0, _("cannot sort object symidx"));
1075 return CTF_ERR; /* errno is set for us. */
1079 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
1080 sxlate = fp->ctf_objtidx_sxlate;
1081 names = fp->ctf_objtidx_names;
1082 nidx = fp->ctf_nobjtidx;
1085 ctf_lookup_idx_key_t key = { fp, symname, names };
1086 uint32_t *idx;
1088 idx = bsearch (&key, sxlate, nidx, sizeof (uint32_t), ctf_lookup_idx_name);
1090 if (!idx)
1092 ctf_dprintf ("%s not found in idx\n", symname);
1093 return 0;
1096 /* Should be impossible, but be paranoid. */
1097 if ((idx - sxlate) > (ptrdiff_t) nidx)
1098 return (ctf_set_typed_errno (fp, ECTF_CORRUPT));
1100 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname,
1101 symtypetab[*idx]);
1102 return symtypetab[*idx];
1105 /* Given a symbol name or (if NULL) symbol index, return the type of the
1106 function or data object described by the corresponding entry in the symbol
1107 table. We can only return symbols in read-only dicts and in dicts for which
1108 ctf_link_shuffle_syms has been called to assign symbol indexes to symbol
1109 names.
1111 If try_parent is false, do not check the parent dict too.
1113 If is_function is > -1, only look for data objects or functions in
1114 particular. */
1116 ctf_id_t
1117 ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx,
1118 const char *symname, int try_parent,
1119 int is_function)
1121 const ctf_sect_t *sp = &fp->ctf_ext_symtab;
1122 ctf_id_t type = 0;
1123 int err = 0;
1125 /* Shuffled dynsymidx present? Use that. For now, the dynsymidx and
1126 shuffled-symbol lookup only support dynamically-added symbols, because
1127 this interface is meant for use by linkers, and linkers are only going
1128 to report symbols against newly-created, freshly-ctf_link'ed dicts: so
1129 there will be no static component in any case. */
1130 if (fp->ctf_dynsymidx)
1132 const ctf_link_sym_t *sym;
1134 if (symname)
1135 ctf_dprintf ("Looking up type of object with symname %s in "
1136 "writable dict symtypetab\n", symname);
1137 else
1138 ctf_dprintf ("Looking up type of object with symtab idx %lx in "
1139 "writable dict symtypetab\n", symidx);
1141 /* No name? Need to look it up. */
1142 if (!symname)
1144 err = EINVAL;
1145 if (symidx > fp->ctf_dynsymmax)
1146 goto try_parent;
1148 sym = fp->ctf_dynsymidx[symidx];
1149 err = ECTF_NOTYPEDAT;
1150 if (!sym || (sym->st_type != STT_OBJECT && sym->st_type != STT_FUNC)
1151 || (sym->st_type != STT_OBJECT && is_function == 0)
1152 || (sym->st_type != STT_FUNC && is_function == 1))
1153 goto try_parent;
1155 if (!ctf_assert (fp, !sym->st_nameidx_set))
1156 return CTF_ERR;
1157 symname = sym->st_name;
1160 if (fp->ctf_objthash == NULL
1161 || is_function == 1
1162 || (type = (ctf_id_t) (uintptr_t)
1163 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0)
1165 if (fp->ctf_funchash == NULL
1166 || is_function == 0
1167 || (type = (ctf_id_t) (uintptr_t)
1168 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0)
1169 goto try_parent;
1172 return type;
1175 /* Dict not shuffled: look for a dynamic sym first, and look it up
1176 directly. */
1177 if (symname)
1179 if (fp->ctf_objthash != NULL
1180 && is_function != 1
1181 && ((type = (ctf_id_t) (uintptr_t)
1182 ctf_dynhash_lookup (fp->ctf_objthash, symname)) != 0))
1183 return type;
1185 if (fp->ctf_funchash != NULL
1186 && is_function != 0
1187 && ((type = (ctf_id_t) (uintptr_t)
1188 ctf_dynhash_lookup (fp->ctf_funchash, symname)) != 0))
1189 return type;
1192 err = ECTF_NOSYMTAB;
1193 if (sp->cts_data == NULL && symname == NULL &&
1194 ((is_function && !fp->ctf_funcidx_names) ||
1195 (!is_function && !fp->ctf_objtidx_names)))
1196 goto try_parent;
1198 /* This covers both out-of-range lookups by index and a dynamic dict which
1199 hasn't been shuffled yet. */
1200 err = EINVAL;
1201 if (symname == NULL && symidx >= fp->ctf_nsyms)
1202 goto try_parent;
1204 /* Try an indexed lookup. */
1206 if (fp->ctf_objtidx_names && is_function != 1)
1208 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR)
1209 return CTF_ERR; /* errno is set for us. */
1211 if (type == 0 && fp->ctf_funcidx_names && is_function != 0)
1213 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR)
1214 return CTF_ERR; /* errno is set for us. */
1216 if (type != 0)
1217 return type;
1219 /* Indexed but no symbol found -> not present, try the parent. */
1220 err = ECTF_NOTYPEDAT;
1221 if (fp->ctf_objtidx_names && fp->ctf_funcidx_names)
1222 goto try_parent;
1224 /* Table must be nonindexed. */
1226 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx);
1228 if (symname != NULL)
1229 if ((symidx = ctf_lookup_symbol_idx (fp, symname, try_parent, is_function))
1230 == (unsigned long) -1)
1231 goto try_parent;
1233 if (fp->ctf_sxlate[symidx] == -1u)
1234 goto try_parent;
1236 type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]);
1238 if (type == 0)
1239 goto try_parent;
1241 return type;
1243 try_parent:
1244 if (!try_parent)
1245 return ctf_set_errno (fp, err);
1247 if (fp->ctf_parent)
1249 ctf_id_t ret = ctf_lookup_by_sym_or_name (fp->ctf_parent, symidx,
1250 symname, try_parent,
1251 is_function);
1252 if (ret == CTF_ERR)
1253 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
1254 return ret;
1256 else
1257 return (ctf_set_typed_errno (fp, err));
1260 /* Given a symbol table index, return the type of the function or data object
1261 described by the corresponding entry in the symbol table. */
1262 ctf_id_t
1263 ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx)
1265 return ctf_lookup_by_sym_or_name (fp, symidx, NULL, 1, -1);
1268 /* Given a symbol name, return the type of the function or data object described
1269 by the corresponding entry in the symbol table. */
1270 ctf_id_t
1271 ctf_lookup_by_symbol_name (ctf_dict_t *fp, const char *symname)
1273 return ctf_lookup_by_sym_or_name (fp, 0, symname, 1, -1);
1276 /* Given a symbol table index, return the info for the function described
1277 by the corresponding entry in the symbol table, which may be a function
1278 symbol or may be a data symbol that happens to be a function pointer. */
1281 ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip)
1283 ctf_id_t type;
1285 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1286 return -1; /* errno is set for us. */
1288 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1289 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1291 return ctf_func_type_info (fp, type, fip);
1294 /* Given a symbol table index, return the arguments for the function described
1295 by the corresponding entry in the symbol table. */
1298 ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc,
1299 ctf_id_t *argv)
1301 ctf_id_t type;
1303 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1304 return -1; /* errno is set for us. */
1306 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1307 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1309 return ctf_func_type_args (fp, type, argc, argv);