]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf: avoid the need to ever use ctf_update
[binutils.git] / libctf / ctf-types.c
1 /* Type handling functions.
2    Copyright (C) 2019 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 = strlen (str);
442
443   if (str == NULL)
444     return CTF_ERR;             /* errno is set for us */
445
446   snprintf (buf, len, "%s", str);
447   free (str);
448
449   if (slen >= len)
450     (void) ctf_set_errno (fp, ECTF_NAMELEN);
451
452   return slen;
453 }
454
455 /* Lookup the given type ID and print a string name for it into buf.  If buf
456    is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
457
458 char *
459 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
460 {
461   ssize_t rv = ctf_type_lname (fp, type, buf, len);
462   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
463 }
464
465 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
466    new dynamcally-allocated string.  */
467
468 char *
469 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
470 {
471   const ctf_type_t *tp;
472
473   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
474     return NULL;                /* errno is set for us.  */
475
476   if (ctf_strraw (fp, tp->ctt_name) != NULL)
477     return strdup (ctf_strraw (fp, tp->ctt_name));
478
479   return NULL;
480 }
481
482 /* Resolve the type down to a base type node, and then return the size
483    of the type storage in bytes.  */
484
485 ssize_t
486 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
487 {
488   const ctf_type_t *tp;
489   ssize_t size;
490   ctf_arinfo_t ar;
491
492   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
493     return -1;                  /* errno is set for us.  */
494
495   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
496     return -1;                  /* errno is set for us.  */
497
498   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
499     {
500     case CTF_K_POINTER:
501       return fp->ctf_dmodel->ctd_pointer;
502
503     case CTF_K_FUNCTION:
504       return 0;         /* Function size is only known by symtab.  */
505
506     case CTF_K_ENUM:
507       return fp->ctf_dmodel->ctd_int;
508
509     case CTF_K_ARRAY:
510       /* ctf_add_array() does not directly encode the element size, but
511          requires the user to multiply to determine the element size.
512
513          If ctf_get_ctt_size() returns nonzero, then use the recorded
514          size instead.  */
515
516       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
517         return size;
518
519       if (ctf_array_info (fp, type, &ar) < 0
520           || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
521         return -1;              /* errno is set for us.  */
522
523       return size * ar.ctr_nelems;
524
525     default: /* including slices of enums, etc */
526       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
527     }
528 }
529
530 /* Resolve the type down to a base type node, and then return the alignment
531    needed for the type storage in bytes.
532
533    XXX may need arch-dependent attention.  */
534
535 ssize_t
536 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
537 {
538   const ctf_type_t *tp;
539   ctf_file_t *ofp = fp;
540   int kind;
541
542   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
543     return -1;                  /* errno is set for us.  */
544
545   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
546     return -1;                  /* errno is set for us.  */
547
548   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
549   switch (kind)
550     {
551     case CTF_K_POINTER:
552     case CTF_K_FUNCTION:
553       return fp->ctf_dmodel->ctd_pointer;
554
555     case CTF_K_ARRAY:
556       {
557         ctf_arinfo_t r;
558         if (ctf_array_info (fp, type, &r) < 0)
559           return -1;            /* errno is set for us.  */
560         return (ctf_type_align (fp, r.ctr_contents));
561       }
562
563     case CTF_K_STRUCT:
564     case CTF_K_UNION:
565       {
566         size_t align = 0;
567         ctf_dtdef_t *dtd;
568
569         if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
570           {
571             uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
572             ssize_t size, increment;
573             const void *vmp;
574
575             (void) ctf_get_ctt_size (fp, tp, &size, &increment);
576             vmp = (unsigned char *) tp + increment;
577
578             if (kind == CTF_K_STRUCT)
579               n = MIN (n, 1);   /* Only use first member for structs.  */
580
581             if (size < CTF_LSTRUCT_THRESH)
582               {
583                 const ctf_member_t *mp = vmp;
584                 for (; n != 0; n--, mp++)
585                   {
586                     ssize_t am = ctf_type_align (fp, mp->ctm_type);
587                     align = MAX (align, (size_t) am);
588                   }
589               }
590             else
591               {
592                 const ctf_lmember_t *lmp = vmp;
593                 for (; n != 0; n--, lmp++)
594                   {
595                     ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
596                     align = MAX (align, (size_t) am);
597                   }
598               }
599           }
600         else
601           {
602               ctf_dmdef_t *dmd;
603
604               for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
605                    dmd != NULL; dmd = ctf_list_next (dmd))
606                 {
607                   ssize_t am = ctf_type_align (fp, dmd->dmd_type);
608                   align = MAX (align, (size_t) am);
609                   if (kind == CTF_K_STRUCT)
610                     break;
611                 }
612           }
613
614         return align;
615       }
616
617     case CTF_K_ENUM:
618       return fp->ctf_dmodel->ctd_int;
619
620     default:  /* including slices of enums, etc */
621       return (ctf_get_ctt_size (fp, tp, NULL, NULL));
622     }
623 }
624
625 /* Return the kind (CTF_K_* constant) for the specified type ID.  */
626
627 int
628 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
629 {
630   const ctf_type_t *tp;
631
632   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
633     return -1;                  /* errno is set for us.  */
634
635   return (LCTF_INFO_KIND (fp, tp->ctt_info));
636 }
637
638 /* Return the kind (CTF_K_* constant) for the specified type ID.
639    Slices are considered to be of the same kind as the type sliced.  */
640
641 int
642 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
643 {
644   int kind;
645
646   if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
647     return -1;
648
649   if (kind == CTF_K_SLICE)
650     {
651       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
652         return -1;
653       kind = ctf_type_kind_unsliced (fp, type);
654     }
655
656   return kind;
657 }
658
659 /* If the type is one that directly references another type (such as POINTER),
660    then return the ID of the type to which it refers.  */
661
662 ctf_id_t
663 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
664 {
665   ctf_file_t *ofp = fp;
666   const ctf_type_t *tp;
667
668   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
669     return CTF_ERR;             /* errno is set for us.  */
670
671   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
672     {
673     case CTF_K_POINTER:
674     case CTF_K_TYPEDEF:
675     case CTF_K_VOLATILE:
676     case CTF_K_CONST:
677     case CTF_K_RESTRICT:
678       return tp->ctt_type;
679       /* Slices store their type in an unusual place.  */
680     case CTF_K_SLICE:
681       {
682         const ctf_slice_t *sp;
683         ssize_t increment;
684         (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
685         sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
686         return sp->cts_type;
687       }
688     default:
689       return (ctf_set_errno (ofp, ECTF_NOTREF));
690     }
691 }
692
693 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
694    pointer to the given type, see if we can compute a pointer to the type
695    resulting from resolving the type down to its base type and use that
696    instead.  This helps with cases where the CTF data includes "struct foo *"
697    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
698
699    XXX what about parent containers?  */
700
701 ctf_id_t
702 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
703 {
704   ctf_file_t *ofp = fp;
705   ctf_id_t ntype;
706
707   if (ctf_lookup_by_id (&fp, type) == NULL)
708     return CTF_ERR;             /* errno is set for us.  */
709
710   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
711     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
712
713   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
714     return (ctf_set_errno (ofp, ECTF_NOTYPE));
715
716   if (ctf_lookup_by_id (&fp, type) == NULL)
717     return (ctf_set_errno (ofp, ECTF_NOTYPE));
718
719   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
720     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
721
722   return (ctf_set_errno (ofp, ECTF_NOTYPE));
723 }
724
725 /* Return the encoding for the specified INTEGER or FLOAT.  */
726
727 int
728 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
729 {
730   ctf_file_t *ofp = fp;
731   ctf_dtdef_t *dtd;
732   const ctf_type_t *tp;
733   ssize_t increment;
734   uint32_t data;
735
736   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
737     return -1;                  /* errno is set for us.  */
738
739   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
740     {
741       *ep = dtd->dtd_u.dtu_enc;
742       return 0;
743     }
744
745   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
746
747   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
748     {
749     case CTF_K_INTEGER:
750       data = *(const uint32_t *) ((uintptr_t) tp + increment);
751       ep->cte_format = CTF_INT_ENCODING (data);
752       ep->cte_offset = CTF_INT_OFFSET (data);
753       ep->cte_bits = CTF_INT_BITS (data);
754       break;
755     case CTF_K_FLOAT:
756       data = *(const uint32_t *) ((uintptr_t) tp + increment);
757       ep->cte_format = CTF_FP_ENCODING (data);
758       ep->cte_offset = CTF_FP_OFFSET (data);
759       ep->cte_bits = CTF_FP_BITS (data);
760       break;
761     case CTF_K_SLICE:
762       {
763         const ctf_slice_t *slice;
764         ctf_encoding_t underlying_en;
765
766         slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
767         data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
768
769         ep->cte_format = underlying_en.cte_format;
770         ep->cte_offset = slice->cts_offset;
771         ep->cte_bits = slice->cts_bits;
772         break;
773       }
774     default:
775       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
776     }
777
778   return 0;
779 }
780
781 int
782 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
783               ctf_id_t rtype)
784 {
785   int rval;
786
787   if (ltype < rtype)
788     rval = -1;
789   else if (ltype > rtype)
790     rval = 1;
791   else
792     rval = 0;
793
794   if (lfp == rfp)
795     return rval;
796
797   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
798     lfp = lfp->ctf_parent;
799
800   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
801     rfp = rfp->ctf_parent;
802
803   if (lfp < rfp)
804     return -1;
805
806   if (lfp > rfp)
807     return 1;
808
809   return rval;
810 }
811
812 /* Return a boolean value indicating if two types are compatible.  This function
813    returns true if the two types are the same, or if they (or their ultimate
814    base type) have the same encoding properties, or (for structs / unions /
815    enums / forward declarations) if they have the same name and (for structs /
816    unions) member count.  */
817
818 int
819 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
820                  ctf_file_t *rfp, ctf_id_t rtype)
821 {
822   const ctf_type_t *ltp, *rtp;
823   ctf_encoding_t le, re;
824   ctf_arinfo_t la, ra;
825   uint32_t lkind, rkind;
826   int same_names = 0;
827
828   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
829     return 1;
830
831   ltype = ctf_type_resolve (lfp, ltype);
832   lkind = ctf_type_kind (lfp, ltype);
833
834   rtype = ctf_type_resolve (rfp, rtype);
835   rkind = ctf_type_kind (rfp, rtype);
836
837   ltp = ctf_lookup_by_id (&lfp, ltype);
838   rtp = ctf_lookup_by_id (&rfp, rtype);
839
840   if (ltp != NULL && rtp != NULL)
841     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
842                           ctf_strptr (rfp, rtp->ctt_name)) == 0);
843
844   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
845       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
846     return 1;
847
848   if (lkind != rkind)
849     return 0;
850
851   switch (lkind)
852     {
853     case CTF_K_INTEGER:
854     case CTF_K_FLOAT:
855       memset (&le, 0, sizeof (le));
856       memset (&re, 0, sizeof (re));
857       return (ctf_type_encoding (lfp, ltype, &le) == 0
858               && ctf_type_encoding (rfp, rtype, &re) == 0
859               && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
860     case CTF_K_POINTER:
861       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
862                                rfp, ctf_type_reference (rfp, rtype)));
863     case CTF_K_ARRAY:
864       return (ctf_array_info (lfp, ltype, &la) == 0
865               && ctf_array_info (rfp, rtype, &ra) == 0
866               && la.ctr_nelems == ra.ctr_nelems
867               && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
868               && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
869     case CTF_K_STRUCT:
870     case CTF_K_UNION:
871       return (same_names && (ctf_type_size (lfp, ltype)
872                              == ctf_type_size (rfp, rtype)));
873     case CTF_K_ENUM:
874       {
875         int lencoded, rencoded;
876         lencoded = ctf_type_encoding (lfp, ltype, &le);
877         rencoded = ctf_type_encoding (rfp, rtype, &re);
878
879         if ((lencoded != rencoded) ||
880             ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
881           return 0;
882       }
883       /* FALLTHRU */
884     case CTF_K_FORWARD:
885       return same_names;   /* No other checks required for these type kinds.  */
886     default:
887       return 0;               /* Should not get here since we did a resolve.  */
888     }
889 }
890
891 /* Return the type and offset for a given member of a STRUCT or UNION.  */
892
893 int
894 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
895                  ctf_membinfo_t *mip)
896 {
897   ctf_file_t *ofp = fp;
898   const ctf_type_t *tp;
899   ctf_dtdef_t *dtd;
900   ssize_t size, increment;
901   uint32_t kind, n;
902
903   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
904     return -1;                  /* errno is set for us.  */
905
906   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
907     return -1;                  /* errno is set for us.  */
908
909   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
910   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
911
912   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
913     return (ctf_set_errno (ofp, ECTF_NOTSOU));
914
915   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
916     {
917       if (size < CTF_LSTRUCT_THRESH)
918         {
919           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
920                                                            increment);
921
922           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
923             {
924               if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
925                 {
926                   mip->ctm_type = mp->ctm_type;
927                   mip->ctm_offset = mp->ctm_offset;
928                   return 0;
929                 }
930             }
931         }
932       else
933         {
934           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
935                                                               increment);
936
937           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
938             {
939               if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
940                 {
941                   mip->ctm_type = lmp->ctlm_type;
942                   mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
943                   return 0;
944                 }
945             }
946         }
947     }
948   else
949     {
950       ctf_dmdef_t *dmd;
951
952       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
953            dmd != NULL; dmd = ctf_list_next (dmd))
954         {
955           if (strcmp (dmd->dmd_name, name) == 0)
956             {
957               mip->ctm_type = dmd->dmd_type;
958               mip->ctm_offset = dmd->dmd_offset;
959               return 0;
960             }
961         }
962     }
963
964   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
965 }
966
967 /* Return the array type, index, and size information for the specified ARRAY.  */
968
969 int
970 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
971 {
972   ctf_file_t *ofp = fp;
973   const ctf_type_t *tp;
974   const ctf_array_t *ap;
975   const ctf_dtdef_t *dtd;
976   ssize_t increment;
977
978   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
979     return -1;                  /* errno is set for us.  */
980
981   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
982     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
983
984   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
985     {
986       *arp = dtd->dtd_u.dtu_arr;
987       return 0;
988     }
989
990   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
991
992   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
993   arp->ctr_contents = ap->cta_contents;
994   arp->ctr_index = ap->cta_index;
995   arp->ctr_nelems = ap->cta_nelems;
996
997   return 0;
998 }
999
1000 /* Convert the specified value to the corresponding enum tag name, if a
1001    matching name can be found.  Otherwise NULL is returned.  */
1002
1003 const char *
1004 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1005 {
1006   ctf_file_t *ofp = fp;
1007   const ctf_type_t *tp;
1008   const ctf_enum_t *ep;
1009   const ctf_dtdef_t *dtd;
1010   ssize_t increment;
1011   uint32_t n;
1012
1013   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1014     return NULL;                /* errno is set for us.  */
1015
1016   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1017     return NULL;                /* errno is set for us.  */
1018
1019   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1020     {
1021       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1022       return NULL;
1023     }
1024
1025   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1026
1027   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1028     {
1029       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1030
1031       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1032         {
1033           if (ep->cte_value == value)
1034             return (ctf_strptr (fp, ep->cte_name));
1035         }
1036     }
1037   else
1038     {
1039       ctf_dmdef_t *dmd;
1040
1041       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1042            dmd != NULL; dmd = ctf_list_next (dmd))
1043         {
1044           if (dmd->dmd_value == value)
1045             return dmd->dmd_name;
1046         }
1047     }
1048
1049   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1050   return NULL;
1051 }
1052
1053 /* Convert the specified enum tag name to the corresponding value, if a
1054    matching name can be found.  Otherwise CTF_ERR is returned.  */
1055
1056 int
1057 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1058 {
1059   ctf_file_t *ofp = fp;
1060   const ctf_type_t *tp;
1061   const ctf_enum_t *ep;
1062   const ctf_dtdef_t *dtd;
1063   ssize_t increment;
1064   uint32_t n;
1065
1066   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1067     return -1;                  /* errno is set for us.  */
1068
1069   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1070     return -1;                  /* errno is set for us.  */
1071
1072   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1073     {
1074       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1075       return -1;
1076     }
1077
1078   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1079
1080   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1081
1082   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1083     {
1084       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1085         {
1086           if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1087             {
1088               if (valp != NULL)
1089                 *valp = ep->cte_value;
1090               return 0;
1091             }
1092         }
1093     }
1094   else
1095     {
1096       ctf_dmdef_t *dmd;
1097
1098       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1099            dmd != NULL; dmd = ctf_list_next (dmd))
1100         {
1101           if (strcmp (dmd->dmd_name, name) == 0)
1102             {
1103               if (valp != NULL)
1104                 *valp = dmd->dmd_value;
1105               return 0;
1106             }
1107         }
1108     }
1109
1110   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1111   return -1;
1112 }
1113
1114 /* Given a type ID relating to a function type, return info on return types and
1115    arg counts for that function.  */
1116
1117 int
1118 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1119 {
1120   const ctf_type_t *tp;
1121   uint32_t kind;
1122   const uint32_t *args;
1123   const ctf_dtdef_t *dtd;
1124   ssize_t size, increment;
1125
1126   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1127     return -1;                  /* errno is set for us.  */
1128
1129   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1130     return -1;                  /* errno is set for us.  */
1131
1132   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1133   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1134
1135   if (kind != CTF_K_FUNCTION)
1136     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1137
1138   fip->ctc_return = tp->ctt_type;
1139   fip->ctc_flags = 0;
1140   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1141
1142   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1143     args = (uint32_t *) ((uintptr_t) tp + increment);
1144   else
1145     args = (uint32_t *) dtd->dtd_u.dtu_argv;
1146
1147   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1148     {
1149       fip->ctc_flags |= CTF_FUNC_VARARG;
1150       fip->ctc_argc--;
1151     }
1152
1153   return 0;
1154 }
1155
1156 /* Given a type ID relating to a function type,, return the arguments for the
1157    function.  */
1158
1159 int
1160 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1161 {
1162   const ctf_type_t *tp;
1163   const uint32_t *args;
1164   const ctf_dtdef_t *dtd;
1165   ssize_t size, increment;
1166   ctf_funcinfo_t f;
1167
1168   if (ctf_func_type_info (fp, type, &f) < 0)
1169     return -1;                  /* errno is set for us.  */
1170
1171   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1172     return -1;                  /* errno is set for us.  */
1173
1174   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1175     return -1;                  /* errno is set for us.  */
1176
1177   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1178
1179   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1180     args = (uint32_t *) ((uintptr_t) tp + increment);
1181   else
1182     args = (uint32_t *) dtd->dtd_u.dtu_argv;
1183
1184   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1185     *argv++ = *args++;
1186
1187   return 0;
1188 }
1189
1190 /* Recursively visit the members of any type.  This function is used as the
1191    engine for ctf_type_visit, below.  We resolve the input type, recursively
1192    invoke ourself for each type member if the type is a struct or union, and
1193    then invoke the callback function on the current type.  If any callback
1194    returns non-zero, we abort and percolate the error code back up to the top.  */
1195
1196 static int
1197 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1198                  void *arg, const char *name, unsigned long offset, int depth)
1199 {
1200   ctf_id_t otype = type;
1201   const ctf_type_t *tp;
1202   const ctf_dtdef_t *dtd;
1203   ssize_t size, increment;
1204   uint32_t kind, n;
1205   int rc;
1206
1207   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1208     return -1;                  /* errno is set for us.  */
1209
1210   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1211     return -1;                  /* errno is set for us.  */
1212
1213   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1214     return rc;
1215
1216   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1217
1218   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1219     return 0;
1220
1221   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1222
1223   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1224     {
1225       if (size < CTF_LSTRUCT_THRESH)
1226         {
1227           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1228                                                            increment);
1229
1230           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1231             {
1232               if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1233                                          func, arg, ctf_strptr (fp,
1234                                                                 mp->ctm_name),
1235                                          offset + mp->ctm_offset,
1236                                          depth + 1)) != 0)
1237                 return rc;
1238             }
1239         }
1240       else
1241         {
1242           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1243                                                               increment);
1244
1245           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1246             {
1247               if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1248                                          func, arg, ctf_strptr (fp,
1249                                                                 lmp->ctlm_name),
1250                                          offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1251                                          depth + 1)) != 0)
1252                 return rc;
1253             }
1254         }
1255     }
1256   else
1257     {
1258       ctf_dmdef_t *dmd;
1259
1260       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1261            dmd != NULL; dmd = ctf_list_next (dmd))
1262         {
1263           if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1264                                      dmd->dmd_name, dmd->dmd_offset,
1265                                      depth + 1)) != 0)
1266             return rc;
1267         }
1268     }
1269
1270   return 0;
1271 }
1272
1273 /* Recursively visit the members of any type.  We pass the name, member
1274  type, and offset of each member to the specified callback function.  */
1275 int
1276 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1277 {
1278   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1279 }
This page took 0.097351 seconds and 4 git commands to generate.