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 type in the given CTF container, user-visible or not.
148 We pass the type ID of each type to the specified callback function. */
151 ctf_type_iter_all (ctf_file_t
*fp
, ctf_type_all_f
*func
, void *arg
)
153 ctf_id_t id
, max
= fp
->ctf_typemax
;
154 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
156 for (id
= 1; id
<= max
; id
++)
158 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
159 if ((rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
),
160 LCTF_INFO_ISROOT(fp
, tp
->ctt_info
)
161 ? CTF_ADD_ROOT
: CTF_ADD_NONROOT
, arg
) != 0))
168 /* Iterate over every variable in the given CTF container, in arbitrary order.
169 We pass the name of each variable to the specified callback function. */
172 ctf_variable_iter (ctf_file_t
*fp
, ctf_variable_f
*func
, void *arg
)
177 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
178 return ECTF_NOPARENT
;
180 for (i
= 0; i
< fp
->ctf_nvars
; i
++)
181 if ((rc
= func (ctf_strptr (fp
, fp
->ctf_vars
[i
].ctv_name
),
182 fp
->ctf_vars
[i
].ctv_type
, arg
)) != 0)
188 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
189 RESTRICT nodes until we reach a "base" type node. This is useful when
190 we want to follow a type ID to a node that has members or a size. To guard
191 against infinite loops, we implement simplified cycle detection and check
192 each link against itself, the previous node, and the topmost node.
194 Does not drill down through slices to their contained type. */
197 ctf_type_resolve (ctf_file_t
*fp
, ctf_id_t type
)
199 ctf_id_t prev
= type
, otype
= type
;
200 ctf_file_t
*ofp
= fp
;
201 const ctf_type_t
*tp
;
204 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
206 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
208 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
214 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
215 || tp
->ctt_type
== prev
)
217 ctf_dprintf ("type %ld cycle detected\n", otype
);
218 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
227 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
230 return CTF_ERR
; /* errno is set for us. */
233 /* Like ctf_type_resolve(), but traverse down through slices to their contained
237 ctf_type_resolve_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
239 const ctf_type_t
*tp
;
241 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
244 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
245 return CTF_ERR
; /* errno is set for us. */
247 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
248 return ctf_type_reference (fp
, type
);
252 /* Lookup the given type ID and return its name as a new dynamcally-allocated
256 ctf_type_aname (ctf_file_t
*fp
, ctf_id_t type
)
259 ctf_decl_node_t
*cdp
;
260 ctf_decl_prec_t prec
, lp
, rp
;
265 if (fp
== NULL
&& type
== CTF_ERR
)
266 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
269 ctf_decl_push (&cd
, fp
, type
);
274 ctf_set_errno (fp
, cd
.cd_err
);
278 /* If the type graph's order conflicts with lexical precedence order
279 for pointers or arrays, then we need to surround the declarations at
280 the corresponding lexical precedence with parentheses. This can
281 result in either a parenthesized pointer (*) as in int (*)() or
282 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
284 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
285 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
287 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
288 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
290 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
292 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
294 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
295 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
297 ctf_file_t
*rfp
= fp
;
298 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
299 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
301 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
302 ctf_decl_sprintf (&cd
, " ");
306 ctf_decl_sprintf (&cd
, "(");
310 switch (cdp
->cd_kind
)
315 ctf_decl_sprintf (&cd
, "%s", name
);
318 ctf_decl_sprintf (&cd
, "*");
321 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
324 ctf_decl_sprintf (&cd
, "()");
328 ctf_decl_sprintf (&cd
, "struct %s", name
);
331 ctf_decl_sprintf (&cd
, "union %s", name
);
334 ctf_decl_sprintf (&cd
, "enum %s", name
);
337 ctf_decl_sprintf (&cd
, "volatile");
340 ctf_decl_sprintf (&cd
, "const");
343 ctf_decl_sprintf (&cd
, "restrict");
346 /* No representation: just changes encoding of contained type,
347 which is not in any case printed. Skip it. */
355 ctf_decl_sprintf (&cd
, ")");
359 (void) ctf_set_errno (fp
, ENOMEM
);
361 buf
= ctf_decl_buf (&cd
);
367 /* Lookup the given type ID and print a string name for it into buf. Return
368 the actual number of bytes (not including \0) needed to format the name. */
371 ctf_type_lname (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
373 char *str
= ctf_type_aname (fp
, type
);
374 size_t slen
= strlen (str
);
377 return CTF_ERR
; /* errno is set for us */
379 snprintf (buf
, len
, "%s", str
);
383 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
388 /* Lookup the given type ID and print a string name for it into buf. If buf
389 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
392 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
394 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
395 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
398 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
399 new dynamcally-allocated string. */
402 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
404 const ctf_type_t
*tp
;
406 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
407 return NULL
; /* errno is set for us. */
409 if (ctf_strraw (fp
, tp
->ctt_name
) != NULL
)
410 return strdup (ctf_strraw (fp
, tp
->ctt_name
));
415 /* Resolve the type down to a base type node, and then return the size
416 of the type storage in bytes. */
419 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
421 const ctf_type_t
*tp
;
425 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
426 return -1; /* errno is set for us. */
428 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
429 return -1; /* errno is set for us. */
431 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
434 return fp
->ctf_dmodel
->ctd_pointer
;
437 return 0; /* Function size is only known by symtab. */
440 return fp
->ctf_dmodel
->ctd_int
;
443 /* ctf_add_array() does not directly encode the element size, but
444 requires the user to multiply to determine the element size.
446 If ctf_get_ctt_size() returns nonzero, then use the recorded
449 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
452 if (ctf_array_info (fp
, type
, &ar
) < 0
453 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
454 return -1; /* errno is set for us. */
456 return size
* ar
.ctr_nelems
;
458 default: /* including slices of enums, etc */
459 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
463 /* Resolve the type down to a base type node, and then return the alignment
464 needed for the type storage in bytes.
466 XXX may need arch-dependent attention. */
469 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
471 const ctf_type_t
*tp
;
472 ctf_file_t
*ofp
= fp
;
475 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
476 return -1; /* errno is set for us. */
478 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
479 return -1; /* errno is set for us. */
481 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
486 return fp
->ctf_dmodel
->ctd_pointer
;
491 if (ctf_array_info (fp
, type
, &r
) < 0)
492 return -1; /* errno is set for us. */
493 return (ctf_type_align (fp
, r
.ctr_contents
));
502 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
504 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
505 ssize_t size
, increment
;
508 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
509 vmp
= (unsigned char *) tp
+ increment
;
511 if (kind
== CTF_K_STRUCT
)
512 n
= MIN (n
, 1); /* Only use first member for structs. */
514 if (size
< CTF_LSTRUCT_THRESH
)
516 const ctf_member_t
*mp
= vmp
;
517 for (; n
!= 0; n
--, mp
++)
519 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
520 align
= MAX (align
, (size_t) am
);
525 const ctf_lmember_t
*lmp
= vmp
;
526 for (; n
!= 0; n
--, lmp
++)
528 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
529 align
= MAX (align
, (size_t) am
);
537 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
538 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
540 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
541 align
= MAX (align
, (size_t) am
);
542 if (kind
== CTF_K_STRUCT
)
551 return fp
->ctf_dmodel
->ctd_int
;
553 default: /* including slices of enums, etc */
554 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
558 /* Return the kind (CTF_K_* constant) for the specified type ID. */
561 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
563 const ctf_type_t
*tp
;
565 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
566 return -1; /* errno is set for us. */
568 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
571 /* Return the kind (CTF_K_* constant) for the specified type ID.
572 Slices are considered to be of the same kind as the type sliced. */
575 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
579 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
582 if (kind
== CTF_K_SLICE
)
584 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
586 kind
= ctf_type_kind_unsliced (fp
, type
);
592 /* If the type is one that directly references another type (such as POINTER),
593 then return the ID of the type to which it refers. */
596 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
598 ctf_file_t
*ofp
= fp
;
599 const ctf_type_t
*tp
;
601 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
602 return CTF_ERR
; /* errno is set for us. */
604 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
612 /* Slices store their type in an unusual place. */
615 const ctf_slice_t
*sp
;
617 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
618 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
622 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
626 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
627 pointer to the given type, see if we can compute a pointer to the type
628 resulting from resolving the type down to its base type and use that
629 instead. This helps with cases where the CTF data includes "struct foo *"
630 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
632 XXX what about parent containers? */
635 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
637 ctf_file_t
*ofp
= fp
;
640 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
641 return CTF_ERR
; /* errno is set for us. */
643 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
644 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
646 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
647 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
649 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
650 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
652 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
653 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
655 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
658 /* Return the encoding for the specified INTEGER or FLOAT. */
661 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
663 ctf_file_t
*ofp
= fp
;
665 const ctf_type_t
*tp
;
669 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
670 return -1; /* errno is set for us. */
672 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
674 *ep
= dtd
->dtd_u
.dtu_enc
;
678 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
680 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
683 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
684 ep
->cte_format
= CTF_INT_ENCODING (data
);
685 ep
->cte_offset
= CTF_INT_OFFSET (data
);
686 ep
->cte_bits
= CTF_INT_BITS (data
);
689 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
690 ep
->cte_format
= CTF_FP_ENCODING (data
);
691 ep
->cte_offset
= CTF_FP_OFFSET (data
);
692 ep
->cte_bits
= CTF_FP_BITS (data
);
696 const ctf_slice_t
*slice
;
697 ctf_encoding_t underlying_en
;
699 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
700 data
= ctf_type_encoding (fp
, slice
->cts_type
, &underlying_en
);
702 ep
->cte_format
= underlying_en
.cte_format
;
703 ep
->cte_offset
= slice
->cts_offset
;
704 ep
->cte_bits
= slice
->cts_bits
;
708 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
715 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
722 else if (ltype
> rtype
)
730 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
731 lfp
= lfp
->ctf_parent
;
733 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
734 rfp
= rfp
->ctf_parent
;
745 /* Return a boolean value indicating if two types are compatible. This function
746 returns true if the two types are the same, or if they (or their ultimate
747 base type) have the same encoding properties, or (for structs / unions /
748 enums / forward declarations) if they have the same name and (for structs /
749 unions) member count. */
752 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
753 ctf_file_t
*rfp
, ctf_id_t rtype
)
755 const ctf_type_t
*ltp
, *rtp
;
756 ctf_encoding_t le
, re
;
758 uint32_t lkind
, rkind
;
761 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
764 ltype
= ctf_type_resolve (lfp
, ltype
);
765 lkind
= ctf_type_kind (lfp
, ltype
);
767 rtype
= ctf_type_resolve (rfp
, rtype
);
768 rkind
= ctf_type_kind (rfp
, rtype
);
770 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
771 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
773 if (ltp
!= NULL
&& rtp
!= NULL
)
774 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
775 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
777 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
778 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
788 memset (&le
, 0, sizeof (le
));
789 memset (&re
, 0, sizeof (re
));
790 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
791 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
792 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
794 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
795 rfp
, ctf_type_reference (rfp
, rtype
)));
797 return (ctf_array_info (lfp
, ltype
, &la
) == 0
798 && ctf_array_info (rfp
, rtype
, &ra
) == 0
799 && la
.ctr_nelems
== ra
.ctr_nelems
800 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
801 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
804 return (same_names
&& (ctf_type_size (lfp
, ltype
)
805 == ctf_type_size (rfp
, rtype
)));
808 int lencoded
, rencoded
;
809 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
810 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
812 if ((lencoded
!= rencoded
) ||
813 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
818 return same_names
; /* No other checks required for these type kinds. */
820 return 0; /* Should not get here since we did a resolve. */
824 /* Return the type and offset for a given member of a STRUCT or UNION. */
827 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
830 ctf_file_t
*ofp
= fp
;
831 const ctf_type_t
*tp
;
832 ssize_t size
, increment
;
835 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
836 return -1; /* errno is set for us. */
838 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
839 return -1; /* errno is set for us. */
841 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
842 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
844 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
845 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
847 if (size
< CTF_LSTRUCT_THRESH
)
849 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
852 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
854 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
856 mip
->ctm_type
= mp
->ctm_type
;
857 mip
->ctm_offset
= mp
->ctm_offset
;
864 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
867 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
869 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
871 mip
->ctm_type
= lmp
->ctlm_type
;
872 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
878 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
881 /* Return the array type, index, and size information for the specified ARRAY. */
884 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
886 ctf_file_t
*ofp
= fp
;
887 const ctf_type_t
*tp
;
888 const ctf_array_t
*ap
;
889 const ctf_dtdef_t
*dtd
;
892 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
893 return -1; /* errno is set for us. */
895 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
896 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
898 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
900 *arp
= dtd
->dtd_u
.dtu_arr
;
904 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
906 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
907 arp
->ctr_contents
= ap
->cta_contents
;
908 arp
->ctr_index
= ap
->cta_index
;
909 arp
->ctr_nelems
= ap
->cta_nelems
;
914 /* Convert the specified value to the corresponding enum tag name, if a
915 matching name can be found. Otherwise NULL is returned. */
918 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
920 ctf_file_t
*ofp
= fp
;
921 const ctf_type_t
*tp
;
922 const ctf_enum_t
*ep
;
926 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
927 return NULL
; /* errno is set for us. */
929 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
930 return NULL
; /* errno is set for us. */
932 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
934 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
938 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
940 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
942 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
944 if (ep
->cte_value
== value
)
945 return (ctf_strptr (fp
, ep
->cte_name
));
948 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
952 /* Convert the specified enum tag name to the corresponding value, if a
953 matching name can be found. Otherwise CTF_ERR is returned. */
956 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
958 ctf_file_t
*ofp
= fp
;
959 const ctf_type_t
*tp
;
960 const ctf_enum_t
*ep
;
964 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
965 return -1; /* errno is set for us. */
967 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
968 return -1; /* errno is set for us. */
970 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
972 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
976 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
978 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
980 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
982 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
985 *valp
= ep
->cte_value
;
990 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
994 /* Given a type ID relating to a function type, return info on return types and
995 arg counts for that function. */
998 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1000 const ctf_type_t
*tp
;
1002 const uint32_t *args
;
1003 ssize_t size
, increment
;
1005 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1006 return -1; /* errno is set for us. */
1008 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1009 return -1; /* errno is set for us. */
1011 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1012 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1014 if (kind
!= CTF_K_FUNCTION
)
1015 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1017 fip
->ctc_return
= tp
->ctt_type
;
1018 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1021 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1023 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1025 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1032 /* Given a type ID relating to a function type,, return the arguments for the
1036 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1038 const ctf_type_t
*tp
;
1039 const uint32_t *args
;
1040 ssize_t size
, increment
;
1043 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1044 return -1; /* errno is set for us. */
1046 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1047 return -1; /* errno is set for us. */
1049 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1050 return -1; /* errno is set for us. */
1052 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1054 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1056 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1062 /* Recursively visit the members of any type. This function is used as the
1063 engine for ctf_type_visit, below. We resolve the input type, recursively
1064 invoke ourself for each type member if the type is a struct or union, and
1065 then invoke the callback function on the current type. If any callback
1066 returns non-zero, we abort and percolate the error code back up to the top. */
1069 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1070 void *arg
, const char *name
, unsigned long offset
, int depth
)
1072 ctf_id_t otype
= type
;
1073 const ctf_type_t
*tp
;
1074 ssize_t size
, increment
;
1078 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1079 return -1; /* errno is set for us. */
1081 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1082 return -1; /* errno is set for us. */
1084 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1087 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1089 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1092 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1094 if (size
< CTF_LSTRUCT_THRESH
)
1096 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1099 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1101 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1102 func
, arg
, ctf_strptr (fp
, mp
->ctm_name
),
1103 offset
+ mp
->ctm_offset
,
1111 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1114 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1116 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1117 func
, arg
, ctf_strptr (fp
,
1119 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1128 /* Recursively visit the members of any type. We pass the name, member
1129 type, and offset of each member to the specified callback function. */
1131 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1133 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));