]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf: eliminate dtd_u, part 1: int/float/slice
[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     {
1524       *arp = dtd->dtd_u.dtu_arr;
1525       return 0;
1526     }
1527
1528   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1529
1530   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1531   arp->ctr_contents = ap->cta_contents;
1532   arp->ctr_index = ap->cta_index;
1533   arp->ctr_nelems = ap->cta_nelems;
1534
1535   return 0;
1536 }
1537
1538 /* Convert the specified value to the corresponding enum tag name, if a
1539    matching name can be found.  Otherwise NULL is returned.  */
1540
1541 const char *
1542 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1543 {
1544   ctf_dict_t *ofp = fp;
1545   const ctf_type_t *tp;
1546   const ctf_enum_t *ep;
1547   const ctf_dtdef_t *dtd;
1548   ssize_t increment;
1549   uint32_t n;
1550
1551   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1552     return NULL;                /* errno is set for us.  */
1553
1554   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1555     return NULL;                /* errno is set for us.  */
1556
1557   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1558     {
1559       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1560       return NULL;
1561     }
1562
1563   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1564
1565   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1566     {
1567       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1568
1569       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1570         {
1571           if (ep->cte_value == value)
1572             return (ctf_strptr (fp, ep->cte_name));
1573         }
1574     }
1575   else
1576     {
1577       ctf_dmdef_t *dmd;
1578
1579       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1580            dmd != NULL; dmd = ctf_list_next (dmd))
1581         {
1582           if (dmd->dmd_value == value)
1583             return dmd->dmd_name;
1584         }
1585     }
1586
1587   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1588   return NULL;
1589 }
1590
1591 /* Convert the specified enum tag name to the corresponding value, if a
1592    matching name can be found.  Otherwise CTF_ERR is returned.  */
1593
1594 int
1595 ctf_enum_value (ctf_dict_t * fp, ctf_id_t type, const char *name, int *valp)
1596 {
1597   ctf_dict_t *ofp = fp;
1598   const ctf_type_t *tp;
1599   const ctf_enum_t *ep;
1600   const ctf_dtdef_t *dtd;
1601   ssize_t increment;
1602   uint32_t n;
1603
1604   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1605     return -1;                  /* errno is set for us.  */
1606
1607   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1608     return -1;                  /* errno is set for us.  */
1609
1610   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1611     {
1612       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1613       return -1;
1614     }
1615
1616   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1617
1618   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1619
1620   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1621     {
1622       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1623         {
1624           if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1625             {
1626               if (valp != NULL)
1627                 *valp = ep->cte_value;
1628               return 0;
1629             }
1630         }
1631     }
1632   else
1633     {
1634       ctf_dmdef_t *dmd;
1635
1636       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1637            dmd != NULL; dmd = ctf_list_next (dmd))
1638         {
1639           if (strcmp (dmd->dmd_name, name) == 0)
1640             {
1641               if (valp != NULL)
1642                 *valp = dmd->dmd_value;
1643               return 0;
1644             }
1645         }
1646     }
1647
1648   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1649   return -1;
1650 }
1651
1652 /* Given a type ID relating to a function type, return info on return types and
1653    arg counts for that function.  */
1654
1655 int
1656 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1657 {
1658   const ctf_type_t *tp;
1659   uint32_t kind;
1660   const uint32_t *args;
1661   const ctf_dtdef_t *dtd;
1662   ssize_t size, increment;
1663
1664   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1665     return -1;                  /* errno is set for us.  */
1666
1667   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1668     return -1;                  /* errno is set for us.  */
1669
1670   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1671   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1672
1673   if (kind != CTF_K_FUNCTION)
1674     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1675
1676   fip->ctc_return = tp->ctt_type;
1677   fip->ctc_flags = 0;
1678   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1679
1680   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1681     args = (uint32_t *) ((uintptr_t) tp + increment);
1682   else
1683     args = dtd->dtd_u.dtu_argv;
1684
1685   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1686     {
1687       fip->ctc_flags |= CTF_FUNC_VARARG;
1688       fip->ctc_argc--;
1689     }
1690
1691   return 0;
1692 }
1693
1694 /* Given a type ID relating to a function type, return the arguments for the
1695    function.  */
1696
1697 int
1698 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1699 {
1700   const ctf_type_t *tp;
1701   const uint32_t *args;
1702   const ctf_dtdef_t *dtd;
1703   ssize_t size, increment;
1704   ctf_funcinfo_t f;
1705
1706   if (ctf_func_type_info (fp, type, &f) < 0)
1707     return -1;                  /* errno is set for us.  */
1708
1709   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1710     return -1;                  /* errno is set for us.  */
1711
1712   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1713     return -1;                  /* errno is set for us.  */
1714
1715   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1716
1717   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1718     args = (uint32_t *) ((uintptr_t) tp + increment);
1719   else
1720     args = dtd->dtd_u.dtu_argv;
1721
1722   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1723     *argv++ = *args++;
1724
1725   return 0;
1726 }
1727
1728 /* Recursively visit the members of any type.  This function is used as the
1729    engine for ctf_type_visit, below.  We resolve the input type, recursively
1730    invoke ourself for each type member if the type is a struct or union, and
1731    then invoke the callback function on the current type.  If any callback
1732    returns non-zero, we abort and percolate the error code back up to the top.  */
1733
1734 static int
1735 ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
1736                  void *arg, const char *name, unsigned long offset, int depth)
1737 {
1738   ctf_id_t otype = type;
1739   const ctf_type_t *tp;
1740   const ctf_dtdef_t *dtd;
1741   ssize_t size, increment;
1742   uint32_t kind, n;
1743   int rc;
1744
1745   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1746     return -1;                  /* errno is set for us.  */
1747
1748   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1749     return -1;                  /* errno is set for us.  */
1750
1751   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1752     return rc;
1753
1754   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1755
1756   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1757     return 0;
1758
1759   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1760
1761   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1762     {
1763       if (size < CTF_LSTRUCT_THRESH)
1764         {
1765           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1766                                                            increment);
1767
1768           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1769             {
1770               if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1771                                          func, arg, ctf_strptr (fp,
1772                                                                 mp->ctm_name),
1773                                          offset + mp->ctm_offset,
1774                                          depth + 1)) != 0)
1775                 return rc;
1776             }
1777         }
1778       else
1779         {
1780           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1781                                                               increment);
1782
1783           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1784             {
1785               if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1786                                          func, arg, ctf_strptr (fp,
1787                                                                 lmp->ctlm_name),
1788                                          offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1789                                          depth + 1)) != 0)
1790                 return rc;
1791             }
1792         }
1793     }
1794   else
1795     {
1796       ctf_dmdef_t *dmd;
1797
1798       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1799            dmd != NULL; dmd = ctf_list_next (dmd))
1800         {
1801           if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1802                                      dmd->dmd_name, dmd->dmd_offset,
1803                                      depth + 1)) != 0)
1804             return rc;
1805         }
1806     }
1807
1808   return 0;
1809 }
1810
1811 /* Recursively visit the members of any type.  We pass the name, member
1812  type, and offset of each member to the specified callback function.  */
1813 int
1814 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1815 {
1816   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1817 }
This page took 0.126259 seconds and 4 git commands to generate.