xref: /netbsd-src/external/gpl3/binutils/dist/libctf/ctf-types.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* Type handling functions.
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 <assert.h>
22 #include <string.h>
23 
24 /* Determine whether a type is a parent or a child.  */
25 
26 int
ctf_type_isparent(ctf_dict_t * fp,ctf_id_t id)27 ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id)
28 {
29   return (LCTF_TYPE_ISPARENT (fp, id));
30 }
31 
32 int
ctf_type_ischild(ctf_dict_t * fp,ctf_id_t id)33 ctf_type_ischild (ctf_dict_t * fp, ctf_id_t id)
34 {
35   return (LCTF_TYPE_ISCHILD (fp, id));
36 }
37 
38 /* Expand a structure element into the passed-in ctf_lmember_t.  */
39 
40 static int
ctf_struct_member(ctf_dict_t * fp,ctf_lmember_t * dst,const ctf_type_t * tp,unsigned char * vlen,size_t vbytes,size_t n)41 ctf_struct_member (ctf_dict_t *fp, ctf_lmember_t *dst, const ctf_type_t *tp,
42 		   unsigned char *vlen, size_t vbytes, size_t n)
43 {
44   if (!ctf_assert (fp, n < LCTF_INFO_VLEN (fp, tp->ctt_info)))
45     return -1;					/* errno is set for us.  */
46 
47   /* Already large.  */
48   if (tp->ctt_size == CTF_LSIZE_SENT)
49     {
50       ctf_lmember_t *lmp = (ctf_lmember_t *) vlen;
51 
52       if (!ctf_assert (fp, (n + 1) * sizeof (ctf_lmember_t) <= vbytes))
53 	return -1;				/* errno is set for us.  */
54 
55       memcpy (dst, &lmp[n], sizeof (ctf_lmember_t));
56     }
57   else
58     {
59       ctf_member_t *mp = (ctf_member_t *) vlen;
60       dst->ctlm_name = mp[n].ctm_name;
61       dst->ctlm_type = mp[n].ctm_type;
62       dst->ctlm_offsetlo = mp[n].ctm_offset;
63       dst->ctlm_offsethi = 0;
64     }
65   return 0;
66 }
67 
68 /* Iterate over the members of a STRUCT or UNION.  We pass the name, member
69    type, and offset of each member to the specified callback function.  */
70 
71 int
ctf_member_iter(ctf_dict_t * fp,ctf_id_t type,ctf_member_f * func,void * arg)72 ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
73 {
74   ctf_next_t *i = NULL;
75   ssize_t offset;
76   const char *name;
77   ctf_id_t membtype;
78 
79   while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0)
80     {
81       int rc;
82       if ((rc = func (name, membtype, offset, arg)) != 0)
83 	{
84 	  ctf_next_destroy (i);
85 	  return rc;
86 	}
87     }
88   if (ctf_errno (fp) != ECTF_NEXT_END)
89     return -1;					/* errno is set for us.  */
90 
91   return 0;
92 }
93 
94 /* Iterate over the members of a STRUCT or UNION, returning each member's
95    offset and optionally name and member type in turn.  On end-of-iteration,
96    returns -1.  If FLAGS is CTF_MN_RECURSE, recurse into unnamed members.  */
97 
98 ssize_t
ctf_member_next(ctf_dict_t * fp,ctf_id_t type,ctf_next_t ** it,const char ** name,ctf_id_t * membtype,int flags)99 ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
100 		 const char **name, ctf_id_t *membtype, int flags)
101 {
102   ctf_dict_t *ofp = fp;
103   uint32_t kind;
104   ssize_t offset;
105   uint32_t max_vlen;
106   ctf_next_t *i = *it;
107 
108   if (!i)
109     {
110       const ctf_type_t *tp;
111       ctf_dtdef_t *dtd;
112       ssize_t size;
113       ssize_t increment;
114 
115       if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
116 	return -1;			/* errno is set for us.  */
117 
118       if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
119 	return -1;			/* errno is set for us.  */
120 
121       if ((i = ctf_next_create ()) == NULL)
122 	return ctf_set_errno (ofp, ENOMEM);
123       i->cu.ctn_fp = ofp;
124       i->ctn_tp = tp;
125 
126       ctf_get_ctt_size (fp, tp, &size, &increment);
127       kind = LCTF_INFO_KIND (fp, tp->ctt_info);
128 
129       if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
130 	{
131 	  ctf_next_destroy (i);
132 	  return (ctf_set_errno (ofp, ECTF_NOTSOU));
133 	}
134 
135       if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
136 	{
137 	  i->u.ctn_vlen = dtd->dtd_vlen;
138 	  i->ctn_size = dtd->dtd_vlen_alloc;
139 	}
140       else
141 	{
142 	  unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
143 
144 	  i->u.ctn_vlen = (unsigned char *) tp + increment;
145 	  i->ctn_size = LCTF_VBYTES (fp, kind, size, vlen);;
146 	}
147       i->ctn_iter_fun = (void (*) (void)) ctf_member_next;
148       i->ctn_n = 0;
149       *it = i;
150     }
151 
152   if ((void (*) (void)) ctf_member_next != i->ctn_iter_fun)
153     return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN));
154 
155   if (ofp != i->cu.ctn_fp)
156     return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFP));
157 
158   /* Resolve to the native dict of this type.  */
159   if ((fp = ctf_get_dict (ofp, type)) == NULL)
160     return (ctf_set_errno (ofp, ECTF_NOPARENT));
161 
162   max_vlen = LCTF_INFO_VLEN (fp, i->ctn_tp->ctt_info);
163 
164   /* When we hit an unnamed struct/union member, we set ctn_type to indicate
165      that we are inside one, then return the unnamed member: on the next call,
166      we must skip over top-level member iteration in favour of iteration within
167      the sub-struct until it later turns out that that iteration has ended.  */
168 
169  retry:
170   if (!i->ctn_type)
171     {
172       ctf_lmember_t memb;
173       const char *membname;
174 
175       if (i->ctn_n == max_vlen)
176 	goto end_iter;
177 
178       if (ctf_struct_member (fp, &memb, i->ctn_tp, i->u.ctn_vlen, i->ctn_size,
179 			     i->ctn_n) < 0)
180         return (ctf_set_errno (ofp, ctf_errno (fp)));
181 
182       membname = ctf_strptr (fp, memb.ctlm_name);
183 
184       if (name)
185 	*name = membname;
186       if (membtype)
187 	*membtype = memb.ctlm_type;
188       offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
189 
190       if (membname[0] == 0
191 	  && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
192 	      || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION))
193 	i->ctn_type = memb.ctlm_type;
194       i->ctn_n++;
195 
196       /* The callers might want automatic recursive sub-struct traversal.  */
197       if (!(flags & CTF_MN_RECURSE))
198 	i->ctn_type = 0;
199 
200       /* Sub-struct traversal starting?  Take note of the offset of this member,
201 	 for later boosting of sub-struct members' offsets.  */
202       if (i->ctn_type)
203 	i->ctn_increment = offset;
204     }
205   /* Traversing a sub-struct?  Just return it, with the offset adjusted.  */
206   else
207     {
208       ssize_t ret = ctf_member_next (fp, i->ctn_type, &i->ctn_next, name,
209 				     membtype, flags);
210 
211       if (ret >= 0)
212 	return ret + i->ctn_increment;
213 
214       if (ctf_errno (fp) != ECTF_NEXT_END)
215 	{
216 	  ctf_next_destroy (i);
217 	  *it = NULL;
218 	  i->ctn_type = 0;
219 	  ctf_set_errno (ofp, ctf_errno (fp));
220 	  return ret;
221 	}
222 
223       if (!ctf_assert (fp, (i->ctn_next == NULL)))
224         return (ctf_set_errno (ofp, ctf_errno (fp)));
225 
226       i->ctn_type = 0;
227       /* This sub-struct has ended: on to the next real member.  */
228       goto retry;
229     }
230 
231   return offset;
232 
233  end_iter:
234   ctf_next_destroy (i);
235   *it = NULL;
236   return ctf_set_errno (ofp, ECTF_NEXT_END);
237 }
238 
239 /* Iterate over the members of an ENUM.  We pass the string name and associated
240    integer value of each enum element to the specified callback function.  */
241 
242 int
ctf_enum_iter(ctf_dict_t * fp,ctf_id_t type,ctf_enum_f * func,void * arg)243 ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
244 {
245   ctf_next_t *i = NULL;
246   const char *name;
247   int val;
248 
249   while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
250     {
251       int rc;
252       if ((rc = func (name, val, arg)) != 0)
253 	{
254 	  ctf_next_destroy (i);
255 	  return rc;
256 	}
257     }
258   if (ctf_errno (fp) != ECTF_NEXT_END)
259     return -1;					/* errno is set for us.  */
260 
261   return 0;
262 }
263 
264 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
265    NULL at end of iteration or error, and optionally passing back the
266    enumerand's integer VALue.  */
267 
268 const char *
ctf_enum_next(ctf_dict_t * fp,ctf_id_t type,ctf_next_t ** it,int * val)269 ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
270 	       int *val)
271 {
272   ctf_dict_t *ofp = fp;
273   uint32_t kind;
274   const char *name;
275   ctf_next_t *i = *it;
276 
277   if (!i)
278     {
279       const ctf_type_t *tp;
280       ctf_dtdef_t *dtd;
281 
282       if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
283 	return NULL;			/* errno is set for us.  */
284 
285       if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
286 	return NULL;			/* errno is set for us.  */
287 
288       if ((i = ctf_next_create ()) == NULL)
289 	{
290 	  ctf_set_errno (ofp, ENOMEM);
291 	  return NULL;
292 	}
293       i->cu.ctn_fp = ofp;
294 
295       (void) ctf_get_ctt_size (fp, tp, NULL,
296 			       &i->ctn_increment);
297       kind = LCTF_INFO_KIND (fp, tp->ctt_info);
298 
299       if (kind != CTF_K_ENUM)
300 	{
301 	  ctf_next_destroy (i);
302 	  ctf_set_errno (ofp, ECTF_NOTENUM);
303 	  return NULL;
304 	}
305 
306       dtd = ctf_dynamic_type (fp, type);
307       i->ctn_iter_fun = (void (*) (void)) ctf_enum_next;
308       i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
309 
310       if (dtd == NULL)
311 	i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp +
312 					    i->ctn_increment);
313       else
314 	i->u.ctn_en = (const ctf_enum_t *) dtd->dtd_vlen;
315 
316       *it = i;
317     }
318 
319   if ((void (*) (void)) ctf_enum_next != i->ctn_iter_fun)
320     {
321       ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN);
322       return NULL;
323     }
324 
325   if (ofp != i->cu.ctn_fp)
326     {
327       ctf_set_errno (ofp, ECTF_NEXT_WRONGFP);
328       return NULL;
329     }
330 
331   /* Resolve to the native dict of this type.  */
332   if ((fp = ctf_get_dict (ofp, type)) == NULL)
333     {
334       ctf_set_errno (ofp, ECTF_NOPARENT);
335       return NULL;
336     }
337 
338   if (i->ctn_n == 0)
339     goto end_iter;
340 
341   name = ctf_strptr (fp, i->u.ctn_en->cte_name);
342   if (val)
343     *val = i->u.ctn_en->cte_value;
344   i->u.ctn_en++;
345   i->ctn_n--;
346 
347   return name;
348 
349  end_iter:
350   ctf_next_destroy (i);
351   *it = NULL;
352   ctf_set_errno (ofp, ECTF_NEXT_END);
353   return NULL;
354 }
355 
356 /* Iterate over every root (user-visible) type in the given CTF dict.
357    We pass the type ID of each type to the specified callback function.
358 
359    Does not traverse parent types: you have to do that explicitly.  This is by
360    design, to avoid traversing them more than once if traversing many children
361    of a single parent.  */
362 
363 int
ctf_type_iter(ctf_dict_t * fp,ctf_type_f * func,void * arg)364 ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
365 {
366   ctf_next_t *i = NULL;
367   ctf_id_t type;
368 
369   while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR)
370     {
371       int rc;
372       if ((rc = func (type, arg)) != 0)
373 	{
374 	  ctf_next_destroy (i);
375 	  return rc;
376 	}
377     }
378   if (ctf_errno (fp) != ECTF_NEXT_END)
379     return -1;					/* errno is set for us.  */
380 
381   return 0;
382 }
383 
384 /* Iterate over every type in the given CTF dict, user-visible or not.
385    We pass the type ID of each type to the specified callback function.
386 
387    Does not traverse parent types: you have to do that explicitly.  This is by
388    design, to avoid traversing them more than once if traversing many children
389    of a single parent.  */
390 
391 int
ctf_type_iter_all(ctf_dict_t * fp,ctf_type_all_f * func,void * arg)392 ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
393 {
394   ctf_next_t *i = NULL;
395   ctf_id_t type;
396   int flag;
397 
398   while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR)
399     {
400       int rc;
401       if ((rc = func (type, flag, arg)) != 0)
402 	{
403 	  ctf_next_destroy (i);
404 	  return rc;
405 	}
406     }
407   if (ctf_errno (fp) != ECTF_NEXT_END)
408     return -1;					/* errno is set for us.  */
409 
410   return 0;
411 }
412 
413 /* Iterate over every type in the given CTF dict, optionally including
414    non-user-visible types, returning each type ID and hidden flag in turn.
415    Returns CTF_ERR on end of iteration or error.
416 
417    Does not traverse parent types: you have to do that explicitly.  This is by
418    design, to avoid traversing them more than once if traversing many children
419    of a single parent.  */
420 
421 ctf_id_t
ctf_type_next(ctf_dict_t * fp,ctf_next_t ** it,int * flag,int want_hidden)422 ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden)
423 {
424   ctf_next_t *i = *it;
425 
426   if (!i)
427     {
428       if ((i = ctf_next_create ()) == NULL)
429 	return ctf_set_typed_errno (fp, ENOMEM);
430 
431       i->cu.ctn_fp = fp;
432       i->ctn_type = 1;
433       i->ctn_iter_fun = (void (*) (void)) ctf_type_next;
434       *it = i;
435     }
436 
437   if ((void (*) (void)) ctf_type_next != i->ctn_iter_fun)
438     return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN));
439 
440   if (fp != i->cu.ctn_fp)
441     return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP));
442 
443   while (i->ctn_type <= fp->ctf_typemax)
444     {
445       const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, i->ctn_type);
446 
447       if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info)))
448 	{
449 	  i->ctn_type++;
450 	  continue;
451 	}
452 
453       if (flag)
454 	*flag = LCTF_INFO_ISROOT (fp, tp->ctt_info);
455       return LCTF_INDEX_TO_TYPE (fp, i->ctn_type++, fp->ctf_flags & LCTF_CHILD);
456     }
457   ctf_next_destroy (i);
458   *it = NULL;
459   return ctf_set_typed_errno (fp, ECTF_NEXT_END);
460 }
461 
462 /* Iterate over every variable in the given CTF dict, in arbitrary order.
463    We pass the name of each variable to the specified callback function.  */
464 
465 int
ctf_variable_iter(ctf_dict_t * fp,ctf_variable_f * func,void * arg)466 ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
467 {
468   ctf_next_t *i = NULL;
469   ctf_id_t type;
470   const char *name;
471 
472   while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR)
473     {
474       int rc;
475       if ((rc = func (name, type, arg)) != 0)
476 	{
477 	  ctf_next_destroy (i);
478 	  return rc;
479 	}
480     }
481   if (ctf_errno (fp) != ECTF_NEXT_END)
482     return -1;					/* errno is set for us.  */
483 
484   return 0;
485 }
486 
487 /* Iterate over every variable in the given CTF dict, in arbitrary order,
488    returning the name and type of each variable in turn.  The name argument is
489    not optional.  Returns CTF_ERR on end of iteration or error.  */
490 
491 ctf_id_t
ctf_variable_next(ctf_dict_t * fp,ctf_next_t ** it,const char ** name)492 ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
493 {
494   ctf_next_t *i = *it;
495 
496   if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
497     return (ctf_set_typed_errno (fp, ECTF_NOPARENT));
498 
499   if (!i)
500     {
501       if ((i = ctf_next_create ()) == NULL)
502 	return ctf_set_typed_errno (fp, ENOMEM);
503 
504       i->cu.ctn_fp = fp;
505       i->ctn_iter_fun = (void (*) (void)) ctf_variable_next;
506       if (fp->ctf_flags & LCTF_RDWR)
507 	i->u.ctn_dvd = ctf_list_next (&fp->ctf_dvdefs);
508       *it = i;
509     }
510 
511   if ((void (*) (void)) ctf_variable_next != i->ctn_iter_fun)
512     return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN));
513 
514   if (fp != i->cu.ctn_fp)
515     return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP));
516 
517   if (!(fp->ctf_flags & LCTF_RDWR))
518     {
519       if (i->ctn_n >= fp->ctf_nvars)
520 	goto end_iter;
521 
522       *name = ctf_strptr (fp, fp->ctf_vars[i->ctn_n].ctv_name);
523       return fp->ctf_vars[i->ctn_n++].ctv_type;
524     }
525   else
526     {
527       ctf_id_t id;
528 
529       if (i->u.ctn_dvd == NULL)
530 	goto end_iter;
531 
532       *name = i->u.ctn_dvd->dvd_name;
533       id = i->u.ctn_dvd->dvd_type;
534       i->u.ctn_dvd = ctf_list_next (i->u.ctn_dvd);
535       return id;
536     }
537 
538  end_iter:
539   ctf_next_destroy (i);
540   *it = NULL;
541   return ctf_set_typed_errno (fp, ECTF_NEXT_END);
542 }
543 
544 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
545    RESTRICT nodes until we reach a "base" type node.  This is useful when
546    we want to follow a type ID to a node that has members or a size.  To guard
547    against infinite loops, we implement simplified cycle detection and check
548    each link against itself, the previous node, and the topmost node.
549 
550    Does not drill down through slices to their contained type.
551 
552    Callers of this function must not presume that a type it returns must have a
553    valid ctt_size: forwards do not, and must be separately handled.  */
554 
555 ctf_id_t
ctf_type_resolve(ctf_dict_t * fp,ctf_id_t type)556 ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
557 {
558   ctf_id_t prev = type, otype = type;
559   ctf_dict_t *ofp = fp;
560   const ctf_type_t *tp;
561 
562   if (type == 0)
563     return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
564 
565   while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
566     {
567       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
568 	{
569 	case CTF_K_TYPEDEF:
570 	case CTF_K_VOLATILE:
571 	case CTF_K_CONST:
572 	case CTF_K_RESTRICT:
573 	  if (tp->ctt_type == type || tp->ctt_type == otype
574 	      || tp->ctt_type == prev)
575 	    {
576 	      ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
577 			    otype);
578 	      return (ctf_set_typed_errno (ofp, ECTF_CORRUPT));
579 	    }
580 	  prev = type;
581 	  type = tp->ctt_type;
582 	  break;
583 	case CTF_K_UNKNOWN:
584 	  return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
585 	default:
586 	  return type;
587 	}
588       if (type == 0)
589 	return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
590     }
591 
592   return CTF_ERR;		/* errno is set for us.  */
593 }
594 
595 /* Like ctf_type_resolve(), but traverse down through slices to their contained
596    type.  */
597 
598 ctf_id_t
ctf_type_resolve_unsliced(ctf_dict_t * fp,ctf_id_t type)599 ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
600 {
601   ctf_dict_t *ofp = fp;
602   const ctf_type_t *tp;
603 
604   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
605     return CTF_ERR;
606 
607   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
608     return CTF_ERR;		/* errno is set for us.  */
609 
610   if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
611     {
612       ctf_id_t ret;
613 
614       if ((ret = ctf_type_reference (fp, type)) == CTF_ERR)
615 	return (ctf_set_typed_errno (ofp, ctf_errno (fp)));
616       return ret;
617     }
618   return type;
619 }
620 
621 /* Return the native dict of a given type: if called on a child and the
622    type is in the parent, return the parent.  Needed if you plan to access
623    the type directly, without using the API.  */
624 ctf_dict_t *
ctf_get_dict(ctf_dict_t * fp,ctf_id_t type)625 ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
626 {
627     if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
628       return fp->ctf_parent;
629 
630     return fp;
631 }
632 
633 /* Look up a name in the given name table, in the appropriate hash given the
634    kind of the identifier.  The name is a raw, undecorated identifier.  */
635 
ctf_lookup_by_rawname(ctf_dict_t * fp,int kind,const char * name)636 ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
637 {
638   return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
639 }
640 
641 /* Look up a name in the given name table, in the appropriate hash given the
642    readability state of the dictionary.  The name is a raw, undecorated
643    identifier.  */
644 
ctf_lookup_by_rawhash(ctf_dict_t * fp,ctf_names_t * np,const char * name)645 ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
646 {
647   ctf_id_t id;
648 
649   if (fp->ctf_flags & LCTF_RDWR)
650     id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
651   else
652     id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
653   return id;
654 }
655 
656 /* Lookup the given type ID and return its name as a new dynamically-allocated
657    string.  */
658 
659 char *
ctf_type_aname(ctf_dict_t * fp,ctf_id_t type)660 ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
661 {
662   ctf_decl_t cd;
663   ctf_decl_node_t *cdp;
664   ctf_decl_prec_t prec, lp, rp;
665   int ptr, arr;
666   uint32_t k;
667   char *buf;
668 
669   if (fp == NULL && type == CTF_ERR)
670     return NULL;	/* Simplify caller code by permitting CTF_ERR.  */
671 
672   ctf_decl_init (&cd);
673   ctf_decl_push (&cd, fp, type);
674 
675   if (cd.cd_err != 0)
676     {
677       ctf_decl_fini (&cd);
678       ctf_set_errno (fp, cd.cd_err);
679       return NULL;
680     }
681 
682   /* If the type graph's order conflicts with lexical precedence order
683      for pointers or arrays, then we need to surround the declarations at
684      the corresponding lexical precedence with parentheses.  This can
685      result in either a parenthesized pointer (*) as in int (*)() or
686      int (*)[], or in a parenthesized pointer and array as in int (*[])().  */
687 
688   ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
689   arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
690 
691   rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
692   lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
693 
694   k = CTF_K_POINTER;		/* Avoid leading whitespace (see below).  */
695 
696   for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
697     {
698       for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
699 	   cdp != NULL; cdp = ctf_list_next (cdp))
700 	{
701 	  ctf_dict_t *rfp = fp;
702 	  const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
703 	  const char *name = ctf_strptr (rfp, tp->ctt_name);
704 
705 	  if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
706 	    ctf_decl_sprintf (&cd, " ");
707 
708 	  if (lp == prec)
709 	    {
710 	      ctf_decl_sprintf (&cd, "(");
711 	      lp = -1;
712 	    }
713 
714 	  switch (cdp->cd_kind)
715 	    {
716 	    case CTF_K_INTEGER:
717 	    case CTF_K_FLOAT:
718 	    case CTF_K_TYPEDEF:
719 	      /* Integers, floats, and typedefs must always be named types.  */
720 
721 	      if (name[0] == '\0')
722 		{
723 		  ctf_set_errno (fp, ECTF_CORRUPT);
724 		  ctf_decl_fini (&cd);
725 		  return NULL;
726 		}
727 
728 	      ctf_decl_sprintf (&cd, "%s", name);
729 	      break;
730 	    case CTF_K_POINTER:
731 	      ctf_decl_sprintf (&cd, "*");
732 	      break;
733 	    case CTF_K_ARRAY:
734 	      ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
735 	      break;
736 	    case CTF_K_FUNCTION:
737 	      {
738 		size_t i;
739 		ctf_funcinfo_t fi;
740 		ctf_id_t *argv = NULL;
741 
742 		if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
743 		  goto err;		/* errno is set for us.  */
744 
745 		if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
746 		  {
747 		    ctf_set_errno (rfp, errno);
748 		    goto err;
749 		  }
750 
751 		if (ctf_func_type_args (rfp, cdp->cd_type,
752 					fi.ctc_argc, argv) < 0)
753 		  goto err;		/* errno is set for us.  */
754 
755 		ctf_decl_sprintf (&cd, "(*) (");
756 		for (i = 0; i < fi.ctc_argc; i++)
757 		  {
758 		    char *arg = ctf_type_aname (rfp, argv[i]);
759 
760 		    if (arg == NULL)
761 		      goto err;		/* errno is set for us.  */
762 		    ctf_decl_sprintf (&cd, "%s", arg);
763 		    free (arg);
764 
765 		    if ((i < fi.ctc_argc - 1)
766 			|| (fi.ctc_flags & CTF_FUNC_VARARG))
767 		      ctf_decl_sprintf (&cd, ", ");
768 		  }
769 
770 		if (fi.ctc_flags & CTF_FUNC_VARARG)
771 		  ctf_decl_sprintf (&cd, "...");
772 		ctf_decl_sprintf (&cd, ")");
773 
774 		free (argv);
775 		break;
776 
777 	      err:
778 		ctf_set_errno (fp, ctf_errno (rfp));
779 		free (argv);
780 		ctf_decl_fini (&cd);
781 		return NULL;
782 	      }
783 	      break;
784 	    case CTF_K_STRUCT:
785 	      ctf_decl_sprintf (&cd, "struct %s", name);
786 	      break;
787 	    case CTF_K_UNION:
788 	      ctf_decl_sprintf (&cd, "union %s", name);
789 	      break;
790 	    case CTF_K_ENUM:
791 	      ctf_decl_sprintf (&cd, "enum %s", name);
792 	      break;
793 	    case CTF_K_FORWARD:
794 	      {
795 		switch (ctf_type_kind_forwarded (fp, cdp->cd_type))
796 		  {
797 		  case CTF_K_STRUCT:
798 		    ctf_decl_sprintf (&cd, "struct %s", name);
799 		    break;
800 		  case CTF_K_UNION:
801 		    ctf_decl_sprintf (&cd, "union %s", name);
802 		    break;
803 		  case CTF_K_ENUM:
804 		    ctf_decl_sprintf (&cd, "enum %s", name);
805 		    break;
806 		  default:
807 		    ctf_set_errno (fp, ECTF_CORRUPT);
808 		    ctf_decl_fini (&cd);
809 		    return NULL;
810 		  }
811 		break;
812 	      }
813 	    case CTF_K_VOLATILE:
814 	      ctf_decl_sprintf (&cd, "volatile");
815 	      break;
816 	    case CTF_K_CONST:
817 	      ctf_decl_sprintf (&cd, "const");
818 	      break;
819 	    case CTF_K_RESTRICT:
820 	      ctf_decl_sprintf (&cd, "restrict");
821 	      break;
822 	    case CTF_K_UNKNOWN:
823 	      if (name[0] == '\0')
824 		ctf_decl_sprintf (&cd, _("(nonrepresentable type)"));
825 	      else
826 		ctf_decl_sprintf (&cd, _("(nonrepresentable type %s)"),
827 				  name);
828 	      break;
829 	    }
830 
831 	  k = cdp->cd_kind;
832 	}
833 
834       if (rp == prec)
835 	ctf_decl_sprintf (&cd, ")");
836     }
837 
838   if (cd.cd_enomem)
839     (void) ctf_set_errno (fp, ENOMEM);
840 
841   buf = ctf_decl_buf (&cd);
842 
843   ctf_decl_fini (&cd);
844   return buf;
845 }
846 
847 /* Lookup the given type ID and print a string name for it into buf.  Return
848    the actual number of bytes (not including \0) needed to format the name.  */
849 
850 ssize_t
ctf_type_lname(ctf_dict_t * fp,ctf_id_t type,char * buf,size_t len)851 ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
852 {
853   char *str = ctf_type_aname (fp, type);
854   size_t slen;
855 
856   if (str == NULL)
857     return -1;			/* errno is set for us.  */
858 
859   slen = strlen (str);
860   snprintf (buf, len, "%s", str);
861   free (str);
862 
863   if (slen >= len)
864     (void) ctf_set_errno (fp, ECTF_NAMELEN);
865 
866   return slen;
867 }
868 
869 /* Lookup the given type ID and print a string name for it into buf.  If buf
870    is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
871 
872 char *
ctf_type_name(ctf_dict_t * fp,ctf_id_t type,char * buf,size_t len)873 ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
874 {
875   ssize_t rv = ctf_type_lname (fp, type, buf, len);
876   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
877 }
878 
879 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
880    The name will live as long as its ctf_dict_t does.
881 
882    The only decoration is that a NULL return always means an error: nameless
883    types return a null string.  */
884 
885 const char *
ctf_type_name_raw(ctf_dict_t * fp,ctf_id_t type)886 ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
887 {
888   const ctf_type_t *tp;
889 
890   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
891     return NULL;		/* errno is set for us.  */
892 
893   if (tp->ctt_name == 0)
894     return "";
895 
896   return ctf_strraw (fp, tp->ctt_name);
897 }
898 
899 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
900    new dynamically-allocated string.  */
901 
902 char *
ctf_type_aname_raw(ctf_dict_t * fp,ctf_id_t type)903 ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
904 {
905   const char *name = ctf_type_name_raw (fp, type);
906 
907   if (name != NULL)
908     return strdup (name);
909 
910   return NULL;
911 }
912 
913 /* Resolve the type down to a base type node, and then return the size
914    of the type storage in bytes.  */
915 
916 ssize_t
ctf_type_size(ctf_dict_t * fp,ctf_id_t type)917 ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
918 {
919   ctf_dict_t *ofp = fp;
920   const ctf_type_t *tp;
921   ssize_t size;
922   ctf_arinfo_t ar;
923 
924   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
925     return -1;			/* errno is set for us.  */
926 
927   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
928     return -1;			/* errno is set for us.  */
929 
930   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
931     {
932     case CTF_K_POINTER:
933       return fp->ctf_dmodel->ctd_pointer;
934 
935     case CTF_K_FUNCTION:
936       return 0;		/* Function size is only known by symtab.  */
937 
938     case CTF_K_ENUM:
939       return fp->ctf_dmodel->ctd_int;
940 
941     case CTF_K_ARRAY:
942       /* ctf_add_array() does not directly encode the element size, but
943 	 requires the user to multiply to determine the element size.
944 
945 	 If ctf_get_ctt_size() returns nonzero, then use the recorded
946 	 size instead.  */
947 
948       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
949 	return size;
950 
951       if (ctf_array_info (ofp, type, &ar) < 0
952 	  || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
953 	return -1;		/* errno is set for us.  */
954 
955       return size * ar.ctr_nelems;
956 
957     case CTF_K_FORWARD:
958       /* Forwards do not have a meaningful size.  */
959       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
960 
961     default: /* including slices of enums, etc */
962       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
963     }
964 }
965 
966 /* Resolve the type down to a base type node, and then return the alignment
967    needed for the type storage in bytes.
968 
969    XXX may need arch-dependent attention.  */
970 
971 ssize_t
ctf_type_align(ctf_dict_t * fp,ctf_id_t type)972 ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
973 {
974   const ctf_type_t *tp;
975   ctf_dict_t *ofp = fp;
976   int kind;
977 
978   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
979     return -1;			/* errno is set for us.  */
980 
981   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
982     return -1;			/* errno is set for us.  */
983 
984   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
985   switch (kind)
986     {
987     case CTF_K_POINTER:
988     case CTF_K_FUNCTION:
989       return fp->ctf_dmodel->ctd_pointer;
990 
991     case CTF_K_ARRAY:
992       {
993 	ctf_arinfo_t r;
994 	if (ctf_array_info (ofp, type, &r) < 0)
995 	  return -1;		/* errno is set for us.  */
996 	return (ctf_type_align (ofp, r.ctr_contents));
997       }
998 
999     case CTF_K_STRUCT:
1000     case CTF_K_UNION:
1001       {
1002 	size_t align = 0;
1003 	ctf_dtdef_t *dtd;
1004 	unsigned char *vlen;
1005 	uint32_t i = 0, n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1006 	ssize_t size, increment, vbytes;
1007 
1008 	ctf_get_ctt_size (fp, tp, &size, &increment);
1009 
1010 	if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1011 	  {
1012 	    vlen = dtd->dtd_vlen;
1013 	    vbytes = dtd->dtd_vlen_alloc;
1014 	  }
1015 	else
1016 	  {
1017 	    vlen = (unsigned char *) tp + increment;
1018 	    vbytes = LCTF_VBYTES (fp, kind, size, n);
1019 	  }
1020 
1021 	if (kind == CTF_K_STRUCT)
1022 	  n = MIN (n, 1);	/* Only use first member for structs.  */
1023 
1024 	for (; n != 0; n--, i++)
1025 	  {
1026 	    ctf_lmember_t memb;
1027 
1028 	    if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1029 	      return -1;				/* errno is set for us.  */
1030 
1031 	    ssize_t am = ctf_type_align (ofp, memb.ctlm_type);
1032 	    align = MAX (align, (size_t) am);
1033 	  }
1034 	return align;
1035       }
1036 
1037     case CTF_K_ENUM:
1038       return fp->ctf_dmodel->ctd_int;
1039 
1040     case CTF_K_FORWARD:
1041       /* Forwards do not have a meaningful alignment.  */
1042       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1043 
1044     default:  /* including slices of enums, etc */
1045       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1046     }
1047 }
1048 
1049 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
1050 
1051 int
ctf_type_kind_unsliced(ctf_dict_t * fp,ctf_id_t type)1052 ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
1053 {
1054   const ctf_type_t *tp;
1055 
1056   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1057     return -1;			/* errno is set for us.  */
1058 
1059   return (LCTF_INFO_KIND (fp, tp->ctt_info));
1060 }
1061 
1062 /* Return the kind (CTF_K_* constant) for the specified type ID.
1063    Slices are considered to be of the same kind as the type sliced.  */
1064 
1065 int
ctf_type_kind(ctf_dict_t * fp,ctf_id_t type)1066 ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
1067 {
1068   int kind;
1069 
1070   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1071     return -1;
1072 
1073   if (kind == CTF_K_SLICE)
1074     {
1075       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1076 	return -1;
1077       kind = ctf_type_kind_unsliced (fp, type);
1078     }
1079 
1080   return kind;
1081 }
1082 
1083 /* Return the kind of this type, except, for forwards, return the kind of thing
1084    this is a forward to.  */
1085 int
ctf_type_kind_forwarded(ctf_dict_t * fp,ctf_id_t type)1086 ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
1087 {
1088   int kind;
1089   const ctf_type_t *tp;
1090 
1091   if ((kind = ctf_type_kind (fp, type)) < 0)
1092     return -1;			/* errno is set for us.  */
1093 
1094   if (kind != CTF_K_FORWARD)
1095     return kind;
1096 
1097   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1098     return -1;			/* errno is set for us.  */
1099 
1100   return tp->ctt_type;
1101 }
1102 
1103 /* If the type is one that directly references another type (such as POINTER),
1104    then return the ID of the type to which it refers.  */
1105 
1106 ctf_id_t
ctf_type_reference(ctf_dict_t * fp,ctf_id_t type)1107 ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
1108 {
1109   ctf_dict_t *ofp = fp;
1110   const ctf_type_t *tp;
1111 
1112   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1113     return CTF_ERR;		/* errno is set for us.  */
1114 
1115   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1116     {
1117     case CTF_K_POINTER:
1118     case CTF_K_TYPEDEF:
1119     case CTF_K_VOLATILE:
1120     case CTF_K_CONST:
1121     case CTF_K_RESTRICT:
1122       return tp->ctt_type;
1123       /* Slices store their type in an unusual place.  */
1124     case CTF_K_SLICE:
1125       {
1126 	ctf_dtdef_t *dtd;
1127 	const ctf_slice_t *sp;
1128 
1129 	if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1130 	  {
1131 	    ssize_t increment;
1132 
1133 	    (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1134 	    sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1135 	  }
1136 	else
1137 	  sp = (const ctf_slice_t *) dtd->dtd_vlen;
1138 
1139 	return sp->cts_type;
1140       }
1141     default:
1142       return (ctf_set_typed_errno (ofp, ECTF_NOTREF));
1143     }
1144 }
1145 
1146 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
1147    pointer to the given type, see if we can compute a pointer to the type
1148    resulting from resolving the type down to its base type and use that
1149    instead.  This helps with cases where the CTF data includes "struct foo *"
1150    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1151 
1152    XXX what about parent dicts?  */
1153 
1154 ctf_id_t
ctf_type_pointer(ctf_dict_t * fp,ctf_id_t type)1155 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
1156 {
1157   ctf_dict_t *ofp = fp;
1158   ctf_id_t ntype;
1159 
1160   if (ctf_lookup_by_id (&fp, type) == NULL)
1161     return CTF_ERR;		/* errno is set for us.  */
1162 
1163   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1164     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1165 
1166   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1167     return (ctf_set_typed_errno (ofp, ECTF_NOTYPE));
1168 
1169   if (ctf_lookup_by_id (&fp, type) == NULL)
1170     return (ctf_set_typed_errno (ofp, ECTF_NOTYPE));
1171 
1172   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1173     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1174 
1175   return (ctf_set_typed_errno (ofp, ECTF_NOTYPE));
1176 }
1177 
1178 /* Return the encoding for the specified INTEGER, FLOAT, or ENUM.  */
1179 
1180 int
ctf_type_encoding(ctf_dict_t * fp,ctf_id_t type,ctf_encoding_t * ep)1181 ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1182 {
1183   ctf_dict_t *ofp = fp;
1184   ctf_dtdef_t *dtd;
1185   const ctf_type_t *tp;
1186   ssize_t increment;
1187   const unsigned char *vlen;
1188   uint32_t data;
1189 
1190   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1191     return -1;			/* errno is set for us.  */
1192 
1193   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1194     vlen = dtd->dtd_vlen;
1195   else
1196     {
1197       ctf_get_ctt_size (fp, tp, NULL, &increment);
1198       vlen = (const unsigned char *) ((uintptr_t) tp + increment);
1199     }
1200 
1201   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1202     {
1203     case CTF_K_INTEGER:
1204       data = *(const uint32_t *) vlen;
1205       ep->cte_format = CTF_INT_ENCODING (data);
1206       ep->cte_offset = CTF_INT_OFFSET (data);
1207       ep->cte_bits = CTF_INT_BITS (data);
1208       break;
1209     case CTF_K_FLOAT:
1210       data = *(const uint32_t *) vlen;
1211       ep->cte_format = CTF_FP_ENCODING (data);
1212       ep->cte_offset = CTF_FP_OFFSET (data);
1213       ep->cte_bits = CTF_FP_BITS (data);
1214       break;
1215     case CTF_K_ENUM:
1216       /* v3 only: we must guess at the underlying integral format.  */
1217       ep->cte_format = CTF_INT_SIGNED;
1218       ep->cte_offset = 0;
1219       ep->cte_bits = 0;
1220       break;
1221     case CTF_K_SLICE:
1222       {
1223 	const ctf_slice_t *slice;
1224 	ctf_encoding_t underlying_en;
1225 	ctf_id_t underlying;
1226 
1227 	slice = (ctf_slice_t *) vlen;
1228 	underlying = ctf_type_resolve (ofp, slice->cts_type);
1229 	if (ctf_type_encoding (ofp, underlying, &underlying_en) < 0)
1230 	  return -1;				/* errno is set for us.  */
1231 
1232 	ep->cte_format = underlying_en.cte_format;
1233 	ep->cte_offset = slice->cts_offset;
1234 	ep->cte_bits = slice->cts_bits;
1235 	break;
1236       }
1237     default:
1238       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1239     }
1240 
1241   return 0;
1242 }
1243 
1244 int
ctf_type_cmp(ctf_dict_t * lfp,ctf_id_t ltype,ctf_dict_t * rfp,ctf_id_t rtype)1245 ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
1246 	      ctf_id_t rtype)
1247 {
1248   int rval;
1249 
1250   if (ltype < rtype)
1251     rval = -1;
1252   else if (ltype > rtype)
1253     rval = 1;
1254   else
1255     rval = 0;
1256 
1257   if (lfp == rfp)
1258     return rval;
1259 
1260   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1261     lfp = lfp->ctf_parent;
1262 
1263   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1264     rfp = rfp->ctf_parent;
1265 
1266   if (lfp < rfp)
1267     return -1;
1268 
1269   if (lfp > rfp)
1270     return 1;
1271 
1272   return rval;
1273 }
1274 
1275 /* Return a boolean value indicating if two types are compatible.  This function
1276    returns true if the two types are the same, or if they (or their ultimate
1277    base type) have the same encoding properties, or (for structs / unions /
1278    enums / forward declarations) if they have the same name and (for structs /
1279    unions) member count.  */
1280 
1281 int
ctf_type_compat(ctf_dict_t * lfp,ctf_id_t ltype,ctf_dict_t * rfp,ctf_id_t rtype)1282 ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1283 		 ctf_dict_t *rfp, ctf_id_t rtype)
1284 {
1285   const ctf_type_t *ltp, *rtp;
1286   ctf_encoding_t le, re;
1287   ctf_arinfo_t la, ra;
1288   uint32_t lkind, rkind;
1289   int same_names = 0;
1290 
1291   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1292     return 1;
1293 
1294   ltype = ctf_type_resolve (lfp, ltype);
1295   lkind = ctf_type_kind (lfp, ltype);
1296 
1297   rtype = ctf_type_resolve (rfp, rtype);
1298   rkind = ctf_type_kind (rfp, rtype);
1299 
1300   ltp = ctf_lookup_by_id (&lfp, ltype);
1301   rtp = ctf_lookup_by_id (&rfp, rtype);
1302 
1303   if (ltp != NULL && rtp != NULL)
1304     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1305 			  ctf_strptr (rfp, rtp->ctt_name)) == 0);
1306 
1307   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1308       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1309     return 1;
1310 
1311   if (lkind != rkind)
1312     return 0;
1313 
1314   switch (lkind)
1315     {
1316     case CTF_K_INTEGER:
1317     case CTF_K_FLOAT:
1318       memset (&le, 0, sizeof (le));
1319       memset (&re, 0, sizeof (re));
1320       return (ctf_type_encoding (lfp, ltype, &le) == 0
1321 	      && ctf_type_encoding (rfp, rtype, &re) == 0
1322 	      && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1323     case CTF_K_POINTER:
1324       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1325 			       rfp, ctf_type_reference (rfp, rtype)));
1326     case CTF_K_ARRAY:
1327       return (ctf_array_info (lfp, ltype, &la) == 0
1328 	      && ctf_array_info (rfp, rtype, &ra) == 0
1329 	      && la.ctr_nelems == ra.ctr_nelems
1330 	      && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1331 	      && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1332     case CTF_K_STRUCT:
1333     case CTF_K_UNION:
1334       return (same_names && (ctf_type_size (lfp, ltype)
1335 			     == ctf_type_size (rfp, rtype)));
1336     case CTF_K_ENUM:
1337       {
1338 	int lencoded, rencoded;
1339 	lencoded = ctf_type_encoding (lfp, ltype, &le);
1340 	rencoded = ctf_type_encoding (rfp, rtype, &re);
1341 
1342 	if ((lencoded != rencoded) ||
1343 	    ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1344 	  return 0;
1345       }
1346       /* FALLTHRU */
1347     case CTF_K_FORWARD:
1348       return same_names;   /* No other checks required for these type kinds.  */
1349     default:
1350       return 0;		      /* Should not get here since we did a resolve.  */
1351     }
1352 }
1353 
1354 /* Return the number of members in a STRUCT or UNION, or the number of
1355    enumerators in an ENUM.  The count does not include unnamed sub-members.  */
1356 
1357 int
ctf_member_count(ctf_dict_t * fp,ctf_id_t type)1358 ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
1359 {
1360   ctf_dict_t *ofp = fp;
1361   const ctf_type_t *tp;
1362   uint32_t kind;
1363 
1364   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1365     return -1;			/* errno is set for us.  */
1366 
1367   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1368     return -1;			/* errno is set for us.  */
1369 
1370   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1371 
1372   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1373     return (ctf_set_errno (ofp, ECTF_NOTSUE));
1374 
1375   return LCTF_INFO_VLEN (fp, tp->ctt_info);
1376 }
1377 
1378 /* Return the type and offset for a given member of a STRUCT or UNION.  */
1379 
1380 int
ctf_member_info(ctf_dict_t * fp,ctf_id_t type,const char * name,ctf_membinfo_t * mip)1381 ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
1382 		 ctf_membinfo_t *mip)
1383 {
1384   ctf_dict_t *ofp = fp;
1385   const ctf_type_t *tp;
1386   ctf_dtdef_t *dtd;
1387   unsigned char *vlen;
1388   ssize_t size, increment, vbytes;
1389   uint32_t kind, n, i = 0;
1390 
1391   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1392     return -1;			/* errno is set for us.  */
1393 
1394   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1395     return -1;			/* errno is set for us.  */
1396 
1397   ctf_get_ctt_size (fp, tp, &size, &increment);
1398   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1399 
1400   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1401     return (ctf_set_errno (ofp, ECTF_NOTSOU));
1402 
1403   n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1404   if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1405     {
1406       vlen = dtd->dtd_vlen;
1407       vbytes = dtd->dtd_vlen_alloc;
1408     }
1409   else
1410     {
1411       vlen = (unsigned char *) tp + increment;
1412       vbytes = LCTF_VBYTES (fp, kind, size, n);
1413     }
1414 
1415   for (; n != 0; n--, i++)
1416     {
1417       ctf_lmember_t memb;
1418       const char *membname;
1419 
1420       if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1421         return (ctf_set_errno (ofp, ctf_errno (fp)));
1422 
1423       membname = ctf_strptr (fp, memb.ctlm_name);
1424 
1425       if (membname[0] == 0
1426 	  && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
1427 	      || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION)
1428 	  && (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0))
1429 	{
1430 	  mip->ctm_offset += (unsigned long) CTF_LMEM_OFFSET (&memb);
1431 	  return 0;
1432 	}
1433 
1434       if (strcmp (membname, name) == 0)
1435 	{
1436 	  mip->ctm_type = memb.ctlm_type;
1437 	  mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
1438 	  return 0;
1439 	}
1440     }
1441 
1442   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1443 }
1444 
1445 /* Return the array type, index, and size information for the specified ARRAY.  */
1446 
1447 int
ctf_array_info(ctf_dict_t * fp,ctf_id_t type,ctf_arinfo_t * arp)1448 ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1449 {
1450   ctf_dict_t *ofp = fp;
1451   const ctf_type_t *tp;
1452   const ctf_array_t *ap;
1453   const ctf_dtdef_t *dtd;
1454   ssize_t increment;
1455 
1456   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1457     return -1;			/* errno is set for us.  */
1458 
1459   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1460     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1461 
1462   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1463     ap = (const ctf_array_t *) dtd->dtd_vlen;
1464   else
1465     {
1466       ctf_get_ctt_size (fp, tp, NULL, &increment);
1467       ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1468     }
1469   arp->ctr_contents = ap->cta_contents;
1470   arp->ctr_index = ap->cta_index;
1471   arp->ctr_nelems = ap->cta_nelems;
1472 
1473   return 0;
1474 }
1475 
1476 /* Convert the specified value to the corresponding enum tag name, if a
1477    matching name can be found.  Otherwise NULL is returned.  */
1478 
1479 const char *
ctf_enum_name(ctf_dict_t * fp,ctf_id_t type,int value)1480 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1481 {
1482   ctf_dict_t *ofp = fp;
1483   const ctf_type_t *tp;
1484   const ctf_enum_t *ep;
1485   const ctf_dtdef_t *dtd;
1486   ssize_t increment;
1487   uint32_t n;
1488 
1489   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1490     return NULL;		/* errno is set for us.  */
1491 
1492   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1493     return NULL;		/* errno is set for us.  */
1494 
1495   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1496     {
1497       ctf_set_errno (ofp, ECTF_NOTENUM);
1498       return NULL;
1499     }
1500 
1501   ctf_get_ctt_size (fp, tp, NULL, &increment);
1502 
1503   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1504     ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1505   else
1506     ep = (const ctf_enum_t *) dtd->dtd_vlen;
1507 
1508   for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1509     {
1510       if (ep->cte_value == value)
1511 	return (ctf_strptr (fp, ep->cte_name));
1512     }
1513 
1514   ctf_set_errno (ofp, ECTF_NOENUMNAM);
1515   return NULL;
1516 }
1517 
1518 /* Convert the specified enum tag name to the corresponding value, if a
1519    matching name can be found.  Otherwise CTF_ERR is returned.  */
1520 
1521 int
ctf_enum_value(ctf_dict_t * fp,ctf_id_t type,const char * name,int * valp)1522 ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int *valp)
1523 {
1524   ctf_dict_t *ofp = fp;
1525   const ctf_type_t *tp;
1526   const ctf_enum_t *ep;
1527   const ctf_dtdef_t *dtd;
1528   ssize_t increment;
1529   uint32_t n;
1530 
1531   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1532     return -1;			/* errno is set for us.  */
1533 
1534   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1535     return -1;			/* errno is set for us.  */
1536 
1537   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1538     return ctf_set_errno (ofp, ECTF_NOTENUM);
1539 
1540   ctf_get_ctt_size (fp, tp, NULL, &increment);
1541 
1542   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1543     ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1544   else
1545     ep = (const ctf_enum_t *) dtd->dtd_vlen;
1546 
1547   for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1548     {
1549       if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1550 	{
1551 	  if (valp != NULL)
1552 	    *valp = ep->cte_value;
1553 	  return 0;
1554 	}
1555     }
1556 
1557   return ctf_set_errno (ofp, ECTF_NOENUMNAM);
1558 }
1559 
1560 /* Given a type ID relating to a function type, return info on return types and
1561    arg counts for that function.  */
1562 
1563 int
ctf_func_type_info(ctf_dict_t * fp,ctf_id_t type,ctf_funcinfo_t * fip)1564 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1565 {
1566   ctf_dict_t *ofp = fp;
1567   const ctf_type_t *tp;
1568   uint32_t kind;
1569   const uint32_t *args;
1570   const ctf_dtdef_t *dtd;
1571   ssize_t size, increment;
1572 
1573   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1574     return -1;			/* errno is set for us.  */
1575 
1576   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1577     return -1;			/* errno is set for us.  */
1578 
1579   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1580   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1581 
1582   if (kind != CTF_K_FUNCTION)
1583     return (ctf_set_errno (ofp, ECTF_NOTFUNC));
1584 
1585   fip->ctc_return = tp->ctt_type;
1586   fip->ctc_flags = 0;
1587   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1588 
1589   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1590     args = (uint32_t *) ((uintptr_t) tp + increment);
1591   else
1592     args = (uint32_t *) dtd->dtd_vlen;
1593 
1594   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1595     {
1596       fip->ctc_flags |= CTF_FUNC_VARARG;
1597       fip->ctc_argc--;
1598     }
1599 
1600   return 0;
1601 }
1602 
1603 /* Given a type ID relating to a function type, return the arguments for the
1604    function.  */
1605 
1606 int
ctf_func_type_args(ctf_dict_t * fp,ctf_id_t type,uint32_t argc,ctf_id_t * argv)1607 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1608 {
1609   const ctf_type_t *tp;
1610   const uint32_t *args;
1611   const ctf_dtdef_t *dtd;
1612   ssize_t size, increment;
1613   ctf_funcinfo_t f;
1614 
1615   if (ctf_func_type_info (fp, type, &f) < 0)
1616     return -1;			/* errno is set for us.  */
1617 
1618   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1619     return -1;			/* errno is set for us.  */
1620 
1621   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1622     return -1;			/* errno is set for us.  */
1623 
1624   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1625 
1626   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1627     args = (uint32_t *) ((uintptr_t) tp + increment);
1628   else
1629     args = (uint32_t *) dtd->dtd_vlen;
1630 
1631   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1632     *argv++ = *args++;
1633 
1634   return 0;
1635 }
1636 
1637 /* Recursively visit the members of any type.  This function is used as the
1638    engine for ctf_type_visit, below.  We resolve the input type, recursively
1639    invoke ourself for each type member if the type is a struct or union, and
1640    then invoke the callback function on the current type.  If any callback
1641    returns non-zero, we abort and percolate the error code back up to the top.  */
1642 
1643 static int
ctf_type_rvisit(ctf_dict_t * fp,ctf_id_t type,ctf_visit_f * func,void * arg,const char * name,unsigned long offset,int depth)1644 ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
1645 		 void *arg, const char *name, unsigned long offset, int depth)
1646 {
1647   ctf_dict_t *ofp = fp;
1648   ctf_id_t otype = type;
1649   const ctf_type_t *tp;
1650   const ctf_dtdef_t *dtd;
1651   unsigned char *vlen;
1652   ssize_t size, increment, vbytes;
1653   uint32_t kind, n, i = 0;
1654   int nonrepresentable = 0;
1655   int rc;
1656 
1657   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) {
1658     if (ctf_errno (fp) != ECTF_NONREPRESENTABLE)
1659       return -1;		/* errno is set for us.  */
1660     else
1661       nonrepresentable = 1;
1662   }
1663 
1664   if (!nonrepresentable)
1665     if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1666       return -1;		/* errno is set for us.  */
1667 
1668   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1669     return rc;
1670 
1671   if (!nonrepresentable)
1672     kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1673 
1674   if (nonrepresentable || (kind != CTF_K_STRUCT && kind != CTF_K_UNION))
1675     return 0;
1676 
1677   ctf_get_ctt_size (fp, tp, &size, &increment);
1678 
1679   n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1680   if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1681     {
1682       vlen = dtd->dtd_vlen;
1683       vbytes = dtd->dtd_vlen_alloc;
1684     }
1685   else
1686     {
1687       vlen = (unsigned char *) tp + increment;
1688       vbytes = LCTF_VBYTES (fp, kind, size, n);
1689     }
1690 
1691   for (; n != 0; n--, i++)
1692     {
1693       ctf_lmember_t memb;
1694 
1695       if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1696         return (ctf_set_errno (ofp, ctf_errno (fp)));
1697 
1698       if ((rc = ctf_type_rvisit (fp, memb.ctlm_type,
1699 				 func, arg, ctf_strptr (fp, memb.ctlm_name),
1700 				 offset + (unsigned long) CTF_LMEM_OFFSET (&memb),
1701 				 depth + 1)) != 0)
1702 	return rc;
1703     }
1704 
1705   return 0;
1706 }
1707 
1708 /* Recursively visit the members of any type.  We pass the name, member
1709  type, and offset of each member to the specified callback function.  */
1710 int
ctf_type_visit(ctf_dict_t * fp,ctf_id_t type,ctf_visit_f * func,void * arg)1711 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1712 {
1713   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1714 }
1715