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