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