1 /* Type handling functions.
2    Copyright (C) 2019-2020 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 <string.h>
22 
23 /* Determine whether a type is a parent or a child.  */
24 
25 int
26 ctf_type_isparent (ctf_file_t *fp, ctf_id_t id)
27 {
28   return (LCTF_TYPE_ISPARENT (fp, id));
29 }
30 
31 int
32 ctf_type_ischild (ctf_file_t * fp, ctf_id_t id)
33 {
34   return (LCTF_TYPE_ISCHILD (fp, id));
35 }
36 
37 /* Iterate over the members of a STRUCT or UNION.  We pass the name, member
38    type, and offset of each member to the specified callback function.  */
39 
40 int
41 ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
42 {
43   ctf_file_t *ofp = fp;
44   const ctf_type_t *tp;
45   ctf_dtdef_t *dtd;
46   ssize_t size, increment;
47   uint32_t kind, n;
48   int rc;
49 
50   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
51     return -1;			/* errno is set for us.  */
52 
53   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
54     return -1;			/* errno is set for us.  */
55 
56   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
57   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
58 
59   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
60     return (ctf_set_errno (ofp, ECTF_NOTSOU));
61 
62   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
63     {
64       if (size < CTF_LSTRUCT_THRESH)
65 	{
66 	  const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
67 							   increment);
68 
69 	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
70 	    {
71 	      const char *name = ctf_strptr (fp, mp->ctm_name);
72 	      if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0)
73 	    return rc;
74 	    }
75 	}
76       else
77 	{
78 	  const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
79 							      increment);
80 
81 	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
82 	    {
83 	      const char *name = ctf_strptr (fp, lmp->ctlm_name);
84 	      if ((rc = func (name, lmp->ctlm_type,
85 			      (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0)
86 		return rc;
87 	    }
88 	}
89     }
90   else
91     {
92       ctf_dmdef_t *dmd;
93 
94       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
95 	   dmd != NULL; dmd = ctf_list_next (dmd))
96 	{
97 	  if ((rc = func (dmd->dmd_name, dmd->dmd_type,
98 			  dmd->dmd_offset, arg)) != 0)
99 	    return rc;
100 	}
101     }
102 
103   return 0;
104 }
105 
106 /* Iterate over the members of an ENUM.  We pass the string name and associated
107    integer value of each enum element to the specified callback function.  */
108 
109 int
110 ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
111 {
112   ctf_file_t *ofp = fp;
113   const ctf_type_t *tp;
114   const ctf_enum_t *ep;
115   ctf_dtdef_t *dtd;
116   ssize_t increment;
117   uint32_t n;
118   int rc;
119 
120   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
121     return -1;			/* errno is set for us.  */
122 
123   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
124     return -1;			/* errno is set for us.  */
125 
126   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
127     return (ctf_set_errno (ofp, ECTF_NOTENUM));
128 
129   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
130 
131   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
132     {
133       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
134 
135       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
136 	{
137 	  const char *name = ctf_strptr (fp, ep->cte_name);
138 	  if ((rc = func (name, ep->cte_value, arg)) != 0)
139 	    return rc;
140 	}
141     }
142   else
143     {
144       ctf_dmdef_t *dmd;
145 
146       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
147 	   dmd != NULL; dmd = ctf_list_next (dmd))
148 	{
149 	  if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0)
150 	    return rc;
151 	}
152     }
153 
154   return 0;
155 }
156 
157 /* Iterate over every root (user-visible) type in the given CTF container.
158    We pass the type ID of each type to the specified callback function.  */
159 
160 int
161 ctf_type_iter (ctf_file_t *fp, ctf_type_f *func, void *arg)
162 {
163   ctf_id_t id, max = fp->ctf_typemax;
164   int rc, child = (fp->ctf_flags & LCTF_CHILD);
165 
166   for (id = 1; id <= max; id++)
167     {
168       const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
169       if (LCTF_INFO_ISROOT (fp, tp->ctt_info)
170 	  && (rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), arg)) != 0)
171 	return rc;
172     }
173 
174   return 0;
175 }
176 
177 /* Iterate over every type in the given CTF container, user-visible or not.
178    We pass the type ID of each type to the specified callback function.  */
179 
180 int
181 ctf_type_iter_all (ctf_file_t *fp, ctf_type_all_f *func, void *arg)
182 {
183   ctf_id_t id, max = fp->ctf_typemax;
184   int rc, child = (fp->ctf_flags & LCTF_CHILD);
185 
186   for (id = 1; id <= max; id++)
187     {
188       const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
189       if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child),
190 		      LCTF_INFO_ISROOT(fp, tp->ctt_info)
191 		      ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0))
192 	return rc;
193     }
194 
195   return 0;
196 }
197 
198 /* Iterate over every variable in the given CTF container, in arbitrary order.
199    We pass the name of each variable to the specified callback function.  */
200 
201 int
202 ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg)
203 {
204   int rc;
205 
206   if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
207     return ECTF_NOPARENT;
208 
209   if (!(fp->ctf_flags & LCTF_RDWR))
210     {
211       unsigned long i;
212       for (i = 0; i < fp->ctf_nvars; i++)
213 	if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
214 			fp->ctf_vars[i].ctv_type, arg)) != 0)
215 	  return rc;
216     }
217   else
218     {
219       ctf_dvdef_t *dvd;
220 
221       for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
222 	   dvd = ctf_list_next (dvd))
223 	{
224 	  if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
225 	    return rc;
226 	}
227     }
228 
229   return 0;
230 }
231 
232 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
233    RESTRICT nodes until we reach a "base" type node.  This is useful when
234    we want to follow a type ID to a node that has members or a size.  To guard
235    against infinite loops, we implement simplified cycle detection and check
236    each link against itself, the previous node, and the topmost node.
237 
238    Does not drill down through slices to their contained type.  */
239 
240 ctf_id_t
241 ctf_type_resolve (ctf_file_t *fp, ctf_id_t type)
242 {
243   ctf_id_t prev = type, otype = type;
244   ctf_file_t *ofp = fp;
245   const ctf_type_t *tp;
246 
247   if (type == 0)
248     return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
249 
250   while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
251     {
252       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
253 	{
254 	case CTF_K_TYPEDEF:
255 	case CTF_K_VOLATILE:
256 	case CTF_K_CONST:
257 	case CTF_K_RESTRICT:
258 	  if (tp->ctt_type == type || tp->ctt_type == otype
259 	      || tp->ctt_type == prev)
260 	    {
261 	      ctf_dprintf ("type %ld cycle detected\n", otype);
262 	      return (ctf_set_errno (ofp, ECTF_CORRUPT));
263 	    }
264 	  prev = type;
265 	  type = tp->ctt_type;
266 	  break;
267 	default:
268 	  return type;
269 	}
270       if (type == 0)
271 	return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
272     }
273 
274   return CTF_ERR;		/* errno is set for us.  */
275 }
276 
277 /* Like ctf_type_resolve(), but traverse down through slices to their contained
278    type.  */
279 
280 ctf_id_t
281 ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type)
282 {
283   const ctf_type_t *tp;
284 
285   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
286     return -1;
287 
288   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
289     return CTF_ERR;		/* errno is set for us.  */
290 
291   if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
292     return ctf_type_reference (fp, type);
293   return type;
294 }
295 
296 /* Look up a name in the given name table, in the appropriate hash given the
297    kind of the identifier.  The name is a raw, undecorated identifier.  */
298 
299 ctf_id_t ctf_lookup_by_rawname (ctf_file_t *fp, int kind, const char *name)
300 {
301   return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
302 }
303 
304 /* Look up a name in the given name table, in the appropriate hash given the
305    readability state of the dictionary.  The name is a raw, undecorated
306    identifier.  */
307 
308 ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *fp, ctf_names_t *np, const char *name)
309 {
310   ctf_id_t id;
311 
312   if (fp->ctf_flags & LCTF_RDWR)
313     id = (ctf_id_t) ctf_dynhash_lookup (np->ctn_writable, name);
314   else
315     id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
316   return id;
317 }
318 
319 /* Lookup the given type ID and return its name as a new dynamcally-allocated
320    string.  */
321 
322 char *
323 ctf_type_aname (ctf_file_t *fp, ctf_id_t type)
324 {
325   ctf_decl_t cd;
326   ctf_decl_node_t *cdp;
327   ctf_decl_prec_t prec, lp, rp;
328   int ptr, arr;
329   uint32_t k;
330   char *buf;
331 
332   if (fp == NULL && type == CTF_ERR)
333     return NULL;	/* Simplify caller code by permitting CTF_ERR.  */
334 
335   ctf_decl_init (&cd);
336   ctf_decl_push (&cd, fp, type);
337 
338   if (cd.cd_err != 0)
339     {
340       ctf_decl_fini (&cd);
341       ctf_set_errno (fp, cd.cd_err);
342       return NULL;
343     }
344 
345   /* If the type graph's order conflicts with lexical precedence order
346      for pointers or arrays, then we need to surround the declarations at
347      the corresponding lexical precedence with parentheses.  This can
348      result in either a parenthesized pointer (*) as in int (*)() or
349      int (*)[], or in a parenthesized pointer and array as in int (*[])().  */
350 
351   ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
352   arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
353 
354   rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
355   lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
356 
357   k = CTF_K_POINTER;		/* Avoid leading whitespace (see below).  */
358 
359   for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
360     {
361       for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
362 	   cdp != NULL; cdp = ctf_list_next (cdp))
363 	{
364 	  ctf_file_t *rfp = fp;
365 	  const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
366 	  const char *name = ctf_strptr (rfp, tp->ctt_name);
367 
368 	  if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
369 	    ctf_decl_sprintf (&cd, " ");
370 
371 	  if (lp == prec)
372 	    {
373 	      ctf_decl_sprintf (&cd, "(");
374 	      lp = -1;
375 	    }
376 
377 	  switch (cdp->cd_kind)
378 	    {
379 	    case CTF_K_INTEGER:
380 	    case CTF_K_FLOAT:
381 	    case CTF_K_TYPEDEF:
382 	      ctf_decl_sprintf (&cd, "%s", name);
383 	      break;
384 	    case CTF_K_POINTER:
385 	      ctf_decl_sprintf (&cd, "*");
386 	      break;
387 	    case CTF_K_ARRAY:
388 	      ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
389 	      break;
390 	    case CTF_K_FUNCTION:
391 	      ctf_decl_sprintf (&cd, "()");
392 	      break;
393 	    case CTF_K_STRUCT:
394 	    case CTF_K_FORWARD:
395 	      ctf_decl_sprintf (&cd, "struct %s", name);
396 	      break;
397 	    case CTF_K_UNION:
398 	      ctf_decl_sprintf (&cd, "union %s", name);
399 	      break;
400 	    case CTF_K_ENUM:
401 	      ctf_decl_sprintf (&cd, "enum %s", name);
402 	      break;
403 	    case CTF_K_VOLATILE:
404 	      ctf_decl_sprintf (&cd, "volatile");
405 	      break;
406 	    case CTF_K_CONST:
407 	      ctf_decl_sprintf (&cd, "const");
408 	      break;
409 	    case CTF_K_RESTRICT:
410 	      ctf_decl_sprintf (&cd, "restrict");
411 	      break;
412 	    case CTF_K_SLICE:
413 	      /* No representation: just changes encoding of contained type,
414 		 which is not in any case printed.  Skip it.  */
415 	      break;
416 	    }
417 
418 	  k = cdp->cd_kind;
419 	}
420 
421       if (rp == prec)
422 	ctf_decl_sprintf (&cd, ")");
423     }
424 
425   if (cd.cd_enomem)
426     (void) ctf_set_errno (fp, ENOMEM);
427 
428   buf = ctf_decl_buf (&cd);
429 
430   ctf_decl_fini (&cd);
431   return buf;
432 }
433 
434 /* Lookup the given type ID and print a string name for it into buf.  Return
435    the actual number of bytes (not including \0) needed to format the name.  */
436 
437 ssize_t
438 ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
439 {
440   char *str = ctf_type_aname (fp, type);
441   size_t slen;
442 
443   if (str == NULL)
444     return CTF_ERR;			/* errno is set for us.  */
445 
446   slen = strlen (str);
447   snprintf (buf, len, "%s", str);
448   free (str);
449 
450   if (slen >= len)
451     (void) ctf_set_errno (fp, ECTF_NAMELEN);
452 
453   return slen;
454 }
455 
456 /* Lookup the given type ID and print a string name for it into buf.  If buf
457    is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
458 
459 char *
460 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
461 {
462   ssize_t rv = ctf_type_lname (fp, type, buf, len);
463   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
464 }
465 
466 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
467    new dynamcally-allocated string.  */
468 
469 char *
470 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
471 {
472   const ctf_type_t *tp;
473 
474   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
475     return NULL;		/* errno is set for us.  */
476 
477   if (ctf_strraw (fp, tp->ctt_name) != NULL)
478     return strdup (ctf_strraw (fp, tp->ctt_name));
479 
480   return NULL;
481 }
482 
483 /* Resolve the type down to a base type node, and then return the size
484    of the type storage in bytes.  */
485 
486 ssize_t
487 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
488 {
489   const ctf_type_t *tp;
490   ssize_t size;
491   ctf_arinfo_t ar;
492 
493   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
494     return -1;			/* errno is set for us.  */
495 
496   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
497     return -1;			/* errno is set for us.  */
498 
499   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
500     {
501     case CTF_K_POINTER:
502       return fp->ctf_dmodel->ctd_pointer;
503 
504     case CTF_K_FUNCTION:
505       return 0;		/* Function size is only known by symtab.  */
506 
507     case CTF_K_ENUM:
508       return fp->ctf_dmodel->ctd_int;
509 
510     case CTF_K_ARRAY:
511       /* ctf_add_array() does not directly encode the element size, but
512 	 requires the user to multiply to determine the element size.
513 
514 	 If ctf_get_ctt_size() returns nonzero, then use the recorded
515 	 size instead.  */
516 
517       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
518 	return size;
519 
520       if (ctf_array_info (fp, type, &ar) < 0
521 	  || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
522 	return -1;		/* errno is set for us.  */
523 
524       return size * ar.ctr_nelems;
525 
526     default: /* including slices of enums, etc */
527       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
528     }
529 }
530 
531 /* Resolve the type down to a base type node, and then return the alignment
532    needed for the type storage in bytes.
533 
534    XXX may need arch-dependent attention.  */
535 
536 ssize_t
537 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
538 {
539   const ctf_type_t *tp;
540   ctf_file_t *ofp = fp;
541   int kind;
542 
543   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
544     return -1;			/* errno is set for us.  */
545 
546   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
547     return -1;			/* errno is set for us.  */
548 
549   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
550   switch (kind)
551     {
552     case CTF_K_POINTER:
553     case CTF_K_FUNCTION:
554       return fp->ctf_dmodel->ctd_pointer;
555 
556     case CTF_K_ARRAY:
557       {
558 	ctf_arinfo_t r;
559 	if (ctf_array_info (fp, type, &r) < 0)
560 	  return -1;		/* errno is set for us.  */
561 	return (ctf_type_align (fp, r.ctr_contents));
562       }
563 
564     case CTF_K_STRUCT:
565     case CTF_K_UNION:
566       {
567 	size_t align = 0;
568 	ctf_dtdef_t *dtd;
569 
570 	if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
571 	  {
572 	    uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
573 	    ssize_t size, increment;
574 	    const void *vmp;
575 
576 	    (void) ctf_get_ctt_size (fp, tp, &size, &increment);
577 	    vmp = (unsigned char *) tp + increment;
578 
579 	    if (kind == CTF_K_STRUCT)
580 	      n = MIN (n, 1);	/* Only use first member for structs.  */
581 
582 	    if (size < CTF_LSTRUCT_THRESH)
583 	      {
584 		const ctf_member_t *mp = vmp;
585 		for (; n != 0; n--, mp++)
586 		  {
587 		    ssize_t am = ctf_type_align (fp, mp->ctm_type);
588 		    align = MAX (align, (size_t) am);
589 		  }
590 	      }
591 	    else
592 	      {
593 		const ctf_lmember_t *lmp = vmp;
594 		for (; n != 0; n--, lmp++)
595 		  {
596 		    ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
597 		    align = MAX (align, (size_t) am);
598 		  }
599 	      }
600 	  }
601 	else
602 	  {
603 	      ctf_dmdef_t *dmd;
604 
605 	      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
606 		   dmd != NULL; dmd = ctf_list_next (dmd))
607 		{
608 		  ssize_t am = ctf_type_align (fp, dmd->dmd_type);
609 		  align = MAX (align, (size_t) am);
610 		  if (kind == CTF_K_STRUCT)
611 		    break;
612 		}
613 	  }
614 
615 	return align;
616       }
617 
618     case CTF_K_ENUM:
619       return fp->ctf_dmodel->ctd_int;
620 
621     default:  /* including slices of enums, etc */
622       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
623     }
624 }
625 
626 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
627 
628 int
629 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
630 {
631   const ctf_type_t *tp;
632 
633   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
634     return -1;			/* errno is set for us.  */
635 
636   return (LCTF_INFO_KIND (fp, tp->ctt_info));
637 }
638 
639 /* Return the kind (CTF_K_* constant) for the specified type ID.
640    Slices are considered to be of the same kind as the type sliced.  */
641 
642 int
643 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
644 {
645   int kind;
646 
647   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
648     return -1;
649 
650   if (kind == CTF_K_SLICE)
651     {
652       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
653 	return -1;
654       kind = ctf_type_kind_unsliced (fp, type);
655     }
656 
657   return kind;
658 }
659 
660 /* If the type is one that directly references another type (such as POINTER),
661    then return the ID of the type to which it refers.  */
662 
663 ctf_id_t
664 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
665 {
666   ctf_file_t *ofp = fp;
667   const ctf_type_t *tp;
668 
669   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
670     return CTF_ERR;		/* errno is set for us.  */
671 
672   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
673     {
674     case CTF_K_POINTER:
675     case CTF_K_TYPEDEF:
676     case CTF_K_VOLATILE:
677     case CTF_K_CONST:
678     case CTF_K_RESTRICT:
679       return tp->ctt_type;
680       /* Slices store their type in an unusual place.  */
681     case CTF_K_SLICE:
682       {
683 	const ctf_slice_t *sp;
684 	ssize_t increment;
685 	(void) ctf_get_ctt_size (fp, tp, NULL, &increment);
686 	sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
687 	return sp->cts_type;
688       }
689     default:
690       return (ctf_set_errno (ofp, ECTF_NOTREF));
691     }
692 }
693 
694 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
695    pointer to the given type, see if we can compute a pointer to the type
696    resulting from resolving the type down to its base type and use that
697    instead.  This helps with cases where the CTF data includes "struct foo *"
698    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
699 
700    XXX what about parent containers?  */
701 
702 ctf_id_t
703 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
704 {
705   ctf_file_t *ofp = fp;
706   ctf_id_t ntype;
707 
708   if (ctf_lookup_by_id (&fp, type) == NULL)
709     return CTF_ERR;		/* errno is set for us.  */
710 
711   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
712     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
713 
714   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
715     return (ctf_set_errno (ofp, ECTF_NOTYPE));
716 
717   if (ctf_lookup_by_id (&fp, type) == NULL)
718     return (ctf_set_errno (ofp, ECTF_NOTYPE));
719 
720   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
721     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
722 
723   return (ctf_set_errno (ofp, ECTF_NOTYPE));
724 }
725 
726 /* Return the encoding for the specified INTEGER or FLOAT.  */
727 
728 int
729 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
730 {
731   ctf_file_t *ofp = fp;
732   ctf_dtdef_t *dtd;
733   const ctf_type_t *tp;
734   ssize_t increment;
735   uint32_t data;
736 
737   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
738     return -1;			/* errno is set for us.  */
739 
740   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
741     {
742       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
743 	{
744 	case CTF_K_INTEGER:
745 	case CTF_K_FLOAT:
746 	  *ep = dtd->dtd_u.dtu_enc;
747 	  break;
748 	case CTF_K_SLICE:
749 	  {
750 	    const ctf_slice_t *slice;
751 	    ctf_encoding_t underlying_en;
752 	    slice = &dtd->dtd_u.dtu_slice;
753 
754 	    data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
755 	    ep->cte_format = underlying_en.cte_format;
756 	    ep->cte_offset = slice->cts_offset;
757 	    ep->cte_bits = slice->cts_bits;
758 	    break;
759 	  }
760 	default:
761 	  return (ctf_set_errno (ofp, ECTF_NOTINTFP));
762 	}
763       return 0;
764     }
765 
766   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
767 
768   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
769     {
770     case CTF_K_INTEGER:
771       data = *(const uint32_t *) ((uintptr_t) tp + increment);
772       ep->cte_format = CTF_INT_ENCODING (data);
773       ep->cte_offset = CTF_INT_OFFSET (data);
774       ep->cte_bits = CTF_INT_BITS (data);
775       break;
776     case CTF_K_FLOAT:
777       data = *(const uint32_t *) ((uintptr_t) tp + increment);
778       ep->cte_format = CTF_FP_ENCODING (data);
779       ep->cte_offset = CTF_FP_OFFSET (data);
780       ep->cte_bits = CTF_FP_BITS (data);
781       break;
782     case CTF_K_SLICE:
783       {
784 	const ctf_slice_t *slice;
785 	ctf_encoding_t underlying_en;
786 
787 	slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
788 	data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
789 
790 	ep->cte_format = underlying_en.cte_format;
791 	ep->cte_offset = slice->cts_offset;
792 	ep->cte_bits = slice->cts_bits;
793 	break;
794       }
795     default:
796       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
797     }
798 
799   return 0;
800 }
801 
802 int
803 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
804 	      ctf_id_t rtype)
805 {
806   int rval;
807 
808   if (ltype < rtype)
809     rval = -1;
810   else if (ltype > rtype)
811     rval = 1;
812   else
813     rval = 0;
814 
815   if (lfp == rfp)
816     return rval;
817 
818   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
819     lfp = lfp->ctf_parent;
820 
821   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
822     rfp = rfp->ctf_parent;
823 
824   if (lfp < rfp)
825     return -1;
826 
827   if (lfp > rfp)
828     return 1;
829 
830   return rval;
831 }
832 
833 /* Return a boolean value indicating if two types are compatible.  This function
834    returns true if the two types are the same, or if they (or their ultimate
835    base type) have the same encoding properties, or (for structs / unions /
836    enums / forward declarations) if they have the same name and (for structs /
837    unions) member count.  */
838 
839 int
840 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
841 		 ctf_file_t *rfp, ctf_id_t rtype)
842 {
843   const ctf_type_t *ltp, *rtp;
844   ctf_encoding_t le, re;
845   ctf_arinfo_t la, ra;
846   uint32_t lkind, rkind;
847   int same_names = 0;
848 
849   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
850     return 1;
851 
852   ltype = ctf_type_resolve (lfp, ltype);
853   lkind = ctf_type_kind (lfp, ltype);
854 
855   rtype = ctf_type_resolve (rfp, rtype);
856   rkind = ctf_type_kind (rfp, rtype);
857 
858   ltp = ctf_lookup_by_id (&lfp, ltype);
859   rtp = ctf_lookup_by_id (&rfp, rtype);
860 
861   if (ltp != NULL && rtp != NULL)
862     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
863 			  ctf_strptr (rfp, rtp->ctt_name)) == 0);
864 
865   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
866       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
867     return 1;
868 
869   if (lkind != rkind)
870     return 0;
871 
872   switch (lkind)
873     {
874     case CTF_K_INTEGER:
875     case CTF_K_FLOAT:
876       memset (&le, 0, sizeof (le));
877       memset (&re, 0, sizeof (re));
878       return (ctf_type_encoding (lfp, ltype, &le) == 0
879 	      && ctf_type_encoding (rfp, rtype, &re) == 0
880 	      && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
881     case CTF_K_POINTER:
882       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
883 			       rfp, ctf_type_reference (rfp, rtype)));
884     case CTF_K_ARRAY:
885       return (ctf_array_info (lfp, ltype, &la) == 0
886 	      && ctf_array_info (rfp, rtype, &ra) == 0
887 	      && la.ctr_nelems == ra.ctr_nelems
888 	      && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
889 	      && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
890     case CTF_K_STRUCT:
891     case CTF_K_UNION:
892       return (same_names && (ctf_type_size (lfp, ltype)
893 			     == ctf_type_size (rfp, rtype)));
894     case CTF_K_ENUM:
895       {
896 	int lencoded, rencoded;
897 	lencoded = ctf_type_encoding (lfp, ltype, &le);
898 	rencoded = ctf_type_encoding (rfp, rtype, &re);
899 
900 	if ((lencoded != rencoded) ||
901 	    ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
902 	  return 0;
903       }
904       /* FALLTHRU */
905     case CTF_K_FORWARD:
906       return same_names;   /* No other checks required for these type kinds.  */
907     default:
908       return 0;		      /* Should not get here since we did a resolve.  */
909     }
910 }
911 
912 /* Return the type and offset for a given member of a STRUCT or UNION.  */
913 
914 int
915 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
916 		 ctf_membinfo_t *mip)
917 {
918   ctf_file_t *ofp = fp;
919   const ctf_type_t *tp;
920   ctf_dtdef_t *dtd;
921   ssize_t size, increment;
922   uint32_t kind, n;
923 
924   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
925     return -1;			/* errno is set for us.  */
926 
927   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
928     return -1;			/* errno is set for us.  */
929 
930   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
931   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
932 
933   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
934     return (ctf_set_errno (ofp, ECTF_NOTSOU));
935 
936   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
937     {
938       if (size < CTF_LSTRUCT_THRESH)
939 	{
940 	  const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
941 							   increment);
942 
943 	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
944 	    {
945 	      if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
946 		{
947 		  mip->ctm_type = mp->ctm_type;
948 		  mip->ctm_offset = mp->ctm_offset;
949 		  return 0;
950 		}
951 	    }
952 	}
953       else
954 	{
955 	  const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
956 							      increment);
957 
958 	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
959 	    {
960 	      if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
961 		{
962 		  mip->ctm_type = lmp->ctlm_type;
963 		  mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
964 		  return 0;
965 		}
966 	    }
967 	}
968     }
969   else
970     {
971       ctf_dmdef_t *dmd;
972 
973       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
974 	   dmd != NULL; dmd = ctf_list_next (dmd))
975 	{
976 	  if (strcmp (dmd->dmd_name, name) == 0)
977 	    {
978 	      mip->ctm_type = dmd->dmd_type;
979 	      mip->ctm_offset = dmd->dmd_offset;
980 	      return 0;
981 	    }
982 	}
983     }
984 
985   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
986 }
987 
988 /* Return the array type, index, and size information for the specified ARRAY.  */
989 
990 int
991 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
992 {
993   ctf_file_t *ofp = fp;
994   const ctf_type_t *tp;
995   const ctf_array_t *ap;
996   const ctf_dtdef_t *dtd;
997   ssize_t increment;
998 
999   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1000     return -1;			/* errno is set for us.  */
1001 
1002   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1003     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1004 
1005   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1006     {
1007       *arp = dtd->dtd_u.dtu_arr;
1008       return 0;
1009     }
1010 
1011   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1012 
1013   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1014   arp->ctr_contents = ap->cta_contents;
1015   arp->ctr_index = ap->cta_index;
1016   arp->ctr_nelems = ap->cta_nelems;
1017 
1018   return 0;
1019 }
1020 
1021 /* Convert the specified value to the corresponding enum tag name, if a
1022    matching name can be found.  Otherwise NULL is returned.  */
1023 
1024 const char *
1025 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1026 {
1027   ctf_file_t *ofp = fp;
1028   const ctf_type_t *tp;
1029   const ctf_enum_t *ep;
1030   const ctf_dtdef_t *dtd;
1031   ssize_t increment;
1032   uint32_t n;
1033 
1034   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1035     return NULL;		/* errno is set for us.  */
1036 
1037   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1038     return NULL;		/* errno is set for us.  */
1039 
1040   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1041     {
1042       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1043       return NULL;
1044     }
1045 
1046   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1047 
1048   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1049     {
1050       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1051 
1052       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1053 	{
1054 	  if (ep->cte_value == value)
1055 	    return (ctf_strptr (fp, ep->cte_name));
1056 	}
1057     }
1058   else
1059     {
1060       ctf_dmdef_t *dmd;
1061 
1062       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1063 	   dmd != NULL; dmd = ctf_list_next (dmd))
1064 	{
1065 	  if (dmd->dmd_value == value)
1066 	    return dmd->dmd_name;
1067 	}
1068     }
1069 
1070   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1071   return NULL;
1072 }
1073 
1074 /* Convert the specified enum tag name to the corresponding value, if a
1075    matching name can be found.  Otherwise CTF_ERR is returned.  */
1076 
1077 int
1078 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1079 {
1080   ctf_file_t *ofp = fp;
1081   const ctf_type_t *tp;
1082   const ctf_enum_t *ep;
1083   const ctf_dtdef_t *dtd;
1084   ssize_t increment;
1085   uint32_t n;
1086 
1087   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1088     return -1;			/* errno is set for us.  */
1089 
1090   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1091     return -1;			/* errno is set for us.  */
1092 
1093   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1094     {
1095       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1096       return -1;
1097     }
1098 
1099   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1100 
1101   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1102 
1103   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1104     {
1105       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1106 	{
1107 	  if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1108 	    {
1109 	      if (valp != NULL)
1110 		*valp = ep->cte_value;
1111 	      return 0;
1112 	    }
1113 	}
1114     }
1115   else
1116     {
1117       ctf_dmdef_t *dmd;
1118 
1119       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1120 	   dmd != NULL; dmd = ctf_list_next (dmd))
1121 	{
1122 	  if (strcmp (dmd->dmd_name, name) == 0)
1123 	    {
1124 	      if (valp != NULL)
1125 		*valp = dmd->dmd_value;
1126 	      return 0;
1127 	    }
1128 	}
1129     }
1130 
1131   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1132   return -1;
1133 }
1134 
1135 /* Given a type ID relating to a function type, return info on return types and
1136    arg counts for that function.  */
1137 
1138 int
1139 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1140 {
1141   const ctf_type_t *tp;
1142   uint32_t kind;
1143   const uint32_t *args;
1144   const ctf_dtdef_t *dtd;
1145   ssize_t size, increment;
1146 
1147   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1148     return -1;			/* errno is set for us.  */
1149 
1150   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1151     return -1;			/* errno is set for us.  */
1152 
1153   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1154   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1155 
1156   if (kind != CTF_K_FUNCTION)
1157     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1158 
1159   fip->ctc_return = tp->ctt_type;
1160   fip->ctc_flags = 0;
1161   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1162 
1163   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1164     args = (uint32_t *) ((uintptr_t) tp + increment);
1165   else
1166     args = (uint32_t *) dtd->dtd_u.dtu_argv;
1167 
1168   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1169     {
1170       fip->ctc_flags |= CTF_FUNC_VARARG;
1171       fip->ctc_argc--;
1172     }
1173 
1174   return 0;
1175 }
1176 
1177 /* Given a type ID relating to a function type,, return the arguments for the
1178    function.  */
1179 
1180 int
1181 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1182 {
1183   const ctf_type_t *tp;
1184   const uint32_t *args;
1185   const ctf_dtdef_t *dtd;
1186   ssize_t size, increment;
1187   ctf_funcinfo_t f;
1188 
1189   if (ctf_func_type_info (fp, type, &f) < 0)
1190     return -1;			/* errno is set for us.  */
1191 
1192   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1193     return -1;			/* errno is set for us.  */
1194 
1195   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1196     return -1;			/* errno is set for us.  */
1197 
1198   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1199 
1200   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1201     args = (uint32_t *) ((uintptr_t) tp + increment);
1202   else
1203     args = (uint32_t *) dtd->dtd_u.dtu_argv;
1204 
1205   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1206     *argv++ = *args++;
1207 
1208   return 0;
1209 }
1210 
1211 /* Recursively visit the members of any type.  This function is used as the
1212    engine for ctf_type_visit, below.  We resolve the input type, recursively
1213    invoke ourself for each type member if the type is a struct or union, and
1214    then invoke the callback function on the current type.  If any callback
1215    returns non-zero, we abort and percolate the error code back up to the top.  */
1216 
1217 static int
1218 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1219 		 void *arg, const char *name, unsigned long offset, int depth)
1220 {
1221   ctf_id_t otype = type;
1222   const ctf_type_t *tp;
1223   const ctf_dtdef_t *dtd;
1224   ssize_t size, increment;
1225   uint32_t kind, n;
1226   int rc;
1227 
1228   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1229     return -1;			/* errno is set for us.  */
1230 
1231   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1232     return -1;			/* errno is set for us.  */
1233 
1234   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1235     return rc;
1236 
1237   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1238 
1239   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1240     return 0;
1241 
1242   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1243 
1244   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1245     {
1246       if (size < CTF_LSTRUCT_THRESH)
1247 	{
1248 	  const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1249 							   increment);
1250 
1251 	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1252 	    {
1253 	      if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1254 					 func, arg, ctf_strptr (fp,
1255 								mp->ctm_name),
1256 					 offset + mp->ctm_offset,
1257 					 depth + 1)) != 0)
1258 		return rc;
1259 	    }
1260 	}
1261       else
1262 	{
1263 	  const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1264 							      increment);
1265 
1266 	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1267 	    {
1268 	      if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1269 					 func, arg, ctf_strptr (fp,
1270 								lmp->ctlm_name),
1271 					 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1272 					 depth + 1)) != 0)
1273 		return rc;
1274 	    }
1275 	}
1276     }
1277   else
1278     {
1279       ctf_dmdef_t *dmd;
1280 
1281       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1282 	   dmd != NULL; dmd = ctf_list_next (dmd))
1283 	{
1284 	  if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1285 				     dmd->dmd_name, dmd->dmd_offset,
1286 				     depth + 1)) != 0)
1287 	    return rc;
1288 	}
1289     }
1290 
1291   return 0;
1292 }
1293 
1294 /* Recursively visit the members of any type.  We pass the name, member
1295  type, and offset of each member to the specified callback function.  */
1296 int
1297 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1298 {
1299   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1300 }
1301