]> Git Repo - binutils.git/blob - libctf/ctf-types.c
libctf: allow ctf_type_lname of a null pointer.
[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;
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         const ctf_slice_t *sp;
684         ssize_t increment;
685         (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
686         sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
687         return sp->cts_type;
688       }
689     default:
690       return (ctf_set_errno (ofp, ECTF_NOTREF));
691     }
692 }
693
694 /* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
695    pointer to the given type, see if we can compute a pointer to the type
696    resulting from resolving the type down to its base type and use that
697    instead.  This helps with cases where the CTF data includes "struct foo *"
698    but not "foo_t *" and the user accesses "foo_t *" in the debugger.
699
700    XXX what about parent containers?  */
701
702 ctf_id_t
703 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
704 {
705   ctf_file_t *ofp = fp;
706   ctf_id_t ntype;
707
708   if (ctf_lookup_by_id (&fp, type) == NULL)
709     return CTF_ERR;             /* errno is set for us.  */
710
711   if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
712     return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
713
714   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
715     return (ctf_set_errno (ofp, ECTF_NOTYPE));
716
717   if (ctf_lookup_by_id (&fp, type) == NULL)
718     return (ctf_set_errno (ofp, ECTF_NOTYPE));
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   return (ctf_set_errno (ofp, ECTF_NOTYPE));
724 }
725
726 /* Return the encoding for the specified INTEGER or FLOAT.  */
727
728 int
729 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
730 {
731   ctf_file_t *ofp = fp;
732   ctf_dtdef_t *dtd;
733   const ctf_type_t *tp;
734   ssize_t increment;
735   uint32_t data;
736
737   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
738     return -1;                  /* errno is set for us.  */
739
740   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
741     {
742       *ep = dtd->dtd_u.dtu_enc;
743       return 0;
744     }
745
746   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
747
748   switch (LCTF_INFO_KIND (fp, tp->ctt_info))
749     {
750     case CTF_K_INTEGER:
751       data = *(const uint32_t *) ((uintptr_t) tp + increment);
752       ep->cte_format = CTF_INT_ENCODING (data);
753       ep->cte_offset = CTF_INT_OFFSET (data);
754       ep->cte_bits = CTF_INT_BITS (data);
755       break;
756     case CTF_K_FLOAT:
757       data = *(const uint32_t *) ((uintptr_t) tp + increment);
758       ep->cte_format = CTF_FP_ENCODING (data);
759       ep->cte_offset = CTF_FP_OFFSET (data);
760       ep->cte_bits = CTF_FP_BITS (data);
761       break;
762     case CTF_K_SLICE:
763       {
764         const ctf_slice_t *slice;
765         ctf_encoding_t underlying_en;
766
767         slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
768         data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
769
770         ep->cte_format = underlying_en.cte_format;
771         ep->cte_offset = slice->cts_offset;
772         ep->cte_bits = slice->cts_bits;
773         break;
774       }
775     default:
776       return (ctf_set_errno (ofp, ECTF_NOTINTFP));
777     }
778
779   return 0;
780 }
781
782 int
783 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
784               ctf_id_t rtype)
785 {
786   int rval;
787
788   if (ltype < rtype)
789     rval = -1;
790   else if (ltype > rtype)
791     rval = 1;
792   else
793     rval = 0;
794
795   if (lfp == rfp)
796     return rval;
797
798   if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
799     lfp = lfp->ctf_parent;
800
801   if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
802     rfp = rfp->ctf_parent;
803
804   if (lfp < rfp)
805     return -1;
806
807   if (lfp > rfp)
808     return 1;
809
810   return rval;
811 }
812
813 /* Return a boolean value indicating if two types are compatible.  This function
814    returns true if the two types are the same, or if they (or their ultimate
815    base type) have the same encoding properties, or (for structs / unions /
816    enums / forward declarations) if they have the same name and (for structs /
817    unions) member count.  */
818
819 int
820 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
821                  ctf_file_t *rfp, ctf_id_t rtype)
822 {
823   const ctf_type_t *ltp, *rtp;
824   ctf_encoding_t le, re;
825   ctf_arinfo_t la, ra;
826   uint32_t lkind, rkind;
827   int same_names = 0;
828
829   if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
830     return 1;
831
832   ltype = ctf_type_resolve (lfp, ltype);
833   lkind = ctf_type_kind (lfp, ltype);
834
835   rtype = ctf_type_resolve (rfp, rtype);
836   rkind = ctf_type_kind (rfp, rtype);
837
838   ltp = ctf_lookup_by_id (&lfp, ltype);
839   rtp = ctf_lookup_by_id (&rfp, rtype);
840
841   if (ltp != NULL && rtp != NULL)
842     same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
843                           ctf_strptr (rfp, rtp->ctt_name)) == 0);
844
845   if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
846       ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
847     return 1;
848
849   if (lkind != rkind)
850     return 0;
851
852   switch (lkind)
853     {
854     case CTF_K_INTEGER:
855     case CTF_K_FLOAT:
856       memset (&le, 0, sizeof (le));
857       memset (&re, 0, sizeof (re));
858       return (ctf_type_encoding (lfp, ltype, &le) == 0
859               && ctf_type_encoding (rfp, rtype, &re) == 0
860               && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
861     case CTF_K_POINTER:
862       return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
863                                rfp, ctf_type_reference (rfp, rtype)));
864     case CTF_K_ARRAY:
865       return (ctf_array_info (lfp, ltype, &la) == 0
866               && ctf_array_info (rfp, rtype, &ra) == 0
867               && la.ctr_nelems == ra.ctr_nelems
868               && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
869               && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
870     case CTF_K_STRUCT:
871     case CTF_K_UNION:
872       return (same_names && (ctf_type_size (lfp, ltype)
873                              == ctf_type_size (rfp, rtype)));
874     case CTF_K_ENUM:
875       {
876         int lencoded, rencoded;
877         lencoded = ctf_type_encoding (lfp, ltype, &le);
878         rencoded = ctf_type_encoding (rfp, rtype, &re);
879
880         if ((lencoded != rencoded) ||
881             ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
882           return 0;
883       }
884       /* FALLTHRU */
885     case CTF_K_FORWARD:
886       return same_names;   /* No other checks required for these type kinds.  */
887     default:
888       return 0;               /* Should not get here since we did a resolve.  */
889     }
890 }
891
892 /* Return the type and offset for a given member of a STRUCT or UNION.  */
893
894 int
895 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
896                  ctf_membinfo_t *mip)
897 {
898   ctf_file_t *ofp = fp;
899   const ctf_type_t *tp;
900   ctf_dtdef_t *dtd;
901   ssize_t size, increment;
902   uint32_t kind, n;
903
904   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
905     return -1;                  /* errno is set for us.  */
906
907   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
908     return -1;                  /* errno is set for us.  */
909
910   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
911   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
912
913   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
914     return (ctf_set_errno (ofp, ECTF_NOTSOU));
915
916   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
917     {
918       if (size < CTF_LSTRUCT_THRESH)
919         {
920           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
921                                                            increment);
922
923           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
924             {
925               if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
926                 {
927                   mip->ctm_type = mp->ctm_type;
928                   mip->ctm_offset = mp->ctm_offset;
929                   return 0;
930                 }
931             }
932         }
933       else
934         {
935           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
936                                                               increment);
937
938           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
939             {
940               if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
941                 {
942                   mip->ctm_type = lmp->ctlm_type;
943                   mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
944                   return 0;
945                 }
946             }
947         }
948     }
949   else
950     {
951       ctf_dmdef_t *dmd;
952
953       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
954            dmd != NULL; dmd = ctf_list_next (dmd))
955         {
956           if (strcmp (dmd->dmd_name, name) == 0)
957             {
958               mip->ctm_type = dmd->dmd_type;
959               mip->ctm_offset = dmd->dmd_offset;
960               return 0;
961             }
962         }
963     }
964
965   return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
966 }
967
968 /* Return the array type, index, and size information for the specified ARRAY.  */
969
970 int
971 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
972 {
973   ctf_file_t *ofp = fp;
974   const ctf_type_t *tp;
975   const ctf_array_t *ap;
976   const ctf_dtdef_t *dtd;
977   ssize_t increment;
978
979   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
980     return -1;                  /* errno is set for us.  */
981
982   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
983     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
984
985   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
986     {
987       *arp = dtd->dtd_u.dtu_arr;
988       return 0;
989     }
990
991   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
992
993   ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
994   arp->ctr_contents = ap->cta_contents;
995   arp->ctr_index = ap->cta_index;
996   arp->ctr_nelems = ap->cta_nelems;
997
998   return 0;
999 }
1000
1001 /* Convert the specified value to the corresponding enum tag name, if a
1002    matching name can be found.  Otherwise NULL is returned.  */
1003
1004 const char *
1005 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1006 {
1007   ctf_file_t *ofp = fp;
1008   const ctf_type_t *tp;
1009   const ctf_enum_t *ep;
1010   const ctf_dtdef_t *dtd;
1011   ssize_t increment;
1012   uint32_t n;
1013
1014   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1015     return NULL;                /* errno is set for us.  */
1016
1017   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1018     return NULL;                /* errno is set for us.  */
1019
1020   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1021     {
1022       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1023       return NULL;
1024     }
1025
1026   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1027
1028   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1029     {
1030       ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1031
1032       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1033         {
1034           if (ep->cte_value == value)
1035             return (ctf_strptr (fp, ep->cte_name));
1036         }
1037     }
1038   else
1039     {
1040       ctf_dmdef_t *dmd;
1041
1042       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1043            dmd != NULL; dmd = ctf_list_next (dmd))
1044         {
1045           if (dmd->dmd_value == value)
1046             return dmd->dmd_name;
1047         }
1048     }
1049
1050   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1051   return NULL;
1052 }
1053
1054 /* Convert the specified enum tag name to the corresponding value, if a
1055    matching name can be found.  Otherwise CTF_ERR is returned.  */
1056
1057 int
1058 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1059 {
1060   ctf_file_t *ofp = fp;
1061   const ctf_type_t *tp;
1062   const ctf_enum_t *ep;
1063   const ctf_dtdef_t *dtd;
1064   ssize_t increment;
1065   uint32_t n;
1066
1067   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1068     return -1;                  /* errno is set for us.  */
1069
1070   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1071     return -1;                  /* errno is set for us.  */
1072
1073   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1074     {
1075       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1076       return -1;
1077     }
1078
1079   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1080
1081   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1082
1083   if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1084     {
1085       for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1086         {
1087           if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1088             {
1089               if (valp != NULL)
1090                 *valp = ep->cte_value;
1091               return 0;
1092             }
1093         }
1094     }
1095   else
1096     {
1097       ctf_dmdef_t *dmd;
1098
1099       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1100            dmd != NULL; dmd = ctf_list_next (dmd))
1101         {
1102           if (strcmp (dmd->dmd_name, name) == 0)
1103             {
1104               if (valp != NULL)
1105                 *valp = dmd->dmd_value;
1106               return 0;
1107             }
1108         }
1109     }
1110
1111   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1112   return -1;
1113 }
1114
1115 /* Given a type ID relating to a function type, return info on return types and
1116    arg counts for that function.  */
1117
1118 int
1119 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1120 {
1121   const ctf_type_t *tp;
1122   uint32_t kind;
1123   const uint32_t *args;
1124   const ctf_dtdef_t *dtd;
1125   ssize_t size, increment;
1126
1127   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1128     return -1;                  /* errno is set for us.  */
1129
1130   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1131     return -1;                  /* errno is set for us.  */
1132
1133   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1134   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1135
1136   if (kind != CTF_K_FUNCTION)
1137     return (ctf_set_errno (fp, ECTF_NOTFUNC));
1138
1139   fip->ctc_return = tp->ctt_type;
1140   fip->ctc_flags = 0;
1141   fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1142
1143   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1144     args = (uint32_t *) ((uintptr_t) tp + increment);
1145   else
1146     args = (uint32_t *) dtd->dtd_u.dtu_argv;
1147
1148   if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1149     {
1150       fip->ctc_flags |= CTF_FUNC_VARARG;
1151       fip->ctc_argc--;
1152     }
1153
1154   return 0;
1155 }
1156
1157 /* Given a type ID relating to a function type,, return the arguments for the
1158    function.  */
1159
1160 int
1161 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1162 {
1163   const ctf_type_t *tp;
1164   const uint32_t *args;
1165   const ctf_dtdef_t *dtd;
1166   ssize_t size, increment;
1167   ctf_funcinfo_t f;
1168
1169   if (ctf_func_type_info (fp, type, &f) < 0)
1170     return -1;                  /* errno is set for us.  */
1171
1172   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1173     return -1;                  /* errno is set for us.  */
1174
1175   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1176     return -1;                  /* errno is set for us.  */
1177
1178   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1179
1180   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1181     args = (uint32_t *) ((uintptr_t) tp + increment);
1182   else
1183     args = (uint32_t *) dtd->dtd_u.dtu_argv;
1184
1185   for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1186     *argv++ = *args++;
1187
1188   return 0;
1189 }
1190
1191 /* Recursively visit the members of any type.  This function is used as the
1192    engine for ctf_type_visit, below.  We resolve the input type, recursively
1193    invoke ourself for each type member if the type is a struct or union, and
1194    then invoke the callback function on the current type.  If any callback
1195    returns non-zero, we abort and percolate the error code back up to the top.  */
1196
1197 static int
1198 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1199                  void *arg, const char *name, unsigned long offset, int depth)
1200 {
1201   ctf_id_t otype = type;
1202   const ctf_type_t *tp;
1203   const ctf_dtdef_t *dtd;
1204   ssize_t size, increment;
1205   uint32_t kind, n;
1206   int rc;
1207
1208   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1209     return -1;                  /* errno is set for us.  */
1210
1211   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1212     return -1;                  /* errno is set for us.  */
1213
1214   if ((rc = func (name, otype, offset, depth, arg)) != 0)
1215     return rc;
1216
1217   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1218
1219   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1220     return 0;
1221
1222   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1223
1224   if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1225     {
1226       if (size < CTF_LSTRUCT_THRESH)
1227         {
1228           const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1229                                                            increment);
1230
1231           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1232             {
1233               if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1234                                          func, arg, ctf_strptr (fp,
1235                                                                 mp->ctm_name),
1236                                          offset + mp->ctm_offset,
1237                                          depth + 1)) != 0)
1238                 return rc;
1239             }
1240         }
1241       else
1242         {
1243           const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1244                                                               increment);
1245
1246           for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1247             {
1248               if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1249                                          func, arg, ctf_strptr (fp,
1250                                                                 lmp->ctlm_name),
1251                                          offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1252                                          depth + 1)) != 0)
1253                 return rc;
1254             }
1255         }
1256     }
1257   else
1258     {
1259       ctf_dmdef_t *dmd;
1260
1261       for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1262            dmd != NULL; dmd = ctf_list_next (dmd))
1263         {
1264           if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1265                                      dmd->dmd_name, dmd->dmd_offset,
1266                                      depth + 1)) != 0)
1267             return rc;
1268         }
1269     }
1270
1271   return 0;
1272 }
1273
1274 /* Recursively visit the members of any type.  We pass the name, member
1275  type, and offset of each member to the specified callback function.  */
1276 int
1277 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1278 {
1279   return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1280 }
This page took 0.093165 seconds and 4 git commands to generate.