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