libctf: rip out dead code handling typedefs with no name
[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;
114 const struct qual *qp = &qhash[h];
115
116 return (h >= 0 && (size_t) h < sizeof (qhash) / sizeof (qhash[0])
117 && (size_t) len == qp->q_len &&
118 strncmp (qp->q_name, s, qp->q_len) == 0);
119}
120
121/* Attempt to convert the given C type name into the corresponding CTF type ID.
122 It is not possible to do complete and proper conversion of type names
123 without implementing a more full-fledged parser, which is necessary to
124 handle things like types that are function pointers to functions that
125 have arguments that are function pointers, and fun stuff like that.
126 Instead, this function implements a very simple conversion algorithm that
127 finds the things that we actually care about: structs, unions, enums,
128 integers, floats, typedefs, and pointers to any of these named types. */
129
abe4ca69
NA
130static ctf_id_t
131ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
132 const char *name)
b437bfe0
NA
133{
134 static const char delimiters[] = " \t\n\r\v\f*";
135
136 const ctf_lookup_t *lp;
137 const char *p, *q, *end;
138 ctf_id_t type = 0;
139 ctf_id_t ntype, ptype;
140
141 if (name == NULL)
142 return (ctf_set_errno (fp, EINVAL));
143
144 for (p = name, end = name + strlen (name); *p != '\0'; p = q)
145 {
734c8942 146 while (isspace ((int) *p))
b437bfe0
NA
147 p++; /* Skip leading whitespace. */
148
149 if (p == end)
150 break;
151
152 if ((q = strpbrk (p + 1, delimiters)) == NULL)
153 q = end; /* Compare until end. */
154
155 if (*p == '*')
156 {
abe4ca69
NA
157 /* Find a pointer to type by looking in child->ctf_pptrtab (if child
158 is set) and fp->ctf_ptrtab. If we can't find a pointer to the
159 given type, see if we can compute a pointer to the type resulting
160 from resolving the type down to its base type and use that instead.
161 This helps with cases where the CTF data includes "struct foo *"
162 but not "foo_t *" and the user tries to access "foo_t *" in the
e05a3e5a
NA
163 debugger.
164
165 There is extra complexity here because uninitialized elements in
166 the pptrtab and ptrtab are set to zero, but zero (as the type ID
167 meaning the unimplemented type) is a valid return type from
168 ctf_lookup_by_name. (Pointers to types are never of type 0, so
169 this is unambiguous, just fiddly to deal with.) */
abe4ca69
NA
170
171 uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type);
172 int in_child = 0;
173
e05a3e5a 174 ntype = CTF_ERR;
abe4ca69
NA
175 if (child && idx <= child->ctf_pptrtab_len)
176 {
177 ntype = child->ctf_pptrtab[idx];
178 if (ntype)
179 in_child = 1;
e05a3e5a
NA
180 else
181 ntype = CTF_ERR;
abe4ca69 182 }
b437bfe0 183
e05a3e5a
NA
184 if (ntype == CTF_ERR)
185 {
186 ntype = fp->ctf_ptrtab[idx];
187 if (ntype == 0)
188 ntype = CTF_ERR;
189 }
b437bfe0 190
abe4ca69 191 /* Try resolving to its base type and check again. */
e05a3e5a 192 if (ntype == CTF_ERR)
b437bfe0 193 {
abe4ca69
NA
194 if (child)
195 ntype = ctf_type_resolve_unsliced (child, type);
196 else
197 ntype = ctf_type_resolve_unsliced (fp, type);
198
199 if (ntype == CTF_ERR)
200 goto notype;
201
202 idx = LCTF_TYPE_TO_INDEX (fp, ntype);
203
e05a3e5a 204 ntype = CTF_ERR;
abe4ca69 205 if (child && idx <= child->ctf_pptrtab_len)
b437bfe0 206 {
abe4ca69
NA
207 ntype = child->ctf_pptrtab[idx];
208 if (ntype)
209 in_child = 1;
e05a3e5a
NA
210 else
211 ntype = CTF_ERR;
b437bfe0 212 }
abe4ca69 213
e05a3e5a
NA
214 if (ntype == CTF_ERR)
215 {
216 ntype = fp->ctf_ptrtab[idx];
217 if (ntype == 0)
218 ntype = CTF_ERR;
219 }
abe4ca69
NA
220 if (ntype == CTF_ERR)
221 goto notype;
b437bfe0
NA
222 }
223
abe4ca69
NA
224 type = LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)
225 || in_child);
226
227 /* We are looking up a type in the parent, but the pointed-to type is
228 in the child. Switch to looking in the child: if we need to go
229 back into the parent, we can recurse again. */
230 if (in_child)
231 {
232 fp = child;
233 child = NULL;
234 }
b437bfe0
NA
235
236 q = p + 1;
237 continue;
238 }
239
240 if (isqualifier (p, (size_t) (q - p)))
241 continue; /* Skip qualifier keyword. */
242
243 for (lp = fp->ctf_lookups; lp->ctl_prefix != NULL; lp++)
244 {
245 /* TODO: This is not MT-safe. */
246 if ((lp->ctl_prefix[0] == '\0' ||
247 strncmp (p, lp->ctl_prefix, (size_t) (q - p)) == 0) &&
248 (size_t) (q - p) >= lp->ctl_len)
249 {
734c8942 250 for (p += lp->ctl_len; isspace ((int) *p); p++)
b437bfe0
NA
251 continue; /* Skip prefix and next whitespace. */
252
253 if ((q = strchr (p, '*')) == NULL)
254 q = end; /* Compare until end. */
255
734c8942 256 while (isspace ((int) q[-1]))
b437bfe0
NA
257 q--; /* Exclude trailing whitespace. */
258
259 /* Expand and/or allocate storage for a slice of the name, then
260 copy it in. */
261
262 if (fp->ctf_tmp_typeslicelen >= (size_t) (q - p) + 1)
263 {
264 memcpy (fp->ctf_tmp_typeslice, p, (size_t) (q - p));
265 fp->ctf_tmp_typeslice[(size_t) (q - p)] = '\0';
266 }
267 else
268 {
269 free (fp->ctf_tmp_typeslice);
942d35f7 270 fp->ctf_tmp_typeslice = xstrndup (p, (size_t) (q - p));
b437bfe0
NA
271 if (fp->ctf_tmp_typeslice == NULL)
272 {
abe4ca69 273 ctf_set_errno (fp, ENOMEM);
b437bfe0
NA
274 return CTF_ERR;
275 }
276 }
277
676c3ecb
NA
278 if ((type = ctf_lookup_by_rawhash (fp, lp->ctl_hash,
279 fp->ctf_tmp_typeslice)) == 0)
abe4ca69 280 goto notype;
b437bfe0
NA
281
282 break;
283 }
284 }
285
286 if (lp->ctl_prefix == NULL)
abe4ca69 287 goto notype;
b437bfe0
NA
288 }
289
290 if (*p != '\0' || type == 0)
291 return (ctf_set_errno (fp, ECTF_SYNTAX));
292
293 return type;
294
abe4ca69
NA
295 notype:
296 ctf_set_errno (fp, ECTF_NOTYPE);
297 if (fp->ctf_parent != NULL)
298 {
299 /* Need to look up in the parent, from the child's perspective.
300 Make sure the pptrtab is up to date. */
301
302 if (fp->ctf_pptrtab_typemax < fp->ctf_typemax)
303 {
304 if (refresh_pptrtab (fp, fp->ctf_parent) < 0)
305 return -1; /* errno is set for us. */
306 }
307
308 if ((ptype = ctf_lookup_by_name_internal (fp->ctf_parent, fp,
309 name)) != CTF_ERR)
310 return ptype;
311 return (ctf_set_errno (fp, ctf_errno (fp->ctf_parent)));
312 }
b437bfe0
NA
313
314 return CTF_ERR;
315}
316
abe4ca69
NA
317ctf_id_t
318ctf_lookup_by_name (ctf_dict_t *fp, const char *name)
319{
320 return ctf_lookup_by_name_internal (fp, NULL, name);
321}
322
1136c379
NA
323/* Return the pointer to the internal CTF type data corresponding to the
324 given type ID. If the ID is invalid, the function returns NULL.
325 This function is not exported outside of the library. */
326
327const ctf_type_t *
328ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type)
b437bfe0 329{
1136c379
NA
330 ctf_dict_t *fp = *fpp; /* Caller passes in starting CTF dict. */
331 ctf_id_t idx;
332
333 if ((fp = ctf_get_dict (fp, type)) == NULL)
334 {
335 (void) ctf_set_errno (*fpp, ECTF_NOPARENT);
336 return NULL;
337 }
338
339 /* If this dict is writable, check for a dynamic type. */
340
341 if (fp->ctf_flags & LCTF_RDWR)
342 {
343 ctf_dtdef_t *dtd;
344
345 if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
346 {
347 *fpp = fp;
348 return &dtd->dtd_data;
349 }
350 (void) ctf_set_errno (*fpp, ECTF_BADID);
351 return NULL;
352 }
353
354 /* Check for a type in the static portion. */
355
356 idx = LCTF_TYPE_TO_INDEX (fp, type);
357 if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax)
358 {
359 *fpp = fp; /* Function returns ending CTF dict. */
360 return (LCTF_INDEX_TO_TYPEPTR (fp, idx));
361 }
362
363 (void) ctf_set_errno (*fpp, ECTF_BADID);
364 return NULL;
365}
366
367typedef struct ctf_lookup_idx_key
368{
369 ctf_dict_t *clik_fp;
370 const char *clik_name;
371 uint32_t *clik_names;
372} ctf_lookup_idx_key_t;
b437bfe0
NA
373
374/* A bsearch function for variable names. */
375
376static int
1136c379 377ctf_lookup_var (const void *key_, const void *lookup_)
b437bfe0 378{
1136c379
NA
379 const ctf_lookup_idx_key_t *key = key_;
380 const ctf_varent_t *lookup = lookup_;
b437bfe0 381
1136c379 382 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name)));
b437bfe0
NA
383}
384
385/* Given a variable name, return the type of the variable with that name. */
386
387ctf_id_t
139633c3 388ctf_lookup_variable (ctf_dict_t *fp, const char *name)
b437bfe0
NA
389{
390 ctf_varent_t *ent;
1136c379 391 ctf_lookup_idx_key_t key = { fp, name, NULL };
b437bfe0
NA
392
393 /* This array is sorted, so we can bsearch for it. */
394
395 ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t),
396 ctf_lookup_var);
397
398 if (ent == NULL)
399 {
400 if (fp->ctf_parent != NULL)
401 return ctf_lookup_variable (fp->ctf_parent, name);
402
403 return (ctf_set_errno (fp, ECTF_NOTYPEDAT));
404 }
405
406 return ent->ctv_type;
407}
408
1136c379
NA
409typedef struct ctf_symidx_sort_arg_cb
410{
411 ctf_dict_t *fp;
412 uint32_t *names;
413} ctf_symidx_sort_arg_cb_t;
414
415static int
416sort_symidx_by_name (const void *one_, const void *two_, void *arg_)
417{
418 const uint32_t *one = one_;
419 const uint32_t *two = two_;
420 ctf_symidx_sort_arg_cb_t *arg = arg_;
421
422 return (strcmp (ctf_strptr (arg->fp, arg->names[*one]),
423 ctf_strptr (arg->fp, arg->names[*two])));
424}
425
426/* Sort a symbol index section by name. Takes a 1:1 mapping of names to the
427 corresponding symbol table. Returns a lexicographically sorted array of idx
428 indexes (and thus, of indexes into the corresponding func info / data object
429 section). */
430
431static uint32_t *
432ctf_symidx_sort (ctf_dict_t *fp, uint32_t *idx, size_t *nidx,
433 size_t len)
434{
435 uint32_t *sorted;
436 size_t i;
437
438 if ((sorted = malloc (len)) == NULL)
439 {
440 ctf_set_errno (fp, ENOMEM);
441 return NULL;
442 }
443
444 *nidx = len / sizeof (uint32_t);
445 for (i = 0; i < *nidx; i++)
446 sorted[i] = i;
447
448 if (!(fp->ctf_header->cth_flags & CTF_F_IDXSORTED))
449 {
450 ctf_symidx_sort_arg_cb_t arg = { fp, idx };
451 ctf_dprintf ("Index section unsorted: sorting.");
452 ctf_qsort_r (sorted, *nidx, sizeof (uint32_t), sort_symidx_by_name, &arg);
453 fp->ctf_header->cth_flags |= CTF_F_IDXSORTED;
454 }
455
456 return sorted;
457}
458
459/* Given a symbol index, return the name of that symbol from the table provided
460 by ctf_link_shuffle_syms, or failing that from the secondary string table, or
461 the null string. */
b437bfe0 462const char *
139633c3 463ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx)
b437bfe0
NA
464{
465 const ctf_sect_t *sp = &fp->ctf_symtab;
1136c379
NA
466 ctf_link_sym_t sym;
467 int err;
b437bfe0 468
1136c379 469 if (fp->ctf_dynsymidx)
b437bfe0 470 {
1136c379
NA
471 err = EINVAL;
472 if (symidx > fp->ctf_dynsymmax)
473 goto try_parent;
474
475 ctf_link_sym_t *symp = fp->ctf_dynsymidx[symidx];
476
477 if (!symp)
478 goto try_parent;
479
480 return symp->st_name;
b437bfe0
NA
481 }
482
1136c379
NA
483 err = ECTF_NOSYMTAB;
484 if (sp->cts_data == NULL)
485 goto try_parent;
486
b437bfe0 487 if (symidx >= fp->ctf_nsyms)
1136c379
NA
488 goto try_parent;
489
490 switch (sp->cts_entsize)
b437bfe0 491 {
1136c379
NA
492 case sizeof (Elf64_Sym):
493 {
494 const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx;
495 ctf_elf64_to_link_sym (fp, &sym, symp, symidx);
496 }
497 break;
498 case sizeof (Elf32_Sym):
499 {
500 const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx;
501 ctf_elf32_to_link_sym (fp, &sym, symp, symidx);
502 }
503 break;
504 default:
505 ctf_set_errno (fp, ECTF_SYMTAB);
b437bfe0
NA
506 return _CTF_NULLSTR;
507 }
508
1136c379 509 assert (!sym.st_nameidx_set);
b437bfe0 510
1136c379 511 return sym.st_name;
b437bfe0 512
1136c379
NA
513 try_parent:
514 if (fp->ctf_parent)
515 return ctf_lookup_symbol_name (fp->ctf_parent, symidx);
516 else
517 {
518 ctf_set_errno (fp, err);
519 return _CTF_NULLSTR;
520 }
b437bfe0
NA
521}
522
1136c379
NA
523/* Iterate over all symbols with types: if FUNC, function symbols, otherwise,
524 data symbols. The name argument is not optional. The return order is
525 arbitrary, though is likely to be in symbol index or name order. You can
526 change the value of 'functions' in the middle of iteration over non-dynamic
527 dicts, but doing so on dynamic dicts will fail. (This is probably not very
528 useful, but there is no reason to prohibit it.) */
b437bfe0
NA
529
530ctf_id_t
1136c379
NA
531ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name,
532 int functions)
b437bfe0 533{
1136c379
NA
534 ctf_id_t sym;
535 ctf_next_t *i = *it;
536 int err;
b437bfe0 537
1136c379
NA
538 if (!i)
539 {
540 if ((i = ctf_next_create ()) == NULL)
541 return ctf_set_errno (fp, ENOMEM);
b437bfe0 542
1136c379
NA
543 i->cu.ctn_fp = fp;
544 i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next;
545 i->ctn_n = 0;
546 *it = i;
547 }
548
549 if ((void (*) (void)) ctf_symbol_next != i->ctn_iter_fun)
550 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
b437bfe0 551
1136c379
NA
552 if (fp != i->cu.ctn_fp)
553 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
554
555 /* We intentionally use raw access, not ctf_lookup_by_symbol, to avoid
556 incurring additional sorting cost for unsorted symtypetabs coming from the
557 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and
558 finally because it's easier to work out what the name of each symbol is if
559 we do that. */
560
561 if (fp->ctf_flags & LCTF_RDWR)
b437bfe0 562 {
1136c379
NA
563 ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash;
564 void *dyn_name = NULL, *dyn_value = NULL;
565
566 if (!dynh)
567 {
568 ctf_next_destroy (i);
569 return (ctf_set_errno (fp, ECTF_NEXT_END));
570 }
571
6c3a3877 572 err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value);
1136c379
NA
573 /* This covers errors and also end-of-iteration. */
574 if (err != 0)
575 {
576 ctf_next_destroy (i);
577 *it = NULL;
578 return ctf_set_errno (fp, err);
579 }
580
581 *name = dyn_name;
582 sym = (ctf_id_t) (uintptr_t) dyn_value;
b437bfe0 583 }
1136c379
NA
584 else if ((!functions && fp->ctf_objtidx_names) ||
585 (functions && fp->ctf_funcidx_names))
b437bfe0 586 {
1136c379
NA
587 ctf_header_t *hp = fp->ctf_header;
588 uint32_t *idx = functions ? fp->ctf_funcidx_names : fp->ctf_objtidx_names;
589 uint32_t *tab;
590 size_t len;
591
592 if (functions)
593 {
594 len = (hp->cth_varoff - hp->cth_funcidxoff) / sizeof (uint32_t);
595 tab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
596 }
597 else
598 {
599 len = (hp->cth_funcidxoff - hp->cth_objtidxoff) / sizeof (uint32_t);
600 tab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
601 }
602
603 do
604 {
605 if (i->ctn_n >= len)
606 goto end;
607
608 *name = ctf_strptr (fp, idx[i->ctn_n]);
609 sym = tab[i->ctn_n++];
610 } while (sym == -1u || sym == 0);
b437bfe0 611 }
1136c379
NA
612 else
613 {
614 /* Skip over pads in ctf_xslate, padding for typeless symbols in the
615 symtypetab itself, and symbols in the wrong table. */
616 for (; i->ctn_n < fp->ctf_nsyms; i->ctn_n++)
617 {
618 ctf_header_t *hp = fp->ctf_header;
b437bfe0 619
1136c379
NA
620 if (fp->ctf_sxlate[i->ctn_n] == -1u)
621 continue;
b437bfe0 622
1136c379 623 sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[i->ctn_n]);
b437bfe0 624
1136c379
NA
625 if (sym == 0)
626 continue;
627
628 if (functions)
629 {
630 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_funcoff
631 && fp->ctf_sxlate[i->ctn_n] < hp->cth_objtidxoff)
632 break;
633 }
634 else
635 {
636 if (fp->ctf_sxlate[i->ctn_n] >= hp->cth_objtoff
637 && fp->ctf_sxlate[i->ctn_n] < hp->cth_funcoff)
638 break;
639 }
640 }
641
642 if (i->ctn_n >= fp->ctf_nsyms)
643 goto end;
644
645 *name = ctf_lookup_symbol_name (fp, i->ctn_n++);
646 }
647
648 return sym;
649
650 end:
651 ctf_next_destroy (i);
652 *it = NULL;
653 return (ctf_set_errno (fp, ECTF_NEXT_END));
b437bfe0
NA
654}
655
1136c379
NA
656/* A bsearch function for function and object index names. */
657
658static int
659ctf_lookup_idx_name (const void *key_, const void *idx_)
688d28f6 660{
1136c379
NA
661 const ctf_lookup_idx_key_t *key = key_;
662 const uint32_t *idx = idx_;
688d28f6 663
1136c379 664 return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx])));
688d28f6
NA
665}
666
1136c379
NA
667/* Given a symbol number, look up that symbol in the function or object
668 index table (which must exist). Return 0 if not found there (or pad). */
47d546f4 669
1136c379
NA
670static ctf_id_t
671ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx, int is_function)
47d546f4 672{
1136c379
NA
673 const char *symname = ctf_lookup_symbol_name (fp, symidx);
674 struct ctf_header *hp = fp->ctf_header;
675 uint32_t *symtypetab;
676 uint32_t *names;
677 uint32_t *sxlate;
678 size_t nidx;
47d546f4 679
1136c379
NA
680 ctf_dprintf ("Looking up type of object with symtab idx %lx (%s) in "
681 "indexed symtypetab\n", symidx, symname);
47d546f4 682
1136c379
NA
683 if (symname[0] == '\0')
684 return -1; /* errno is set for us. */
47d546f4 685
1136c379 686 if (is_function)
47d546f4 687 {
1136c379 688 if (!fp->ctf_funcidx_sxlate)
47d546f4 689 {
1136c379
NA
690 if ((fp->ctf_funcidx_sxlate
691 = ctf_symidx_sort (fp, (uint32_t *)
692 (fp->ctf_buf + hp->cth_funcidxoff),
693 &fp->ctf_nfuncidx,
694 hp->cth_varoff - hp->cth_funcidxoff))
695 == NULL)
696 {
697 ctf_err_warn (fp, 0, 0, _("cannot sort function symidx"));
698 return -1; /* errno is set for us. */
699 }
47d546f4 700 }
1136c379
NA
701 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
702 sxlate = fp->ctf_funcidx_sxlate;
703 names = fp->ctf_funcidx_names;
704 nidx = fp->ctf_nfuncidx;
47d546f4 705 }
1136c379
NA
706 else
707 {
708 if (!fp->ctf_objtidx_sxlate)
709 {
710 if ((fp->ctf_objtidx_sxlate
711 = ctf_symidx_sort (fp, (uint32_t *)
712 (fp->ctf_buf + hp->cth_objtidxoff),
713 &fp->ctf_nobjtidx,
714 hp->cth_funcidxoff - hp->cth_objtidxoff))
715 == NULL)
716 {
717 ctf_err_warn (fp, 0, 0, _("cannot sort object symidx"));
718 return -1; /* errno is set for us. */
719 }
720 }
676c3ecb 721
1136c379
NA
722 symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
723 sxlate = fp->ctf_objtidx_sxlate;
724 names = fp->ctf_objtidx_names;
725 nidx = fp->ctf_nobjtidx;
726 }
676c3ecb 727
1136c379
NA
728 ctf_lookup_idx_key_t key = { fp, symname, names };
729 uint32_t *idx;
730
731 idx = bsearch (&key, sxlate, nidx, sizeof (uint32_t), ctf_lookup_idx_name);
732
733 if (!idx)
676c3ecb 734 {
1136c379
NA
735 ctf_dprintf ("%s not found in idx\n", symname);
736 return 0;
676c3ecb
NA
737 }
738
1136c379
NA
739 /* Should be impossible, but be paranoid. */
740 if ((idx - sxlate) > (ptrdiff_t) nidx)
741 return (ctf_set_errno (fp, ECTF_CORRUPT));
742
743 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname,
744 symtypetab[*idx]);
745 return symtypetab[*idx];
47d546f4
NA
746}
747
1136c379
NA
748/* Given a symbol table index, return the type of the function or data object
749 described by the corresponding entry in the symbol table. We can only return
750 symbols in read-only dicts and in dicts for which ctf_link_shuffle_syms has
751 been called to assign symbol indexes to symbol names. */
b437bfe0 752
1136c379
NA
753ctf_id_t
754ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx)
b437bfe0
NA
755{
756 const ctf_sect_t *sp = &fp->ctf_symtab;
1136c379
NA
757 ctf_id_t type = 0;
758 int err = 0;
759
760 /* Shuffled dynsymidx present? Use that. */
761 if (fp->ctf_dynsymidx)
762 {
763 const ctf_link_sym_t *sym;
764
765 ctf_dprintf ("Looking up type of object with symtab idx %lx in "
766 "writable dict symtypetab\n", symidx);
767
768 /* The dict must be dynamic. */
769 if (!ctf_assert (fp, fp->ctf_flags & LCTF_RDWR))
770 return CTF_ERR;
771
772 err = EINVAL;
773 if (symidx > fp->ctf_dynsymmax)
774 goto try_parent;
775
776 sym = fp->ctf_dynsymidx[symidx];
777 err = ECTF_NOTYPEDAT;
778 if (!sym || (sym->st_shndx != STT_OBJECT && sym->st_shndx != STT_FUNC))
779 goto try_parent;
780
781 if (!ctf_assert (fp, !sym->st_nameidx_set))
782 return CTF_ERR;
783
784 if (fp->ctf_objthash == NULL
785 || ((type = (ctf_id_t) (uintptr_t)
786 ctf_dynhash_lookup (fp->ctf_objthash, sym->st_name)) == 0))
787 {
788 if (fp->ctf_funchash == NULL
789 || ((type = (ctf_id_t) (uintptr_t)
790 ctf_dynhash_lookup (fp->ctf_funchash, sym->st_name)) == 0))
791 goto try_parent;
792 }
793
794 return type;
795 }
b437bfe0 796
1136c379 797 err = ECTF_NOSYMTAB;
b437bfe0 798 if (sp->cts_data == NULL)
1136c379 799 goto try_parent;
b437bfe0 800
1136c379
NA
801 /* This covers both out-of-range lookups and a dynamic dict which hasn't been
802 shuffled yet. */
803 err = EINVAL;
b437bfe0 804 if (symidx >= fp->ctf_nsyms)
1136c379 805 goto try_parent;
b437bfe0 806
1136c379 807 if (fp->ctf_objtidx_names)
b437bfe0 808 {
1136c379
NA
809 if ((type = ctf_try_lookup_indexed (fp, symidx, 0)) == CTF_ERR)
810 return CTF_ERR; /* errno is set for us. */
b437bfe0 811 }
1136c379 812 if (type == 0 && fp->ctf_funcidx_names)
b437bfe0 813 {
1136c379
NA
814 if ((type = ctf_try_lookup_indexed (fp, symidx, 1)) == CTF_ERR)
815 return CTF_ERR; /* errno is set for us. */
b437bfe0 816 }
1136c379
NA
817 if (type != 0)
818 return type;
819
820 err = ECTF_NOTYPEDAT;
821 if (fp->ctf_objtidx_names && fp->ctf_funcidx_names)
822 goto try_parent;
823
824 /* Table must be nonindexed. */
825
826 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx);
b437bfe0
NA
827
828 if (fp->ctf_sxlate[symidx] == -1u)
1136c379
NA
829 goto try_parent;
830
831 type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]);
b437bfe0 832
1136c379
NA
833 if (type == 0)
834 goto try_parent;
b437bfe0 835
1136c379
NA
836 return type;
837 try_parent:
838 if (fp->ctf_parent)
839 return ctf_lookup_by_symbol (fp->ctf_parent, symidx);
840 else
841 return (ctf_set_errno (fp, err));
842}
b437bfe0 843
1136c379
NA
844/* Given a symbol table index, return the info for the function described
845 by the corresponding entry in the symbol table, which may be a function
846 symbol or may be a data symbol that happens to be a function pointer. */
b437bfe0 847
1136c379
NA
848int
849ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip)
850{
851 ctf_id_t type;
b437bfe0 852
1136c379
NA
853 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
854 return -1; /* errno is set for us. */
b437bfe0 855
1136c379
NA
856 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
857 return (ctf_set_errno (fp, ECTF_NOTFUNC));
b437bfe0 858
1136c379 859 return ctf_func_type_info (fp, type, fip);
b437bfe0
NA
860}
861
862/* Given a symbol table index, return the arguments for the function described
863 by the corresponding entry in the symbol table. */
864
865int
139633c3 866ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc,
1136c379 867 ctf_id_t *argv)
b437bfe0 868{
1136c379 869 ctf_id_t type;
b437bfe0 870
1136c379
NA
871 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
872 return -1; /* errno is set for us. */
b437bfe0 873
1136c379
NA
874 if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
875 return (ctf_set_errno (fp, ECTF_NOTFUNC));
b437bfe0 876
1136c379 877 return ctf_func_type_args (fp, type, argc, argv);
b437bfe0 878}
This page took 0.151837 seconds and 4 git commands to generate.