1/* Symbol, variable and name lookup.
2   Copyright (C) 2019-2022 Free Software Foundation, Inc.
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>
23#include <assert.h>
24
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
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.  */
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
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;
115
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 &&
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
134static ctf_id_t
135ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
136			     const char *name)
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    {
150      while (isspace ((int) *p))
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	{
161	  /* Find a pointer to type by looking in child->ctf_pptrtab (if child
162	     is set) and fp->ctf_ptrtab.  If we can't find a pointer to the
163	     given type, see if we can compute a pointer to the type resulting
164	     from resolving the type down to its base type and use that instead.
165	     This helps with cases where the CTF data includes "struct foo *"
166	     but not "foo_t *" and the user tries to access "foo_t *" in the
167	     debugger.
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.)  */
174
175	  uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type);
176	  int in_child = 0;
177
178	  ntype = CTF_ERR;
179	  if (child && idx < child->ctf_pptrtab_len)
180	    {
181	      ntype = child->ctf_pptrtab[idx];
182	      if (ntype)
183		in_child = 1;
184	      else
185		ntype = CTF_ERR;
186	    }
187
188	  if (ntype == CTF_ERR)
189	    {
190	      ntype = fp->ctf_ptrtab[idx];
191	      if (ntype == 0)
192		ntype = CTF_ERR;
193	    }
194
195	  /* Try resolving to its base type and check again.  */
196	  if (ntype == CTF_ERR)
197	    {
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
208	      ntype = CTF_ERR;
209	      if (child && idx < child->ctf_pptrtab_len)
210		{
211		  ntype = child->ctf_pptrtab[idx];
212		  if (ntype)
213		    in_child = 1;
214		  else
215		    ntype = CTF_ERR;
216		}
217
218	      if (ntype == CTF_ERR)
219		{
220		  ntype = fp->ctf_ptrtab[idx];
221		  if (ntype == 0)
222		    ntype = CTF_ERR;
223		}
224	      if (ntype == CTF_ERR)
225		goto notype;
226	    }
227
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	    }
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	    {
254	      for (p += lp->ctl_len; isspace ((int) *p); p++)
255		continue;	/* Skip prefix and next whitespace.  */
256
257	      if ((q = strchr (p, '*')) == NULL)
258		q = end;	/* Compare until end.  */
259
260	      while (isspace ((int) q[-1]))
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);
274		  fp->ctf_tmp_typeslice = xstrndup (p, (size_t) (q - p));
275		  if (fp->ctf_tmp_typeslice == NULL)
276		    {
277		      ctf_set_errno (fp, ENOMEM);
278		      return CTF_ERR;
279		    }
280		}
281
282	      if ((type = ctf_lookup_by_rawhash (fp, lp->ctl_hash,
283						 fp->ctf_tmp_typeslice)) == 0)
284		goto notype;
285
286	      break;
287	    }
288	}
289
290      if (lp->ctl_prefix == NULL)
291	goto notype;
292    }
293
294  if (*p != '\0' || type == 0)
295    return (ctf_set_errno (fp, ECTF_SYNTAX));
296
297  return type;
298
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    }
317
318  return CTF_ERR;
319}
320
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
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)
333{
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;
377
378/* A bsearch function for variable names.  */
379
380static int
381ctf_lookup_var (const void *key_, const void *lookup_)
382{
383  const ctf_lookup_idx_key_t *key = key_;
384  const ctf_varent_t *lookup = lookup_;
385
386  return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name)));
387}
388
389/* Given a variable name, return the type of the variable with that name.  */
390
391ctf_id_t
392ctf_lookup_variable (ctf_dict_t *fp, const char *name)
393{
394  ctf_varent_t *ent;
395  ctf_lookup_idx_key_t key = { fp, name, NULL };
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
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.  */
466static const char *
467ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx)
468{
469  const ctf_sect_t *sp = &fp->ctf_symtab;
470  ctf_link_sym_t sym;
471  int err;
472
473  if (fp->ctf_dynsymidx)
474    {
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;
485    }
486
487  err = ECTF_NOSYMTAB;
488  if (sp->cts_data == NULL)
489    goto try_parent;
490
491  if (symidx >= fp->ctf_nsyms)
492    goto try_parent;
493
494  switch (sp->cts_entsize)
495    {
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);
510      return _CTF_NULLSTR;
511    }
512
513  assert (!sym.st_nameidx_set);
514
515  return sym.st_name;
516
517 try_parent:
518  if (fp->ctf_parent)
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    }
526  else
527    {
528      ctf_set_errno (fp, err);
529      return _CTF_NULLSTR;
530    }
531}
532
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)
599	      return cache->ctf_symhash_latest++;
600	  }
601	  break;
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)
614	      return cache->ctf_symhash_latest++;
615	  }
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
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.)  */
649
650ctf_id_t
651ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name,
652		 int functions)
653{
654  ctf_id_t sym;
655  ctf_next_t *i = *it;
656  int err;
657
658  if (!i)
659    {
660      if ((i = ctf_next_create ()) == NULL)
661	return ctf_set_errno (fp, ENOMEM);
662
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));
671
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)
682    {
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
692      err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value);
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;
703    }
704  else if ((!functions && fp->ctf_objtidx_names) ||
705	   (functions && fp->ctf_funcidx_names))
706    {
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++];
730	}
731      while (sym == -1u || sym == 0);
732    }
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;
740
741	  if (fp->ctf_sxlate[i->ctn_n] == -1u)
742	    continue;
743
744	  sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[i->ctn_n]);
745
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));
775}
776
777/* A bsearch function for function and object index names.  */
778
779static int
780ctf_lookup_idx_name (const void *key_, const void *idx_)
781{
782  const ctf_lookup_idx_key_t *key = key_;
783  const uint32_t *idx = idx_;
784
785  return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx])));
786}
787
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).  */
791
792static ctf_id_t
793ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx,
794			const char *symname, int is_function)
795{
796  struct ctf_header *hp = fp->ctf_header;
797  uint32_t *symtypetab;
798  uint32_t *names;
799  uint32_t *sxlate;
800  size_t nidx;
801
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 "
806	       "indexed symtypetab\n", symidx, symname);
807
808  if (symname[0] == '\0')
809    return -1;					/* errno is set for us.  */
810
811  if (is_function)
812    {
813      if (!fp->ctf_funcidx_sxlate)
814	{
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	    }
825	}
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;
830    }
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	}
846
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    }
852
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)
859    {
860      ctf_dprintf ("%s not found in idx\n", symname);
861      return 0;
862    }
863
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];
871}
872
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.  */
878
879static ctf_id_t
880ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx,
881			   const char *symname)
882{
883  const ctf_sect_t *sp = &fp->ctf_symtab;
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
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);
898
899      /* The dict must be dynamic.  */
900      if (!ctf_assert (fp, fp->ctf_flags & LCTF_RDWR))
901	return CTF_ERR;
902
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;
909
910	  sym = fp->ctf_dynsymidx[symidx];
911	  err = ECTF_NOTYPEDAT;
912	  if (!sym || (sym->st_shndx != STT_OBJECT && sym->st_shndx != STT_FUNC))
913	    goto try_parent;
914
915	  if (!ctf_assert (fp, !sym->st_nameidx_set))
916	    return CTF_ERR;
917	  symname = sym->st_name;
918     }
919
920      if (fp->ctf_objthash == NULL
921	  || ((type = (ctf_id_t) (uintptr_t)
922	       ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0))
923	{
924	  if (fp->ctf_funchash == NULL
925	      || ((type = (ctf_id_t) (uintptr_t)
926		   ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0))
927	    goto try_parent;
928	}
929
930      return type;
931    }
932
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
948  err = ECTF_NOSYMTAB;
949  if (sp->cts_data == NULL)
950    goto try_parent;
951
952  /* This covers both out-of-range lookups and a dynamic dict which hasn't been
953     shuffled yet.  */
954  err = EINVAL;
955  if (symname == NULL && symidx >= fp->ctf_nsyms)
956    goto try_parent;
957
958  if (fp->ctf_objtidx_names)
959    {
960      if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR)
961	return CTF_ERR;				/* errno is set for us.  */
962    }
963  if (type == 0 && fp->ctf_funcidx_names)
964    {
965      if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR)
966	return CTF_ERR;				/* errno is set for us.  */
967    }
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);
978
979  if (symname != NULL)
980    if ((symidx = ctf_lookup_symbol_idx (fp, symname)) == (unsigned long) -1)
981      goto try_parent;
982
983  if (fp->ctf_sxlate[symidx] == -1u)
984    goto try_parent;
985
986  type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]);
987
988  if (type == 0)
989    goto try_parent;
990
991  return type;
992 try_parent:
993  if (fp->ctf_parent)
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    }
1001  else
1002    return (ctf_set_errno (fp, err));
1003}
1004
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
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.  */
1024
1025int
1026ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip)
1027{
1028  ctf_id_t type;
1029
1030  if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1031    return -1;					/* errno is set for us.  */
1032
1033  if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1034    return (ctf_set_errno (fp, ECTF_NOTFUNC));
1035
1036  return ctf_func_type_info (fp, type, fip);
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
1043ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc,
1044	       ctf_id_t *argv)
1045{
1046  ctf_id_t type;
1047
1048  if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
1049    return -1;					/* errno is set for us.  */
1050
1051  if (ctf_type_kind (fp, type) != CTF_K_FUNCTION)
1052    return (ctf_set_errno (fp, ECTF_NOTFUNC));
1053
1054  return ctf_func_type_args (fp, type, argc, argv);
1055}
1056