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
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/>. */
23 /* Determine whether a type is a parent or a child. */
26 ctf_type_isparent (ctf_file_t
*fp
, ctf_id_t id
)
28 return (LCTF_TYPE_ISPARENT (fp
, id
));
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. */
41 ctf_member_iter (ctf_file_t
*fp
, ctf_id_t type
, ctf_member_f
*func
, void *arg
)
45 ssize_t size
, increment
;
49 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
50 return -1; /* errno is set for us. */
52 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
53 return -1; /* errno is set for us. */
55 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
56 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
58 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
59 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
61 if (size
< CTF_LSTRUCT_THRESH
)
63 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
66 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
68 const char *name
= ctf_strptr (fp
, mp
->ctm_name
);
69 if ((rc
= func (name
, mp
->ctm_type
, mp
->ctm_offset
, arg
)) != 0)
76 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
79 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
81 const char *name
= ctf_strptr (fp
, lmp
->ctlm_name
);
82 if ((rc
= func (name
, lmp
->ctlm_type
,
83 (unsigned long) CTF_LMEM_OFFSET (lmp
), arg
)) != 0)
91 /* Iterate over the members of an ENUM. We pass the string name and associated
92 integer value of each enum element to the specified callback function. */
95 ctf_enum_iter (ctf_file_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
104 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
105 return -1; /* errno is set for us. */
107 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
108 return -1; /* errno is set for us. */
110 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
111 return (ctf_set_errno (ofp
, ECTF_NOTENUM
));
113 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
115 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
117 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
119 const char *name
= ctf_strptr (fp
, ep
->cte_name
);
120 if ((rc
= func (name
, ep
->cte_value
, arg
)) != 0)
127 /* Iterate over every root (user-visible) type in the given CTF container.
128 We pass the type ID of each type to the specified callback function. */
131 ctf_type_iter (ctf_file_t
*fp
, ctf_type_f
*func
, void *arg
)
133 ctf_id_t id
, max
= fp
->ctf_typemax
;
134 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
136 for (id
= 1; id
<= max
; id
++)
138 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
139 if (LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)
140 && (rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
), arg
)) != 0)
147 /* Iterate over every variable in the given CTF container, in arbitrary order.
148 We pass the name of each variable to the specified callback function. */
151 ctf_variable_iter (ctf_file_t
*fp
, ctf_variable_f
*func
, void *arg
)
156 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
157 return ECTF_NOPARENT
;
159 for (i
= 0; i
< fp
->ctf_nvars
; i
++)
160 if ((rc
= func (ctf_strptr (fp
, fp
->ctf_vars
[i
].ctv_name
),
161 fp
->ctf_vars
[i
].ctv_type
, arg
)) != 0)
167 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
168 RESTRICT nodes until we reach a "base" type node. This is useful when
169 we want to follow a type ID to a node that has members or a size. To guard
170 against infinite loops, we implement simplified cycle detection and check
171 each link against itself, the previous node, and the topmost node.
173 Does not drill down through slices to their contained type. */
176 ctf_type_resolve (ctf_file_t
*fp
, ctf_id_t type
)
178 ctf_id_t prev
= type
, otype
= type
;
179 ctf_file_t
*ofp
= fp
;
180 const ctf_type_t
*tp
;
182 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
184 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
190 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
191 || tp
->ctt_type
== prev
)
193 ctf_dprintf ("type %ld cycle detected\n", otype
);
194 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
204 return CTF_ERR
; /* errno is set for us. */
207 /* Like ctf_type_resolve(), but traverse down through slices to their contained
211 ctf_type_resolve_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
213 const ctf_type_t
*tp
;
215 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
218 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
219 return CTF_ERR
; /* errno is set for us. */
221 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
222 return ctf_type_reference (fp
, type
);
226 /* Lookup the given type ID and return its name as a new dynamcally-allocated
230 ctf_type_aname (ctf_file_t
*fp
, ctf_id_t type
)
233 ctf_decl_node_t
*cdp
;
234 ctf_decl_prec_t prec
, lp
, rp
;
239 if (fp
== NULL
&& type
== CTF_ERR
)
240 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
243 ctf_decl_push (&cd
, fp
, type
);
248 ctf_set_errno (fp
, cd
.cd_err
);
252 /* If the type graph's order conflicts with lexical precedence order
253 for pointers or arrays, then we need to surround the declarations at
254 the corresponding lexical precedence with parentheses. This can
255 result in either a parenthesized pointer (*) as in int (*)() or
256 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
258 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
259 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
261 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
262 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
264 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
266 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
268 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
269 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
271 ctf_file_t
*rfp
= fp
;
272 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
273 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
275 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
276 ctf_decl_sprintf (&cd
, " ");
280 ctf_decl_sprintf (&cd
, "(");
284 switch (cdp
->cd_kind
)
289 ctf_decl_sprintf (&cd
, "%s", name
);
292 ctf_decl_sprintf (&cd
, "*");
295 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
298 ctf_decl_sprintf (&cd
, "()");
302 ctf_decl_sprintf (&cd
, "struct %s", name
);
305 ctf_decl_sprintf (&cd
, "union %s", name
);
308 ctf_decl_sprintf (&cd
, "enum %s", name
);
311 ctf_decl_sprintf (&cd
, "volatile");
314 ctf_decl_sprintf (&cd
, "const");
317 ctf_decl_sprintf (&cd
, "restrict");
320 /* No representation: just changes encoding of contained type,
321 which is not in any case printed. Skip it. */
329 ctf_decl_sprintf (&cd
, ")");
333 (void) ctf_set_errno (fp
, ENOMEM
);
335 buf
= ctf_decl_buf (&cd
);
341 /* Lookup the given type ID and print a string name for it into buf. Return
342 the actual number of bytes (not including \0) needed to format the name. */
345 ctf_type_lname (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
347 char *str
= ctf_type_aname (fp
, type
);
348 size_t slen
= strlen (str
);
351 return CTF_ERR
; /* errno is set for us */
353 snprintf (buf
, len
, "%s", str
);
357 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
362 /* Lookup the given type ID and print a string name for it into buf. If buf
363 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
366 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
368 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
369 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
372 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
373 new dynamcally-allocated string. */
376 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
378 const ctf_type_t
*tp
;
380 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
381 return NULL
; /* errno is set for us. */
383 if (ctf_strraw (fp
, tp
->ctt_name
) != NULL
)
384 return strdup (ctf_strraw (fp
, tp
->ctt_name
));
389 /* Resolve the type down to a base type node, and then return the size
390 of the type storage in bytes. */
393 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
395 const ctf_type_t
*tp
;
399 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
400 return -1; /* errno is set for us. */
402 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
403 return -1; /* errno is set for us. */
405 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
408 return fp
->ctf_dmodel
->ctd_pointer
;
411 return 0; /* Function size is only known by symtab. */
414 return fp
->ctf_dmodel
->ctd_int
;
417 /* ctf_add_array() does not directly encode the element size, but
418 requires the user to multiply to determine the element size.
420 If ctf_get_ctt_size() returns nonzero, then use the recorded
423 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
426 if (ctf_array_info (fp
, type
, &ar
) < 0
427 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
428 return -1; /* errno is set for us. */
430 return size
* ar
.ctr_nelems
;
432 default: /* including slices of enums, etc */
433 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
437 /* Resolve the type down to a base type node, and then return the alignment
438 needed for the type storage in bytes.
440 XXX may need arch-dependent attention. */
443 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
445 const ctf_type_t
*tp
;
446 ctf_file_t
*ofp
= fp
;
449 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
450 return -1; /* errno is set for us. */
452 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
453 return -1; /* errno is set for us. */
455 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
460 return fp
->ctf_dmodel
->ctd_pointer
;
465 if (ctf_array_info (fp
, type
, &r
) < 0)
466 return -1; /* errno is set for us. */
467 return (ctf_type_align (fp
, r
.ctr_contents
));
476 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
478 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
479 ssize_t size
, increment
;
482 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
483 vmp
= (unsigned char *) tp
+ increment
;
485 if (kind
== CTF_K_STRUCT
)
486 n
= MIN (n
, 1); /* Only use first member for structs. */
488 if (size
< CTF_LSTRUCT_THRESH
)
490 const ctf_member_t
*mp
= vmp
;
491 for (; n
!= 0; n
--, mp
++)
493 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
494 align
= MAX (align
, (size_t) am
);
499 const ctf_lmember_t
*lmp
= vmp
;
500 for (; n
!= 0; n
--, lmp
++)
502 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
503 align
= MAX (align
, (size_t) am
);
511 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
512 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
514 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
515 align
= MAX (align
, (size_t) am
);
516 if (kind
== CTF_K_STRUCT
)
525 return fp
->ctf_dmodel
->ctd_int
;
527 default: /* including slices of enums, etc */
528 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
532 /* Return the kind (CTF_K_* constant) for the specified type ID. */
535 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
537 const ctf_type_t
*tp
;
539 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
540 return -1; /* errno is set for us. */
542 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
545 /* Return the kind (CTF_K_* constant) for the specified type ID.
546 Slices are considered to be of the same kind as the type sliced. */
549 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
553 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
556 if (kind
== CTF_K_SLICE
)
558 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
560 kind
= ctf_type_kind_unsliced (fp
, type
);
566 /* If the type is one that directly references another type (such as POINTER),
567 then return the ID of the type to which it refers. */
570 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
572 ctf_file_t
*ofp
= fp
;
573 const ctf_type_t
*tp
;
575 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
576 return CTF_ERR
; /* errno is set for us. */
578 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
586 /* Slices store their type in an unusual place. */
589 const ctf_slice_t
*sp
;
591 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
592 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
596 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
600 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
601 pointer to the given type, see if we can compute a pointer to the type
602 resulting from resolving the type down to its base type and use that
603 instead. This helps with cases where the CTF data includes "struct foo *"
604 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
606 XXX what about parent containers? */
609 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
611 ctf_file_t
*ofp
= fp
;
614 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
615 return CTF_ERR
; /* errno is set for us. */
617 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
618 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
620 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
621 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
623 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
624 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
626 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
627 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
629 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
632 /* Return the encoding for the specified INTEGER or FLOAT. */
635 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
637 ctf_file_t
*ofp
= fp
;
639 const ctf_type_t
*tp
;
643 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
644 return -1; /* errno is set for us. */
646 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
648 *ep
= dtd
->dtd_u
.dtu_enc
;
652 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
654 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
657 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
658 ep
->cte_format
= CTF_INT_ENCODING (data
);
659 ep
->cte_offset
= CTF_INT_OFFSET (data
);
660 ep
->cte_bits
= CTF_INT_BITS (data
);
663 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
664 ep
->cte_format
= CTF_FP_ENCODING (data
);
665 ep
->cte_offset
= CTF_FP_OFFSET (data
);
666 ep
->cte_bits
= CTF_FP_BITS (data
);
670 const ctf_slice_t
*slice
;
671 ctf_encoding_t underlying_en
;
673 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
674 data
= ctf_type_encoding (fp
, slice
->cts_type
, &underlying_en
);
676 ep
->cte_format
= underlying_en
.cte_format
;
677 ep
->cte_offset
= slice
->cts_offset
;
678 ep
->cte_bits
= slice
->cts_bits
;
682 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
689 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
696 else if (ltype
> rtype
)
704 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
705 lfp
= lfp
->ctf_parent
;
707 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
708 rfp
= rfp
->ctf_parent
;
719 /* Return a boolean value indicating if two types are compatible. This function
720 returns true if the two types are the same, or if they (or their ultimate
721 base type) have the same encoding properties, or (for structs / unions /
722 enums / forward declarations) if they have the same name and (for structs /
723 unions) member count. */
726 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
727 ctf_file_t
*rfp
, ctf_id_t rtype
)
729 const ctf_type_t
*ltp
, *rtp
;
730 ctf_encoding_t le
, re
;
732 uint32_t lkind
, rkind
;
735 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
738 ltype
= ctf_type_resolve (lfp
, ltype
);
739 lkind
= ctf_type_kind (lfp
, ltype
);
741 rtype
= ctf_type_resolve (rfp
, rtype
);
742 rkind
= ctf_type_kind (rfp
, rtype
);
744 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
745 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
747 if (ltp
!= NULL
&& rtp
!= NULL
)
748 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
749 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
751 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
752 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
762 memset (&le
, 0, sizeof (le
));
763 memset (&re
, 0, sizeof (re
));
764 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
765 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
766 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
768 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
769 rfp
, ctf_type_reference (rfp
, rtype
)));
771 return (ctf_array_info (lfp
, ltype
, &la
) == 0
772 && ctf_array_info (rfp
, rtype
, &ra
) == 0
773 && la
.ctr_nelems
== ra
.ctr_nelems
774 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
775 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
778 return (same_names
&& (ctf_type_size (lfp
, ltype
)
779 == ctf_type_size (rfp
, rtype
)));
782 int lencoded
, rencoded
;
783 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
784 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
786 if ((lencoded
!= rencoded
) ||
787 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
792 return same_names
; /* No other checks required for these type kinds. */
794 return 0; /* Should not get here since we did a resolve. */
798 /* Return the type and offset for a given member of a STRUCT or UNION. */
801 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
804 ctf_file_t
*ofp
= fp
;
805 const ctf_type_t
*tp
;
806 ssize_t size
, increment
;
809 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
810 return -1; /* errno is set for us. */
812 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
813 return -1; /* errno is set for us. */
815 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
816 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
818 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
819 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
821 if (size
< CTF_LSTRUCT_THRESH
)
823 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
826 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
828 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
830 mip
->ctm_type
= mp
->ctm_type
;
831 mip
->ctm_offset
= mp
->ctm_offset
;
838 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
841 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
843 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
845 mip
->ctm_type
= lmp
->ctlm_type
;
846 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
852 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
855 /* Return the array type, index, and size information for the specified ARRAY. */
858 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
860 ctf_file_t
*ofp
= fp
;
861 const ctf_type_t
*tp
;
862 const ctf_array_t
*ap
;
863 const ctf_dtdef_t
*dtd
;
866 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
867 return -1; /* errno is set for us. */
869 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
870 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
872 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
874 *arp
= dtd
->dtd_u
.dtu_arr
;
878 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
880 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
881 arp
->ctr_contents
= ap
->cta_contents
;
882 arp
->ctr_index
= ap
->cta_index
;
883 arp
->ctr_nelems
= ap
->cta_nelems
;
888 /* Convert the specified value to the corresponding enum tag name, if a
889 matching name can be found. Otherwise NULL is returned. */
892 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
894 ctf_file_t
*ofp
= fp
;
895 const ctf_type_t
*tp
;
896 const ctf_enum_t
*ep
;
900 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
901 return NULL
; /* errno is set for us. */
903 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
904 return NULL
; /* errno is set for us. */
906 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
908 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
912 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
914 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
916 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
918 if (ep
->cte_value
== value
)
919 return (ctf_strptr (fp
, ep
->cte_name
));
922 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
926 /* Convert the specified enum tag name to the corresponding value, if a
927 matching name can be found. Otherwise CTF_ERR is returned. */
930 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
932 ctf_file_t
*ofp
= fp
;
933 const ctf_type_t
*tp
;
934 const ctf_enum_t
*ep
;
938 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
939 return -1; /* errno is set for us. */
941 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
942 return -1; /* errno is set for us. */
944 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
946 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
950 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
952 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
954 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
956 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
959 *valp
= ep
->cte_value
;
964 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
968 /* Given a type ID relating to a function type, return info on return types and
969 arg counts for that function. */
972 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
974 const ctf_type_t
*tp
;
976 const uint32_t *args
;
977 ssize_t size
, increment
;
979 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
980 return -1; /* errno is set for us. */
982 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
983 return -1; /* errno is set for us. */
985 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
986 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
988 if (kind
!= CTF_K_FUNCTION
)
989 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
991 fip
->ctc_return
= tp
->ctt_type
;
992 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
995 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
997 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
999 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1006 /* Given a type ID relating to a function type,, return the arguments for the
1010 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1012 const ctf_type_t
*tp
;
1013 const uint32_t *args
;
1014 ssize_t size
, increment
;
1017 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1018 return -1; /* errno is set for us. */
1020 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1021 return -1; /* errno is set for us. */
1023 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1024 return -1; /* errno is set for us. */
1026 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1028 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1030 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1036 /* Recursively visit the members of any type. This function is used as the
1037 engine for ctf_type_visit, below. We resolve the input type, recursively
1038 invoke ourself for each type member if the type is a struct or union, and
1039 then invoke the callback function on the current type. If any callback
1040 returns non-zero, we abort and percolate the error code back up to the top. */
1043 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1044 void *arg
, const char *name
, unsigned long offset
, int depth
)
1046 ctf_id_t otype
= type
;
1047 const ctf_type_t
*tp
;
1048 ssize_t size
, increment
;
1052 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1053 return -1; /* errno is set for us. */
1055 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1056 return -1; /* errno is set for us. */
1058 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1061 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1063 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1066 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1068 if (size
< CTF_LSTRUCT_THRESH
)
1070 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1073 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1075 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1076 func
, arg
, ctf_strptr (fp
, mp
->ctm_name
),
1077 offset
+ mp
->ctm_offset
,
1085 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1088 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1090 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1091 func
, arg
, ctf_strptr (fp
,
1093 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1102 /* Recursively visit the members of any type. We pass the name, member
1103 type, and offset of each member to the specified callback function. */
1105 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1107 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));