]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf, types: allow ctf_type_reference of dynamic slices
[binutils.git] / libctf / ctf-types.c
1 /* Type handling functions.
2    Copyright (C) 2019-2020 Free Software Foundation, Inc.
3
4    This file is part of libctf.
5
6    libctf is free software; you can redistribute it and/or modify it under
7    the terms of the GNU General Public License as published by the Free
8    Software Foundation; either version 3, or (at your option) any later
9    version.
10
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14    See the GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; see the file COPYING.  If not see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <ctf-impl.h>
21 #include <string.h>
22
23 /* Determine whether a type is a parent or a child.  */
24
25 int
26 ctf_type_isparent (ctf_file_t *fp, ctf_id_t id)
27 {
28   return (LCTF_TYPE_ISPARENT (fp, id));
29 }
30
31 int
32 ctf_type_ischild (ctf_file_t * fp, ctf_id_t id)
33 {
34   return (LCTF_TYPE_ISCHILD (fp, id));
35 }
36
37 /* Iterate over the members of a STRUCT or UNION.  We pass the name, member
38    type, and offset of each member to the specified callback function.  */
39
40 int
41 ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
42 {
43   ctf_file_t *ofp = fp;
44   const ctf_type_t *tp;
45   ctf_dtdef_t *dtd;
46   ssize_t size, increment;
47   uint32_t kind, n;
48   int rc;
49
50   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
51     return -1;                  /* errno is set for us.  */
52
53   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
54     return -1;                  /* errno is set for us.  */
55
56   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
57   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
58
59   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
60     return (ctf_set_errno (ofp, ECTF_NOTSOU));
61
62   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
63     {
64       if (size < CTF_LSTRUCT_THRESH)
65         {
66           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
67                                                            increment);
68
69           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
70             {
71               const char *name = ctf_strptr (fp, mp->ctm_name);
72               if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0)
73             return rc;
74             }
75         }
76       else
77         {
78           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
79                                                               increment);
80
81           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
82             {
83               const char *name = ctf_strptr (fp, lmp->ctlm_name);
84               if ((rc = func (name, lmp->ctlm_type,
85                               (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0)
86                 return rc;
87             }
88         }
89     }
90   else
91     {
92       ctf_dmdef_t *dmd;
93
94       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
95            dmd != NULL; dmd = ctf_list_next (dmd))
96         {
97           if ((rc = func (dmd->dmd_name, dmd->dmd_type,
98                           dmd->dmd_offset, arg)) != 0)
99             return rc;
100         }
101     }
102
103   return 0;
104 }
105
106 /* Iterate over the members of an ENUM.  We pass the string name and associated
107    integer value of each enum element to the specified callback function.  */
108
109 int
110 ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
111 {
112   ctf_file_t *ofp = fp;
113   const ctf_type_t *tp;
114   const ctf_enum_t *ep;
115   ctf_dtdef_t *dtd;
116   ssize_t increment;
117   uint32_t n;
118   int rc;
119
120   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
121     return -1;                  /* errno is set for us.  */
122
123   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
124     return -1;                  /* errno is set for us.  */
125
126   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
127     return (ctf_set_errno (ofp, ECTF_NOTENUM));
128
129   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
130
131   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
132     {
133       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
134
135       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
136         {
137           const char *name = ctf_strptr (fp, ep->cte_name);
138           if ((rc = func (name, ep->cte_value, arg)) != 0)
139             return rc;
140         }
141     }
142   else
143     {
144       ctf_dmdef_t *dmd;
145
146       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
147            dmd != NULL; dmd = ctf_list_next (dmd))
148         {
149           if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0)
150             return rc;
151         }
152     }
153
154   return 0;
155 }
156
157 /* Iterate over every root (user-visible) type in the given CTF container.
158    We pass the type ID of each type to the specified callback function.  */
159
160 int
161 ctf_type_iter (ctf_file_t *fp, ctf_type_f *func, void *arg)
162 {
163   ctf_id_t id, max = fp->ctf_typemax;
164   int rc, child = (fp->ctf_flags & LCTF_CHILD);
165
166   for (id = 1; id <= max; id++)
167     {
168       const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
169       if (LCTF_INFO_ISROOT (fp, tp->ctt_info)
170           && (rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), arg)) != 0)
171         return rc;
172     }
173
174   return 0;
175 }
176
177 /* Iterate over every type in the given CTF container, user-visible or not.
178    We pass the type ID of each type to the specified callback function.  */
179
180 int
181 ctf_type_iter_all (ctf_file_t *fp, ctf_type_all_f *func, void *arg)
182 {
183   ctf_id_t id, max = fp->ctf_typemax;
184   int rc, child = (fp->ctf_flags & LCTF_CHILD);
185
186   for (id = 1; id <= max; id++)
187     {
188       const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
189       if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child),
190                       LCTF_INFO_ISROOT(fp, tp->ctt_info)
191                       ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0))
192         return rc;
193     }
194
195   return 0;
196 }
197
198 /* Iterate over every variable in the given CTF container, in arbitrary order.
199    We pass the name of each variable to the specified callback function.  */
200
201 int
202 ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg)
203 {
204   int rc;
205
206   if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
207     return ECTF_NOPARENT;
208
209   if (!(fp->ctf_flags & LCTF_RDWR))
210     {
211       unsigned long i;
212       for (i = 0; i < fp->ctf_nvars; i++)
213         if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
214                         fp->ctf_vars[i].ctv_type, arg)) != 0)
215           return rc;
216     }
217   else
218     {
219       ctf_dvdef_t *dvd;
220
221       for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
222            dvd = ctf_list_next (dvd))
223         {
224           if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
225             return rc;
226         }
227     }
228
229   return 0;
230 }
231
232 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
233    RESTRICT nodes until we reach a "base" type node.  This is useful when
234    we want to follow a type ID to a node that has members or a size.  To guard
235    against infinite loops, we implement simplified cycle detection and check
236    each link against itself, the previous node, and the topmost node.
237
238    Does not drill down through slices to their contained type.  */
239
240 ctf_id_t
241 ctf_type_resolve (ctf_file_t *fp, ctf_id_t type)
242 {
243   ctf_id_t prev = type, otype = type;
244   ctf_file_t *ofp = fp;
245   const ctf_type_t *tp;
246
247   if (type == 0)
248     return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
249
250   while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
251     {
252       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
253         {
254         case CTF_K_TYPEDEF:
255         case CTF_K_VOLATILE:
256         case CTF_K_CONST:
257         case CTF_K_RESTRICT:
258           if (tp->ctt_type == type || tp->ctt_type == otype
259               || tp->ctt_type == prev)
260             {
261               ctf_dprintf ("type %ld cycle detected\n", otype);
262               return (ctf_set_errno (ofp, ECTF_CORRUPT));
263             }
264           prev = type;
265           type = tp->ctt_type;
266           break;
267         default:
268           return type;
269         }
270       if (type == 0)
271         return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
272     }
273
274   return CTF_ERR;               /* errno is set for us.  */
275 }
276
277 /* Like ctf_type_resolve(), but traverse down through slices to their contained
278    type.  */
279
280 ctf_id_t
281 ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type)
282 {
283   const ctf_type_t *tp;
284
285   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
286     return -1;
287
288   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
289     return CTF_ERR;             /* errno is set for us.  */
290
291   if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
292     return ctf_type_reference (fp, type);
293   return type;
294 }
295
296 /* Look up a name in the given name table, in the appropriate hash given the
297    kind of the identifier.  The name is a raw, undecorated identifier.  */
298
299 ctf_id_t ctf_lookup_by_rawname (ctf_file_t *fp, int kind, const char *name)
300 {
301   return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
302 }
303
304 /* Look up a name in the given name table, in the appropriate hash given the
305    readability state of the dictionary.  The name is a raw, undecorated
306    identifier.  */
307
308 ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *fp, ctf_names_t *np, const char *name)
309 {
310   ctf_id_t id;
311
312   if (fp->ctf_flags & LCTF_RDWR)
313     id = (ctf_id_t) ctf_dynhash_lookup (np->ctn_writable, name);
314   else
315     id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
316   return id;
317 }
318
319 /* Lookup the given type ID and return its name as a new dynamcally-allocated
320    string.  */
321
322 char *
323 ctf_type_aname (ctf_file_t *fp, ctf_id_t type)
324 {
325   ctf_decl_t cd;
326   ctf_decl_node_t *cdp;
327   ctf_decl_prec_t prec, lp, rp;
328   int ptr, arr;
329   uint32_t k;
330   char *buf;
331
332   if (fp == NULL && type == CTF_ERR)
333     return NULL;        /* Simplify caller code by permitting CTF_ERR.  */
334
335   ctf_decl_init (&cd);
336   ctf_decl_push (&cd, fp, type);
337
338   if (cd.cd_err != 0)
339     {
340       ctf_decl_fini (&cd);
341       ctf_set_errno (fp, cd.cd_err);
342       return NULL;
343     }
344
345   /* If the type graph's order conflicts with lexical precedence order
346      for pointers or arrays, then we need to surround the declarations at
347      the corresponding lexical precedence with parentheses.  This can
348      result in either a parenthesized pointer (*) as in int (*)() or
349      int (*)[], or in a parenthesized pointer and array as in int (*[])().  */
350
351   ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
352   arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
353
354   rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
355   lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
356
357   k = CTF_K_POINTER;            /* Avoid leading whitespace (see below).  */
358
359   for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
360     {
361       for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
362            cdp != NULL; cdp = ctf_list_next (cdp))
363         {
364           ctf_file_t *rfp = fp;
365           const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
366           const char *name = ctf_strptr (rfp, tp->ctt_name);
367
368           if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
369             ctf_decl_sprintf (&cd, " ");
370
371           if (lp == prec)
372             {
373               ctf_decl_sprintf (&cd, "(");
374               lp = -1;
375             }
376
377           switch (cdp->cd_kind)
378             {
379             case CTF_K_INTEGER:
380             case CTF_K_FLOAT:
381             case CTF_K_TYPEDEF:
382               ctf_decl_sprintf (&cd, "%s", name);
383               break;
384             case CTF_K_POINTER:
385               ctf_decl_sprintf (&cd, "*");
386               break;
387             case CTF_K_ARRAY:
388               ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
389               break;
390             case CTF_K_FUNCTION:
391               ctf_decl_sprintf (&cd, "()");
392               break;
393             case CTF_K_STRUCT:
394             case CTF_K_FORWARD:
395               ctf_decl_sprintf (&cd, "struct %s", name);
396               break;
397             case CTF_K_UNION:
398               ctf_decl_sprintf (&cd, "union %s", name);
399               break;
400             case CTF_K_ENUM:
401               ctf_decl_sprintf (&cd, "enum %s", name);
402               break;
403             case CTF_K_VOLATILE:
404               ctf_decl_sprintf (&cd, "volatile");
405               break;
406             case CTF_K_CONST:
407               ctf_decl_sprintf (&cd, "const");
408               break;
409             case CTF_K_RESTRICT:
410               ctf_decl_sprintf (&cd, "restrict");
411               break;
412             case CTF_K_SLICE:
413               /* No representation: just changes encoding of contained type,
414                  which is not in any case printed.  Skip it.  */
415               break;
416             }
417
418           k = cdp->cd_kind;
419         }
420
421       if (rp == prec)
422         ctf_decl_sprintf (&cd, ")");
423     }
424
425   if (cd.cd_enomem)
426     (void) ctf_set_errno (fp, ENOMEM);
427
428   buf = ctf_decl_buf (&cd);
429
430   ctf_decl_fini (&cd);
431   return buf;
432 }
433
434 /* Lookup the given type ID and print a string name for it into buf.  Return
435    the actual number of bytes (not including \0) needed to format the name.  */
436
437 ssize_t
438 ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
439 {
440   char *str = ctf_type_aname (fp, type);
441   size_t slen;
442
443   if (str == NULL)
444     return CTF_ERR;                     /* errno is set for us.  */
445
446   slen = strlen (str);
447   snprintf (buf, len, "%s", str);
448   free (str);
449
450   if (slen >= len)
451     (void) ctf_set_errno (fp, ECTF_NAMELEN);
452
453   return slen;
454 }
455
456 /* Lookup the given type ID and print a string name for it into buf.  If buf
457    is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
458
459 char *
460 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
461 {
462   ssize_t rv = ctf_type_lname (fp, type, buf, len);
463   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
464 }
465
466 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
467    new dynamcally-allocated string.  */
468
469 char *
470 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
471 {
472   const ctf_type_t *tp;
473
474   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
475     return NULL;                /* errno is set for us.  */
476
477   if (ctf_strraw (fp, tp->ctt_name) != NULL)
478     return strdup (ctf_strraw (fp, tp->ctt_name));
479
480   return NULL;
481 }
482
483 /* Resolve the type down to a base type node, and then return the size
484    of the type storage in bytes.  */
485
486 ssize_t
487 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
488 {
489   const ctf_type_t *tp;
490   ssize_t size;
491   ctf_arinfo_t ar;
492
493   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
494     return -1;                  /* errno is set for us.  */
495
496   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
497     return -1;                  /* errno is set for us.  */
498
499   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
500     {
501     case CTF_K_POINTER:
502       return fp->ctf_dmodel->ctd_pointer;
503
504     case CTF_K_FUNCTION:
505       return 0;         /* Function size is only known by symtab.  */
506
507     case CTF_K_ENUM:
508       return fp->ctf_dmodel->ctd_int;
509
510     case CTF_K_ARRAY:
511       /* ctf_add_array() does not directly encode the element size, but
512          requires the user to multiply to determine the element size.
513
514          If ctf_get_ctt_size() returns nonzero, then use the recorded
515          size instead.  */
516
517       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
518         return size;
519
520       if (ctf_array_info (fp, type, &ar) < 0
521           || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
522         return -1;              /* errno is set for us.  */
523
524       return size * ar.ctr_nelems;
525
526     default: /* including slices of enums, etc */
527       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
528     }
529 }
530
531 /* Resolve the type down to a base type node, and then return the alignment
532    needed for the type storage in bytes.
533
534    XXX may need arch-dependent attention.  */
535
536 ssize_t
537 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
538 {
539   const ctf_type_t *tp;
540   ctf_file_t *ofp = fp;
541   int kind;
542
543   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
544     return -1;                  /* errno is set for us.  */
545
546   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
547     return -1;                  /* errno is set for us.  */
548
549   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
550   switch (kind)
551     {
552     case CTF_K_POINTER:
553     case CTF_K_FUNCTION:
554       return fp->ctf_dmodel->ctd_pointer;
555
556     case CTF_K_ARRAY:
557       {
558         ctf_arinfo_t r;
559         if (ctf_array_info (fp, type, &r) < 0)
560           return -1;            /* errno is set for us.  */
561         return (ctf_type_align (fp, r.ctr_contents));
562       }
563
564     case CTF_K_STRUCT:
565     case CTF_K_UNION:
566       {
567         size_t align = 0;
568         ctf_dtdef_t *dtd;
569
570         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
571           {
572             uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
573             ssize_t size, increment;
574             const void *vmp;
575
576             (void) ctf_get_ctt_size (fp, tp, &size, &increment);
577             vmp = (unsigned char *) tp + increment;
578
579             if (kind == CTF_K_STRUCT)
580               n = MIN (n, 1);   /* Only use first member for structs.  */
581
582             if (size < CTF_LSTRUCT_THRESH)
583               {
584                 const ctf_member_t *mp = vmp;
585                 for (; n != 0; n--, mp++)
586                   {
587                     ssize_t am = ctf_type_align (fp, mp->ctm_type);
588                     align = MAX (align, (size_t) am);
589                   }
590               }
591             else
592               {
593                 const ctf_lmember_t *lmp = vmp;
594                 for (; n != 0; n--, lmp++)
595                   {
596                     ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
597                     align = MAX (align, (size_t) am);
598                   }
599               }
600           }
601         else
602           {
603               ctf_dmdef_t *dmd;
604
605               for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
606                    dmd != NULL; dmd = ctf_list_next (dmd))
607                 {
608                   ssize_t am = ctf_type_align (fp, dmd->dmd_type);
609                   align = MAX (align, (size_t) am);
610                   if (kind == CTF_K_STRUCT)
611                     break;
612                 }
613           }
614
615         return align;
616       }
617
618     case CTF_K_ENUM:
619       return fp->ctf_dmodel->ctd_int;
620
621     default:  /* including slices of enums, etc */
622       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
623     }
624 }
625
626 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
627
628 int
629 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
630 {
631   const ctf_type_t *tp;
632
633   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
634     return -1;                  /* errno is set for us.  */
635
636   return (LCTF_INFO_KIND (fp, tp->ctt_info));
637 }
638
639 /* Return the kind (CTF_K_* constant) for the specified type ID.
640    Slices are considered to be of the same kind as the type sliced.  */
641
642 int
643 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
644 {
645   int kind;
646
647   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
648     return -1;
649
650   if (kind == CTF_K_SLICE)
651     {
652       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
653         return -1;
654       kind = ctf_type_kind_unsliced (fp, type);
655     }
656
657   return kind;
658 }
659
660 /* If the type is one that directly references another type (such as POINTER),
661    then return the ID of the type to which it refers.  */
662
663 ctf_id_t
664 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
665 {
666   ctf_file_t *ofp = fp;
667   const ctf_type_t *tp;
668
669   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
670     return CTF_ERR;             /* errno is set for us.  */
671
672   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
673     {
674     case CTF_K_POINTER:
675     case CTF_K_TYPEDEF:
676     case CTF_K_VOLATILE:
677     case CTF_K_CONST:
678     case CTF_K_RESTRICT:
679       return tp->ctt_type;
680       /* Slices store their type in an unusual place.  */
681     case CTF_K_SLICE:
682       {
683         ctf_dtdef_t *dtd;
684         const ctf_slice_t *sp;
685
686         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
687           {
688             ssize_t increment;
689
690             (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
691             sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
692           }
693         else
694           sp = &dtd->dtd_u.dtu_slice;
695
696         return sp->cts_type;
697       }
698     default:
699       return (ctf_set_errno (ofp, ECTF_NOTREF));
700     }
701 }
702
703 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
704    pointer to the given type, see if we can compute a pointer to the type
705    resulting from resolving the type down to its base type and use that
706    instead.  This helps with cases where the CTF data includes "struct foo *"
707    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
708
709    XXX what about parent containers?  */
710
711 ctf_id_t
712 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
713 {
714   ctf_file_t *ofp = fp;
715   ctf_id_t ntype;
716
717   if (ctf_lookup_by_id (&fp, type) == NULL)
718     return CTF_ERR;             /* errno is set for us.  */
719
720   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
721     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
722
723   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
724     return (ctf_set_errno (ofp, ECTF_NOTYPE));
725
726   if (ctf_lookup_by_id (&fp, type) == NULL)
727     return (ctf_set_errno (ofp, ECTF_NOTYPE));
728
729   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
730     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
731
732   return (ctf_set_errno (ofp, ECTF_NOTYPE));
733 }
734
735 /* Return the encoding for the specified INTEGER or FLOAT.  */
736
737 int
738 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
739 {
740   ctf_file_t *ofp = fp;
741   ctf_dtdef_t *dtd;
742   const ctf_type_t *tp;
743   ssize_t increment;
744   uint32_t data;
745
746   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
747     return -1;                  /* errno is set for us.  */
748
749   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
750     {
751       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
752         {
753         case CTF_K_INTEGER:
754         case CTF_K_FLOAT:
755           *ep = dtd->dtd_u.dtu_enc;
756           break;
757         case CTF_K_SLICE:
758           {
759             const ctf_slice_t *slice;
760             ctf_encoding_t underlying_en;
761             slice = &dtd->dtd_u.dtu_slice;
762
763             data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
764             ep->cte_format = underlying_en.cte_format;
765             ep->cte_offset = slice->cts_offset;
766             ep->cte_bits = slice->cts_bits;
767             break;
768           }
769         default:
770           return (ctf_set_errno (ofp, ECTF_NOTINTFP));
771         }
772       return 0;
773     }
774
775   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
776
777   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
778     {
779     case CTF_K_INTEGER:
780       data = *(const uint32_t *) ((uintptr_t) tp + increment);
781       ep->cte_format = CTF_INT_ENCODING (data);
782       ep->cte_offset = CTF_INT_OFFSET (data);
783       ep->cte_bits = CTF_INT_BITS (data);
784       break;
785     case CTF_K_FLOAT:
786       data = *(const uint32_t *) ((uintptr_t) tp + increment);
787       ep->cte_format = CTF_FP_ENCODING (data);
788       ep->cte_offset = CTF_FP_OFFSET (data);
789       ep->cte_bits = CTF_FP_BITS (data);
790       break;
791     case CTF_K_SLICE:
792       {
793         const ctf_slice_t *slice;
794         ctf_encoding_t underlying_en;
795
796         slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
797         data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
798
799         ep->cte_format = underlying_en.cte_format;
800         ep->cte_offset = slice->cts_offset;
801         ep->cte_bits = slice->cts_bits;
802         break;
803       }
804     default:
805       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
806     }
807
808   return 0;
809 }
810
811 int
812 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
813               ctf_id_t rtype)
814 {
815   int rval;
816
817   if (ltype < rtype)
818     rval = -1;
819   else if (ltype > rtype)
820     rval = 1;
821   else
822     rval = 0;
823
824   if (lfp == rfp)
825     return rval;
826
827   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
828     lfp = lfp->ctf_parent;
829
830   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
831     rfp = rfp->ctf_parent;
832
833   if (lfp < rfp)
834     return -1;
835
836   if (lfp > rfp)
837     return 1;
838
839   return rval;
840 }
841
842 /* Return a boolean value indicating if two types are compatible.  This function
843    returns true if the two types are the same, or if they (or their ultimate
844    base type) have the same encoding properties, or (for structs / unions /
845    enums / forward declarations) if they have the same name and (for structs /
846    unions) member count.  */
847
848 int
849 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
850                  ctf_file_t *rfp, ctf_id_t rtype)
851 {
852   const ctf_type_t *ltp, *rtp;
853   ctf_encoding_t le, re;
854   ctf_arinfo_t la, ra;
855   uint32_t lkind, rkind;
856   int same_names = 0;
857
858   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
859     return 1;
860
861   ltype = ctf_type_resolve (lfp, ltype);
862   lkind = ctf_type_kind (lfp, ltype);
863
864   rtype = ctf_type_resolve (rfp, rtype);
865   rkind = ctf_type_kind (rfp, rtype);
866
867   ltp = ctf_lookup_by_id (&lfp, ltype);
868   rtp = ctf_lookup_by_id (&rfp, rtype);
869
870   if (ltp != NULL && rtp != NULL)
871     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
872                           ctf_strptr (rfp, rtp->ctt_name)) == 0);
873
874   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
875       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
876     return 1;
877
878   if (lkind != rkind)
879     return 0;
880
881   switch (lkind)
882     {
883     case CTF_K_INTEGER:
884     case CTF_K_FLOAT:
885       memset (&le, 0, sizeof (le));
886       memset (&re, 0, sizeof (re));
887       return (ctf_type_encoding (lfp, ltype, &le) == 0
888               && ctf_type_encoding (rfp, rtype, &re) == 0
889               && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
890     case CTF_K_POINTER:
891       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
892                                rfp, ctf_type_reference (rfp, rtype)));
893     case CTF_K_ARRAY:
894       return (ctf_array_info (lfp, ltype, &la) == 0
895               && ctf_array_info (rfp, rtype, &ra) == 0
896               && la.ctr_nelems == ra.ctr_nelems
897               && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
898               && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
899     case CTF_K_STRUCT:
900     case CTF_K_UNION:
901       return (same_names && (ctf_type_size (lfp, ltype)
902                              == ctf_type_size (rfp, rtype)));
903     case CTF_K_ENUM:
904       {
905         int lencoded, rencoded;
906         lencoded = ctf_type_encoding (lfp, ltype, &le);
907         rencoded = ctf_type_encoding (rfp, rtype, &re);
908
909         if ((lencoded != rencoded) ||
910             ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
911           return 0;
912       }
913       /* FALLTHRU */
914     case CTF_K_FORWARD:
915       return same_names;   /* No other checks required for these type kinds.  */
916     default:
917       return 0;               /* Should not get here since we did a resolve.  */
918     }
919 }
920
921 /* Return the type and offset for a given member of a STRUCT or UNION.  */
922
923 int
924 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
925                  ctf_membinfo_t *mip)
926 {
927   ctf_file_t *ofp = fp;
928   const ctf_type_t *tp;
929   ctf_dtdef_t *dtd;
930   ssize_t size, increment;
931   uint32_t kind, n;
932
933   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
934     return -1;                  /* errno is set for us.  */
935
936   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
937     return -1;                  /* errno is set for us.  */
938
939   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
940   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
941
942   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
943     return (ctf_set_errno (ofp, ECTF_NOTSOU));
944
945   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
946     {
947       if (size < CTF_LSTRUCT_THRESH)
948         {
949           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
950                                                            increment);
951
952           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
953             {
954               if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
955                 {
956                   mip->ctm_type = mp->ctm_type;
957                   mip->ctm_offset = mp->ctm_offset;
958                   return 0;
959                 }
960             }
961         }
962       else
963         {
964           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
965                                                               increment);
966
967           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
968             {
969               if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
970                 {
971                   mip->ctm_type = lmp->ctlm_type;
972                   mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
973                   return 0;
974                 }
975             }
976         }
977     }
978   else
979     {
980       ctf_dmdef_t *dmd;
981
982       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
983            dmd != NULL; dmd = ctf_list_next (dmd))
984         {
985           if (strcmp (dmd->dmd_name, name) == 0)
986             {
987               mip->ctm_type = dmd->dmd_type;
988               mip->ctm_offset = dmd->dmd_offset;
989               return 0;
990             }
991         }
992     }
993
994   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
995 }
996
997 /* Return the array type, index, and size information for the specified ARRAY.  */
998
999 int
1000 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1001 {
1002   ctf_file_t *ofp = fp;
1003   const ctf_type_t *tp;
1004   const ctf_array_t *ap;
1005   const ctf_dtdef_t *dtd;
1006   ssize_t increment;
1007
1008   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1009     return -1;                  /* errno is set for us.  */
1010
1011   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1012     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1013
1014   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1015     {
1016       *arp = dtd->dtd_u.dtu_arr;
1017       return 0;
1018     }
1019
1020   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1021
1022   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1023   arp->ctr_contents = ap->cta_contents;
1024   arp->ctr_index = ap->cta_index;
1025   arp->ctr_nelems = ap->cta_nelems;
1026
1027   return 0;
1028 }
1029
1030 /* Convert the specified value to the corresponding enum tag name, if a
1031    matching name can be found.  Otherwise NULL is returned.  */
1032
1033 const char *
1034 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1035 {
1036   ctf_file_t *ofp = fp;
1037   const ctf_type_t *tp;
1038   const ctf_enum_t *ep;
1039   const ctf_dtdef_t *dtd;
1040   ssize_t increment;
1041   uint32_t n;
1042
1043   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1044     return NULL;                /* errno is set for us.  */
1045
1046   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1047     return NULL;                /* errno is set for us.  */
1048
1049   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1050     {
1051       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1052       return NULL;
1053     }
1054
1055   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1056
1057   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1058     {
1059       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1060
1061       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1062         {
1063           if (ep->cte_value == value)
1064             return (ctf_strptr (fp, ep->cte_name));
1065         }
1066     }
1067   else
1068     {
1069       ctf_dmdef_t *dmd;
1070
1071       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1072            dmd != NULL; dmd = ctf_list_next (dmd))
1073         {
1074           if (dmd->dmd_value == value)
1075             return dmd->dmd_name;
1076         }
1077     }
1078
1079   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1080   return NULL;
1081 }
1082
1083 /* Convert the specified enum tag name to the corresponding value, if a
1084    matching name can be found.  Otherwise CTF_ERR is returned.  */
1085
1086 int
1087 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1088 {
1089   ctf_file_t *ofp = fp;
1090   const ctf_type_t *tp;
1091   const ctf_enum_t *ep;
1092   const ctf_dtdef_t *dtd;
1093   ssize_t increment;
1094   uint32_t n;
1095
1096   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1097     return -1;                  /* errno is set for us.  */
1098
1099   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1100     return -1;                  /* errno is set for us.  */
1101
1102   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1103     {
1104       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1105       return -1;
1106     }
1107
1108   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1109
1110   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1111
1112   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1113     {
1114       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1115         {
1116           if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1117             {
1118               if (valp != NULL)
1119                 *valp = ep->cte_value;
1120               return 0;
1121             }
1122         }
1123     }
1124   else
1125     {
1126       ctf_dmdef_t *dmd;
1127
1128       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1129            dmd != NULL; dmd = ctf_list_next (dmd))
1130         {
1131           if (strcmp (dmd->dmd_name, name) == 0)
1132             {
1133               if (valp != NULL)
1134                 *valp = dmd->dmd_value;
1135               return 0;
1136             }
1137         }
1138     }
1139
1140   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1141   return -1;
1142 }
1143
1144 /* Given a type ID relating to a function type, return info on return types and
1145    arg counts for that function.  */
1146
1147 int
1148 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1149 {
1150   const ctf_type_t *tp;
1151   uint32_t kind;
1152   const uint32_t *args;
1153   const ctf_dtdef_t *dtd;
1154   ssize_t size, increment;
1155
1156   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1157     return -1;                  /* errno is set for us.  */
1158
1159   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1160     return -1;                  /* errno is set for us.  */
1161
1162   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1163   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1164
1165   if (kind != CTF_K_FUNCTION)
1166     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1167
1168   fip->ctc_return = tp->ctt_type;
1169   fip->ctc_flags = 0;
1170   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1171
1172   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1173     args = (uint32_t *) ((uintptr_t) tp + increment);
1174   else
1175     args = dtd->dtd_u.dtu_argv;
1176
1177   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1178     {
1179       fip->ctc_flags |= CTF_FUNC_VARARG;
1180       fip->ctc_argc--;
1181     }
1182
1183   return 0;
1184 }
1185
1186 /* Given a type ID relating to a function type, return the arguments for the
1187    function.  */
1188
1189 int
1190 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1191 {
1192   const ctf_type_t *tp;
1193   const uint32_t *args;
1194   const ctf_dtdef_t *dtd;
1195   ssize_t size, increment;
1196   ctf_funcinfo_t f;
1197
1198   if (ctf_func_type_info (fp, type, &f) < 0)
1199     return -1;                  /* errno is set for us.  */
1200
1201   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1202     return -1;                  /* errno is set for us.  */
1203
1204   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1205     return -1;                  /* errno is set for us.  */
1206
1207   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1208
1209   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1210     args = (uint32_t *) ((uintptr_t) tp + increment);
1211   else
1212     args = dtd->dtd_u.dtu_argv;
1213
1214   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1215     *argv++ = *args++;
1216
1217   return 0;
1218 }
1219
1220 /* Recursively visit the members of any type.  This function is used as the
1221    engine for ctf_type_visit, below.  We resolve the input type, recursively
1222    invoke ourself for each type member if the type is a struct or union, and
1223    then invoke the callback function on the current type.  If any callback
1224    returns non-zero, we abort and percolate the error code back up to the top.  */
1225
1226 static int
1227 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1228                  void *arg, const char *name, unsigned long offset, int depth)
1229 {
1230   ctf_id_t otype = type;
1231   const ctf_type_t *tp;
1232   const ctf_dtdef_t *dtd;
1233   ssize_t size, increment;
1234   uint32_t kind, n;
1235   int rc;
1236
1237   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1238     return -1;                  /* errno is set for us.  */
1239
1240   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1241     return -1;                  /* errno is set for us.  */
1242
1243   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1244     return rc;
1245
1246   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1247
1248   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1249     return 0;
1250
1251   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1252
1253   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1254     {
1255       if (size < CTF_LSTRUCT_THRESH)
1256         {
1257           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1258                                                            increment);
1259
1260           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1261             {
1262               if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1263                                          func, arg, ctf_strptr (fp,
1264                                                                 mp->ctm_name),
1265                                          offset + mp->ctm_offset,
1266                                          depth + 1)) != 0)
1267                 return rc;
1268             }
1269         }
1270       else
1271         {
1272           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1273                                                               increment);
1274
1275           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1276             {
1277               if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1278                                          func, arg, ctf_strptr (fp,
1279                                                                 lmp->ctlm_name),
1280                                          offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1281                                          depth + 1)) != 0)
1282                 return rc;
1283             }
1284         }
1285     }
1286   else
1287     {
1288       ctf_dmdef_t *dmd;
1289
1290       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1291            dmd != NULL; dmd = ctf_list_next (dmd))
1292         {
1293           if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1294                                      dmd->dmd_name, dmd->dmd_offset,
1295                                      depth + 1)) != 0)
1296             return rc;
1297         }
1298     }
1299
1300   return 0;
1301 }
1302
1303 /* Recursively visit the members of any type.  We pass the name, member
1304  type, and offset of each member to the specified callback function.  */
1305 int
1306 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1307 {
1308   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1309 }
This page took 0.097906 seconds and 4 git commands to generate.