]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf: add ctf_type_kind_forwarded
[binutils.git] / libctf / ctf-types.c
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 dynamically-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               /* Integers, floats, and typedefs must always be named types.  */
383
384               if (name[0] == '\0')
385                 {
386                   ctf_set_errno (fp, ECTF_CORRUPT);
387                   ctf_decl_fini (&cd);
388                   return NULL;
389                 }
390
391               ctf_decl_sprintf (&cd, "%s", name);
392               break;
393             case CTF_K_POINTER:
394               ctf_decl_sprintf (&cd, "*");
395               break;
396             case CTF_K_ARRAY:
397               ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
398               break;
399             case CTF_K_FUNCTION:
400               ctf_decl_sprintf (&cd, "()");
401               break;
402             case CTF_K_STRUCT:
403             case CTF_K_FORWARD:
404               ctf_decl_sprintf (&cd, "struct %s", name);
405               break;
406             case CTF_K_UNION:
407               ctf_decl_sprintf (&cd, "union %s", name);
408               break;
409             case CTF_K_ENUM:
410               ctf_decl_sprintf (&cd, "enum %s", name);
411               break;
412             case CTF_K_VOLATILE:
413               ctf_decl_sprintf (&cd, "volatile");
414               break;
415             case CTF_K_CONST:
416               ctf_decl_sprintf (&cd, "const");
417               break;
418             case CTF_K_RESTRICT:
419               ctf_decl_sprintf (&cd, "restrict");
420               break;
421             case CTF_K_SLICE:
422               /* No representation: just changes encoding of contained type,
423                  which is not in any case printed.  Skip it.  */
424               break;
425             }
426
427           k = cdp->cd_kind;
428         }
429
430       if (rp == prec)
431         ctf_decl_sprintf (&cd, ")");
432     }
433
434   if (cd.cd_enomem)
435     (void) ctf_set_errno (fp, ENOMEM);
436
437   buf = ctf_decl_buf (&cd);
438
439   ctf_decl_fini (&cd);
440   return buf;
441 }
442
443 /* Lookup the given type ID and print a string name for it into buf.  Return
444    the actual number of bytes (not including \0) needed to format the name.  */
445
446 ssize_t
447 ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
448 {
449   char *str = ctf_type_aname (fp, type);
450   size_t slen;
451
452   if (str == NULL)
453     return CTF_ERR;                     /* errno is set for us.  */
454
455   slen = strlen (str);
456   snprintf (buf, len, "%s", str);
457   free (str);
458
459   if (slen >= len)
460     (void) ctf_set_errno (fp, ECTF_NAMELEN);
461
462   return slen;
463 }
464
465 /* Lookup the given type ID and print a string name for it into buf.  If buf
466    is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
467
468 char *
469 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
470 {
471   ssize_t rv = ctf_type_lname (fp, type, buf, len);
472   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
473 }
474
475 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
476    The name will live as long as its ctf_file_t does.  */
477
478 const char *
479 ctf_type_name_raw (ctf_file_t *fp, ctf_id_t type)
480 {
481   const ctf_type_t *tp;
482
483   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
484     return NULL;                /* errno is set for us.  */
485
486   return ctf_strraw (fp, tp->ctt_name);
487 }
488
489 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
490    new dynamically-allocated string.  */
491
492 char *
493 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
494 {
495   const char *name = ctf_type_name_raw (fp, type);
496
497   if (name != NULL)
498     return strdup (name);
499
500   return NULL;
501 }
502
503 /* Resolve the type down to a base type node, and then return the size
504    of the type storage in bytes.  */
505
506 ssize_t
507 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
508 {
509   const ctf_type_t *tp;
510   ssize_t size;
511   ctf_arinfo_t ar;
512
513   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
514     return -1;                  /* errno is set for us.  */
515
516   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
517     return -1;                  /* errno is set for us.  */
518
519   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
520     {
521     case CTF_K_POINTER:
522       return fp->ctf_dmodel->ctd_pointer;
523
524     case CTF_K_FUNCTION:
525       return 0;         /* Function size is only known by symtab.  */
526
527     case CTF_K_ENUM:
528       return fp->ctf_dmodel->ctd_int;
529
530     case CTF_K_ARRAY:
531       /* ctf_add_array() does not directly encode the element size, but
532          requires the user to multiply to determine the element size.
533
534          If ctf_get_ctt_size() returns nonzero, then use the recorded
535          size instead.  */
536
537       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
538         return size;
539
540       if (ctf_array_info (fp, type, &ar) < 0
541           || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
542         return -1;              /* errno is set for us.  */
543
544       return size * ar.ctr_nelems;
545
546     default: /* including slices of enums, etc */
547       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
548     }
549 }
550
551 /* Resolve the type down to a base type node, and then return the alignment
552    needed for the type storage in bytes.
553
554    XXX may need arch-dependent attention.  */
555
556 ssize_t
557 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
558 {
559   const ctf_type_t *tp;
560   ctf_file_t *ofp = fp;
561   int kind;
562
563   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
564     return -1;                  /* errno is set for us.  */
565
566   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
567     return -1;                  /* errno is set for us.  */
568
569   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
570   switch (kind)
571     {
572     case CTF_K_POINTER:
573     case CTF_K_FUNCTION:
574       return fp->ctf_dmodel->ctd_pointer;
575
576     case CTF_K_ARRAY:
577       {
578         ctf_arinfo_t r;
579         if (ctf_array_info (fp, type, &r) < 0)
580           return -1;            /* errno is set for us.  */
581         return (ctf_type_align (fp, r.ctr_contents));
582       }
583
584     case CTF_K_STRUCT:
585     case CTF_K_UNION:
586       {
587         size_t align = 0;
588         ctf_dtdef_t *dtd;
589
590         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
591           {
592             uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
593             ssize_t size, increment;
594             const void *vmp;
595
596             (void) ctf_get_ctt_size (fp, tp, &size, &increment);
597             vmp = (unsigned char *) tp + increment;
598
599             if (kind == CTF_K_STRUCT)
600               n = MIN (n, 1);   /* Only use first member for structs.  */
601
602             if (size < CTF_LSTRUCT_THRESH)
603               {
604                 const ctf_member_t *mp = vmp;
605                 for (; n != 0; n--, mp++)
606                   {
607                     ssize_t am = ctf_type_align (fp, mp->ctm_type);
608                     align = MAX (align, (size_t) am);
609                   }
610               }
611             else
612               {
613                 const ctf_lmember_t *lmp = vmp;
614                 for (; n != 0; n--, lmp++)
615                   {
616                     ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
617                     align = MAX (align, (size_t) am);
618                   }
619               }
620           }
621         else
622           {
623               ctf_dmdef_t *dmd;
624
625               for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
626                    dmd != NULL; dmd = ctf_list_next (dmd))
627                 {
628                   ssize_t am = ctf_type_align (fp, dmd->dmd_type);
629                   align = MAX (align, (size_t) am);
630                   if (kind == CTF_K_STRUCT)
631                     break;
632                 }
633           }
634
635         return align;
636       }
637
638     case CTF_K_ENUM:
639       return fp->ctf_dmodel->ctd_int;
640
641     default:  /* including slices of enums, etc */
642       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
643     }
644 }
645
646 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
647
648 int
649 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
650 {
651   const ctf_type_t *tp;
652
653   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
654     return -1;                  /* errno is set for us.  */
655
656   return (LCTF_INFO_KIND (fp, tp->ctt_info));
657 }
658
659 /* Return the kind (CTF_K_* constant) for the specified type ID.
660    Slices are considered to be of the same kind as the type sliced.  */
661
662 int
663 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
664 {
665   int kind;
666
667   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
668     return -1;
669
670   if (kind == CTF_K_SLICE)
671     {
672       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
673         return -1;
674       kind = ctf_type_kind_unsliced (fp, type);
675     }
676
677   return kind;
678 }
679
680 /* Return the kind of this type, except, for forwards, return the kind of thing
681    this is a forward to.  */
682 int
683 ctf_type_kind_forwarded (ctf_file_t *fp, ctf_id_t type)
684 {
685   int kind;
686   const ctf_type_t *tp;
687
688   if ((kind = ctf_type_kind (fp, type)) < 0)
689     return -1;                  /* errno is set for us.  */
690
691   if (kind != CTF_K_FORWARD)
692     return kind;
693
694   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
695     return -1;                  /* errno is set for us.  */
696
697   return tp->ctt_type;
698 }
699
700 /* If the type is one that directly references another type (such as POINTER),
701    then return the ID of the type to which it refers.  */
702
703 ctf_id_t
704 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
705 {
706   ctf_file_t *ofp = fp;
707   const ctf_type_t *tp;
708
709   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
710     return CTF_ERR;             /* errno is set for us.  */
711
712   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
713     {
714     case CTF_K_POINTER:
715     case CTF_K_TYPEDEF:
716     case CTF_K_VOLATILE:
717     case CTF_K_CONST:
718     case CTF_K_RESTRICT:
719       return tp->ctt_type;
720       /* Slices store their type in an unusual place.  */
721     case CTF_K_SLICE:
722       {
723         ctf_dtdef_t *dtd;
724         const ctf_slice_t *sp;
725
726         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
727           {
728             ssize_t increment;
729
730             (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
731             sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
732           }
733         else
734           sp = &dtd->dtd_u.dtu_slice;
735
736         return sp->cts_type;
737       }
738     default:
739       return (ctf_set_errno (ofp, ECTF_NOTREF));
740     }
741 }
742
743 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
744    pointer to the given type, see if we can compute a pointer to the type
745    resulting from resolving the type down to its base type and use that
746    instead.  This helps with cases where the CTF data includes "struct foo *"
747    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
748
749    XXX what about parent containers?  */
750
751 ctf_id_t
752 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
753 {
754   ctf_file_t *ofp = fp;
755   ctf_id_t ntype;
756
757   if (ctf_lookup_by_id (&fp, type) == NULL)
758     return CTF_ERR;             /* errno is set for us.  */
759
760   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
761     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
762
763   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
764     return (ctf_set_errno (ofp, ECTF_NOTYPE));
765
766   if (ctf_lookup_by_id (&fp, type) == NULL)
767     return (ctf_set_errno (ofp, ECTF_NOTYPE));
768
769   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
770     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
771
772   return (ctf_set_errno (ofp, ECTF_NOTYPE));
773 }
774
775 /* Return the encoding for the specified INTEGER or FLOAT.  */
776
777 int
778 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
779 {
780   ctf_file_t *ofp = fp;
781   ctf_dtdef_t *dtd;
782   const ctf_type_t *tp;
783   ssize_t increment;
784   uint32_t data;
785
786   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
787     return -1;                  /* errno is set for us.  */
788
789   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
790     {
791       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
792         {
793         case CTF_K_INTEGER:
794         case CTF_K_FLOAT:
795           *ep = dtd->dtd_u.dtu_enc;
796           break;
797         case CTF_K_SLICE:
798           {
799             const ctf_slice_t *slice;
800             ctf_encoding_t underlying_en;
801             ctf_id_t underlying;
802
803             slice = &dtd->dtd_u.dtu_slice;
804             underlying = ctf_type_resolve (fp, slice->cts_type);
805             data = ctf_type_encoding (fp, underlying, &underlying_en);
806
807             ep->cte_format = underlying_en.cte_format;
808             ep->cte_offset = slice->cts_offset;
809             ep->cte_bits = slice->cts_bits;
810             break;
811           }
812         default:
813           return (ctf_set_errno (ofp, ECTF_NOTINTFP));
814         }
815       return 0;
816     }
817
818   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
819
820   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
821     {
822     case CTF_K_INTEGER:
823       data = *(const uint32_t *) ((uintptr_t) tp + increment);
824       ep->cte_format = CTF_INT_ENCODING (data);
825       ep->cte_offset = CTF_INT_OFFSET (data);
826       ep->cte_bits = CTF_INT_BITS (data);
827       break;
828     case CTF_K_FLOAT:
829       data = *(const uint32_t *) ((uintptr_t) tp + increment);
830       ep->cte_format = CTF_FP_ENCODING (data);
831       ep->cte_offset = CTF_FP_OFFSET (data);
832       ep->cte_bits = CTF_FP_BITS (data);
833       break;
834     case CTF_K_SLICE:
835       {
836         const ctf_slice_t *slice;
837         ctf_encoding_t underlying_en;
838         ctf_id_t underlying;
839
840         slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
841         underlying = ctf_type_resolve (fp, slice->cts_type);
842         data = ctf_type_encoding (fp, underlying, &underlying_en);
843
844         ep->cte_format = underlying_en.cte_format;
845         ep->cte_offset = slice->cts_offset;
846         ep->cte_bits = slice->cts_bits;
847         break;
848       }
849     default:
850       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
851     }
852
853   return 0;
854 }
855
856 int
857 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
858               ctf_id_t rtype)
859 {
860   int rval;
861
862   if (ltype < rtype)
863     rval = -1;
864   else if (ltype > rtype)
865     rval = 1;
866   else
867     rval = 0;
868
869   if (lfp == rfp)
870     return rval;
871
872   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
873     lfp = lfp->ctf_parent;
874
875   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
876     rfp = rfp->ctf_parent;
877
878   if (lfp < rfp)
879     return -1;
880
881   if (lfp > rfp)
882     return 1;
883
884   return rval;
885 }
886
887 /* Return a boolean value indicating if two types are compatible.  This function
888    returns true if the two types are the same, or if they (or their ultimate
889    base type) have the same encoding properties, or (for structs / unions /
890    enums / forward declarations) if they have the same name and (for structs /
891    unions) member count.  */
892
893 int
894 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
895                  ctf_file_t *rfp, ctf_id_t rtype)
896 {
897   const ctf_type_t *ltp, *rtp;
898   ctf_encoding_t le, re;
899   ctf_arinfo_t la, ra;
900   uint32_t lkind, rkind;
901   int same_names = 0;
902
903   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
904     return 1;
905
906   ltype = ctf_type_resolve (lfp, ltype);
907   lkind = ctf_type_kind (lfp, ltype);
908
909   rtype = ctf_type_resolve (rfp, rtype);
910   rkind = ctf_type_kind (rfp, rtype);
911
912   ltp = ctf_lookup_by_id (&lfp, ltype);
913   rtp = ctf_lookup_by_id (&rfp, rtype);
914
915   if (ltp != NULL && rtp != NULL)
916     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
917                           ctf_strptr (rfp, rtp->ctt_name)) == 0);
918
919   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
920       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
921     return 1;
922
923   if (lkind != rkind)
924     return 0;
925
926   switch (lkind)
927     {
928     case CTF_K_INTEGER:
929     case CTF_K_FLOAT:
930       memset (&le, 0, sizeof (le));
931       memset (&re, 0, sizeof (re));
932       return (ctf_type_encoding (lfp, ltype, &le) == 0
933               && ctf_type_encoding (rfp, rtype, &re) == 0
934               && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
935     case CTF_K_POINTER:
936       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
937                                rfp, ctf_type_reference (rfp, rtype)));
938     case CTF_K_ARRAY:
939       return (ctf_array_info (lfp, ltype, &la) == 0
940               && ctf_array_info (rfp, rtype, &ra) == 0
941               && la.ctr_nelems == ra.ctr_nelems
942               && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
943               && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
944     case CTF_K_STRUCT:
945     case CTF_K_UNION:
946       return (same_names && (ctf_type_size (lfp, ltype)
947                              == ctf_type_size (rfp, rtype)));
948     case CTF_K_ENUM:
949       {
950         int lencoded, rencoded;
951         lencoded = ctf_type_encoding (lfp, ltype, &le);
952         rencoded = ctf_type_encoding (rfp, rtype, &re);
953
954         if ((lencoded != rencoded) ||
955             ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
956           return 0;
957       }
958       /* FALLTHRU */
959     case CTF_K_FORWARD:
960       return same_names;   /* No other checks required for these type kinds.  */
961     default:
962       return 0;               /* Should not get here since we did a resolve.  */
963     }
964 }
965
966 /* Return the type and offset for a given member of a STRUCT or UNION.  */
967
968 int
969 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
970                  ctf_membinfo_t *mip)
971 {
972   ctf_file_t *ofp = fp;
973   const ctf_type_t *tp;
974   ctf_dtdef_t *dtd;
975   ssize_t size, increment;
976   uint32_t kind, n;
977
978   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
979     return -1;                  /* errno is set for us.  */
980
981   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
982     return -1;                  /* errno is set for us.  */
983
984   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
985   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
986
987   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
988     return (ctf_set_errno (ofp, ECTF_NOTSOU));
989
990   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
991     {
992       if (size < CTF_LSTRUCT_THRESH)
993         {
994           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
995                                                            increment);
996
997           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
998             {
999               if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
1000                 {
1001                   mip->ctm_type = mp->ctm_type;
1002                   mip->ctm_offset = mp->ctm_offset;
1003                   return 0;
1004                 }
1005             }
1006         }
1007       else
1008         {
1009           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1010                                                               increment);
1011
1012           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1013             {
1014               if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
1015                 {
1016                   mip->ctm_type = lmp->ctlm_type;
1017                   mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1018                   return 0;
1019                 }
1020             }
1021         }
1022     }
1023   else
1024     {
1025       ctf_dmdef_t *dmd;
1026
1027       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1028            dmd != NULL; dmd = ctf_list_next (dmd))
1029         {
1030           if (strcmp (dmd->dmd_name, name) == 0)
1031             {
1032               mip->ctm_type = dmd->dmd_type;
1033               mip->ctm_offset = dmd->dmd_offset;
1034               return 0;
1035             }
1036         }
1037     }
1038
1039   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1040 }
1041
1042 /* Return the array type, index, and size information for the specified ARRAY.  */
1043
1044 int
1045 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1046 {
1047   ctf_file_t *ofp = fp;
1048   const ctf_type_t *tp;
1049   const ctf_array_t *ap;
1050   const ctf_dtdef_t *dtd;
1051   ssize_t increment;
1052
1053   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1054     return -1;                  /* errno is set for us.  */
1055
1056   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1057     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1058
1059   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1060     {
1061       *arp = dtd->dtd_u.dtu_arr;
1062       return 0;
1063     }
1064
1065   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1066
1067   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1068   arp->ctr_contents = ap->cta_contents;
1069   arp->ctr_index = ap->cta_index;
1070   arp->ctr_nelems = ap->cta_nelems;
1071
1072   return 0;
1073 }
1074
1075 /* Convert the specified value to the corresponding enum tag name, if a
1076    matching name can be found.  Otherwise NULL is returned.  */
1077
1078 const char *
1079 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1080 {
1081   ctf_file_t *ofp = fp;
1082   const ctf_type_t *tp;
1083   const ctf_enum_t *ep;
1084   const ctf_dtdef_t *dtd;
1085   ssize_t increment;
1086   uint32_t n;
1087
1088   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1089     return NULL;                /* errno is set for us.  */
1090
1091   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1092     return NULL;                /* errno is set for us.  */
1093
1094   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1095     {
1096       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1097       return NULL;
1098     }
1099
1100   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1101
1102   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1103     {
1104       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1105
1106       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1107         {
1108           if (ep->cte_value == value)
1109             return (ctf_strptr (fp, ep->cte_name));
1110         }
1111     }
1112   else
1113     {
1114       ctf_dmdef_t *dmd;
1115
1116       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1117            dmd != NULL; dmd = ctf_list_next (dmd))
1118         {
1119           if (dmd->dmd_value == value)
1120             return dmd->dmd_name;
1121         }
1122     }
1123
1124   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1125   return NULL;
1126 }
1127
1128 /* Convert the specified enum tag name to the corresponding value, if a
1129    matching name can be found.  Otherwise CTF_ERR is returned.  */
1130
1131 int
1132 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1133 {
1134   ctf_file_t *ofp = fp;
1135   const ctf_type_t *tp;
1136   const ctf_enum_t *ep;
1137   const ctf_dtdef_t *dtd;
1138   ssize_t increment;
1139   uint32_t n;
1140
1141   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1142     return -1;                  /* errno is set for us.  */
1143
1144   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1145     return -1;                  /* errno is set for us.  */
1146
1147   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1148     {
1149       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1150       return -1;
1151     }
1152
1153   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1154
1155   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1156
1157   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1158     {
1159       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1160         {
1161           if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1162             {
1163               if (valp != NULL)
1164                 *valp = ep->cte_value;
1165               return 0;
1166             }
1167         }
1168     }
1169   else
1170     {
1171       ctf_dmdef_t *dmd;
1172
1173       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1174            dmd != NULL; dmd = ctf_list_next (dmd))
1175         {
1176           if (strcmp (dmd->dmd_name, name) == 0)
1177             {
1178               if (valp != NULL)
1179                 *valp = dmd->dmd_value;
1180               return 0;
1181             }
1182         }
1183     }
1184
1185   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1186   return -1;
1187 }
1188
1189 /* Given a type ID relating to a function type, return info on return types and
1190    arg counts for that function.  */
1191
1192 int
1193 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1194 {
1195   const ctf_type_t *tp;
1196   uint32_t kind;
1197   const uint32_t *args;
1198   const ctf_dtdef_t *dtd;
1199   ssize_t size, increment;
1200
1201   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1202     return -1;                  /* errno is set for us.  */
1203
1204   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1205     return -1;                  /* errno is set for us.  */
1206
1207   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1208   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1209
1210   if (kind != CTF_K_FUNCTION)
1211     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1212
1213   fip->ctc_return = tp->ctt_type;
1214   fip->ctc_flags = 0;
1215   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1216
1217   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1218     args = (uint32_t *) ((uintptr_t) tp + increment);
1219   else
1220     args = dtd->dtd_u.dtu_argv;
1221
1222   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1223     {
1224       fip->ctc_flags |= CTF_FUNC_VARARG;
1225       fip->ctc_argc--;
1226     }
1227
1228   return 0;
1229 }
1230
1231 /* Given a type ID relating to a function type, return the arguments for the
1232    function.  */
1233
1234 int
1235 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1236 {
1237   const ctf_type_t *tp;
1238   const uint32_t *args;
1239   const ctf_dtdef_t *dtd;
1240   ssize_t size, increment;
1241   ctf_funcinfo_t f;
1242
1243   if (ctf_func_type_info (fp, type, &f) < 0)
1244     return -1;                  /* errno is set for us.  */
1245
1246   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1247     return -1;                  /* errno is set for us.  */
1248
1249   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1250     return -1;                  /* errno is set for us.  */
1251
1252   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1253
1254   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1255     args = (uint32_t *) ((uintptr_t) tp + increment);
1256   else
1257     args = dtd->dtd_u.dtu_argv;
1258
1259   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1260     *argv++ = *args++;
1261
1262   return 0;
1263 }
1264
1265 /* Recursively visit the members of any type.  This function is used as the
1266    engine for ctf_type_visit, below.  We resolve the input type, recursively
1267    invoke ourself for each type member if the type is a struct or union, and
1268    then invoke the callback function on the current type.  If any callback
1269    returns non-zero, we abort and percolate the error code back up to the top.  */
1270
1271 static int
1272 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1273                  void *arg, const char *name, unsigned long offset, int depth)
1274 {
1275   ctf_id_t otype = type;
1276   const ctf_type_t *tp;
1277   const ctf_dtdef_t *dtd;
1278   ssize_t size, increment;
1279   uint32_t kind, n;
1280   int rc;
1281
1282   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1283     return -1;                  /* errno is set for us.  */
1284
1285   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1286     return -1;                  /* errno is set for us.  */
1287
1288   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1289     return rc;
1290
1291   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1292
1293   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1294     return 0;
1295
1296   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1297
1298   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1299     {
1300       if (size < CTF_LSTRUCT_THRESH)
1301         {
1302           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1303                                                            increment);
1304
1305           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1306             {
1307               if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1308                                          func, arg, ctf_strptr (fp,
1309                                                                 mp->ctm_name),
1310                                          offset + mp->ctm_offset,
1311                                          depth + 1)) != 0)
1312                 return rc;
1313             }
1314         }
1315       else
1316         {
1317           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1318                                                               increment);
1319
1320           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1321             {
1322               if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1323                                          func, arg, ctf_strptr (fp,
1324                                                                 lmp->ctlm_name),
1325                                          offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1326                                          depth + 1)) != 0)
1327                 return rc;
1328             }
1329         }
1330     }
1331   else
1332     {
1333       ctf_dmdef_t *dmd;
1334
1335       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1336            dmd != NULL; dmd = ctf_list_next (dmd))
1337         {
1338           if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1339                                      dmd->dmd_name, dmd->dmd_offset,
1340                                      depth + 1)) != 0)
1341             return rc;
1342         }
1343     }
1344
1345   return 0;
1346 }
1347
1348 /* Recursively visit the members of any type.  We pass the name, member
1349  type, and offset of each member to the specified callback function.  */
1350 int
1351 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1352 {
1353   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1354 }
This page took 0.098644 seconds and 4 git commands to generate.