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