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