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