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