]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf: add ctf_member_count
[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 number of members in a STRUCT or UNION, or the number of
967    enumerators in an ENUM.  */
968
969 int
970 ctf_member_count (ctf_file_t *fp, ctf_id_t type)
971 {
972   ctf_file_t *ofp = fp;
973   const ctf_type_t *tp;
974   uint32_t kind;
975
976   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
977     return -1;                  /* errno is set for us.  */
978
979   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
980     return -1;                  /* errno is set for us.  */
981
982   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
983
984   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
985     return (ctf_set_errno (ofp, ECTF_NOTSUE));
986
987   return LCTF_INFO_VLEN (fp, tp->ctt_info);
988 }
989
990 /* Return the type and offset for a given member of a STRUCT or UNION.  */
991
992 int
993 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
994                  ctf_membinfo_t *mip)
995 {
996   ctf_file_t *ofp = fp;
997   const ctf_type_t *tp;
998   ctf_dtdef_t *dtd;
999   ssize_t size, increment;
1000   uint32_t kind, n;
1001
1002   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1003     return -1;                  /* errno is set for us.  */
1004
1005   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1006     return -1;                  /* errno is set for us.  */
1007
1008   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1009   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1010
1011   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1012     return (ctf_set_errno (ofp, ECTF_NOTSOU));
1013
1014   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1015     {
1016       if (size < CTF_LSTRUCT_THRESH)
1017         {
1018           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1019                                                            increment);
1020
1021           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1022             {
1023               if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
1024                 {
1025                   mip->ctm_type = mp->ctm_type;
1026                   mip->ctm_offset = mp->ctm_offset;
1027                   return 0;
1028                 }
1029             }
1030         }
1031       else
1032         {
1033           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1034                                                               increment);
1035
1036           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1037             {
1038               if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
1039                 {
1040                   mip->ctm_type = lmp->ctlm_type;
1041                   mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1042                   return 0;
1043                 }
1044             }
1045         }
1046     }
1047   else
1048     {
1049       ctf_dmdef_t *dmd;
1050
1051       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1052            dmd != NULL; dmd = ctf_list_next (dmd))
1053         {
1054           if (strcmp (dmd->dmd_name, name) == 0)
1055             {
1056               mip->ctm_type = dmd->dmd_type;
1057               mip->ctm_offset = dmd->dmd_offset;
1058               return 0;
1059             }
1060         }
1061     }
1062
1063   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1064 }
1065
1066 /* Return the array type, index, and size information for the specified ARRAY.  */
1067
1068 int
1069 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1070 {
1071   ctf_file_t *ofp = fp;
1072   const ctf_type_t *tp;
1073   const ctf_array_t *ap;
1074   const ctf_dtdef_t *dtd;
1075   ssize_t increment;
1076
1077   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1078     return -1;                  /* errno is set for us.  */
1079
1080   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1081     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1082
1083   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1084     {
1085       *arp = dtd->dtd_u.dtu_arr;
1086       return 0;
1087     }
1088
1089   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1090
1091   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1092   arp->ctr_contents = ap->cta_contents;
1093   arp->ctr_index = ap->cta_index;
1094   arp->ctr_nelems = ap->cta_nelems;
1095
1096   return 0;
1097 }
1098
1099 /* Convert the specified value to the corresponding enum tag name, if a
1100    matching name can be found.  Otherwise NULL is returned.  */
1101
1102 const char *
1103 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1104 {
1105   ctf_file_t *ofp = fp;
1106   const ctf_type_t *tp;
1107   const ctf_enum_t *ep;
1108   const ctf_dtdef_t *dtd;
1109   ssize_t increment;
1110   uint32_t n;
1111
1112   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1113     return NULL;                /* errno is set for us.  */
1114
1115   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1116     return NULL;                /* errno is set for us.  */
1117
1118   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1119     {
1120       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1121       return NULL;
1122     }
1123
1124   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1125
1126   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1127     {
1128       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1129
1130       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1131         {
1132           if (ep->cte_value == value)
1133             return (ctf_strptr (fp, ep->cte_name));
1134         }
1135     }
1136   else
1137     {
1138       ctf_dmdef_t *dmd;
1139
1140       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1141            dmd != NULL; dmd = ctf_list_next (dmd))
1142         {
1143           if (dmd->dmd_value == value)
1144             return dmd->dmd_name;
1145         }
1146     }
1147
1148   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1149   return NULL;
1150 }
1151
1152 /* Convert the specified enum tag name to the corresponding value, if a
1153    matching name can be found.  Otherwise CTF_ERR is returned.  */
1154
1155 int
1156 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1157 {
1158   ctf_file_t *ofp = fp;
1159   const ctf_type_t *tp;
1160   const ctf_enum_t *ep;
1161   const ctf_dtdef_t *dtd;
1162   ssize_t increment;
1163   uint32_t n;
1164
1165   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1166     return -1;                  /* errno is set for us.  */
1167
1168   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1169     return -1;                  /* errno is set for us.  */
1170
1171   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1172     {
1173       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1174       return -1;
1175     }
1176
1177   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1178
1179   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1180
1181   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1182     {
1183       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1184         {
1185           if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1186             {
1187               if (valp != NULL)
1188                 *valp = ep->cte_value;
1189               return 0;
1190             }
1191         }
1192     }
1193   else
1194     {
1195       ctf_dmdef_t *dmd;
1196
1197       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1198            dmd != NULL; dmd = ctf_list_next (dmd))
1199         {
1200           if (strcmp (dmd->dmd_name, name) == 0)
1201             {
1202               if (valp != NULL)
1203                 *valp = dmd->dmd_value;
1204               return 0;
1205             }
1206         }
1207     }
1208
1209   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1210   return -1;
1211 }
1212
1213 /* Given a type ID relating to a function type, return info on return types and
1214    arg counts for that function.  */
1215
1216 int
1217 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1218 {
1219   const ctf_type_t *tp;
1220   uint32_t kind;
1221   const uint32_t *args;
1222   const ctf_dtdef_t *dtd;
1223   ssize_t size, increment;
1224
1225   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1226     return -1;                  /* errno is set for us.  */
1227
1228   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1229     return -1;                  /* errno is set for us.  */
1230
1231   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1232   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1233
1234   if (kind != CTF_K_FUNCTION)
1235     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1236
1237   fip->ctc_return = tp->ctt_type;
1238   fip->ctc_flags = 0;
1239   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1240
1241   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1242     args = (uint32_t *) ((uintptr_t) tp + increment);
1243   else
1244     args = dtd->dtd_u.dtu_argv;
1245
1246   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1247     {
1248       fip->ctc_flags |= CTF_FUNC_VARARG;
1249       fip->ctc_argc--;
1250     }
1251
1252   return 0;
1253 }
1254
1255 /* Given a type ID relating to a function type, return the arguments for the
1256    function.  */
1257
1258 int
1259 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1260 {
1261   const ctf_type_t *tp;
1262   const uint32_t *args;
1263   const ctf_dtdef_t *dtd;
1264   ssize_t size, increment;
1265   ctf_funcinfo_t f;
1266
1267   if (ctf_func_type_info (fp, type, &f) < 0)
1268     return -1;                  /* errno is set for us.  */
1269
1270   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1271     return -1;                  /* errno is set for us.  */
1272
1273   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1274     return -1;                  /* errno is set for us.  */
1275
1276   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1277
1278   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1279     args = (uint32_t *) ((uintptr_t) tp + increment);
1280   else
1281     args = dtd->dtd_u.dtu_argv;
1282
1283   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1284     *argv++ = *args++;
1285
1286   return 0;
1287 }
1288
1289 /* Recursively visit the members of any type.  This function is used as the
1290    engine for ctf_type_visit, below.  We resolve the input type, recursively
1291    invoke ourself for each type member if the type is a struct or union, and
1292    then invoke the callback function on the current type.  If any callback
1293    returns non-zero, we abort and percolate the error code back up to the top.  */
1294
1295 static int
1296 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1297                  void *arg, const char *name, unsigned long offset, int depth)
1298 {
1299   ctf_id_t otype = type;
1300   const ctf_type_t *tp;
1301   const ctf_dtdef_t *dtd;
1302   ssize_t size, increment;
1303   uint32_t kind, n;
1304   int rc;
1305
1306   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1307     return -1;                  /* errno is set for us.  */
1308
1309   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1310     return -1;                  /* errno is set for us.  */
1311
1312   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1313     return rc;
1314
1315   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1316
1317   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1318     return 0;
1319
1320   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1321
1322   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1323     {
1324       if (size < CTF_LSTRUCT_THRESH)
1325         {
1326           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1327                                                            increment);
1328
1329           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1330             {
1331               if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1332                                          func, arg, ctf_strptr (fp,
1333                                                                 mp->ctm_name),
1334                                          offset + mp->ctm_offset,
1335                                          depth + 1)) != 0)
1336                 return rc;
1337             }
1338         }
1339       else
1340         {
1341           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1342                                                               increment);
1343
1344           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1345             {
1346               if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1347                                          func, arg, ctf_strptr (fp,
1348                                                                 lmp->ctlm_name),
1349                                          offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1350                                          depth + 1)) != 0)
1351                 return rc;
1352             }
1353         }
1354     }
1355   else
1356     {
1357       ctf_dmdef_t *dmd;
1358
1359       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1360            dmd != NULL; dmd = ctf_list_next (dmd))
1361         {
1362           if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1363                                      dmd->dmd_name, dmd->dmd_offset,
1364                                      depth + 1)) != 0)
1365             return rc;
1366         }
1367     }
1368
1369   return 0;
1370 }
1371
1372 /* Recursively visit the members of any type.  We pass the name, member
1373  type, and offset of each member to the specified callback function.  */
1374 int
1375 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1376 {
1377   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1378 }
This page took 0.1008 seconds and 4 git commands to generate.