]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf, ld: fix formatting of forwards to unions and enums
[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 const char *
928 ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
929 {
930   const ctf_type_t *tp;
931
932   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
933     return NULL;                /* errno is set for us.  */
934
935   return ctf_strraw (fp, tp->ctt_name);
936 }
937
938 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
939    new dynamically-allocated string.  */
940
941 char *
942 ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
943 {
944   const char *name = ctf_type_name_raw (fp, type);
945
946   if (name != NULL)
947     return strdup (name);
948
949   return NULL;
950 }
951
952 /* Resolve the type down to a base type node, and then return the size
953    of the type storage in bytes.  */
954
955 ssize_t
956 ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
957 {
958   ctf_dict_t *ofp = fp;
959   const ctf_type_t *tp;
960   ssize_t size;
961   ctf_arinfo_t ar;
962
963   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
964     return -1;                  /* errno is set for us.  */
965
966   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
967     return -1;                  /* errno is set for us.  */
968
969   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
970     {
971     case CTF_K_POINTER:
972       return fp->ctf_dmodel->ctd_pointer;
973
974     case CTF_K_FUNCTION:
975       return 0;         /* Function size is only known by symtab.  */
976
977     case CTF_K_ENUM:
978       return fp->ctf_dmodel->ctd_int;
979
980     case CTF_K_ARRAY:
981       /* ctf_add_array() does not directly encode the element size, but
982          requires the user to multiply to determine the element size.
983
984          If ctf_get_ctt_size() returns nonzero, then use the recorded
985          size instead.  */
986
987       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
988         return size;
989
990       if (ctf_array_info (ofp, type, &ar) < 0
991           || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
992         return -1;              /* errno is set for us.  */
993
994       return size * ar.ctr_nelems;
995
996     case CTF_K_FORWARD:
997       /* Forwards do not have a meaningful size.  */
998       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
999
1000     default: /* including slices of enums, etc */
1001       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1002     }
1003 }
1004
1005 /* Resolve the type down to a base type node, and then return the alignment
1006    needed for the type storage in bytes.
1007
1008    XXX may need arch-dependent attention.  */
1009
1010 ssize_t
1011 ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
1012 {
1013   const ctf_type_t *tp;
1014   ctf_dict_t *ofp = fp;
1015   int kind;
1016
1017   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1018     return -1;                  /* errno is set for us.  */
1019
1020   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1021     return -1;                  /* errno is set for us.  */
1022
1023   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1024   switch (kind)
1025     {
1026     case CTF_K_POINTER:
1027     case CTF_K_FUNCTION:
1028       return fp->ctf_dmodel->ctd_pointer;
1029
1030     case CTF_K_ARRAY:
1031       {
1032         ctf_arinfo_t r;
1033         if (ctf_array_info (ofp, type, &r) < 0)
1034           return -1;            /* errno is set for us.  */
1035         return (ctf_type_align (ofp, r.ctr_contents));
1036       }
1037
1038     case CTF_K_STRUCT:
1039     case CTF_K_UNION:
1040       {
1041         size_t align = 0;
1042         ctf_dtdef_t *dtd;
1043
1044         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1045           {
1046             uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1047             ssize_t size, increment;
1048             const void *vmp;
1049
1050             (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1051             vmp = (unsigned char *) tp + increment;
1052
1053             if (kind == CTF_K_STRUCT)
1054               n = MIN (n, 1);   /* Only use first member for structs.  */
1055
1056             if (size < CTF_LSTRUCT_THRESH)
1057               {
1058                 const ctf_member_t *mp = vmp;
1059                 for (; n != 0; n--, mp++)
1060                   {
1061                     ssize_t am = ctf_type_align (ofp, mp->ctm_type);
1062                     align = MAX (align, (size_t) am);
1063                   }
1064               }
1065             else
1066               {
1067                 const ctf_lmember_t *lmp = vmp;
1068                 for (; n != 0; n--, lmp++)
1069                   {
1070                     ssize_t am = ctf_type_align (ofp, lmp->ctlm_type);
1071                     align = MAX (align, (size_t) am);
1072                   }
1073               }
1074           }
1075         else
1076           {
1077               ctf_dmdef_t *dmd;
1078
1079               for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1080                    dmd != NULL; dmd = ctf_list_next (dmd))
1081                 {
1082                   ssize_t am = ctf_type_align (ofp, dmd->dmd_type);
1083                   align = MAX (align, (size_t) am);
1084                   if (kind == CTF_K_STRUCT)
1085                     break;
1086                 }
1087           }
1088
1089         return align;
1090       }
1091
1092     case CTF_K_ENUM:
1093       return fp->ctf_dmodel->ctd_int;
1094
1095     case CTF_K_FORWARD:
1096       /* Forwards do not have a meaningful alignment.  */
1097       return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1098
1099     default:  /* including slices of enums, etc */
1100       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1101     }
1102 }
1103
1104 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
1105
1106 int
1107 ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
1108 {
1109   const ctf_type_t *tp;
1110
1111   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1112     return -1;                  /* errno is set for us.  */
1113
1114   return (LCTF_INFO_KIND (fp, tp->ctt_info));
1115 }
1116
1117 /* Return the kind (CTF_K_* constant) for the specified type ID.
1118    Slices are considered to be of the same kind as the type sliced.  */
1119
1120 int
1121 ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
1122 {
1123   int kind;
1124
1125   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1126     return -1;
1127
1128   if (kind == CTF_K_SLICE)
1129     {
1130       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1131         return -1;
1132       kind = ctf_type_kind_unsliced (fp, type);
1133     }
1134
1135   return kind;
1136 }
1137
1138 /* Return the kind of this type, except, for forwards, return the kind of thing
1139    this is a forward to.  */
1140 int
1141 ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
1142 {
1143   int kind;
1144   const ctf_type_t *tp;
1145
1146   if ((kind = ctf_type_kind (fp, type)) < 0)
1147     return -1;                  /* errno is set for us.  */
1148
1149   if (kind != CTF_K_FORWARD)
1150     return kind;
1151
1152   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1153     return -1;                  /* errno is set for us.  */
1154
1155   return tp->ctt_type;
1156 }
1157
1158 /* If the type is one that directly references another type (such as POINTER),
1159    then return the ID of the type to which it refers.  */
1160
1161 ctf_id_t
1162 ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
1163 {
1164   ctf_dict_t *ofp = fp;
1165   const ctf_type_t *tp;
1166
1167   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1168     return CTF_ERR;             /* errno is set for us.  */
1169
1170   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1171     {
1172     case CTF_K_POINTER:
1173     case CTF_K_TYPEDEF:
1174     case CTF_K_VOLATILE:
1175     case CTF_K_CONST:
1176     case CTF_K_RESTRICT:
1177       return tp->ctt_type;
1178       /* Slices store their type in an unusual place.  */
1179     case CTF_K_SLICE:
1180       {
1181         ctf_dtdef_t *dtd;
1182         const ctf_slice_t *sp;
1183
1184         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1185           {
1186             ssize_t increment;
1187
1188             (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1189             sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1190           }
1191         else
1192           sp = &dtd->dtd_u.dtu_slice;
1193
1194         return sp->cts_type;
1195       }
1196     default:
1197       return (ctf_set_errno (ofp, ECTF_NOTREF));
1198     }
1199 }
1200
1201 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
1202    pointer to the given type, see if we can compute a pointer to the type
1203    resulting from resolving the type down to its base type and use that
1204    instead.  This helps with cases where the CTF data includes "struct foo *"
1205    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1206
1207    XXX what about parent dicts?  */
1208
1209 ctf_id_t
1210 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
1211 {
1212   ctf_dict_t *ofp = fp;
1213   ctf_id_t ntype;
1214
1215   if (ctf_lookup_by_id (&fp, type) == NULL)
1216     return CTF_ERR;             /* errno is set for us.  */
1217
1218   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1219     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1220
1221   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1222     return (ctf_set_errno (ofp, ECTF_NOTYPE));
1223
1224   if (ctf_lookup_by_id (&fp, type) == NULL)
1225     return (ctf_set_errno (ofp, ECTF_NOTYPE));
1226
1227   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1228     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1229
1230   return (ctf_set_errno (ofp, ECTF_NOTYPE));
1231 }
1232
1233 /* Return the encoding for the specified INTEGER or FLOAT.  */
1234
1235 int
1236 ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1237 {
1238   ctf_dict_t *ofp = fp;
1239   ctf_dtdef_t *dtd;
1240   const ctf_type_t *tp;
1241   ssize_t increment;
1242   uint32_t data;
1243
1244   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1245     return -1;                  /* errno is set for us.  */
1246
1247   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1248     {
1249       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1250         {
1251         case CTF_K_INTEGER:
1252         case CTF_K_FLOAT:
1253           *ep = dtd->dtd_u.dtu_enc;
1254           break;
1255         case CTF_K_SLICE:
1256           {
1257             const ctf_slice_t *slice;
1258             ctf_encoding_t underlying_en;
1259             ctf_id_t underlying;
1260
1261             slice = &dtd->dtd_u.dtu_slice;
1262             underlying = ctf_type_resolve (fp, slice->cts_type);
1263             data = ctf_type_encoding (fp, underlying, &underlying_en);
1264
1265             ep->cte_format = underlying_en.cte_format;
1266             ep->cte_offset = slice->cts_offset;
1267             ep->cte_bits = slice->cts_bits;
1268             break;
1269           }
1270         default:
1271           return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1272         }
1273       return 0;
1274     }
1275
1276   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1277
1278   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1279     {
1280     case CTF_K_INTEGER:
1281       data = *(const uint32_t *) ((uintptr_t) tp + increment);
1282       ep->cte_format = CTF_INT_ENCODING (data);
1283       ep->cte_offset = CTF_INT_OFFSET (data);
1284       ep->cte_bits = CTF_INT_BITS (data);
1285       break;
1286     case CTF_K_FLOAT:
1287       data = *(const uint32_t *) ((uintptr_t) tp + increment);
1288       ep->cte_format = CTF_FP_ENCODING (data);
1289       ep->cte_offset = CTF_FP_OFFSET (data);
1290       ep->cte_bits = CTF_FP_BITS (data);
1291       break;
1292     case CTF_K_SLICE:
1293       {
1294         const ctf_slice_t *slice;
1295         ctf_encoding_t underlying_en;
1296         ctf_id_t underlying;
1297
1298         slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
1299         underlying = ctf_type_resolve (fp, slice->cts_type);
1300         data = ctf_type_encoding (fp, underlying, &underlying_en);
1301
1302         ep->cte_format = underlying_en.cte_format;
1303         ep->cte_offset = slice->cts_offset;
1304         ep->cte_bits = slice->cts_bits;
1305         break;
1306       }
1307     default:
1308       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1309     }
1310
1311   return 0;
1312 }
1313
1314 int
1315 ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
1316               ctf_id_t rtype)
1317 {
1318   int rval;
1319
1320   if (ltype < rtype)
1321     rval = -1;
1322   else if (ltype > rtype)
1323     rval = 1;
1324   else
1325     rval = 0;
1326
1327   if (lfp == rfp)
1328     return rval;
1329
1330   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1331     lfp = lfp->ctf_parent;
1332
1333   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1334     rfp = rfp->ctf_parent;
1335
1336   if (lfp < rfp)
1337     return -1;
1338
1339   if (lfp > rfp)
1340     return 1;
1341
1342   return rval;
1343 }
1344
1345 /* Return a boolean value indicating if two types are compatible.  This function
1346    returns true if the two types are the same, or if they (or their ultimate
1347    base type) have the same encoding properties, or (for structs / unions /
1348    enums / forward declarations) if they have the same name and (for structs /
1349    unions) member count.  */
1350
1351 int
1352 ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1353                  ctf_dict_t *rfp, ctf_id_t rtype)
1354 {
1355   const ctf_type_t *ltp, *rtp;
1356   ctf_encoding_t le, re;
1357   ctf_arinfo_t la, ra;
1358   uint32_t lkind, rkind;
1359   int same_names = 0;
1360
1361   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1362     return 1;
1363
1364   ltype = ctf_type_resolve (lfp, ltype);
1365   lkind = ctf_type_kind (lfp, ltype);
1366
1367   rtype = ctf_type_resolve (rfp, rtype);
1368   rkind = ctf_type_kind (rfp, rtype);
1369
1370   ltp = ctf_lookup_by_id (&lfp, ltype);
1371   rtp = ctf_lookup_by_id (&rfp, rtype);
1372
1373   if (ltp != NULL && rtp != NULL)
1374     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1375                           ctf_strptr (rfp, rtp->ctt_name)) == 0);
1376
1377   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1378       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1379     return 1;
1380
1381   if (lkind != rkind)
1382     return 0;
1383
1384   switch (lkind)
1385     {
1386     case CTF_K_INTEGER:
1387     case CTF_K_FLOAT:
1388       memset (&le, 0, sizeof (le));
1389       memset (&re, 0, sizeof (re));
1390       return (ctf_type_encoding (lfp, ltype, &le) == 0
1391               && ctf_type_encoding (rfp, rtype, &re) == 0
1392               && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1393     case CTF_K_POINTER:
1394       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1395                                rfp, ctf_type_reference (rfp, rtype)));
1396     case CTF_K_ARRAY:
1397       return (ctf_array_info (lfp, ltype, &la) == 0
1398               && ctf_array_info (rfp, rtype, &ra) == 0
1399               && la.ctr_nelems == ra.ctr_nelems
1400               && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1401               && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1402     case CTF_K_STRUCT:
1403     case CTF_K_UNION:
1404       return (same_names && (ctf_type_size (lfp, ltype)
1405                              == ctf_type_size (rfp, rtype)));
1406     case CTF_K_ENUM:
1407       {
1408         int lencoded, rencoded;
1409         lencoded = ctf_type_encoding (lfp, ltype, &le);
1410         rencoded = ctf_type_encoding (rfp, rtype, &re);
1411
1412         if ((lencoded != rencoded) ||
1413             ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1414           return 0;
1415       }
1416       /* FALLTHRU */
1417     case CTF_K_FORWARD:
1418       return same_names;   /* No other checks required for these type kinds.  */
1419     default:
1420       return 0;               /* Should not get here since we did a resolve.  */
1421     }
1422 }
1423
1424 /* Return the number of members in a STRUCT or UNION, or the number of
1425    enumerators in an ENUM.  The count does not include unnamed sub-members.  */
1426
1427 int
1428 ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
1429 {
1430   ctf_dict_t *ofp = fp;
1431   const ctf_type_t *tp;
1432   uint32_t kind;
1433
1434   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1435     return -1;                  /* errno is set for us.  */
1436
1437   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1438     return -1;                  /* errno is set for us.  */
1439
1440   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1441
1442   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1443     return (ctf_set_errno (ofp, ECTF_NOTSUE));
1444
1445   return LCTF_INFO_VLEN (fp, tp->ctt_info);
1446 }
1447
1448 /* Return the type and offset for a given member of a STRUCT or UNION.  */
1449
1450 int
1451 ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
1452                  ctf_membinfo_t *mip)
1453 {
1454   ctf_dict_t *ofp = fp;
1455   const ctf_type_t *tp;
1456   ctf_dtdef_t *dtd;
1457   ssize_t size, increment;
1458   uint32_t kind, n;
1459
1460   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1461     return -1;                  /* errno is set for us.  */
1462
1463   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1464     return -1;                  /* errno is set for us.  */
1465
1466   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1467   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1468
1469   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1470     return (ctf_set_errno (ofp, ECTF_NOTSOU));
1471
1472   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1473     {
1474       if (size < CTF_LSTRUCT_THRESH)
1475         {
1476           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1477                                                            increment);
1478
1479           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1480             {
1481               const char *membname = ctf_strptr (fp, mp->ctm_name);
1482
1483               if (membname[0] == 0
1484                   && (ctf_type_kind (fp, mp->ctm_type) == CTF_K_STRUCT
1485                       || ctf_type_kind (fp, mp->ctm_type) == CTF_K_UNION)
1486                   && (ctf_member_info (fp, mp->ctm_type, name, mip) == 0))
1487                 return 0;
1488
1489               if (strcmp (membname, name) == 0)
1490                 {
1491                   mip->ctm_type = mp->ctm_type;
1492                   mip->ctm_offset = mp->ctm_offset;
1493                   return 0;
1494                 }
1495             }
1496         }
1497       else
1498         {
1499           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1500                                                               increment);
1501
1502           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1503             {
1504               const char *membname = ctf_strptr (fp, lmp->ctlm_name);
1505
1506               if (membname[0] == 0
1507                   && (ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_STRUCT
1508                       || ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_UNION)
1509                   && (ctf_member_info (fp, lmp->ctlm_type, name, mip) == 0))
1510                 return 0;
1511
1512               if (strcmp (membname, name) == 0)
1513                 {
1514                   mip->ctm_type = lmp->ctlm_type;
1515                   mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1516                   return 0;
1517                 }
1518             }
1519         }
1520     }
1521   else
1522     {
1523       ctf_dmdef_t *dmd;
1524
1525       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1526            dmd != NULL; dmd = ctf_list_next (dmd))
1527         {
1528           if (dmd->dmd_name == NULL
1529               && (ctf_type_kind (fp, dmd->dmd_type) == CTF_K_STRUCT
1530                   || ctf_type_kind (fp, dmd->dmd_type) == CTF_K_UNION)
1531               && (ctf_member_info (fp, dmd->dmd_type, name, mip) == 0))
1532             return 0;
1533
1534           if (dmd->dmd_name != NULL
1535               && strcmp (dmd->dmd_name, name) == 0)
1536             {
1537               mip->ctm_type = dmd->dmd_type;
1538               mip->ctm_offset = dmd->dmd_offset;
1539               return 0;
1540             }
1541         }
1542     }
1543
1544   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1545 }
1546
1547 /* Return the array type, index, and size information for the specified ARRAY.  */
1548
1549 int
1550 ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1551 {
1552   ctf_dict_t *ofp = fp;
1553   const ctf_type_t *tp;
1554   const ctf_array_t *ap;
1555   const ctf_dtdef_t *dtd;
1556   ssize_t increment;
1557
1558   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1559     return -1;                  /* errno is set for us.  */
1560
1561   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1562     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1563
1564   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1565     {
1566       *arp = dtd->dtd_u.dtu_arr;
1567       return 0;
1568     }
1569
1570   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1571
1572   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1573   arp->ctr_contents = ap->cta_contents;
1574   arp->ctr_index = ap->cta_index;
1575   arp->ctr_nelems = ap->cta_nelems;
1576
1577   return 0;
1578 }
1579
1580 /* Convert the specified value to the corresponding enum tag name, if a
1581    matching name can be found.  Otherwise NULL is returned.  */
1582
1583 const char *
1584 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1585 {
1586   ctf_dict_t *ofp = fp;
1587   const ctf_type_t *tp;
1588   const ctf_enum_t *ep;
1589   const ctf_dtdef_t *dtd;
1590   ssize_t increment;
1591   uint32_t n;
1592
1593   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1594     return NULL;                /* errno is set for us.  */
1595
1596   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1597     return NULL;                /* errno is set for us.  */
1598
1599   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1600     {
1601       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1602       return NULL;
1603     }
1604
1605   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1606
1607   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1608     {
1609       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1610
1611       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1612         {
1613           if (ep->cte_value == value)
1614             return (ctf_strptr (fp, ep->cte_name));
1615         }
1616     }
1617   else
1618     {
1619       ctf_dmdef_t *dmd;
1620
1621       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1622            dmd != NULL; dmd = ctf_list_next (dmd))
1623         {
1624           if (dmd->dmd_value == value)
1625             return dmd->dmd_name;
1626         }
1627     }
1628
1629   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1630   return NULL;
1631 }
1632
1633 /* Convert the specified enum tag name to the corresponding value, if a
1634    matching name can be found.  Otherwise CTF_ERR is returned.  */
1635
1636 int
1637 ctf_enum_value (ctf_dict_t * fp, ctf_id_t type, const char *name, int *valp)
1638 {
1639   ctf_dict_t *ofp = fp;
1640   const ctf_type_t *tp;
1641   const ctf_enum_t *ep;
1642   const ctf_dtdef_t *dtd;
1643   ssize_t increment;
1644   uint32_t n;
1645
1646   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1647     return -1;                  /* errno is set for us.  */
1648
1649   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1650     return -1;                  /* errno is set for us.  */
1651
1652   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1653     {
1654       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1655       return -1;
1656     }
1657
1658   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1659
1660   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1661
1662   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1663     {
1664       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1665         {
1666           if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1667             {
1668               if (valp != NULL)
1669                 *valp = ep->cte_value;
1670               return 0;
1671             }
1672         }
1673     }
1674   else
1675     {
1676       ctf_dmdef_t *dmd;
1677
1678       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1679            dmd != NULL; dmd = ctf_list_next (dmd))
1680         {
1681           if (strcmp (dmd->dmd_name, name) == 0)
1682             {
1683               if (valp != NULL)
1684                 *valp = dmd->dmd_value;
1685               return 0;
1686             }
1687         }
1688     }
1689
1690   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1691   return -1;
1692 }
1693
1694 /* Given a type ID relating to a function type, return info on return types and
1695    arg counts for that function.  */
1696
1697 int
1698 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1699 {
1700   const ctf_type_t *tp;
1701   uint32_t kind;
1702   const uint32_t *args;
1703   const ctf_dtdef_t *dtd;
1704   ssize_t size, increment;
1705
1706   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1707     return -1;                  /* errno is set for us.  */
1708
1709   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1710     return -1;                  /* errno is set for us.  */
1711
1712   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1713   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1714
1715   if (kind != CTF_K_FUNCTION)
1716     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1717
1718   fip->ctc_return = tp->ctt_type;
1719   fip->ctc_flags = 0;
1720   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1721
1722   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1723     args = (uint32_t *) ((uintptr_t) tp + increment);
1724   else
1725     args = dtd->dtd_u.dtu_argv;
1726
1727   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1728     {
1729       fip->ctc_flags |= CTF_FUNC_VARARG;
1730       fip->ctc_argc--;
1731     }
1732
1733   return 0;
1734 }
1735
1736 /* Given a type ID relating to a function type, return the arguments for the
1737    function.  */
1738
1739 int
1740 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1741 {
1742   const ctf_type_t *tp;
1743   const uint32_t *args;
1744   const ctf_dtdef_t *dtd;
1745   ssize_t size, increment;
1746   ctf_funcinfo_t f;
1747
1748   if (ctf_func_type_info (fp, type, &f) < 0)
1749     return -1;                  /* errno is set for us.  */
1750
1751   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1752     return -1;                  /* errno is set for us.  */
1753
1754   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1755     return -1;                  /* errno is set for us.  */
1756
1757   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1758
1759   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1760     args = (uint32_t *) ((uintptr_t) tp + increment);
1761   else
1762     args = dtd->dtd_u.dtu_argv;
1763
1764   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1765     *argv++ = *args++;
1766
1767   return 0;
1768 }
1769
1770 /* Recursively visit the members of any type.  This function is used as the
1771    engine for ctf_type_visit, below.  We resolve the input type, recursively
1772    invoke ourself for each type member if the type is a struct or union, and
1773    then invoke the callback function on the current type.  If any callback
1774    returns non-zero, we abort and percolate the error code back up to the top.  */
1775
1776 static int
1777 ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
1778                  void *arg, const char *name, unsigned long offset, int depth)
1779 {
1780   ctf_id_t otype = type;
1781   const ctf_type_t *tp;
1782   const ctf_dtdef_t *dtd;
1783   ssize_t size, increment;
1784   uint32_t kind, n;
1785   int rc;
1786
1787   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1788     return -1;                  /* errno is set for us.  */
1789
1790   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1791     return -1;                  /* errno is set for us.  */
1792
1793   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1794     return rc;
1795
1796   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1797
1798   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1799     return 0;
1800
1801   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1802
1803   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1804     {
1805       if (size < CTF_LSTRUCT_THRESH)
1806         {
1807           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1808                                                            increment);
1809
1810           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1811             {
1812               if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1813                                          func, arg, ctf_strptr (fp,
1814                                                                 mp->ctm_name),
1815                                          offset + mp->ctm_offset,
1816                                          depth + 1)) != 0)
1817                 return rc;
1818             }
1819         }
1820       else
1821         {
1822           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1823                                                               increment);
1824
1825           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1826             {
1827               if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1828                                          func, arg, ctf_strptr (fp,
1829                                                                 lmp->ctlm_name),
1830                                          offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1831                                          depth + 1)) != 0)
1832                 return rc;
1833             }
1834         }
1835     }
1836   else
1837     {
1838       ctf_dmdef_t *dmd;
1839
1840       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1841            dmd != NULL; dmd = ctf_list_next (dmd))
1842         {
1843           if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1844                                      dmd->dmd_name, dmd->dmd_offset,
1845                                      depth + 1)) != 0)
1846             return rc;
1847         }
1848     }
1849
1850   return 0;
1851 }
1852
1853 /* Recursively visit the members of any type.  We pass the name, member
1854  type, and offset of each member to the specified callback function.  */
1855 int
1856 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1857 {
1858   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1859 }
This page took 0.12551 seconds and 4 git commands to generate.