]> Git Repo - binutils.git/blob - libctf/ctf-types.c
243de9348d3ec01c68faa50f8b797b84611c7663
[binutils.git] / libctf / ctf-types.c
1 /* Type handling functions.
2    Copyright (C) 2019-2021 Free Software Foundation, Inc.
3
4    This file is part of libctf.
5
6    libctf is free software; you can redistribute it and/or modify it under
7    the terms of the GNU General Public License as published by the Free
8    Software Foundation; either version 3, or (at your option) any later
9    version.
10
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14    See the GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; see the file COPYING.  If not see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <ctf-impl.h>
21 #include <assert.h>
22 #include <string.h>
23
24 /* Determine whether a type is a parent or a child.  */
25
26 int
27 ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id)
28 {
29   return (LCTF_TYPE_ISPARENT (fp, id));
30 }
31
32 int
33 ctf_type_ischild (ctf_dict_t * fp, ctf_id_t id)
34 {
35   return (LCTF_TYPE_ISCHILD (fp, id));
36 }
37
38 /* Expand a structure element into the passed-in ctf_lmember_t.  */
39
40 static int
41 ctf_struct_member (ctf_dict_t *fp, ctf_lmember_t *dst, const ctf_type_t *tp,
42                    unsigned char *vlen, size_t vbytes, size_t n)
43 {
44   if (!ctf_assert (fp, n < LCTF_INFO_VLEN (fp, tp->ctt_info)))
45     return -1;                                  /* errno is set for us.  */
46
47   /* Already large.  */
48   if (tp->ctt_size == CTF_LSIZE_SENT)
49     {
50       ctf_lmember_t *lmp = (ctf_lmember_t *) vlen;
51
52       if (!ctf_assert (fp, (n + 1) * sizeof (ctf_lmember_t) <= vbytes))
53         return -1;                              /* errno is set for us.  */
54
55       memcpy (dst, &lmp[n], sizeof (ctf_lmember_t));
56     }
57   else
58     {
59       ctf_member_t *mp = (ctf_member_t *) vlen;
60       dst->ctlm_name = mp[n].ctm_name;
61       dst->ctlm_type = mp[n].ctm_type;
62       dst->ctlm_offsetlo = mp[n].ctm_offset;
63       dst->ctlm_offsethi = 0;
64     }
65   return 0;
66 }
67
68 /* Iterate over the members of a STRUCT or UNION.  We pass the name, member
69    type, and offset of each member to the specified callback function.  */
70
71 int
72 ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
73 {
74   ctf_next_t *i = NULL;
75   ssize_t offset;
76   const char *name;
77   ctf_id_t membtype;
78
79   while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0)
80     {
81       int rc;
82       if ((rc = func (name, membtype, offset, arg)) != 0)
83         {
84           ctf_next_destroy (i);
85           return rc;
86         }
87     }
88   if (ctf_errno (fp) != ECTF_NEXT_END)
89     return -1;                                  /* errno is set for us.  */
90
91   return 0;
92 }
93
94 /* Iterate over the members of a STRUCT or UNION, returning each member's
95    offset and optionally name and member type in turn.  On end-of-iteration,
96    returns -1.  If FLAGS is CTF_MN_RECURSE, recurse into unnamed members.  */
97
98 ssize_t
99 ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
100                  const char **name, ctf_id_t *membtype, int flags)
101 {
102   ctf_dict_t *ofp = fp;
103   uint32_t kind;
104   ssize_t offset;
105   uint32_t max_vlen;
106   ctf_next_t *i = *it;
107
108   if (!i)
109     {
110       const ctf_type_t *tp;
111       ctf_dtdef_t *dtd;
112       ssize_t size;
113       ssize_t increment;
114
115       if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
116         return -1;                      /* errno is set for us.  */
117
118       if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
119         return -1;                      /* errno is set for us.  */
120
121       if ((i = ctf_next_create ()) == NULL)
122         return ctf_set_errno (ofp, ENOMEM);
123       i->cu.ctn_fp = ofp;
124       i->ctn_tp = tp;
125
126       ctf_get_ctt_size (fp, tp, &size, &increment);
127       kind = LCTF_INFO_KIND (fp, tp->ctt_info);
128
129       if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
130         {
131           ctf_next_destroy (i);
132           return (ctf_set_errno (ofp, ECTF_NOTSOU));
133         }
134
135       if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
136         {
137           i->u.ctn_vlen = dtd->dtd_vlen;
138           i->ctn_size = dtd->dtd_vlen_alloc;
139         }
140       else
141         {
142           unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
143
144           i->u.ctn_vlen = (unsigned char *) tp + increment;
145           i->ctn_size = LCTF_VBYTES (fp, kind, size, vlen);;
146         }
147       i->ctn_iter_fun = (void (*) (void)) ctf_member_next;
148       i->ctn_n = 0;
149       *it = i;
150     }
151
152   if ((void (*) (void)) ctf_member_next != i->ctn_iter_fun)
153     return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN));
154
155   if (ofp != i->cu.ctn_fp)
156     return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFP));
157
158   /* Resolve to the native dict of this type.  */
159   if ((fp = ctf_get_dict (ofp, type)) == NULL)
160     return (ctf_set_errno (ofp, ECTF_NOPARENT));
161
162   max_vlen = LCTF_INFO_VLEN (fp, i->ctn_tp->ctt_info);
163
164   /* When we hit an unnamed struct/union member, we set ctn_type to indicate
165      that we are inside one, then return the unnamed member: on the next call,
166      we must skip over top-level member iteration in favour of iteration within
167      the sub-struct until it later turns out that that iteration has ended.  */
168
169  retry:
170   if (!i->ctn_type)
171     {
172       ctf_lmember_t memb;
173       const char *membname;
174
175       if (i->ctn_n == max_vlen)
176         goto end_iter;
177
178       if (ctf_struct_member (fp, &memb, i->ctn_tp, i->u.ctn_vlen, i->ctn_size,
179                              i->ctn_n) < 0)
180         return -1;                              /* errno is set for us.  */
181
182       membname = ctf_strptr (fp, memb.ctlm_name);
183
184       if (name)
185         *name = membname;
186       if (membtype)
187         *membtype = memb.ctlm_type;
188       offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
189
190       if (membname[0] == 0
191           && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
192               || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION))
193         i->ctn_type = memb.ctlm_type;
194       i->ctn_n++;
195
196       /* The callers might want automatic recursive sub-struct traversal.  */
197       if (!(flags & CTF_MN_RECURSE))
198         i->ctn_type = 0;
199
200       /* Sub-struct traversal starting?  Take note of the offset of this member,
201          for later boosting of sub-struct members' offsets.  */
202       if (i->ctn_type)
203         i->ctn_increment = offset;
204     }
205   /* Traversing a sub-struct?  Just return it, with the offset adjusted.  */
206   else
207     {
208       ssize_t ret = ctf_member_next (fp, i->ctn_type, &i->ctn_next, name,
209                                      membtype, flags);
210
211       if (ret >= 0)
212         return ret + i->ctn_increment;
213
214       if (ctf_errno (fp) != ECTF_NEXT_END)
215         {
216           ctf_next_destroy (i);
217           *it = NULL;
218           i->ctn_type = 0;
219           return ret;                           /* errno is set for us.  */
220         }
221
222       if (!ctf_assert (fp, (i->ctn_next == NULL)))
223         return -1;                              /* errno is set for us.  */
224
225       i->ctn_type = 0;
226       /* This sub-struct has ended: on to the next real member.  */
227       goto retry;
228     }
229
230   return offset;
231
232  end_iter:
233   ctf_next_destroy (i);
234   *it = NULL;
235   return ctf_set_errno (ofp, ECTF_NEXT_END);
236 }
237
238 /* Iterate over the members of an ENUM.  We pass the string name and associated
239    integer value of each enum element to the specified callback function.  */
240
241 int
242 ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
243 {
244   ctf_next_t *i = NULL;
245   const char *name;
246   int val;
247
248   while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
249     {
250       int rc;
251       if ((rc = func (name, val, arg)) != 0)
252         {
253           ctf_next_destroy (i);
254           return rc;
255         }
256     }
257   if (ctf_errno (fp) != ECTF_NEXT_END)
258     return -1;                                  /* errno is set for us.  */
259
260   return 0;
261 }
262
263 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
264    NULL at end of iteration or error, and optionally passing back the
265    enumerand's integer VALue.  */
266
267 const char *
268 ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
269                int *val)
270 {
271   ctf_dict_t *ofp = fp;
272   uint32_t kind;
273   const char *name;
274   ctf_next_t *i = *it;
275
276   if (!i)
277     {
278       const ctf_type_t *tp;
279       ctf_dtdef_t *dtd;
280
281       if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
282         return NULL;                    /* errno is set for us.  */
283
284       if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
285         return NULL;                    /* errno is set for us.  */
286
287       if ((i = ctf_next_create ()) == NULL)
288         {
289           ctf_set_errno (ofp, ENOMEM);
290           return NULL;
291         }
292       i->cu.ctn_fp = ofp;
293
294       (void) ctf_get_ctt_size (fp, tp, NULL,
295                                &i->ctn_increment);
296       kind = LCTF_INFO_KIND (fp, tp->ctt_info);
297
298       if (kind != CTF_K_ENUM)
299         {
300           ctf_next_destroy (i);
301           ctf_set_errno (ofp, ECTF_NOTENUM);
302           return NULL;
303         }
304
305       dtd = ctf_dynamic_type (fp, type);
306       i->ctn_iter_fun = (void (*) (void)) ctf_enum_next;
307       i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
308
309       if (dtd == NULL)
310         i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp +
311                                             i->ctn_increment);
312       else
313         i->u.ctn_en = (const ctf_enum_t *) dtd->dtd_vlen;
314
315       *it = i;
316     }
317
318   if ((void (*) (void)) ctf_enum_next != i->ctn_iter_fun)
319     {
320       ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN);
321       return NULL;
322     }
323
324   if (ofp != i->cu.ctn_fp)
325     {
326       ctf_set_errno (ofp, ECTF_NEXT_WRONGFP);
327       return NULL;
328     }
329
330   /* Resolve to the native dict of this type.  */
331   if ((fp = ctf_get_dict (ofp, type)) == NULL)
332     {
333       ctf_set_errno (ofp, ECTF_NOPARENT);
334       return NULL;
335     }
336
337   if (i->ctn_n == 0)
338     goto end_iter;
339
340   name = ctf_strptr (fp, i->u.ctn_en->cte_name);
341   if (val)
342     *val = i->u.ctn_en->cte_value;
343   i->u.ctn_en++;
344   i->ctn_n--;
345
346   return name;
347
348  end_iter:
349   ctf_next_destroy (i);
350   *it = NULL;
351   ctf_set_errno (ofp, ECTF_NEXT_END);
352   return NULL;
353 }
354
355 /* Iterate over every root (user-visible) type in the given CTF dict.
356    We pass the type ID of each type to the specified callback function.
357
358    Does not traverse parent types: you have to do that explicitly.  This is by
359    design, to avoid traversing them more than once if traversing many children
360    of a single parent.  */
361
362 int
363 ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
364 {
365   ctf_next_t *i = NULL;
366   ctf_id_t type;
367
368   while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR)
369     {
370       int rc;
371       if ((rc = func (type, arg)) != 0)
372         {
373           ctf_next_destroy (i);
374           return rc;
375         }
376     }
377   if (ctf_errno (fp) != ECTF_NEXT_END)
378     return -1;                                  /* errno is set for us.  */
379
380   return 0;
381 }
382
383 /* Iterate over every type in the given CTF dict, user-visible or not.
384    We pass the type ID of each type to the specified callback function.
385
386    Does not traverse parent types: you have to do that explicitly.  This is by
387    design, to avoid traversing them more than once if traversing many children
388    of a single parent.  */
389
390 int
391 ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
392 {
393   ctf_next_t *i = NULL;
394   ctf_id_t type;
395   int flag;
396
397   while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR)
398     {
399       int rc;
400       if ((rc = func (type, flag, arg)) != 0)
401         {
402           ctf_next_destroy (i);
403           return rc;
404         }
405     }
406   if (ctf_errno (fp) != ECTF_NEXT_END)
407     return -1;                                  /* errno is set for us.  */
408
409   return 0;
410 }
411
412 /* Iterate over every type in the given CTF dict, optionally including
413    non-user-visible types, returning each type ID and hidden flag in turn.
414    Returns CTF_ERR on end of iteration or error.
415
416    Does not traverse parent types: you have to do that explicitly.  This is by
417    design, to avoid traversing them more than once if traversing many children
418    of a single parent.  */
419
420 ctf_id_t
421 ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden)
422 {
423   ctf_next_t *i = *it;
424
425   if (!i)
426     {
427       if ((i = ctf_next_create ()) == NULL)
428         return ctf_set_errno (fp, ENOMEM);
429
430       i->cu.ctn_fp = fp;
431       i->ctn_type = 1;
432       i->ctn_iter_fun = (void (*) (void)) ctf_type_next;
433       *it = i;
434     }
435
436   if ((void (*) (void)) ctf_type_next != i->ctn_iter_fun)
437     return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
438
439   if (fp != i->cu.ctn_fp)
440     return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
441
442   while (i->ctn_type <= fp->ctf_typemax)
443     {
444       const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, i->ctn_type);
445
446       if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info)))
447         {
448           i->ctn_type++;
449           continue;
450         }
451
452       if (flag)
453         *flag = LCTF_INFO_ISROOT (fp, tp->ctt_info);
454       return LCTF_INDEX_TO_TYPE (fp, i->ctn_type++, fp->ctf_flags & LCTF_CHILD);
455     }
456   ctf_next_destroy (i);
457   *it = NULL;
458   return ctf_set_errno (fp, ECTF_NEXT_END);
459 }
460
461 /* Iterate over every variable in the given CTF dict, in arbitrary order.
462    We pass the name of each variable to the specified callback function.  */
463
464 int
465 ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
466 {
467   ctf_next_t *i = NULL;
468   ctf_id_t type;
469   const char *name;
470
471   while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR)
472     {
473       int rc;
474       if ((rc = func (name, type, arg)) != 0)
475         {
476           ctf_next_destroy (i);
477           return rc;
478         }
479     }
480   if (ctf_errno (fp) != ECTF_NEXT_END)
481     return -1;                                  /* errno is set for us.  */
482
483   return 0;
484 }
485
486 /* Iterate over every variable in the given CTF dict, in arbitrary order,
487    returning the name and type of each variable in turn.  The name argument is
488    not optional.  Returns CTF_ERR on end of iteration or error.  */
489
490 ctf_id_t
491 ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
492 {
493   ctf_next_t *i = *it;
494
495   if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
496     return (ctf_set_errno (fp, ECTF_NOPARENT));
497
498   if (!i)
499     {
500       if ((i = ctf_next_create ()) == NULL)
501         return ctf_set_errno (fp, ENOMEM);
502
503       i->cu.ctn_fp = fp;
504       i->ctn_iter_fun = (void (*) (void)) ctf_variable_next;
505       if (fp->ctf_flags & LCTF_RDWR)
506         i->u.ctn_dvd = ctf_list_next (&fp->ctf_dvdefs);
507       *it = i;
508     }
509
510   if ((void (*) (void)) ctf_variable_next != i->ctn_iter_fun)
511     return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
512
513   if (fp != i->cu.ctn_fp)
514     return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
515
516   if (!(fp->ctf_flags & LCTF_RDWR))
517     {
518       if (i->ctn_n >= fp->ctf_nvars)
519         goto end_iter;
520
521       *name = ctf_strptr (fp, fp->ctf_vars[i->ctn_n].ctv_name);
522       return fp->ctf_vars[i->ctn_n++].ctv_type;
523     }
524   else
525     {
526       ctf_id_t id;
527
528       if (i->u.ctn_dvd == NULL)
529         goto end_iter;
530
531       *name = i->u.ctn_dvd->dvd_name;
532       id = i->u.ctn_dvd->dvd_type;
533       i->u.ctn_dvd = ctf_list_next (i->u.ctn_dvd);
534       return id;
535     }
536
537  end_iter:
538   ctf_next_destroy (i);
539   *it = NULL;
540   return ctf_set_errno (fp, ECTF_NEXT_END);
541 }
542
543 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
544    RESTRICT nodes until we reach a "base" type node.  This is useful when
545    we want to follow a type ID to a node that has members or a size.  To guard
546    against infinite loops, we implement simplified cycle detection and check
547    each link against itself, the previous node, and the topmost node.
548
549    Does not drill down through slices to their contained type.
550
551    Callers of this function must not presume that a type it returns must have a
552    valid ctt_size: forwards do not, and must be separately handled.  */
553
554 ctf_id_t
555 ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
556 {
557   ctf_id_t prev = type, otype = type;
558   ctf_dict_t *ofp = fp;
559   const ctf_type_t *tp;
560
561   if (type == 0)
562     return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
563
564   while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
565     {
566       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
567         {
568         case CTF_K_TYPEDEF:
569         case CTF_K_VOLATILE:
570         case CTF_K_CONST:
571         case CTF_K_RESTRICT:
572           if (tp->ctt_type == type || tp->ctt_type == otype
573               || tp->ctt_type == prev)
574             {
575               ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
576                             otype);
577               return (ctf_set_errno (ofp, ECTF_CORRUPT));
578             }
579           prev = type;
580           type = tp->ctt_type;
581           break;
582         case CTF_K_UNKNOWN:
583           return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
584         default:
585           return type;
586         }
587       if (type == 0)
588         return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
589     }
590
591   return CTF_ERR;               /* errno is set for us.  */
592 }
593
594 /* Like ctf_type_resolve(), but traverse down through slices to their contained
595    type.  */
596
597 ctf_id_t
598 ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
599 {
600   const ctf_type_t *tp;
601
602   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
603     return -1;
604
605   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
606     return CTF_ERR;             /* errno is set for us.  */
607
608   if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
609     return ctf_type_reference (fp, type);
610   return type;
611 }
612
613 /* Return the native dict of a given type: if called on a child and the
614    type is in the parent, return the parent.  Needed if you plan to access
615    the type directly, without using the API.  */
616 ctf_dict_t *
617 ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
618 {
619     if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
620       return fp->ctf_parent;
621
622     return fp;
623 }
624
625 /* Look up a name in the given name table, in the appropriate hash given the
626    kind of the identifier.  The name is a raw, undecorated identifier.  */
627
628 ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
629 {
630   return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
631 }
632
633 /* Look up a name in the given name table, in the appropriate hash given the
634    readability state of the dictionary.  The name is a raw, undecorated
635    identifier.  */
636
637 ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
638 {
639   ctf_id_t id;
640
641   if (fp->ctf_flags & LCTF_RDWR)
642     id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
643   else
644     id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
645   return id;
646 }
647
648 /* Lookup the given type ID and return its name as a new dynamically-allocated
649    string.  */
650
651 char *
652 ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
653 {
654   ctf_decl_t cd;
655   ctf_decl_node_t *cdp;
656   ctf_decl_prec_t prec, lp, rp;
657   int ptr, arr;
658   uint32_t k;
659   char *buf;
660
661   if (fp == NULL && type == CTF_ERR)
662     return NULL;        /* Simplify caller code by permitting CTF_ERR.  */
663
664   ctf_decl_init (&cd);
665   ctf_decl_push (&cd, fp, type);
666
667   if (cd.cd_err != 0)
668     {
669       ctf_decl_fini (&cd);
670       ctf_set_errno (fp, cd.cd_err);
671       return NULL;
672     }
673
674   /* If the type graph's order conflicts with lexical precedence order
675      for pointers or arrays, then we need to surround the declarations at
676      the corresponding lexical precedence with parentheses.  This can
677      result in either a parenthesized pointer (*) as in int (*)() or
678      int (*)[], or in a parenthesized pointer and array as in int (*[])().  */
679
680   ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
681   arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
682
683   rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
684   lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
685
686   k = CTF_K_POINTER;            /* Avoid leading whitespace (see below).  */
687
688   for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
689     {
690       for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
691            cdp != NULL; cdp = ctf_list_next (cdp))
692         {
693           ctf_dict_t *rfp = fp;
694           const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
695           const char *name = ctf_strptr (rfp, tp->ctt_name);
696
697           if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
698             ctf_decl_sprintf (&cd, " ");
699
700           if (lp == prec)
701             {
702               ctf_decl_sprintf (&cd, "(");
703               lp = -1;
704             }
705
706           switch (cdp->cd_kind)
707             {
708             case CTF_K_INTEGER:
709             case CTF_K_FLOAT:
710             case CTF_K_TYPEDEF:
711               /* Integers, floats, and typedefs must always be named types.  */
712
713               if (name[0] == '\0')
714                 {
715                   ctf_set_errno (fp, ECTF_CORRUPT);
716                   ctf_decl_fini (&cd);
717                   return NULL;
718                 }
719
720               ctf_decl_sprintf (&cd, "%s", name);
721               break;
722             case CTF_K_POINTER:
723               ctf_decl_sprintf (&cd, "*");
724               break;
725             case CTF_K_ARRAY:
726               ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
727               break;
728             case CTF_K_FUNCTION:
729               {
730                 size_t i;
731                 ctf_funcinfo_t fi;
732                 ctf_id_t *argv = NULL;
733
734                 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
735                   goto err;             /* errno is set for us.  */
736
737                 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
738                   {
739                     ctf_set_errno (rfp, errno);
740                     goto err;
741                   }
742
743                 if (ctf_func_type_args (rfp, cdp->cd_type,
744                                         fi.ctc_argc, argv) < 0)
745                   goto err;             /* errno is set for us.  */
746
747                 ctf_decl_sprintf (&cd, "(*) (");
748                 for (i = 0; i < fi.ctc_argc; i++)
749                   {
750                     char *arg = ctf_type_aname (rfp, argv[i]);
751
752                     if (arg == NULL)
753                       goto err;         /* errno is set for us.  */
754                     ctf_decl_sprintf (&cd, "%s", arg);
755                     free (arg);
756
757                     if ((i < fi.ctc_argc - 1)
758                         || (fi.ctc_flags & CTF_FUNC_VARARG))
759                       ctf_decl_sprintf (&cd, ", ");
760                   }
761
762                 if (fi.ctc_flags & CTF_FUNC_VARARG)
763                   ctf_decl_sprintf (&cd, "...");
764                 ctf_decl_sprintf (&cd, ")");
765
766                 free (argv);
767                 break;
768
769               err:
770                 free (argv);
771                 ctf_decl_fini (&cd);
772                 return NULL;
773               }
774               break;
775             case CTF_K_STRUCT:
776               ctf_decl_sprintf (&cd, "struct %s", name);
777               break;
778             case CTF_K_UNION:
779               ctf_decl_sprintf (&cd, "union %s", name);
780               break;
781             case CTF_K_ENUM:
782               ctf_decl_sprintf (&cd, "enum %s", name);
783               break;
784             case CTF_K_FORWARD:
785               {
786                 switch (ctf_type_kind_forwarded (fp, cdp->cd_type))
787                   {
788                   case CTF_K_STRUCT:
789                     ctf_decl_sprintf (&cd, "struct %s", name);
790                     break;
791                   case CTF_K_UNION:
792                     ctf_decl_sprintf (&cd, "union %s", name);
793                     break;
794                   case CTF_K_ENUM:
795                     ctf_decl_sprintf (&cd, "enum %s", name);
796                     break;
797                   default:
798                     ctf_set_errno (fp, ECTF_CORRUPT);
799                     ctf_decl_fini (&cd);
800                     return NULL;
801                   }
802                 break;
803               }
804             case CTF_K_VOLATILE:
805               ctf_decl_sprintf (&cd, "volatile");
806               break;
807             case CTF_K_CONST:
808               ctf_decl_sprintf (&cd, "const");
809               break;
810             case CTF_K_RESTRICT:
811               ctf_decl_sprintf (&cd, "restrict");
812               break;
813             case CTF_K_UNKNOWN:
814               if (name[0] == '\0')
815                 ctf_decl_sprintf (&cd, _("(nonrepresentable type)"));
816               else
817                 ctf_decl_sprintf (&cd, _("(nonrepresentable type %s)"),
818                                   name);
819               break;
820             }
821
822           k = cdp->cd_kind;
823         }
824
825       if (rp == prec)
826         ctf_decl_sprintf (&cd, ")");
827     }
828
829   if (cd.cd_enomem)
830     (void) ctf_set_errno (fp, ENOMEM);
831
832   buf = ctf_decl_buf (&cd);
833
834   ctf_decl_fini (&cd);
835   return buf;
836 }
837
838 /* Lookup the given type ID and print a string name for it into buf.  Return
839    the actual number of bytes (not including \0) needed to format the name.  */
840
841 ssize_t
842 ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
843 {
844   char *str = ctf_type_aname (fp, type);
845   size_t slen;
846
847   if (str == NULL)
848     return CTF_ERR;                     /* errno is set for us.  */
849
850   slen = strlen (str);
851   snprintf (buf, len, "%s", str);
852   free (str);
853
854   if (slen >= len)
855     (void) ctf_set_errno (fp, ECTF_NAMELEN);
856
857   return slen;
858 }
859
860 /* Lookup the given type ID and print a string name for it into buf.  If buf
861    is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
862
863 char *
864 ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
865 {
866   ssize_t rv = ctf_type_lname (fp, type, buf, len);
867   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
868 }
869
870 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
871    The name will live as long as its ctf_dict_t does.
872
873    The only decoration is that a NULL return always means an error: nameless
874    types return a null string.  */
875
876 const char *
877 ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
878 {
879   const ctf_type_t *tp;
880
881   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
882     return NULL;                /* errno is set for us.  */
883
884   if (tp->ctt_name == 0)
885     return "";
886
887   return ctf_strraw (fp, tp->ctt_name);
888 }
889
890 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
891    new dynamically-allocated string.  */
892
893 char *
894 ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
895 {
896   const char *name = ctf_type_name_raw (fp, type);
897
898   if (name != NULL)
899     return strdup (name);
900
901   return NULL;
902 }
903
904 /* Resolve the type down to a base type node, and then return the size
905    of the type storage in bytes.  */
906
907 ssize_t
908 ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
909 {
910   ctf_dict_t *ofp = fp;
911   const ctf_type_t *tp;
912   ssize_t size;
913   ctf_arinfo_t ar;
914
915   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
916     return -1;                  /* errno is set for us.  */
917
918   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
919     return -1;                  /* errno is set for us.  */
920
921   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
922     {
923     case CTF_K_POINTER:
924       return fp->ctf_dmodel->ctd_pointer;
925
926     case CTF_K_FUNCTION:
927       return 0;         /* Function size is only known by symtab.  */
928
929     case CTF_K_ENUM:
930       return fp->ctf_dmodel->ctd_int;
931
932     case CTF_K_ARRAY:
933       /* ctf_add_array() does not directly encode the element size, but
934          requires the user to multiply to determine the element size.
935
936          If ctf_get_ctt_size() returns nonzero, then use the recorded
937          size instead.  */
938
939       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
940         return size;
941
942       if (ctf_array_info (ofp, type, &ar) < 0
943           || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
944         return -1;              /* errno is set for us.  */
945
946       return size * ar.ctr_nelems;
947
948     case CTF_K_FORWARD:
949       /* Forwards do not have a meaningful size.  */
950       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
951
952     default: /* including slices of enums, etc */
953       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
954     }
955 }
956
957 /* Resolve the type down to a base type node, and then return the alignment
958    needed for the type storage in bytes.
959
960    XXX may need arch-dependent attention.  */
961
962 ssize_t
963 ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
964 {
965   const ctf_type_t *tp;
966   ctf_dict_t *ofp = fp;
967   int kind;
968
969   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
970     return -1;                  /* errno is set for us.  */
971
972   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
973     return -1;                  /* errno is set for us.  */
974
975   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
976   switch (kind)
977     {
978     case CTF_K_POINTER:
979     case CTF_K_FUNCTION:
980       return fp->ctf_dmodel->ctd_pointer;
981
982     case CTF_K_ARRAY:
983       {
984         ctf_arinfo_t r;
985         if (ctf_array_info (ofp, type, &r) < 0)
986           return -1;            /* errno is set for us.  */
987         return (ctf_type_align (ofp, r.ctr_contents));
988       }
989
990     case CTF_K_STRUCT:
991     case CTF_K_UNION:
992       {
993         size_t align = 0;
994         ctf_dtdef_t *dtd;
995         unsigned char *vlen;
996         uint32_t i = 0, n = LCTF_INFO_VLEN (fp, tp->ctt_info);
997         ssize_t size, increment, vbytes;
998
999         ctf_get_ctt_size (fp, tp, &size, &increment);
1000
1001         if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1002           {
1003             vlen = dtd->dtd_vlen;
1004             vbytes = dtd->dtd_vlen_alloc;
1005           }
1006         else
1007           {
1008             vlen = (unsigned char *) tp + increment;
1009             vbytes = LCTF_VBYTES (fp, kind, size, n);
1010           }
1011
1012         if (kind == CTF_K_STRUCT)
1013           n = MIN (n, 1);       /* Only use first member for structs.  */
1014
1015         for (; n != 0; n--, i++)
1016           {
1017             ctf_lmember_t memb;
1018
1019             if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1020               return -1;                                /* errno is set for us.  */
1021
1022             ssize_t am = ctf_type_align (ofp, memb.ctlm_type);
1023             align = MAX (align, (size_t) am);
1024           }
1025         return align;
1026       }
1027
1028     case CTF_K_ENUM:
1029       return fp->ctf_dmodel->ctd_int;
1030
1031     case CTF_K_FORWARD:
1032       /* Forwards do not have a meaningful alignment.  */
1033       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1034
1035     default:  /* including slices of enums, etc */
1036       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1037     }
1038 }
1039
1040 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
1041
1042 int
1043 ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
1044 {
1045   const ctf_type_t *tp;
1046
1047   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1048     return -1;                  /* errno is set for us.  */
1049
1050   return (LCTF_INFO_KIND (fp, tp->ctt_info));
1051 }
1052
1053 /* Return the kind (CTF_K_* constant) for the specified type ID.
1054    Slices are considered to be of the same kind as the type sliced.  */
1055
1056 int
1057 ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
1058 {
1059   int kind;
1060
1061   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1062     return -1;
1063
1064   if (kind == CTF_K_SLICE)
1065     {
1066       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1067         return -1;
1068       kind = ctf_type_kind_unsliced (fp, type);
1069     }
1070
1071   return kind;
1072 }
1073
1074 /* Return the kind of this type, except, for forwards, return the kind of thing
1075    this is a forward to.  */
1076 int
1077 ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
1078 {
1079   int kind;
1080   const ctf_type_t *tp;
1081
1082   if ((kind = ctf_type_kind (fp, type)) < 0)
1083     return -1;                  /* errno is set for us.  */
1084
1085   if (kind != CTF_K_FORWARD)
1086     return kind;
1087
1088   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1089     return -1;                  /* errno is set for us.  */
1090
1091   return tp->ctt_type;
1092 }
1093
1094 /* If the type is one that directly references another type (such as POINTER),
1095    then return the ID of the type to which it refers.  */
1096
1097 ctf_id_t
1098 ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
1099 {
1100   ctf_dict_t *ofp = fp;
1101   const ctf_type_t *tp;
1102
1103   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1104     return CTF_ERR;             /* errno is set for us.  */
1105
1106   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1107     {
1108     case CTF_K_POINTER:
1109     case CTF_K_TYPEDEF:
1110     case CTF_K_VOLATILE:
1111     case CTF_K_CONST:
1112     case CTF_K_RESTRICT:
1113       return tp->ctt_type;
1114       /* Slices store their type in an unusual place.  */
1115     case CTF_K_SLICE:
1116       {
1117         ctf_dtdef_t *dtd;
1118         const ctf_slice_t *sp;
1119
1120         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1121           {
1122             ssize_t increment;
1123
1124             (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1125             sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1126           }
1127         else
1128           sp = (const ctf_slice_t *) dtd->dtd_vlen;
1129
1130         return sp->cts_type;
1131       }
1132     default:
1133       return (ctf_set_errno (ofp, ECTF_NOTREF));
1134     }
1135 }
1136
1137 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
1138    pointer to the given type, see if we can compute a pointer to the type
1139    resulting from resolving the type down to its base type and use that
1140    instead.  This helps with cases where the CTF data includes "struct foo *"
1141    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1142
1143    XXX what about parent dicts?  */
1144
1145 ctf_id_t
1146 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
1147 {
1148   ctf_dict_t *ofp = fp;
1149   ctf_id_t ntype;
1150
1151   if (ctf_lookup_by_id (&fp, type) == NULL)
1152     return CTF_ERR;             /* errno is set for us.  */
1153
1154   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1155     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1156
1157   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1158     return (ctf_set_errno (ofp, ECTF_NOTYPE));
1159
1160   if (ctf_lookup_by_id (&fp, type) == NULL)
1161     return (ctf_set_errno (ofp, ECTF_NOTYPE));
1162
1163   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1164     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1165
1166   return (ctf_set_errno (ofp, ECTF_NOTYPE));
1167 }
1168
1169 /* Return the encoding for the specified INTEGER, FLOAT, or ENUM.  */
1170
1171 int
1172 ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1173 {
1174   ctf_dict_t *ofp = fp;
1175   ctf_dtdef_t *dtd;
1176   const ctf_type_t *tp;
1177   ssize_t increment;
1178   const unsigned char *vlen;
1179   uint32_t data;
1180
1181   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1182     return -1;                  /* errno is set for us.  */
1183
1184   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1185     vlen = dtd->dtd_vlen;
1186   else
1187     {
1188       ctf_get_ctt_size (fp, tp, NULL, &increment);
1189       vlen = (const unsigned char *) ((uintptr_t) tp + increment);
1190     }
1191
1192   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1193     {
1194     case CTF_K_INTEGER:
1195       data = *(const uint32_t *) vlen;
1196       ep->cte_format = CTF_INT_ENCODING (data);
1197       ep->cte_offset = CTF_INT_OFFSET (data);
1198       ep->cte_bits = CTF_INT_BITS (data);
1199       break;
1200     case CTF_K_FLOAT:
1201       data = *(const uint32_t *) vlen;
1202       ep->cte_format = CTF_FP_ENCODING (data);
1203       ep->cte_offset = CTF_FP_OFFSET (data);
1204       ep->cte_bits = CTF_FP_BITS (data);
1205       break;
1206     case CTF_K_ENUM:
1207       /* v3 only: we must guess at the underlying integral format.  */
1208       ep->cte_format = CTF_INT_SIGNED;
1209       ep->cte_offset = 0;
1210       ep->cte_bits = 0;
1211       break;
1212     case CTF_K_SLICE:
1213       {
1214         const ctf_slice_t *slice;
1215         ctf_encoding_t underlying_en;
1216         ctf_id_t underlying;
1217
1218         slice = (ctf_slice_t *) vlen;
1219         underlying = ctf_type_resolve (fp, slice->cts_type);
1220         if (ctf_type_encoding (fp, underlying, &underlying_en) < 0)
1221           return -1;                            /* errno is set for us.  */
1222
1223         ep->cte_format = underlying_en.cte_format;
1224         ep->cte_offset = slice->cts_offset;
1225         ep->cte_bits = slice->cts_bits;
1226         break;
1227       }
1228     default:
1229       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1230     }
1231
1232   return 0;
1233 }
1234
1235 int
1236 ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
1237               ctf_id_t rtype)
1238 {
1239   int rval;
1240
1241   if (ltype < rtype)
1242     rval = -1;
1243   else if (ltype > rtype)
1244     rval = 1;
1245   else
1246     rval = 0;
1247
1248   if (lfp == rfp)
1249     return rval;
1250
1251   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1252     lfp = lfp->ctf_parent;
1253
1254   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1255     rfp = rfp->ctf_parent;
1256
1257   if (lfp < rfp)
1258     return -1;
1259
1260   if (lfp > rfp)
1261     return 1;
1262
1263   return rval;
1264 }
1265
1266 /* Return a boolean value indicating if two types are compatible.  This function
1267    returns true if the two types are the same, or if they (or their ultimate
1268    base type) have the same encoding properties, or (for structs / unions /
1269    enums / forward declarations) if they have the same name and (for structs /
1270    unions) member count.  */
1271
1272 int
1273 ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1274                  ctf_dict_t *rfp, ctf_id_t rtype)
1275 {
1276   const ctf_type_t *ltp, *rtp;
1277   ctf_encoding_t le, re;
1278   ctf_arinfo_t la, ra;
1279   uint32_t lkind, rkind;
1280   int same_names = 0;
1281
1282   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1283     return 1;
1284
1285   ltype = ctf_type_resolve (lfp, ltype);
1286   lkind = ctf_type_kind (lfp, ltype);
1287
1288   rtype = ctf_type_resolve (rfp, rtype);
1289   rkind = ctf_type_kind (rfp, rtype);
1290
1291   ltp = ctf_lookup_by_id (&lfp, ltype);
1292   rtp = ctf_lookup_by_id (&rfp, rtype);
1293
1294   if (ltp != NULL && rtp != NULL)
1295     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1296                           ctf_strptr (rfp, rtp->ctt_name)) == 0);
1297
1298   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1299       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1300     return 1;
1301
1302   if (lkind != rkind)
1303     return 0;
1304
1305   switch (lkind)
1306     {
1307     case CTF_K_INTEGER:
1308     case CTF_K_FLOAT:
1309       memset (&le, 0, sizeof (le));
1310       memset (&re, 0, sizeof (re));
1311       return (ctf_type_encoding (lfp, ltype, &le) == 0
1312               && ctf_type_encoding (rfp, rtype, &re) == 0
1313               && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1314     case CTF_K_POINTER:
1315       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1316                                rfp, ctf_type_reference (rfp, rtype)));
1317     case CTF_K_ARRAY:
1318       return (ctf_array_info (lfp, ltype, &la) == 0
1319               && ctf_array_info (rfp, rtype, &ra) == 0
1320               && la.ctr_nelems == ra.ctr_nelems
1321               && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1322               && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1323     case CTF_K_STRUCT:
1324     case CTF_K_UNION:
1325       return (same_names && (ctf_type_size (lfp, ltype)
1326                              == ctf_type_size (rfp, rtype)));
1327     case CTF_K_ENUM:
1328       {
1329         int lencoded, rencoded;
1330         lencoded = ctf_type_encoding (lfp, ltype, &le);
1331         rencoded = ctf_type_encoding (rfp, rtype, &re);
1332
1333         if ((lencoded != rencoded) ||
1334             ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1335           return 0;
1336       }
1337       /* FALLTHRU */
1338     case CTF_K_FORWARD:
1339       return same_names;   /* No other checks required for these type kinds.  */
1340     default:
1341       return 0;               /* Should not get here since we did a resolve.  */
1342     }
1343 }
1344
1345 /* Return the number of members in a STRUCT or UNION, or the number of
1346    enumerators in an ENUM.  The count does not include unnamed sub-members.  */
1347
1348 int
1349 ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
1350 {
1351   ctf_dict_t *ofp = fp;
1352   const ctf_type_t *tp;
1353   uint32_t kind;
1354
1355   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1356     return -1;                  /* errno is set for us.  */
1357
1358   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1359     return -1;                  /* errno is set for us.  */
1360
1361   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1362
1363   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1364     return (ctf_set_errno (ofp, ECTF_NOTSUE));
1365
1366   return LCTF_INFO_VLEN (fp, tp->ctt_info);
1367 }
1368
1369 /* Return the type and offset for a given member of a STRUCT or UNION.  */
1370
1371 int
1372 ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
1373                  ctf_membinfo_t *mip)
1374 {
1375   ctf_dict_t *ofp = fp;
1376   const ctf_type_t *tp;
1377   ctf_dtdef_t *dtd;
1378   unsigned char *vlen;
1379   ssize_t size, increment, vbytes;
1380   uint32_t kind, n, i = 0;
1381
1382   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1383     return -1;                  /* errno is set for us.  */
1384
1385   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1386     return -1;                  /* errno is set for us.  */
1387
1388   ctf_get_ctt_size (fp, tp, &size, &increment);
1389   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1390
1391   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1392     return (ctf_set_errno (ofp, ECTF_NOTSOU));
1393
1394   n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1395   if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1396     {
1397       vlen = dtd->dtd_vlen;
1398       vbytes = dtd->dtd_vlen_alloc;
1399     }
1400   else
1401     {
1402       vlen = (unsigned char *) tp + increment;
1403       vbytes = LCTF_VBYTES (fp, kind, size, n);
1404     }
1405
1406   for (; n != 0; n--, i++)
1407     {
1408       ctf_lmember_t memb;
1409       const char *membname;
1410
1411       if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1412         return -1;                              /* errno is set for us.  */
1413
1414       membname = ctf_strptr (fp, memb.ctlm_name);
1415
1416       if (membname[0] == 0
1417           && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
1418               || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION)
1419           && (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0))
1420         return 0;
1421
1422       if (strcmp (membname, name) == 0)
1423         {
1424           mip->ctm_type = memb.ctlm_type;
1425           mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
1426           return 0;
1427         }
1428     }
1429
1430   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1431 }
1432
1433 /* Return the array type, index, and size information for the specified ARRAY.  */
1434
1435 int
1436 ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1437 {
1438   ctf_dict_t *ofp = fp;
1439   const ctf_type_t *tp;
1440   const ctf_array_t *ap;
1441   const ctf_dtdef_t *dtd;
1442   ssize_t increment;
1443
1444   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1445     return -1;                  /* errno is set for us.  */
1446
1447   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1448     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1449
1450   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1451     ap = (const ctf_array_t *) dtd->dtd_vlen;
1452   else
1453     {
1454       ctf_get_ctt_size (fp, tp, NULL, &increment);
1455       ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1456     }
1457   arp->ctr_contents = ap->cta_contents;
1458   arp->ctr_index = ap->cta_index;
1459   arp->ctr_nelems = ap->cta_nelems;
1460
1461   return 0;
1462 }
1463
1464 /* Convert the specified value to the corresponding enum tag name, if a
1465    matching name can be found.  Otherwise NULL is returned.  */
1466
1467 const char *
1468 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1469 {
1470   ctf_dict_t *ofp = fp;
1471   const ctf_type_t *tp;
1472   const ctf_enum_t *ep;
1473   const ctf_dtdef_t *dtd;
1474   ssize_t increment;
1475   uint32_t n;
1476
1477   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1478     return NULL;                /* errno is set for us.  */
1479
1480   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1481     return NULL;                /* errno is set for us.  */
1482
1483   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1484     {
1485       ctf_set_errno (ofp, ECTF_NOTENUM);
1486       return NULL;
1487     }
1488
1489   ctf_get_ctt_size (fp, tp, NULL, &increment);
1490
1491   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1492     ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1493   else
1494     ep = (const ctf_enum_t *) dtd->dtd_vlen;
1495
1496   for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1497     {
1498       if (ep->cte_value == value)
1499         return (ctf_strptr (fp, ep->cte_name));
1500     }
1501
1502   ctf_set_errno (ofp, ECTF_NOENUMNAM);
1503   return NULL;
1504 }
1505
1506 /* Convert the specified enum tag name to the corresponding value, if a
1507    matching name can be found.  Otherwise CTF_ERR is returned.  */
1508
1509 int
1510 ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int *valp)
1511 {
1512   ctf_dict_t *ofp = fp;
1513   const ctf_type_t *tp;
1514   const ctf_enum_t *ep;
1515   const ctf_dtdef_t *dtd;
1516   ssize_t increment;
1517   uint32_t n;
1518
1519   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1520     return -1;                  /* errno is set for us.  */
1521
1522   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1523     return -1;                  /* errno is set for us.  */
1524
1525   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1526     {
1527       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1528       return -1;
1529     }
1530
1531   ctf_get_ctt_size (fp, tp, NULL, &increment);
1532
1533   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1534     ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1535   else
1536     ep = (const ctf_enum_t *) dtd->dtd_vlen;
1537
1538   for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1539     {
1540       if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1541         {
1542           if (valp != NULL)
1543             *valp = ep->cte_value;
1544           return 0;
1545         }
1546     }
1547
1548   ctf_set_errno (ofp, ECTF_NOENUMNAM);
1549   return -1;
1550 }
1551
1552 /* Given a type ID relating to a function type, return info on return types and
1553    arg counts for that function.  */
1554
1555 int
1556 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1557 {
1558   const ctf_type_t *tp;
1559   uint32_t kind;
1560   const uint32_t *args;
1561   const ctf_dtdef_t *dtd;
1562   ssize_t size, increment;
1563
1564   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1565     return -1;                  /* errno is set for us.  */
1566
1567   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1568     return -1;                  /* errno is set for us.  */
1569
1570   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1571   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1572
1573   if (kind != CTF_K_FUNCTION)
1574     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1575
1576   fip->ctc_return = tp->ctt_type;
1577   fip->ctc_flags = 0;
1578   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1579
1580   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1581     args = (uint32_t *) ((uintptr_t) tp + increment);
1582   else
1583     args = (uint32_t *) dtd->dtd_vlen;
1584
1585   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1586     {
1587       fip->ctc_flags |= CTF_FUNC_VARARG;
1588       fip->ctc_argc--;
1589     }
1590
1591   return 0;
1592 }
1593
1594 /* Given a type ID relating to a function type, return the arguments for the
1595    function.  */
1596
1597 int
1598 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1599 {
1600   const ctf_type_t *tp;
1601   const uint32_t *args;
1602   const ctf_dtdef_t *dtd;
1603   ssize_t size, increment;
1604   ctf_funcinfo_t f;
1605
1606   if (ctf_func_type_info (fp, type, &f) < 0)
1607     return -1;                  /* errno is set for us.  */
1608
1609   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1610     return -1;                  /* errno is set for us.  */
1611
1612   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1613     return -1;                  /* errno is set for us.  */
1614
1615   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1616
1617   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1618     args = (uint32_t *) ((uintptr_t) tp + increment);
1619   else
1620     args = (uint32_t *) dtd->dtd_vlen;
1621
1622   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1623     *argv++ = *args++;
1624
1625   return 0;
1626 }
1627
1628 /* Recursively visit the members of any type.  This function is used as the
1629    engine for ctf_type_visit, below.  We resolve the input type, recursively
1630    invoke ourself for each type member if the type is a struct or union, and
1631    then invoke the callback function on the current type.  If any callback
1632    returns non-zero, we abort and percolate the error code back up to the top.  */
1633
1634 static int
1635 ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
1636                  void *arg, const char *name, unsigned long offset, int depth)
1637 {
1638   ctf_id_t otype = type;
1639   const ctf_type_t *tp;
1640   const ctf_dtdef_t *dtd;
1641   unsigned char *vlen;
1642   ssize_t size, increment, vbytes;
1643   uint32_t kind, n, i = 0;
1644   int rc;
1645
1646   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1647     return -1;                  /* errno is set for us.  */
1648
1649   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1650     return -1;                  /* errno is set for us.  */
1651
1652   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1653     return rc;
1654
1655   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1656
1657   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1658     return 0;
1659
1660   ctf_get_ctt_size (fp, tp, &size, &increment);
1661
1662   n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1663   if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1664     {
1665       vlen = dtd->dtd_vlen;
1666       vbytes = dtd->dtd_vlen_alloc;
1667     }
1668   else
1669     {
1670       vlen = (unsigned char *) tp + increment;
1671       vbytes = LCTF_VBYTES (fp, kind, size, n);
1672     }
1673
1674   for (; n != 0; n--, i++)
1675     {
1676       ctf_lmember_t memb;
1677
1678       if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1679         return -1;                              /* errno is set for us.  */
1680
1681       if ((rc = ctf_type_rvisit (fp, memb.ctlm_type,
1682                                  func, arg, ctf_strptr (fp, memb.ctlm_name),
1683                                  offset + (unsigned long) CTF_LMEM_OFFSET (&memb),
1684                                  depth + 1)) != 0)
1685         return rc;
1686     }
1687
1688   return 0;
1689 }
1690
1691 /* Recursively visit the members of any type.  We pass the name, member
1692  type, and offset of each member to the specified callback function.  */
1693 int
1694 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1695 {
1696   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1697 }
This page took 0.113962 seconds and 2 git commands to generate.