]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf, serialize: functions with no args have a NULL dtd_vlen
[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         default:
583           return type;
584         }
585       if (type == 0)
586         return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
587     }
588
589   return CTF_ERR;               /* errno is set for us.  */
590 }
591
592 /* Like ctf_type_resolve(), but traverse down through slices to their contained
593    type.  */
594
595 ctf_id_t
596 ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
597 {
598   const ctf_type_t *tp;
599
600   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
601     return -1;
602
603   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
604     return CTF_ERR;             /* errno is set for us.  */
605
606   if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
607     return ctf_type_reference (fp, type);
608   return type;
609 }
610
611 /* Return the native dict of a given type: if called on a child and the
612    type is in the parent, return the parent.  Needed if you plan to access
613    the type directly, without using the API.  */
614 ctf_dict_t *
615 ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
616 {
617     if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
618       return fp->ctf_parent;
619
620     return fp;
621 }
622
623 /* Look up a name in the given name table, in the appropriate hash given the
624    kind of the identifier.  The name is a raw, undecorated identifier.  */
625
626 ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
627 {
628   return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
629 }
630
631 /* Look up a name in the given name table, in the appropriate hash given the
632    readability state of the dictionary.  The name is a raw, undecorated
633    identifier.  */
634
635 ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
636 {
637   ctf_id_t id;
638
639   if (fp->ctf_flags & LCTF_RDWR)
640     id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
641   else
642     id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
643   return id;
644 }
645
646 /* Lookup the given type ID and return its name as a new dynamically-allocated
647    string.  */
648
649 char *
650 ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
651 {
652   ctf_decl_t cd;
653   ctf_decl_node_t *cdp;
654   ctf_decl_prec_t prec, lp, rp;
655   int ptr, arr;
656   uint32_t k;
657   char *buf;
658
659   if (fp == NULL && type == CTF_ERR)
660     return NULL;        /* Simplify caller code by permitting CTF_ERR.  */
661
662   ctf_decl_init (&cd);
663   ctf_decl_push (&cd, fp, type);
664
665   if (cd.cd_err != 0)
666     {
667       ctf_decl_fini (&cd);
668       ctf_set_errno (fp, cd.cd_err);
669       return NULL;
670     }
671
672   /* If the type graph's order conflicts with lexical precedence order
673      for pointers or arrays, then we need to surround the declarations at
674      the corresponding lexical precedence with parentheses.  This can
675      result in either a parenthesized pointer (*) as in int (*)() or
676      int (*)[], or in a parenthesized pointer and array as in int (*[])().  */
677
678   ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
679   arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
680
681   rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
682   lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
683
684   k = CTF_K_POINTER;            /* Avoid leading whitespace (see below).  */
685
686   for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
687     {
688       for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
689            cdp != NULL; cdp = ctf_list_next (cdp))
690         {
691           ctf_dict_t *rfp = fp;
692           const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
693           const char *name = ctf_strptr (rfp, tp->ctt_name);
694
695           if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
696             ctf_decl_sprintf (&cd, " ");
697
698           if (lp == prec)
699             {
700               ctf_decl_sprintf (&cd, "(");
701               lp = -1;
702             }
703
704           switch (cdp->cd_kind)
705             {
706             case CTF_K_INTEGER:
707             case CTF_K_FLOAT:
708             case CTF_K_TYPEDEF:
709               /* Integers, floats, and typedefs must always be named types.  */
710
711               if (name[0] == '\0')
712                 {
713                   ctf_set_errno (fp, ECTF_CORRUPT);
714                   ctf_decl_fini (&cd);
715                   return NULL;
716                 }
717
718               ctf_decl_sprintf (&cd, "%s", name);
719               break;
720             case CTF_K_POINTER:
721               ctf_decl_sprintf (&cd, "*");
722               break;
723             case CTF_K_ARRAY:
724               ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
725               break;
726             case CTF_K_FUNCTION:
727               {
728                 size_t i;
729                 ctf_funcinfo_t fi;
730                 ctf_id_t *argv = NULL;
731
732                 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
733                   goto err;             /* errno is set for us.  */
734
735                 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
736                   {
737                     ctf_set_errno (rfp, errno);
738                     goto err;
739                   }
740
741                 if (ctf_func_type_args (rfp, cdp->cd_type,
742                                         fi.ctc_argc, argv) < 0)
743                   goto err;             /* errno is set for us.  */
744
745                 ctf_decl_sprintf (&cd, "(*) (");
746                 for (i = 0; i < fi.ctc_argc; i++)
747                   {
748                     char *arg = ctf_type_aname (rfp, argv[i]);
749
750                     if (arg == NULL)
751                       goto err;         /* errno is set for us.  */
752                     ctf_decl_sprintf (&cd, "%s", arg);
753                     free (arg);
754
755                     if ((i < fi.ctc_argc - 1)
756                         || (fi.ctc_flags & CTF_FUNC_VARARG))
757                       ctf_decl_sprintf (&cd, ", ");
758                   }
759
760                 if (fi.ctc_flags & CTF_FUNC_VARARG)
761                   ctf_decl_sprintf (&cd, "...");
762                 ctf_decl_sprintf (&cd, ")");
763
764                 free (argv);
765                 break;
766
767               err:
768                 free (argv);
769                 ctf_decl_fini (&cd);
770                 return NULL;
771               }
772               break;
773             case CTF_K_STRUCT:
774               ctf_decl_sprintf (&cd, "struct %s", name);
775               break;
776             case CTF_K_UNION:
777               ctf_decl_sprintf (&cd, "union %s", name);
778               break;
779             case CTF_K_ENUM:
780               ctf_decl_sprintf (&cd, "enum %s", name);
781               break;
782             case CTF_K_FORWARD:
783               {
784                 switch (ctf_type_kind_forwarded (fp, cdp->cd_type))
785                   {
786                   case CTF_K_STRUCT:
787                     ctf_decl_sprintf (&cd, "struct %s", name);
788                     break;
789                   case CTF_K_UNION:
790                     ctf_decl_sprintf (&cd, "union %s", name);
791                     break;
792                   case CTF_K_ENUM:
793                     ctf_decl_sprintf (&cd, "enum %s", name);
794                     break;
795                   default:
796                     ctf_set_errno (fp, ECTF_CORRUPT);
797                     ctf_decl_fini (&cd);
798                     return NULL;
799                   }
800                 break;
801               }
802             case CTF_K_VOLATILE:
803               ctf_decl_sprintf (&cd, "volatile");
804               break;
805             case CTF_K_CONST:
806               ctf_decl_sprintf (&cd, "const");
807               break;
808             case CTF_K_RESTRICT:
809               ctf_decl_sprintf (&cd, "restrict");
810               break;
811             }
812
813           k = cdp->cd_kind;
814         }
815
816       if (rp == prec)
817         ctf_decl_sprintf (&cd, ")");
818     }
819
820   if (cd.cd_enomem)
821     (void) ctf_set_errno (fp, ENOMEM);
822
823   buf = ctf_decl_buf (&cd);
824
825   ctf_decl_fini (&cd);
826   return buf;
827 }
828
829 /* Lookup the given type ID and print a string name for it into buf.  Return
830    the actual number of bytes (not including \0) needed to format the name.  */
831
832 ssize_t
833 ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
834 {
835   char *str = ctf_type_aname (fp, type);
836   size_t slen;
837
838   if (str == NULL)
839     return CTF_ERR;                     /* errno is set for us.  */
840
841   slen = strlen (str);
842   snprintf (buf, len, "%s", str);
843   free (str);
844
845   if (slen >= len)
846     (void) ctf_set_errno (fp, ECTF_NAMELEN);
847
848   return slen;
849 }
850
851 /* Lookup the given type ID and print a string name for it into buf.  If buf
852    is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
853
854 char *
855 ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
856 {
857   ssize_t rv = ctf_type_lname (fp, type, buf, len);
858   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
859 }
860
861 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
862    The name will live as long as its ctf_dict_t does.
863
864    The only decoration is that a NULL return always means an error: nameless
865    types return a null string.  */
866
867 const char *
868 ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
869 {
870   const ctf_type_t *tp;
871
872   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
873     return NULL;                /* errno is set for us.  */
874
875   if (tp->ctt_name == 0)
876     return "";
877
878   return ctf_strraw (fp, tp->ctt_name);
879 }
880
881 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
882    new dynamically-allocated string.  */
883
884 char *
885 ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
886 {
887   const char *name = ctf_type_name_raw (fp, type);
888
889   if (name != NULL)
890     return strdup (name);
891
892   return NULL;
893 }
894
895 /* Resolve the type down to a base type node, and then return the size
896    of the type storage in bytes.  */
897
898 ssize_t
899 ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
900 {
901   ctf_dict_t *ofp = fp;
902   const ctf_type_t *tp;
903   ssize_t size;
904   ctf_arinfo_t ar;
905
906   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
907     return -1;                  /* errno is set for us.  */
908
909   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
910     return -1;                  /* errno is set for us.  */
911
912   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
913     {
914     case CTF_K_POINTER:
915       return fp->ctf_dmodel->ctd_pointer;
916
917     case CTF_K_FUNCTION:
918       return 0;         /* Function size is only known by symtab.  */
919
920     case CTF_K_ENUM:
921       return fp->ctf_dmodel->ctd_int;
922
923     case CTF_K_ARRAY:
924       /* ctf_add_array() does not directly encode the element size, but
925          requires the user to multiply to determine the element size.
926
927          If ctf_get_ctt_size() returns nonzero, then use the recorded
928          size instead.  */
929
930       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
931         return size;
932
933       if (ctf_array_info (ofp, type, &ar) < 0
934           || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
935         return -1;              /* errno is set for us.  */
936
937       return size * ar.ctr_nelems;
938
939     case CTF_K_FORWARD:
940       /* Forwards do not have a meaningful size.  */
941       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
942
943     default: /* including slices of enums, etc */
944       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
945     }
946 }
947
948 /* Resolve the type down to a base type node, and then return the alignment
949    needed for the type storage in bytes.
950
951    XXX may need arch-dependent attention.  */
952
953 ssize_t
954 ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
955 {
956   const ctf_type_t *tp;
957   ctf_dict_t *ofp = fp;
958   int kind;
959
960   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
961     return -1;                  /* errno is set for us.  */
962
963   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
964     return -1;                  /* errno is set for us.  */
965
966   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
967   switch (kind)
968     {
969     case CTF_K_POINTER:
970     case CTF_K_FUNCTION:
971       return fp->ctf_dmodel->ctd_pointer;
972
973     case CTF_K_ARRAY:
974       {
975         ctf_arinfo_t r;
976         if (ctf_array_info (ofp, type, &r) < 0)
977           return -1;            /* errno is set for us.  */
978         return (ctf_type_align (ofp, r.ctr_contents));
979       }
980
981     case CTF_K_STRUCT:
982     case CTF_K_UNION:
983       {
984         size_t align = 0;
985         ctf_dtdef_t *dtd;
986         unsigned char *vlen;
987         uint32_t i = 0, n = LCTF_INFO_VLEN (fp, tp->ctt_info);
988         ssize_t size, increment, vbytes;
989
990         ctf_get_ctt_size (fp, tp, &size, &increment);
991
992         if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
993           {
994             vlen = dtd->dtd_vlen;
995             vbytes = dtd->dtd_vlen_alloc;
996           }
997         else
998           {
999             vlen = (unsigned char *) tp + increment;
1000             vbytes = LCTF_VBYTES (fp, kind, size, n);
1001           }
1002
1003         if (kind == CTF_K_STRUCT)
1004           n = MIN (n, 1);       /* Only use first member for structs.  */
1005
1006         for (; n != 0; n--, i++)
1007           {
1008             ctf_lmember_t memb;
1009
1010             if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1011               return -1;                                /* errno is set for us.  */
1012
1013             ssize_t am = ctf_type_align (ofp, memb.ctlm_type);
1014             align = MAX (align, (size_t) am);
1015           }
1016         return align;
1017       }
1018
1019     case CTF_K_ENUM:
1020       return fp->ctf_dmodel->ctd_int;
1021
1022     case CTF_K_FORWARD:
1023       /* Forwards do not have a meaningful alignment.  */
1024       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1025
1026     default:  /* including slices of enums, etc */
1027       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1028     }
1029 }
1030
1031 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
1032
1033 int
1034 ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
1035 {
1036   const ctf_type_t *tp;
1037
1038   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1039     return -1;                  /* errno is set for us.  */
1040
1041   return (LCTF_INFO_KIND (fp, tp->ctt_info));
1042 }
1043
1044 /* Return the kind (CTF_K_* constant) for the specified type ID.
1045    Slices are considered to be of the same kind as the type sliced.  */
1046
1047 int
1048 ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
1049 {
1050   int kind;
1051
1052   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1053     return -1;
1054
1055   if (kind == CTF_K_SLICE)
1056     {
1057       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1058         return -1;
1059       kind = ctf_type_kind_unsliced (fp, type);
1060     }
1061
1062   return kind;
1063 }
1064
1065 /* Return the kind of this type, except, for forwards, return the kind of thing
1066    this is a forward to.  */
1067 int
1068 ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
1069 {
1070   int kind;
1071   const ctf_type_t *tp;
1072
1073   if ((kind = ctf_type_kind (fp, type)) < 0)
1074     return -1;                  /* errno is set for us.  */
1075
1076   if (kind != CTF_K_FORWARD)
1077     return kind;
1078
1079   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1080     return -1;                  /* errno is set for us.  */
1081
1082   return tp->ctt_type;
1083 }
1084
1085 /* If the type is one that directly references another type (such as POINTER),
1086    then return the ID of the type to which it refers.  */
1087
1088 ctf_id_t
1089 ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
1090 {
1091   ctf_dict_t *ofp = fp;
1092   const ctf_type_t *tp;
1093
1094   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1095     return CTF_ERR;             /* errno is set for us.  */
1096
1097   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1098     {
1099     case CTF_K_POINTER:
1100     case CTF_K_TYPEDEF:
1101     case CTF_K_VOLATILE:
1102     case CTF_K_CONST:
1103     case CTF_K_RESTRICT:
1104       return tp->ctt_type;
1105       /* Slices store their type in an unusual place.  */
1106     case CTF_K_SLICE:
1107       {
1108         ctf_dtdef_t *dtd;
1109         const ctf_slice_t *sp;
1110
1111         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1112           {
1113             ssize_t increment;
1114
1115             (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1116             sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1117           }
1118         else
1119           sp = (const ctf_slice_t *) dtd->dtd_vlen;
1120
1121         return sp->cts_type;
1122       }
1123     default:
1124       return (ctf_set_errno (ofp, ECTF_NOTREF));
1125     }
1126 }
1127
1128 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
1129    pointer to the given type, see if we can compute a pointer to the type
1130    resulting from resolving the type down to its base type and use that
1131    instead.  This helps with cases where the CTF data includes "struct foo *"
1132    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1133
1134    XXX what about parent dicts?  */
1135
1136 ctf_id_t
1137 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
1138 {
1139   ctf_dict_t *ofp = fp;
1140   ctf_id_t ntype;
1141
1142   if (ctf_lookup_by_id (&fp, type) == NULL)
1143     return CTF_ERR;             /* errno is set for us.  */
1144
1145   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1146     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1147
1148   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1149     return (ctf_set_errno (ofp, ECTF_NOTYPE));
1150
1151   if (ctf_lookup_by_id (&fp, type) == NULL)
1152     return (ctf_set_errno (ofp, ECTF_NOTYPE));
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   return (ctf_set_errno (ofp, ECTF_NOTYPE));
1158 }
1159
1160 /* Return the encoding for the specified INTEGER, FLOAT, or ENUM.  */
1161
1162 int
1163 ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1164 {
1165   ctf_dict_t *ofp = fp;
1166   ctf_dtdef_t *dtd;
1167   const ctf_type_t *tp;
1168   ssize_t increment;
1169   const unsigned char *vlen;
1170   uint32_t data;
1171
1172   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1173     return -1;                  /* errno is set for us.  */
1174
1175   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1176     vlen = dtd->dtd_vlen;
1177   else
1178     {
1179       ctf_get_ctt_size (fp, tp, NULL, &increment);
1180       vlen = (const unsigned char *) ((uintptr_t) tp + increment);
1181     }
1182
1183   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1184     {
1185     case CTF_K_INTEGER:
1186       data = *(const uint32_t *) vlen;
1187       ep->cte_format = CTF_INT_ENCODING (data);
1188       ep->cte_offset = CTF_INT_OFFSET (data);
1189       ep->cte_bits = CTF_INT_BITS (data);
1190       break;
1191     case CTF_K_FLOAT:
1192       data = *(const uint32_t *) vlen;
1193       ep->cte_format = CTF_FP_ENCODING (data);
1194       ep->cte_offset = CTF_FP_OFFSET (data);
1195       ep->cte_bits = CTF_FP_BITS (data);
1196       break;
1197     case CTF_K_ENUM:
1198       /* v3 only: we must guess at the underlying integral format.  */
1199       ep->cte_format = CTF_INT_SIGNED;
1200       ep->cte_offset = 0;
1201       ep->cte_bits = 0;
1202       break;
1203     case CTF_K_SLICE:
1204       {
1205         const ctf_slice_t *slice;
1206         ctf_encoding_t underlying_en;
1207         ctf_id_t underlying;
1208
1209         slice = (ctf_slice_t *) vlen;
1210         underlying = ctf_type_resolve (fp, slice->cts_type);
1211         if (ctf_type_encoding (fp, underlying, &underlying_en) < 0)
1212           return -1;                            /* errno is set for us.  */
1213
1214         ep->cte_format = underlying_en.cte_format;
1215         ep->cte_offset = slice->cts_offset;
1216         ep->cte_bits = slice->cts_bits;
1217         break;
1218       }
1219     default:
1220       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1221     }
1222
1223   return 0;
1224 }
1225
1226 int
1227 ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
1228               ctf_id_t rtype)
1229 {
1230   int rval;
1231
1232   if (ltype < rtype)
1233     rval = -1;
1234   else if (ltype > rtype)
1235     rval = 1;
1236   else
1237     rval = 0;
1238
1239   if (lfp == rfp)
1240     return rval;
1241
1242   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1243     lfp = lfp->ctf_parent;
1244
1245   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1246     rfp = rfp->ctf_parent;
1247
1248   if (lfp < rfp)
1249     return -1;
1250
1251   if (lfp > rfp)
1252     return 1;
1253
1254   return rval;
1255 }
1256
1257 /* Return a boolean value indicating if two types are compatible.  This function
1258    returns true if the two types are the same, or if they (or their ultimate
1259    base type) have the same encoding properties, or (for structs / unions /
1260    enums / forward declarations) if they have the same name and (for structs /
1261    unions) member count.  */
1262
1263 int
1264 ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1265                  ctf_dict_t *rfp, ctf_id_t rtype)
1266 {
1267   const ctf_type_t *ltp, *rtp;
1268   ctf_encoding_t le, re;
1269   ctf_arinfo_t la, ra;
1270   uint32_t lkind, rkind;
1271   int same_names = 0;
1272
1273   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1274     return 1;
1275
1276   ltype = ctf_type_resolve (lfp, ltype);
1277   lkind = ctf_type_kind (lfp, ltype);
1278
1279   rtype = ctf_type_resolve (rfp, rtype);
1280   rkind = ctf_type_kind (rfp, rtype);
1281
1282   ltp = ctf_lookup_by_id (&lfp, ltype);
1283   rtp = ctf_lookup_by_id (&rfp, rtype);
1284
1285   if (ltp != NULL && rtp != NULL)
1286     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1287                           ctf_strptr (rfp, rtp->ctt_name)) == 0);
1288
1289   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1290       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1291     return 1;
1292
1293   if (lkind != rkind)
1294     return 0;
1295
1296   switch (lkind)
1297     {
1298     case CTF_K_INTEGER:
1299     case CTF_K_FLOAT:
1300       memset (&le, 0, sizeof (le));
1301       memset (&re, 0, sizeof (re));
1302       return (ctf_type_encoding (lfp, ltype, &le) == 0
1303               && ctf_type_encoding (rfp, rtype, &re) == 0
1304               && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1305     case CTF_K_POINTER:
1306       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1307                                rfp, ctf_type_reference (rfp, rtype)));
1308     case CTF_K_ARRAY:
1309       return (ctf_array_info (lfp, ltype, &la) == 0
1310               && ctf_array_info (rfp, rtype, &ra) == 0
1311               && la.ctr_nelems == ra.ctr_nelems
1312               && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1313               && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1314     case CTF_K_STRUCT:
1315     case CTF_K_UNION:
1316       return (same_names && (ctf_type_size (lfp, ltype)
1317                              == ctf_type_size (rfp, rtype)));
1318     case CTF_K_ENUM:
1319       {
1320         int lencoded, rencoded;
1321         lencoded = ctf_type_encoding (lfp, ltype, &le);
1322         rencoded = ctf_type_encoding (rfp, rtype, &re);
1323
1324         if ((lencoded != rencoded) ||
1325             ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1326           return 0;
1327       }
1328       /* FALLTHRU */
1329     case CTF_K_FORWARD:
1330       return same_names;   /* No other checks required for these type kinds.  */
1331     default:
1332       return 0;               /* Should not get here since we did a resolve.  */
1333     }
1334 }
1335
1336 /* Return the number of members in a STRUCT or UNION, or the number of
1337    enumerators in an ENUM.  The count does not include unnamed sub-members.  */
1338
1339 int
1340 ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
1341 {
1342   ctf_dict_t *ofp = fp;
1343   const ctf_type_t *tp;
1344   uint32_t kind;
1345
1346   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1347     return -1;                  /* errno is set for us.  */
1348
1349   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1350     return -1;                  /* errno is set for us.  */
1351
1352   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1353
1354   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1355     return (ctf_set_errno (ofp, ECTF_NOTSUE));
1356
1357   return LCTF_INFO_VLEN (fp, tp->ctt_info);
1358 }
1359
1360 /* Return the type and offset for a given member of a STRUCT or UNION.  */
1361
1362 int
1363 ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
1364                  ctf_membinfo_t *mip)
1365 {
1366   ctf_dict_t *ofp = fp;
1367   const ctf_type_t *tp;
1368   ctf_dtdef_t *dtd;
1369   unsigned char *vlen;
1370   ssize_t size, increment, vbytes;
1371   uint32_t kind, n, i = 0;
1372
1373   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1374     return -1;                  /* errno is set for us.  */
1375
1376   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1377     return -1;                  /* errno is set for us.  */
1378
1379   ctf_get_ctt_size (fp, tp, &size, &increment);
1380   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1381
1382   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1383     return (ctf_set_errno (ofp, ECTF_NOTSOU));
1384
1385   n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1386   if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1387     {
1388       vlen = dtd->dtd_vlen;
1389       vbytes = dtd->dtd_vlen_alloc;
1390     }
1391   else
1392     {
1393       vlen = (unsigned char *) tp + increment;
1394       vbytes = LCTF_VBYTES (fp, kind, size, n);
1395     }
1396
1397   for (; n != 0; n--, i++)
1398     {
1399       ctf_lmember_t memb;
1400       const char *membname;
1401
1402       if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1403         return -1;                              /* errno is set for us.  */
1404
1405       membname = ctf_strptr (fp, memb.ctlm_name);
1406
1407       if (membname[0] == 0
1408           && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
1409               || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION)
1410           && (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0))
1411         return 0;
1412
1413       if (strcmp (membname, name) == 0)
1414         {
1415           mip->ctm_type = memb.ctlm_type;
1416           mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
1417           return 0;
1418         }
1419     }
1420
1421   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1422 }
1423
1424 /* Return the array type, index, and size information for the specified ARRAY.  */
1425
1426 int
1427 ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1428 {
1429   ctf_dict_t *ofp = fp;
1430   const ctf_type_t *tp;
1431   const ctf_array_t *ap;
1432   const ctf_dtdef_t *dtd;
1433   ssize_t increment;
1434
1435   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1436     return -1;                  /* errno is set for us.  */
1437
1438   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1439     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1440
1441   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1442     ap = (const ctf_array_t *) dtd->dtd_vlen;
1443   else
1444     {
1445       ctf_get_ctt_size (fp, tp, NULL, &increment);
1446       ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1447     }
1448   arp->ctr_contents = ap->cta_contents;
1449   arp->ctr_index = ap->cta_index;
1450   arp->ctr_nelems = ap->cta_nelems;
1451
1452   return 0;
1453 }
1454
1455 /* Convert the specified value to the corresponding enum tag name, if a
1456    matching name can be found.  Otherwise NULL is returned.  */
1457
1458 const char *
1459 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1460 {
1461   ctf_dict_t *ofp = fp;
1462   const ctf_type_t *tp;
1463   const ctf_enum_t *ep;
1464   const ctf_dtdef_t *dtd;
1465   ssize_t increment;
1466   uint32_t n;
1467
1468   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1469     return NULL;                /* errno is set for us.  */
1470
1471   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1472     return NULL;                /* errno is set for us.  */
1473
1474   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1475     {
1476       ctf_set_errno (ofp, ECTF_NOTENUM);
1477       return NULL;
1478     }
1479
1480   ctf_get_ctt_size (fp, tp, NULL, &increment);
1481
1482   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1483     ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1484   else
1485     ep = (const ctf_enum_t *) dtd->dtd_vlen;
1486
1487   for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1488     {
1489       if (ep->cte_value == value)
1490         return (ctf_strptr (fp, ep->cte_name));
1491     }
1492
1493   ctf_set_errno (ofp, ECTF_NOENUMNAM);
1494   return NULL;
1495 }
1496
1497 /* Convert the specified enum tag name to the corresponding value, if a
1498    matching name can be found.  Otherwise CTF_ERR is returned.  */
1499
1500 int
1501 ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int *valp)
1502 {
1503   ctf_dict_t *ofp = fp;
1504   const ctf_type_t *tp;
1505   const ctf_enum_t *ep;
1506   const ctf_dtdef_t *dtd;
1507   ssize_t increment;
1508   uint32_t n;
1509
1510   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1511     return -1;                  /* errno is set for us.  */
1512
1513   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1514     return -1;                  /* errno is set for us.  */
1515
1516   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1517     {
1518       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1519       return -1;
1520     }
1521
1522   ctf_get_ctt_size (fp, tp, NULL, &increment);
1523
1524   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1525     ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1526   else
1527     ep = (const ctf_enum_t *) dtd->dtd_vlen;
1528
1529   for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1530     {
1531       if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1532         {
1533           if (valp != NULL)
1534             *valp = ep->cte_value;
1535           return 0;
1536         }
1537     }
1538
1539   ctf_set_errno (ofp, ECTF_NOENUMNAM);
1540   return -1;
1541 }
1542
1543 /* Given a type ID relating to a function type, return info on return types and
1544    arg counts for that function.  */
1545
1546 int
1547 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1548 {
1549   const ctf_type_t *tp;
1550   uint32_t kind;
1551   const uint32_t *args;
1552   const ctf_dtdef_t *dtd;
1553   ssize_t size, increment;
1554
1555   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1556     return -1;                  /* errno is set for us.  */
1557
1558   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1559     return -1;                  /* errno is set for us.  */
1560
1561   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1562   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1563
1564   if (kind != CTF_K_FUNCTION)
1565     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1566
1567   fip->ctc_return = tp->ctt_type;
1568   fip->ctc_flags = 0;
1569   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1570
1571   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1572     args = (uint32_t *) ((uintptr_t) tp + increment);
1573   else
1574     args = (uint32_t *) dtd->dtd_vlen;
1575
1576   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1577     {
1578       fip->ctc_flags |= CTF_FUNC_VARARG;
1579       fip->ctc_argc--;
1580     }
1581
1582   return 0;
1583 }
1584
1585 /* Given a type ID relating to a function type, return the arguments for the
1586    function.  */
1587
1588 int
1589 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1590 {
1591   const ctf_type_t *tp;
1592   const uint32_t *args;
1593   const ctf_dtdef_t *dtd;
1594   ssize_t size, increment;
1595   ctf_funcinfo_t f;
1596
1597   if (ctf_func_type_info (fp, type, &f) < 0)
1598     return -1;                  /* errno is set for us.  */
1599
1600   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1601     return -1;                  /* errno is set for us.  */
1602
1603   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1604     return -1;                  /* errno is set for us.  */
1605
1606   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1607
1608   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1609     args = (uint32_t *) ((uintptr_t) tp + increment);
1610   else
1611     args = (uint32_t *) dtd->dtd_vlen;
1612
1613   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1614     *argv++ = *args++;
1615
1616   return 0;
1617 }
1618
1619 /* Recursively visit the members of any type.  This function is used as the
1620    engine for ctf_type_visit, below.  We resolve the input type, recursively
1621    invoke ourself for each type member if the type is a struct or union, and
1622    then invoke the callback function on the current type.  If any callback
1623    returns non-zero, we abort and percolate the error code back up to the top.  */
1624
1625 static int
1626 ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
1627                  void *arg, const char *name, unsigned long offset, int depth)
1628 {
1629   ctf_id_t otype = type;
1630   const ctf_type_t *tp;
1631   const ctf_dtdef_t *dtd;
1632   unsigned char *vlen;
1633   ssize_t size, increment, vbytes;
1634   uint32_t kind, n, i = 0;
1635   int rc;
1636
1637   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1638     return -1;                  /* errno is set for us.  */
1639
1640   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1641     return -1;                  /* errno is set for us.  */
1642
1643   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1644     return rc;
1645
1646   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1647
1648   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1649     return 0;
1650
1651   ctf_get_ctt_size (fp, tp, &size, &increment);
1652
1653   n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1654   if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1655     {
1656       vlen = dtd->dtd_vlen;
1657       vbytes = dtd->dtd_vlen_alloc;
1658     }
1659   else
1660     {
1661       vlen = (unsigned char *) tp + increment;
1662       vbytes = LCTF_VBYTES (fp, kind, size, n);
1663     }
1664
1665   for (; n != 0; n--, i++)
1666     {
1667       ctf_lmember_t memb;
1668
1669       if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1670         return -1;                              /* errno is set for us.  */
1671
1672       if ((rc = ctf_type_rvisit (fp, memb.ctlm_type,
1673                                  func, arg, ctf_strptr (fp, memb.ctlm_name),
1674                                  offset + (unsigned long) CTF_LMEM_OFFSET (&memb),
1675                                  depth + 1)) != 0)
1676         return rc;
1677     }
1678
1679   return 0;
1680 }
1681
1682 /* Recursively visit the members of any type.  We pass the name, member
1683  type, and offset of each member to the specified callback function.  */
1684 int
1685 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1686 {
1687   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1688 }
This page took 0.11606 seconds and 4 git commands to generate.