1/* Type handling functions.
2   Copyright (C) 2019-2022 Free Software Foundation, Inc.
3
4   This file is part of libctf.
5
6   libctf is free software; you can redistribute it and/or modify it under
7   the terms of the GNU General Public License as published by the Free
8   Software Foundation; either version 3, or (at your option) any later
9   version.
10
11   This program is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   See the GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; see the file COPYING.  If not see
18   <http://www.gnu.org/licenses/>.  */
19
20#include <ctf-impl.h>
21#include <assert.h>
22#include <string.h>
23
24/* Determine whether a type is a parent or a child.  */
25
26int
27ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id)
28{
29  return (LCTF_TYPE_ISPARENT (fp, id));
30}
31
32int
33ctf_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
40static int
41ctf_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
71int
72ctf_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
98ssize_t
99ctf_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
241int
242ctf_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
267const char *
268ctf_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
362int
363ctf_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
390int
391ctf_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
420ctf_id_t
421ctf_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
464int
465ctf_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
490ctf_id_t
491ctf_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
554ctf_id_t
555ctf_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
597ctf_id_t
598ctf_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.  */
616ctf_dict_t *
617ctf_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
628ctf_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
637ctf_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
651char *
652ctf_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
841ssize_t
842ctf_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
863char *
864ctf_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
876const char *
877ctf_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
893char *
894ctf_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
907ssize_t
908ctf_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
962ssize_t
963ctf_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
1042int
1043ctf_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
1056int
1057ctf_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.  */
1076int
1077ctf_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
1097ctf_id_t
1098ctf_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
1145ctf_id_t
1146ctf_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
1171int
1172ctf_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
1235int
1236ctf_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
1272int
1273ctf_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
1348int
1349ctf_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
1371int
1372ctf_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
1435int
1436ctf_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
1467const char *
1468ctf_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
1509int
1510ctf_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
1555int
1556ctf_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
1597int
1598ctf_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
1634static int
1635ctf_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 nonrepresentable = 0;
1645  int rc;
1646
1647  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) {
1648    if (ctf_errno (fp) != ECTF_NONREPRESENTABLE)
1649      return -1;		/* errno is set for us.  */
1650    else
1651      nonrepresentable = 1;
1652  }
1653
1654  if (!nonrepresentable)
1655    if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1656      return -1;		/* errno is set for us.  */
1657
1658  if ((rc = func (name, otype, offset, depth, arg)) != 0)
1659    return rc;
1660
1661  if (!nonrepresentable)
1662    kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1663
1664  if (nonrepresentable || (kind != CTF_K_STRUCT && kind != CTF_K_UNION))
1665    return 0;
1666
1667  ctf_get_ctt_size (fp, tp, &size, &increment);
1668
1669  n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1670  if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1671    {
1672      vlen = dtd->dtd_vlen;
1673      vbytes = dtd->dtd_vlen_alloc;
1674    }
1675  else
1676    {
1677      vlen = (unsigned char *) tp + increment;
1678      vbytes = LCTF_VBYTES (fp, kind, size, n);
1679    }
1680
1681  for (; n != 0; n--, i++)
1682    {
1683      ctf_lmember_t memb;
1684
1685      if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1686	return -1;				/* errno is set for us.  */
1687
1688      if ((rc = ctf_type_rvisit (fp, memb.ctlm_type,
1689				 func, arg, ctf_strptr (fp, memb.ctlm_name),
1690				 offset + (unsigned long) CTF_LMEM_OFFSET (&memb),
1691				 depth + 1)) != 0)
1692	return rc;
1693    }
1694
1695  return 0;
1696}
1697
1698/* Recursively visit the members of any type.  We pass the name, member
1699 type, and offset of each member to the specified callback function.  */
1700int
1701ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1702{
1703  return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1704}
1705