Update NEWS post GDB 9 branch creation.
[binutils-gdb.git] / libctf / ctf-types.c
blobb0139e82bd75e9a272016883a5f0156dda5bb58e
1 /* Type handling functions.
2 Copyright (C) 2019 Free Software Foundation, Inc.
4 This file is part of libctf.
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.
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.
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/>. */
20 #include <ctf-impl.h>
21 #include <string.h>
23 /* Determine whether a type is a parent or a child. */
25 int
26 ctf_type_isparent (ctf_file_t *fp, ctf_id_t id)
28 return (LCTF_TYPE_ISPARENT (fp, id));
31 int
32 ctf_type_ischild (ctf_file_t * fp, ctf_id_t id)
34 return (LCTF_TYPE_ISCHILD (fp, id));
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. */
40 int
41 ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
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;
50 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
51 return -1; /* errno is set for us. */
53 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
54 return -1; /* errno is set for us. */
56 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
57 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
59 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
60 return (ctf_set_errno (ofp, ECTF_NOTSOU));
62 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
64 if (size < CTF_LSTRUCT_THRESH)
66 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
67 increment);
69 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
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;
76 else
78 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
79 increment);
81 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
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;
90 else
92 ctf_dmdef_t *dmd;
94 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
95 dmd != NULL; dmd = ctf_list_next (dmd))
97 if ((rc = func (dmd->dmd_name, dmd->dmd_type,
98 dmd->dmd_offset, arg)) != 0)
99 return rc;
103 return 0;
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. */
110 ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
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;
120 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
121 return -1; /* errno is set for us. */
123 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
124 return -1; /* errno is set for us. */
126 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
127 return (ctf_set_errno (ofp, ECTF_NOTENUM));
129 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
131 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
133 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
135 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
137 const char *name = ctf_strptr (fp, ep->cte_name);
138 if ((rc = func (name, ep->cte_value, arg)) != 0)
139 return rc;
142 else
144 ctf_dmdef_t *dmd;
146 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
147 dmd != NULL; dmd = ctf_list_next (dmd))
149 if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0)
150 return rc;
154 return 0;
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. */
161 ctf_type_iter (ctf_file_t *fp, ctf_type_f *func, void *arg)
163 ctf_id_t id, max = fp->ctf_typemax;
164 int rc, child = (fp->ctf_flags & LCTF_CHILD);
166 for (id = 1; id <= max; id++)
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;
174 return 0;
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. */
181 ctf_type_iter_all (ctf_file_t *fp, ctf_type_all_f *func, void *arg)
183 ctf_id_t id, max = fp->ctf_typemax;
184 int rc, child = (fp->ctf_flags & LCTF_CHILD);
186 for (id = 1; id <= max; id++)
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;
195 return 0;
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. */
202 ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg)
204 int rc;
206 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
207 return ECTF_NOPARENT;
209 if (!(fp->ctf_flags & LCTF_RDWR))
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;
217 else
219 ctf_dvdef_t *dvd;
221 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
222 dvd = ctf_list_next (dvd))
224 if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
225 return rc;
229 return 0;
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.
238 Does not drill down through slices to their contained type. */
240 ctf_id_t
241 ctf_type_resolve (ctf_file_t *fp, ctf_id_t type)
243 ctf_id_t prev = type, otype = type;
244 ctf_file_t *ofp = fp;
245 const ctf_type_t *tp;
247 if (type == 0)
248 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
250 while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
252 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
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)
261 ctf_dprintf ("type %ld cycle detected\n", otype);
262 return (ctf_set_errno (ofp, ECTF_CORRUPT));
264 prev = type;
265 type = tp->ctt_type;
266 break;
267 default:
268 return type;
270 if (type == 0)
271 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
274 return CTF_ERR; /* errno is set for us. */
277 /* Like ctf_type_resolve(), but traverse down through slices to their contained
278 type. */
280 ctf_id_t
281 ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type)
283 const ctf_type_t *tp;
285 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
286 return -1;
288 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
289 return CTF_ERR; /* errno is set for us. */
291 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
292 return ctf_type_reference (fp, type);
293 return type;
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. */
299 ctf_id_t ctf_lookup_by_rawname (ctf_file_t *fp, int kind, const char *name)
301 return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
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. */
308 ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *fp, ctf_names_t *np, const char *name)
310 ctf_id_t id;
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;
319 /* Lookup the given type ID and return its name as a new dynamcally-allocated
320 string. */
322 char *
323 ctf_type_aname (ctf_file_t *fp, ctf_id_t type)
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;
332 if (fp == NULL && type == CTF_ERR)
333 return NULL; /* Simplify caller code by permitting CTF_ERR. */
335 ctf_decl_init (&cd);
336 ctf_decl_push (&cd, fp, type);
338 if (cd.cd_err != 0)
340 ctf_decl_fini (&cd);
341 ctf_set_errno (fp, cd.cd_err);
342 return NULL;
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 (*[])(). */
351 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
352 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
354 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
355 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
357 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */
359 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
361 for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
362 cdp != NULL; cdp = ctf_list_next (cdp))
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);
368 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
369 ctf_decl_sprintf (&cd, " ");
371 if (lp == prec)
373 ctf_decl_sprintf (&cd, "(");
374 lp = -1;
377 switch (cdp->cd_kind)
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;
418 k = cdp->cd_kind;
421 if (rp == prec)
422 ctf_decl_sprintf (&cd, ")");
425 if (cd.cd_enomem)
426 (void) ctf_set_errno (fp, ENOMEM);
428 buf = ctf_decl_buf (&cd);
430 ctf_decl_fini (&cd);
431 return buf;
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. */
437 ssize_t
438 ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
440 char *str = ctf_type_aname (fp, type);
441 size_t slen;
443 if (str == NULL)
444 return CTF_ERR; /* errno is set for us. */
446 slen = strlen (str);
447 snprintf (buf, len, "%s", str);
448 free (str);
450 if (slen >= len)
451 (void) ctf_set_errno (fp, ECTF_NAMELEN);
453 return slen;
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. */
459 char *
460 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
462 ssize_t rv = ctf_type_lname (fp, type, buf, len);
463 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
466 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
467 new dynamcally-allocated string. */
469 char *
470 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
472 const ctf_type_t *tp;
474 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
475 return NULL; /* errno is set for us. */
477 if (ctf_strraw (fp, tp->ctt_name) != NULL)
478 return strdup (ctf_strraw (fp, tp->ctt_name));
480 return NULL;
483 /* Resolve the type down to a base type node, and then return the size
484 of the type storage in bytes. */
486 ssize_t
487 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
489 const ctf_type_t *tp;
490 ssize_t size;
491 ctf_arinfo_t ar;
493 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
494 return -1; /* errno is set for us. */
496 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
497 return -1; /* errno is set for us. */
499 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
501 case CTF_K_POINTER:
502 return fp->ctf_dmodel->ctd_pointer;
504 case CTF_K_FUNCTION:
505 return 0; /* Function size is only known by symtab. */
507 case CTF_K_ENUM:
508 return fp->ctf_dmodel->ctd_int;
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.
514 If ctf_get_ctt_size() returns nonzero, then use the recorded
515 size instead. */
517 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
518 return size;
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. */
524 return size * ar.ctr_nelems;
526 default: /* including slices of enums, etc */
527 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
531 /* Resolve the type down to a base type node, and then return the alignment
532 needed for the type storage in bytes.
534 XXX may need arch-dependent attention. */
536 ssize_t
537 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
539 const ctf_type_t *tp;
540 ctf_file_t *ofp = fp;
541 int kind;
543 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
544 return -1; /* errno is set for us. */
546 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
547 return -1; /* errno is set for us. */
549 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
550 switch (kind)
552 case CTF_K_POINTER:
553 case CTF_K_FUNCTION:
554 return fp->ctf_dmodel->ctd_pointer;
556 case CTF_K_ARRAY:
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));
564 case CTF_K_STRUCT:
565 case CTF_K_UNION:
567 size_t align = 0;
568 ctf_dtdef_t *dtd;
570 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
572 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
573 ssize_t size, increment;
574 const void *vmp;
576 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
577 vmp = (unsigned char *) tp + increment;
579 if (kind == CTF_K_STRUCT)
580 n = MIN (n, 1); /* Only use first member for structs. */
582 if (size < CTF_LSTRUCT_THRESH)
584 const ctf_member_t *mp = vmp;
585 for (; n != 0; n--, mp++)
587 ssize_t am = ctf_type_align (fp, mp->ctm_type);
588 align = MAX (align, (size_t) am);
591 else
593 const ctf_lmember_t *lmp = vmp;
594 for (; n != 0; n--, lmp++)
596 ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
597 align = MAX (align, (size_t) am);
601 else
603 ctf_dmdef_t *dmd;
605 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
606 dmd != NULL; dmd = ctf_list_next (dmd))
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;
615 return align;
618 case CTF_K_ENUM:
619 return fp->ctf_dmodel->ctd_int;
621 default: /* including slices of enums, etc */
622 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
626 /* Return the kind (CTF_K_* constant) for the specified type ID. */
629 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
631 const ctf_type_t *tp;
633 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
634 return -1; /* errno is set for us. */
636 return (LCTF_INFO_KIND (fp, tp->ctt_info));
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. */
643 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
645 int kind;
647 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
648 return -1;
650 if (kind == CTF_K_SLICE)
652 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
653 return -1;
654 kind = ctf_type_kind_unsliced (fp, type);
657 return kind;
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. */
663 ctf_id_t
664 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
666 ctf_file_t *ofp = fp;
667 const ctf_type_t *tp;
669 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
670 return CTF_ERR; /* errno is set for us. */
672 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
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:
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;
689 default:
690 return (ctf_set_errno (ofp, ECTF_NOTREF));
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.
700 XXX what about parent containers? */
702 ctf_id_t
703 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
705 ctf_file_t *ofp = fp;
706 ctf_id_t ntype;
708 if (ctf_lookup_by_id (&fp, type) == NULL)
709 return CTF_ERR; /* errno is set for us. */
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)));
714 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
715 return (ctf_set_errno (ofp, ECTF_NOTYPE));
717 if (ctf_lookup_by_id (&fp, type) == NULL)
718 return (ctf_set_errno (ofp, ECTF_NOTYPE));
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)));
723 return (ctf_set_errno (ofp, ECTF_NOTYPE));
726 /* Return the encoding for the specified INTEGER or FLOAT. */
729 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
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;
737 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
738 return -1; /* errno is set for us. */
740 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
742 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
744 case CTF_K_INTEGER:
745 case CTF_K_FLOAT:
746 *ep = dtd->dtd_u.dtu_enc;
747 break;
748 case CTF_K_SLICE:
750 const ctf_slice_t *slice;
751 ctf_encoding_t underlying_en;
752 slice = &dtd->dtd_u.dtu_slice;
754 data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
755 ep->cte_format = underlying_en.cte_format;
756 ep->cte_offset = slice->cts_offset;
757 ep->cte_bits = slice->cts_bits;
758 break;
760 default:
761 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
763 return 0;
766 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
768 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
770 case CTF_K_INTEGER:
771 data = *(const uint32_t *) ((uintptr_t) tp + increment);
772 ep->cte_format = CTF_INT_ENCODING (data);
773 ep->cte_offset = CTF_INT_OFFSET (data);
774 ep->cte_bits = CTF_INT_BITS (data);
775 break;
776 case CTF_K_FLOAT:
777 data = *(const uint32_t *) ((uintptr_t) tp + increment);
778 ep->cte_format = CTF_FP_ENCODING (data);
779 ep->cte_offset = CTF_FP_OFFSET (data);
780 ep->cte_bits = CTF_FP_BITS (data);
781 break;
782 case CTF_K_SLICE:
784 const ctf_slice_t *slice;
785 ctf_encoding_t underlying_en;
787 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
788 data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
790 ep->cte_format = underlying_en.cte_format;
791 ep->cte_offset = slice->cts_offset;
792 ep->cte_bits = slice->cts_bits;
793 break;
795 default:
796 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
799 return 0;
803 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
804 ctf_id_t rtype)
806 int rval;
808 if (ltype < rtype)
809 rval = -1;
810 else if (ltype > rtype)
811 rval = 1;
812 else
813 rval = 0;
815 if (lfp == rfp)
816 return rval;
818 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
819 lfp = lfp->ctf_parent;
821 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
822 rfp = rfp->ctf_parent;
824 if (lfp < rfp)
825 return -1;
827 if (lfp > rfp)
828 return 1;
830 return rval;
833 /* Return a boolean value indicating if two types are compatible. This function
834 returns true if the two types are the same, or if they (or their ultimate
835 base type) have the same encoding properties, or (for structs / unions /
836 enums / forward declarations) if they have the same name and (for structs /
837 unions) member count. */
840 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
841 ctf_file_t *rfp, ctf_id_t rtype)
843 const ctf_type_t *ltp, *rtp;
844 ctf_encoding_t le, re;
845 ctf_arinfo_t la, ra;
846 uint32_t lkind, rkind;
847 int same_names = 0;
849 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
850 return 1;
852 ltype = ctf_type_resolve (lfp, ltype);
853 lkind = ctf_type_kind (lfp, ltype);
855 rtype = ctf_type_resolve (rfp, rtype);
856 rkind = ctf_type_kind (rfp, rtype);
858 ltp = ctf_lookup_by_id (&lfp, ltype);
859 rtp = ctf_lookup_by_id (&rfp, rtype);
861 if (ltp != NULL && rtp != NULL)
862 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
863 ctf_strptr (rfp, rtp->ctt_name)) == 0);
865 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
866 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
867 return 1;
869 if (lkind != rkind)
870 return 0;
872 switch (lkind)
874 case CTF_K_INTEGER:
875 case CTF_K_FLOAT:
876 memset (&le, 0, sizeof (le));
877 memset (&re, 0, sizeof (re));
878 return (ctf_type_encoding (lfp, ltype, &le) == 0
879 && ctf_type_encoding (rfp, rtype, &re) == 0
880 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
881 case CTF_K_POINTER:
882 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
883 rfp, ctf_type_reference (rfp, rtype)));
884 case CTF_K_ARRAY:
885 return (ctf_array_info (lfp, ltype, &la) == 0
886 && ctf_array_info (rfp, rtype, &ra) == 0
887 && la.ctr_nelems == ra.ctr_nelems
888 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
889 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
890 case CTF_K_STRUCT:
891 case CTF_K_UNION:
892 return (same_names && (ctf_type_size (lfp, ltype)
893 == ctf_type_size (rfp, rtype)));
894 case CTF_K_ENUM:
896 int lencoded, rencoded;
897 lencoded = ctf_type_encoding (lfp, ltype, &le);
898 rencoded = ctf_type_encoding (rfp, rtype, &re);
900 if ((lencoded != rencoded) ||
901 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
902 return 0;
904 /* FALLTHRU */
905 case CTF_K_FORWARD:
906 return same_names; /* No other checks required for these type kinds. */
907 default:
908 return 0; /* Should not get here since we did a resolve. */
912 /* Return the type and offset for a given member of a STRUCT or UNION. */
915 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
916 ctf_membinfo_t *mip)
918 ctf_file_t *ofp = fp;
919 const ctf_type_t *tp;
920 ctf_dtdef_t *dtd;
921 ssize_t size, increment;
922 uint32_t kind, n;
924 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
925 return -1; /* errno is set for us. */
927 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
928 return -1; /* errno is set for us. */
930 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
931 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
933 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
934 return (ctf_set_errno (ofp, ECTF_NOTSOU));
936 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
938 if (size < CTF_LSTRUCT_THRESH)
940 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
941 increment);
943 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
945 if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
947 mip->ctm_type = mp->ctm_type;
948 mip->ctm_offset = mp->ctm_offset;
949 return 0;
953 else
955 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
956 increment);
958 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
960 if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
962 mip->ctm_type = lmp->ctlm_type;
963 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
964 return 0;
969 else
971 ctf_dmdef_t *dmd;
973 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
974 dmd != NULL; dmd = ctf_list_next (dmd))
976 if (strcmp (dmd->dmd_name, name) == 0)
978 mip->ctm_type = dmd->dmd_type;
979 mip->ctm_offset = dmd->dmd_offset;
980 return 0;
985 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
988 /* Return the array type, index, and size information for the specified ARRAY. */
991 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
993 ctf_file_t *ofp = fp;
994 const ctf_type_t *tp;
995 const ctf_array_t *ap;
996 const ctf_dtdef_t *dtd;
997 ssize_t increment;
999 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1000 return -1; /* errno is set for us. */
1002 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1003 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1005 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1007 *arp = dtd->dtd_u.dtu_arr;
1008 return 0;
1011 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1013 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1014 arp->ctr_contents = ap->cta_contents;
1015 arp->ctr_index = ap->cta_index;
1016 arp->ctr_nelems = ap->cta_nelems;
1018 return 0;
1021 /* Convert the specified value to the corresponding enum tag name, if a
1022 matching name can be found. Otherwise NULL is returned. */
1024 const char *
1025 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1027 ctf_file_t *ofp = fp;
1028 const ctf_type_t *tp;
1029 const ctf_enum_t *ep;
1030 const ctf_dtdef_t *dtd;
1031 ssize_t increment;
1032 uint32_t n;
1034 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1035 return NULL; /* errno is set for us. */
1037 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1038 return NULL; /* errno is set for us. */
1040 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1042 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1043 return NULL;
1046 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1048 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1050 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1052 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1054 if (ep->cte_value == value)
1055 return (ctf_strptr (fp, ep->cte_name));
1058 else
1060 ctf_dmdef_t *dmd;
1062 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1063 dmd != NULL; dmd = ctf_list_next (dmd))
1065 if (dmd->dmd_value == value)
1066 return dmd->dmd_name;
1070 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1071 return NULL;
1074 /* Convert the specified enum tag name to the corresponding value, if a
1075 matching name can be found. Otherwise CTF_ERR is returned. */
1078 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1080 ctf_file_t *ofp = fp;
1081 const ctf_type_t *tp;
1082 const ctf_enum_t *ep;
1083 const ctf_dtdef_t *dtd;
1084 ssize_t increment;
1085 uint32_t n;
1087 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1088 return -1; /* errno is set for us. */
1090 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1091 return -1; /* errno is set for us. */
1093 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1095 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1096 return -1;
1099 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1101 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1103 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1105 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1107 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1109 if (valp != NULL)
1110 *valp = ep->cte_value;
1111 return 0;
1115 else
1117 ctf_dmdef_t *dmd;
1119 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1120 dmd != NULL; dmd = ctf_list_next (dmd))
1122 if (strcmp (dmd->dmd_name, name) == 0)
1124 if (valp != NULL)
1125 *valp = dmd->dmd_value;
1126 return 0;
1131 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1132 return -1;
1135 /* Given a type ID relating to a function type, return info on return types and
1136 arg counts for that function. */
1139 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1141 const ctf_type_t *tp;
1142 uint32_t kind;
1143 const uint32_t *args;
1144 const ctf_dtdef_t *dtd;
1145 ssize_t size, increment;
1147 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1148 return -1; /* errno is set for us. */
1150 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1151 return -1; /* errno is set for us. */
1153 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1154 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1156 if (kind != CTF_K_FUNCTION)
1157 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1159 fip->ctc_return = tp->ctt_type;
1160 fip->ctc_flags = 0;
1161 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1163 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1164 args = (uint32_t *) ((uintptr_t) tp + increment);
1165 else
1166 args = (uint32_t *) dtd->dtd_u.dtu_argv;
1168 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1170 fip->ctc_flags |= CTF_FUNC_VARARG;
1171 fip->ctc_argc--;
1174 return 0;
1177 /* Given a type ID relating to a function type,, return the arguments for the
1178 function. */
1181 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1183 const ctf_type_t *tp;
1184 const uint32_t *args;
1185 const ctf_dtdef_t *dtd;
1186 ssize_t size, increment;
1187 ctf_funcinfo_t f;
1189 if (ctf_func_type_info (fp, type, &f) < 0)
1190 return -1; /* errno is set for us. */
1192 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1193 return -1; /* errno is set for us. */
1195 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1196 return -1; /* errno is set for us. */
1198 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1200 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1201 args = (uint32_t *) ((uintptr_t) tp + increment);
1202 else
1203 args = (uint32_t *) dtd->dtd_u.dtu_argv;
1205 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1206 *argv++ = *args++;
1208 return 0;
1211 /* Recursively visit the members of any type. This function is used as the
1212 engine for ctf_type_visit, below. We resolve the input type, recursively
1213 invoke ourself for each type member if the type is a struct or union, and
1214 then invoke the callback function on the current type. If any callback
1215 returns non-zero, we abort and percolate the error code back up to the top. */
1217 static int
1218 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1219 void *arg, const char *name, unsigned long offset, int depth)
1221 ctf_id_t otype = type;
1222 const ctf_type_t *tp;
1223 const ctf_dtdef_t *dtd;
1224 ssize_t size, increment;
1225 uint32_t kind, n;
1226 int rc;
1228 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1229 return -1; /* errno is set for us. */
1231 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1232 return -1; /* errno is set for us. */
1234 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1235 return rc;
1237 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1239 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1240 return 0;
1242 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1244 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1246 if (size < CTF_LSTRUCT_THRESH)
1248 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1249 increment);
1251 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1253 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1254 func, arg, ctf_strptr (fp,
1255 mp->ctm_name),
1256 offset + mp->ctm_offset,
1257 depth + 1)) != 0)
1258 return rc;
1261 else
1263 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1264 increment);
1266 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1268 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1269 func, arg, ctf_strptr (fp,
1270 lmp->ctlm_name),
1271 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1272 depth + 1)) != 0)
1273 return rc;
1277 else
1279 ctf_dmdef_t *dmd;
1281 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1282 dmd != NULL; dmd = ctf_list_next (dmd))
1284 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1285 dmd->dmd_name, dmd->dmd_offset,
1286 depth + 1)) != 0)
1287 return rc;
1291 return 0;
1294 /* Recursively visit the members of any type. We pass the name, member
1295 type, and offset of each member to the specified callback function. */
1297 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1299 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));