]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-lookup.c
Fix heap-use-after-free in index-cached with --disable-threading
[thirdparty/binutils-gdb.git] / libctf / ctf-lookup.c
CommitLineData
12a0b67d 1/* Symbol, variable and name lookup.
fd67aa11 2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
47d546f4
NA
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>
1136c379 23#include <assert.h>
47d546f4 24
abe4ca69
NA
25/* Grow the pptrtab so that it is at least NEW_LEN long. */
26static int
27grow_pptrtab (ctf_dict_t *fp, size_t new_len)
28{
29 uint32_t *new_pptrtab;
30
31 if ((new_pptrtab = realloc (fp->ctf_pptrtab, sizeof (uint32_t)
32 * new_len)) == NULL)
33 return (ctf_set_errno (fp, ENOMEM));
34
35 fp->ctf_pptrtab = new_pptrtab;
36
37 memset (fp->ctf_pptrtab + fp->ctf_pptrtab_len, 0,
38 sizeof (uint32_t) * (new_len - fp->ctf_pptrtab_len));
39
40 fp->ctf_pptrtab_len = new_len;
41 return 0;
42}
43
44/* Update entries in the pptrtab that relate to types newly added in the
45 child. */
46static int
47refresh_pptrtab (ctf_dict_t *fp, ctf_dict_t *pfp)
48{
49 uint32_t i;
50 for (i = fp->ctf_pptrtab_typemax; i <= fp->ctf_typemax; i++)
51 {
52 ctf_id_t type = LCTF_INDEX_TO_TYPE (fp, i, 1);
53 ctf_id_t reffed_type;
abe4ca69
NA
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. */
abe4ca69
NA
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
b437bfe0
NA
83/* Compare the given input string and length against a table of known C storage
84 qualifier keywords. We just ignore these in ctf_lookup_by_name, below. To
85 do this quickly, we use a pre-computed Perfect Hash Function similar to the
86 technique originally described in the classic paper:
87
88 R.J. Cichelli, "Minimal Perfect Hash Functions Made Simple",
89 Communications of the ACM, Volume 23, Issue 1, January 1980, pp. 17-19.
90
91 For an input string S of length N, we use hash H = S[N - 1] + N - 105, which
92 for the current set of qualifiers yields a unique H in the range [0 .. 20].
93 The hash can be modified when the keyword set changes as necessary. We also
94 store the length of each keyword and check it prior to the final strcmp().
95
96 TODO: just use gperf. */
97
98static int
99isqualifier (const char *s, size_t len)
100{
101 static const struct qual
102 {
103 const char *q_name;
104 size_t q_len;
105 } qhash[] = {
106 {"static", 6}, {"", 0}, {"", 0}, {"", 0},
107 {"volatile", 8}, {"", 0}, {"", 0}, {"", 0}, {"", 0},
108 {"", 0}, {"auto", 4}, {"extern", 6}, {"", 0}, {"", 0},
109 {"", 0}, {"", 0}, {"const", 5}, {"register", 8},
110 {"", 0}, {"restrict", 8}, {"_Restrict", 9}
111 };
112
113 int h = s[len - 1] + (int) len - 105;
0bd65ce3 114 const struct qual *qp;
b437bfe0 115
0bd65ce3
NA
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 &&
b437bfe0
NA
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
abe4ca69
NA
134static ctf_id_t
135ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
136 const char *name)
b437bfe0
NA
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)
998a4f58 146 return (ctf_set_typed_errno (fp, EINVAL));
b437bfe0
NA
147
148 for (p = name, end = name + strlen (name); *p != '\0'; p = q)
149 {
734c8942 150 while (isspace ((int) *p))
b437bfe0
NA
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 {
abe4ca69
NA
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
e05a3e5a
NA
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.) */
abe4ca69
NA
174
175 uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type);
176 int in_child = 0;
177
e05a3e5a 178 ntype = CTF_ERR;
6ab5b6d0 179 if (child && idx < child->ctf_pptrtab_len)
abe4ca69
NA
180 {
181 ntype = child->ctf_pptrtab[idx];
182 if (ntype)
183 in_child = 1;
e05a3e5a
NA
184 else
185 ntype = CTF_ERR;
abe4ca69 186 }
b437bfe0 187
e05a3e5a
NA
188 if (ntype == CTF_ERR)
189 {
190 ntype = fp->ctf_ptrtab[idx];
191 if (ntype == 0)
192 ntype = CTF_ERR;
193 }
b437bfe0 194
abe4ca69 195 /* Try resolving to its base type and check again. */
e05a3e5a 196 if (ntype == CTF_ERR)
b437bfe0 197 {
abe4ca69
NA
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
e05a3e5a 208 ntype = CTF_ERR;
6ab5b6d0 209 if (child && idx < child->ctf_pptrtab_len)
b437bfe0 210 {
abe4ca69
NA
211 ntype = child->ctf_pptrtab[idx];
212 if (ntype)
213 in_child = 1;
e05a3e5a
NA
214 else
215 ntype = CTF_ERR;
b437bfe0 216 }
abe4ca69 217
e05a3e5a
NA
218 if (ntype == CTF_ERR)
219 {
220 ntype = fp->ctf_ptrtab[idx];
221 if (ntype == 0)
222 ntype = CTF_ERR;
223 }
abe4ca69
NA
224 if (ntype == CTF_ERR)
225 goto notype;
b437bfe0
NA
226 }
227
abe4ca69
NA
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 }
b437bfe0
NA
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 {
734c8942 254 for (p += lp->ctl_len; isspace ((int) *p); p++)
b437bfe0
NA
255 continue; /* Skip prefix and next whitespace. */
256
257 if ((q = strchr (p, '*')) == NULL)
258 q = end; /* Compare until end. */
259
734c8942 260 while (isspace ((int) q[-1]))
b437bfe0
NA
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);
942d35f7 274 fp->ctf_tmp_typeslice = xstrndup (p, (size_t) (q - p));
b437bfe0 275 if (fp->ctf_tmp_typeslice == NULL)
998a4f58 276 return ctf_set_typed_errno (fp, ENOMEM);
b437bfe0
NA
277 }
278
54a02191
NA
279 if ((type = (ctf_id_t) (uintptr_t)
280 ctf_dynhash_lookup (lp->ctl_hash,
281 fp->ctf_tmp_typeslice)) == 0)
abe4ca69 282 goto notype;
b437bfe0
NA
283
284 break;
285 }
286 }
287
288 if (lp->ctl_prefix == NULL)
abe4ca69 289 goto notype;
b437bfe0
NA
290 }
291
292 if (*p != '\0' || type == 0)
998a4f58 293 return (ctf_set_typed_errno (fp, ECTF_SYNTAX));
b437bfe0
NA
294
295 return type;
296
abe4ca69
NA
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)
998a4f58 307 return CTF_ERR; /* errno is set for us. */
abe4ca69
NA
308 }
309
310 if ((ptype = ctf_lookup_by_name_internal (fp->ctf_parent, fp,
311 name)) != CTF_ERR)
312 return ptype;
998a4f58 313 return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent)));
abe4ca69 314 }
b437bfe0
NA
315
316 return CTF_ERR;
317}
318
abe4ca69
NA
319ctf_id_t
320ctf_lookup_by_name (ctf_dict_t *fp, const char *name)
321{
322 return ctf_lookup_by_name_internal (fp, NULL, name);
323}
324
1136c379
NA
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
329const ctf_type_t *
330ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type)
b437bfe0 331{
8a60c930 332 ctf_dict_t *fp = *fpp;
1136c379
NA
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
1136c379
NA
341 idx = LCTF_TYPE_TO_INDEX (fp, type);
342 if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax)
343 {
8a60c930 344 *fpp = fp; /* Possibly the parent CTF dict. */
1136c379
NA
345 return (LCTF_INDEX_TO_TYPEPTR (fp, idx));
346 }
347
348 (void) ctf_set_errno (*fpp, ECTF_BADID);
349 return NULL;
350}
351
352typedef 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;
b437bfe0
NA
358
359/* A bsearch function for variable names. */
360
361static int
1136c379 362ctf_lookup_var (const void *key_, const void *lookup_)
b437bfe0 363{
1136c379
NA
364 const ctf_lookup_idx_key_t *key = key_;
365 const ctf_varent_t *lookup = lookup_;
b437bfe0 366
1136c379 367 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name)));
b437bfe0
NA
368}
369
8a60c930
NA
370/* Given a variable name, return the type of the variable with that name.
371 Look only in this dict, not in the parent. */
b437bfe0
NA
372
373ctf_id_t
8a60c930 374ctf_lookup_variable_here (ctf_dict_t *fp, const char *name)
b437bfe0 375{
8a60c930 376 ctf_dvdef_t *dvd = ctf_dvd_lookup (fp, name);
b437bfe0 377 ctf_varent_t *ent;
1136c379 378 ctf_lookup_idx_key_t key = { fp, name, NULL };
b437bfe0 379
8a60c930
NA
380 if (dvd != NULL)
381 return dvd->dvd_type;
382
b437bfe0
NA
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)
8a60c930
NA
389 return (ctf_set_typed_errno (fp, ECTF_NOTYPEDAT));
390
391 return ent->ctv_type;
392}
d7474051 393
8a60c930 394/* As above, but look in the parent too. */
b437bfe0 395
8a60c930
NA
396ctf_id_t
397ctf_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. */
b437bfe0
NA
411 }
412
8a60c930 413 return type;
b437bfe0
NA
414}
415
1136c379
NA
416typedef struct ctf_symidx_sort_arg_cb
417{
418 ctf_dict_t *fp;
419 uint32_t *names;
420} ctf_symidx_sort_arg_cb_t;
421
422static int
423sort_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
438static uint32_t *
439ctf_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 };
a96a9ca9 458 ctf_dprintf ("Index section unsorted: sorting.\n");
1136c379
NA
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. */
f4f60336 469static const char *
139633c3 470ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx)
b437bfe0 471{
629acbe4 472 const ctf_sect_t *sp = &fp->ctf_ext_symtab;
1136c379
NA
473 ctf_link_sym_t sym;
474 int err;
b437bfe0 475
1136c379 476 if (fp->ctf_dynsymidx)
b437bfe0 477 {
1136c379
NA
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;
b437bfe0
NA
488 }
489
1136c379
NA
490 err = ECTF_NOSYMTAB;
491 if (sp->cts_data == NULL)
492 goto try_parent;
493
b437bfe0 494 if (symidx >= fp->ctf_nsyms)
1136c379
NA
495 goto try_parent;
496
497 switch (sp->cts_entsize)
b437bfe0 498 {
1136c379
NA
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);
b437bfe0
NA
513 return _CTF_NULLSTR;
514 }
515
1136c379 516 assert (!sym.st_nameidx_set);
b437bfe0 517
1136c379 518 return sym.st_name;
b437bfe0 519
1136c379
NA
520 try_parent:
521 if (fp->ctf_parent)
f4f60336
NA
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 }
1136c379
NA
529 else
530 {
531 ctf_set_errno (fp, err);
532 return _CTF_NULLSTR;
533 }
b437bfe0
NA
534}
535
f4f60336 536/* Given a symbol name, return the index of that symbol, or -1 on error or if
8a60c930
NA
537 not found. If is_function is >= 0, return only function or data object
538 symbols, respectively. */
f4f60336 539static unsigned long
8a60c930
NA
540ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname, int try_parent,
541 int is_function)
f4f60336 542{
629acbe4 543 const ctf_sect_t *sp = &fp->ctf_ext_symtab;
f4f60336
NA
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
8a60c930
NA
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))
f4f60336
NA
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
8a60c930
NA
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
f4f60336
NA
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
8a60c930
NA
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)
f4f60336
NA
587 goto oom;
588
8a60c930
NA
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))
f4f60336
NA
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 {
8a60c930
NA
603 ctf_dynhash_t *h;
604
f4f60336
NA
605 switch (sp->cts_entsize)
606 {
607 case sizeof (Elf64_Sym):
608 {
609 Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data;
8a60c930 610
f4f60336
NA
611 ctf_elf64_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest],
612 cache->ctf_symhash_latest);
08794526
NA
613 }
614 break;
f4f60336
NA
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);
8a60c930 620 break;
08794526 621 }
f4f60336
NA
622 default:
623 ctf_set_errno (fp, ECTF_SYMTAB);
624 return (unsigned long) -1;
625 }
8a60c930
NA
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++;
f4f60336
NA
642 }
643
644 /* Searched everything, still not found. */
645
646 return (unsigned long) -1;
647
648 try_parent:
8a60c930 649 if (fp->ctf_parent && try_parent)
d7474051
NA
650 {
651 unsigned long psym;
652
8a60c930
NA
653 if ((psym = ctf_lookup_symbol_idx (fp->ctf_parent, symname, try_parent,
654 is_function))
d7474051
NA
655 != (unsigned long) -1)
656 return psym;
657
658 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
659 return (unsigned long) -1;
660 }
f4f60336
NA
661 else
662 {
663 ctf_set_errno (fp, err);
664 return (unsigned long) -1;
665 }
666oom:
667 ctf_set_errno (fp, ENOMEM);
7e1368b5
NA
668 ctf_err_warn (fp, 0, 0, _("cannot allocate memory for symbol "
669 "lookup hashtab"));
f4f60336
NA
670 return (unsigned long) -1;
671
672}
673
8a60c930
NA
674ctf_id_t
675ctf_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. */
b437bfe0
NA
685
686ctf_id_t
1136c379
NA
687ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name,
688 int functions)
b437bfe0 689{
cce0bb8f 690 ctf_id_t sym = CTF_ERR;
1136c379
NA
691 ctf_next_t *i = *it;
692 int err;
b437bfe0 693
1136c379
NA
694 if (!i)
695 {
696 if ((i = ctf_next_create ()) == NULL)
998a4f58 697 return ctf_set_typed_errno (fp, ENOMEM);
b437bfe0 698
1136c379
NA
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)
998a4f58 706 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN));
b437bfe0 707
1136c379 708 if (fp != i->cu.ctn_fp)
998a4f58 709 return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP));
1136c379 710
8a60c930
NA
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
1136c379
NA
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
8a60c930
NA
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;
1136c379 724
8a60c930
NA
725 if (i->ctn_n < dyn_els)
726 {
6c3a3877 727 err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value);
8a60c930 728
1136c379
NA
729 /* This covers errors and also end-of-iteration. */
730 if (err != 0)
731 {
732 ctf_next_destroy (i);
733 *it = NULL;
998a4f58 734 return ctf_set_typed_errno (fp, err);
1136c379
NA
735 }
736
737 *name = dyn_name;
738 sym = (ctf_id_t) (uintptr_t) dyn_value;
8a60c930
NA
739 i->ctn_n++;
740
741 return sym;
b437bfe0 742 }
8a60c930
NA
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. */
750ctf_id_t
751ctf_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))
b437bfe0 783 {
1136c379
NA
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 {
8a60c930 802 if (i->ctn_n - dyn_els >= len)
1136c379
NA
803 goto end;
804
8a60c930
NA
805 *name = ctf_strptr (fp, idx[i->ctn_n - dyn_els]);
806 sym = tab[i->ctn_n - dyn_els];
807 i->ctn_n++;
eefe721e
NA
808 }
809 while (sym == -1u || sym == 0);
b437bfe0 810 }
1136c379
NA
811 else
812 {
8a60c930 813 /* Skip over pads in ctf_sxlate, padding for typeless symbols in the
1136c379 814 symtypetab itself, and symbols in the wrong table. */
8a60c930 815 for (; i->ctn_n - dyn_els < fp->ctf_nsyms; i->ctn_n++)
1136c379
NA
816 {
817 ctf_header_t *hp = fp->ctf_header;
8a60c930 818 size_t n = i->ctn_n - dyn_els;
b437bfe0 819
8a60c930 820 if (fp->ctf_sxlate[n] == -1u)
1136c379 821 continue;
b437bfe0 822
8a60c930 823 sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[n]);
b437bfe0 824
1136c379
NA
825 if (sym == 0)
826 continue;
827
828 if (functions)
829 {
8a60c930
NA
830 if (fp->ctf_sxlate[n] >= hp->cth_funcoff
831 && fp->ctf_sxlate[n] < hp->cth_objtidxoff)
1136c379
NA
832 break;
833 }
834 else
835 {
8a60c930
NA
836 if (fp->ctf_sxlate[n] >= hp->cth_objtoff
837 && fp->ctf_sxlate[n] < hp->cth_funcoff)
1136c379
NA
838 break;
839 }
840 }
841
8a60c930 842 if (i->ctn_n - dyn_els >= fp->ctf_nsyms)
1136c379
NA
843 goto end;
844
8a60c930
NA
845 *name = ctf_lookup_symbol_name (fp, i->ctn_n - dyn_els);
846 i->ctn_n++;
1136c379
NA
847 }
848
849 return sym;
850
851 end:
852 ctf_next_destroy (i);
853 *it = NULL;
998a4f58 854 return (ctf_set_typed_errno (fp, ECTF_NEXT_END));
b437bfe0
NA
855}
856
1136c379
NA
857/* A bsearch function for function and object index names. */
858
859static int
860ctf_lookup_idx_name (const void *key_, const void *idx_)
688d28f6 861{
1136c379
NA
862 const ctf_lookup_idx_key_t *key = key_;
863 const uint32_t *idx = idx_;
688d28f6 864
1136c379 865 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx])));
688d28f6
NA
866}
867
f4f60336
NA
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). */
47d546f4 871
1136c379 872static ctf_id_t
f4f60336
NA
873ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx,
874 const char *symname, int is_function)
47d546f4 875{
1136c379
NA
876 struct ctf_header *hp = fp->ctf_header;
877 uint32_t *symtypetab;
878 uint32_t *names;
879 uint32_t *sxlate;
880 size_t nidx;
47d546f4 881
f4f60336
NA
882 if (symname == NULL)
883 symname = ctf_lookup_symbol_name (fp, symidx);
884
8a60c930
NA
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
f4f60336 892 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in "
1136c379 893 "indexed symtypetab\n", symidx, symname);
47d546f4 894
1136c379 895 if (symname[0] == '\0')
998a4f58 896 return CTF_ERR; /* errno is set for us. */
47d546f4 897
1136c379 898 if (is_function)
47d546f4 899 {
1136c379 900 if (!fp->ctf_funcidx_sxlate)
47d546f4 901 {
1136c379
NA
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"));
998a4f58 910 return CTF_ERR; /* errno is set for us. */
1136c379 911 }
47d546f4 912 }
1136c379
NA
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;
47d546f4 917 }
1136c379
NA
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"));
998a4f58 930 return CTF_ERR; /* errno is set for us. */
1136c379
NA
931 }
932 }
676c3ecb 933
1136c379
NA
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 }
676c3ecb 939
1136c379
NA
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)
676c3ecb 946 {
1136c379
NA
947 ctf_dprintf ("%s not found in idx\n", symname);
948 return 0;
676c3ecb
NA
949 }
950
1136c379
NA
951 /* Should be impossible, but be paranoid. */
952 if ((idx - sxlate) > (ptrdiff_t) nidx)
998a4f58 953 return (ctf_set_typed_errno (fp, ECTF_CORRUPT));
1136c379
NA
954
955 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname,
956 symtypetab[*idx]);
957 return symtypetab[*idx];
47d546f4
NA
958}
959
f4f60336
NA
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
8a60c930 964 names.
b437bfe0 965
8a60c930
NA
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
971ctf_id_t
f4f60336 972ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx,
8a60c930
NA
973 const char *symname, int try_parent,
974 int is_function)
b437bfe0 975{
629acbe4 976 const ctf_sect_t *sp = &fp->ctf_ext_symtab;
1136c379
NA
977 ctf_id_t type = 0;
978 int err = 0;
979
8a60c930
NA
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. */
1136c379
NA
985 if (fp->ctf_dynsymidx)
986 {
987 const ctf_link_sym_t *sym;
988
f4f60336
NA
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);
1136c379 995
f4f60336
NA
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;
1136c379 1002
08794526 1003 sym = fp->ctf_dynsymidx[symidx];
f4f60336 1004 err = ECTF_NOTYPEDAT;
8a60c930
NA
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))
f4f60336 1008 goto try_parent;
1136c379 1009
f4f60336
NA
1010 if (!ctf_assert (fp, !sym->st_nameidx_set))
1011 return CTF_ERR;
1012 symname = sym->st_name;
1013 }
1136c379
NA
1014
1015 if (fp->ctf_objthash == NULL
8a60c930
NA
1016 || is_function == 1
1017 || (type = (ctf_id_t) (uintptr_t)
1018 ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0)
1136c379
NA
1019 {
1020 if (fp->ctf_funchash == NULL
8a60c930
NA
1021 || is_function == 0
1022 || (type = (ctf_id_t) (uintptr_t)
1023 ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0)
1136c379
NA
1024 goto try_parent;
1025 }
1026
1027 return type;
1028 }
b437bfe0 1029
8a60c930
NA
1030 /* Dict not shuffled: look for a dynamic sym first, and look it up
1031 directly. */
1032 if (symname)
f4f60336 1033 {
8a60c930
NA
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;
f4f60336
NA
1045 }
1046
1136c379 1047 err = ECTF_NOSYMTAB;
9049b960
NA
1048 if (sp->cts_data == NULL && symname == NULL &&
1049 ((is_function && !fp->ctf_funcidx_names) ||
1050 (!is_function && !fp->ctf_objtidx_names)))
1136c379 1051 goto try_parent;
b437bfe0 1052
8a60c930
NA
1053 /* This covers both out-of-range lookups by index and a dynamic dict which
1054 hasn't been shuffled yet. */
1136c379 1055 err = EINVAL;
f4f60336 1056 if (symname == NULL && symidx >= fp->ctf_nsyms)
1136c379 1057 goto try_parent;
b437bfe0 1058
8a60c930
NA
1059 /* Try an indexed lookup. */
1060
1061 if (fp->ctf_objtidx_names && is_function != 1)
b437bfe0 1062 {
f4f60336 1063 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR)
1136c379 1064 return CTF_ERR; /* errno is set for us. */
b437bfe0 1065 }
8a60c930 1066 if (type == 0 && fp->ctf_funcidx_names && is_function != 0)
b437bfe0 1067 {
f4f60336 1068 if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR)
1136c379 1069 return CTF_ERR; /* errno is set for us. */
b437bfe0 1070 }
1136c379
NA
1071 if (type != 0)
1072 return type;
1073
8a60c930 1074 /* Indexed but no symbol found -> not present, try the parent. */
1136c379
NA
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);
b437bfe0 1082
f4f60336 1083 if (symname != NULL)
8a60c930
NA
1084 if ((symidx = ctf_lookup_symbol_idx (fp, symname, try_parent, is_function))
1085 == (unsigned long) -1)
f4f60336
NA
1086 goto try_parent;
1087
b437bfe0 1088 if (fp->ctf_sxlate[symidx] == -1u)
1136c379
NA
1089 goto try_parent;
1090
1091 type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]);
b437bfe0 1092
1136c379
NA
1093 if (type == 0)
1094 goto try_parent;
b437bfe0 1095
1136c379 1096 return type;
8a60c930 1097
1136c379 1098 try_parent:
8a60c930
NA
1099 if (!try_parent)
1100 return ctf_set_errno (fp, err);
1101
1136c379 1102 if (fp->ctf_parent)
f4f60336
NA
1103 {
1104 ctf_id_t ret = ctf_lookup_by_sym_or_name (fp->ctf_parent, symidx,
8a60c930
NA
1105 symname, try_parent,
1106 is_function);
f4f60336
NA
1107 if (ret == CTF_ERR)
1108 ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
1109 return ret;
1110 }
1136c379 1111 else
998a4f58 1112 return (ctf_set_typed_errno (fp, err));
1136c379 1113}
b437bfe0 1114
f4f60336
NA
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. */
1117ctf_id_t
1118ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx)
1119{
8a60c930 1120 return ctf_lookup_by_sym_or_name (fp, symidx, NULL, 1, -1);
f4f60336
NA
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. */
1125ctf_id_t
1126ctf_lookup_by_symbol_name (ctf_dict_t *fp, const char *symname)
1127{
8a60c930 1128 return ctf_lookup_by_sym_or_name (fp, 0, symname, 1, -1);
f4f60336
NA
1129}
1130
1136c379
NA
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. */
b437bfe0 1134
1136c379
NA
1135int
1136ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip)
1137{
1138 ctf_id_t type;
b437bfe0 1139
1136c379
NA
1140 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1141 return -1; /* errno is set for us. */
b437bfe0 1142
1136c379
NA
1143 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1144 return (ctf_set_errno (fp, ECTF_NOTFUNC));
b437bfe0 1145
1136c379 1146 return ctf_func_type_info (fp, type, fip);
b437bfe0
NA
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
1152int
139633c3 1153ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc,
1136c379 1154 ctf_id_t *argv)
b437bfe0 1155{
1136c379 1156 ctf_id_t type;
b437bfe0 1157
1136c379
NA
1158 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1159 return -1; /* errno is set for us. */
b437bfe0 1160
1136c379
NA
1161 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1162 return (ctf_set_errno (fp, ECTF_NOTFUNC));
b437bfe0 1163
1136c379 1164 return ctf_func_type_args (fp, type, argc, argv);
b437bfe0 1165}