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