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