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