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