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