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