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
;
203 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
205 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
211 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
212 || tp
->ctt_type
== prev
)
214 ctf_dprintf ("type %ld cycle detected\n", otype
);
215 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
225 return CTF_ERR
; /* errno is set for us. */
228 /* Like ctf_type_resolve(), but traverse down through slices to their contained
232 ctf_type_resolve_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
234 const ctf_type_t
*tp
;
236 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
239 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
240 return CTF_ERR
; /* errno is set for us. */
242 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
243 return ctf_type_reference (fp
, type
);
247 /* Lookup the given type ID and return its name as a new dynamcally-allocated
251 ctf_type_aname (ctf_file_t
*fp
, ctf_id_t type
)
254 ctf_decl_node_t
*cdp
;
255 ctf_decl_prec_t prec
, lp
, rp
;
260 if (fp
== NULL
&& type
== CTF_ERR
)
261 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
264 ctf_decl_push (&cd
, fp
, type
);
269 ctf_set_errno (fp
, cd
.cd_err
);
273 /* If the type graph's order conflicts with lexical precedence order
274 for pointers or arrays, then we need to surround the declarations at
275 the corresponding lexical precedence with parentheses. This can
276 result in either a parenthesized pointer (*) as in int (*)() or
277 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
279 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
280 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
282 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
283 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
285 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
287 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
289 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
290 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
292 ctf_file_t
*rfp
= fp
;
293 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
294 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
296 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
297 ctf_decl_sprintf (&cd
, " ");
301 ctf_decl_sprintf (&cd
, "(");
305 switch (cdp
->cd_kind
)
310 ctf_decl_sprintf (&cd
, "%s", name
);
313 ctf_decl_sprintf (&cd
, "*");
316 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
319 ctf_decl_sprintf (&cd
, "()");
323 ctf_decl_sprintf (&cd
, "struct %s", name
);
326 ctf_decl_sprintf (&cd
, "union %s", name
);
329 ctf_decl_sprintf (&cd
, "enum %s", name
);
332 ctf_decl_sprintf (&cd
, "volatile");
335 ctf_decl_sprintf (&cd
, "const");
338 ctf_decl_sprintf (&cd
, "restrict");
341 /* No representation: just changes encoding of contained type,
342 which is not in any case printed. Skip it. */
350 ctf_decl_sprintf (&cd
, ")");
354 (void) ctf_set_errno (fp
, ENOMEM
);
356 buf
= ctf_decl_buf (&cd
);
362 /* Lookup the given type ID and print a string name for it into buf. Return
363 the actual number of bytes (not including \0) needed to format the name. */
366 ctf_type_lname (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
368 char *str
= ctf_type_aname (fp
, type
);
369 size_t slen
= strlen (str
);
372 return CTF_ERR
; /* errno is set for us */
374 snprintf (buf
, len
, "%s", str
);
378 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
383 /* Lookup the given type ID and print a string name for it into buf. If buf
384 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
387 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
389 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
390 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
393 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
394 new dynamcally-allocated string. */
397 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
399 const ctf_type_t
*tp
;
401 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
402 return NULL
; /* errno is set for us. */
404 if (ctf_strraw (fp
, tp
->ctt_name
) != NULL
)
405 return strdup (ctf_strraw (fp
, tp
->ctt_name
));
410 /* Resolve the type down to a base type node, and then return the size
411 of the type storage in bytes. */
414 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
416 const ctf_type_t
*tp
;
420 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
421 return -1; /* errno is set for us. */
423 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
424 return -1; /* errno is set for us. */
426 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
429 return fp
->ctf_dmodel
->ctd_pointer
;
432 return 0; /* Function size is only known by symtab. */
435 return fp
->ctf_dmodel
->ctd_int
;
438 /* ctf_add_array() does not directly encode the element size, but
439 requires the user to multiply to determine the element size.
441 If ctf_get_ctt_size() returns nonzero, then use the recorded
444 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
447 if (ctf_array_info (fp
, type
, &ar
) < 0
448 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
449 return -1; /* errno is set for us. */
451 return size
* ar
.ctr_nelems
;
453 default: /* including slices of enums, etc */
454 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
458 /* Resolve the type down to a base type node, and then return the alignment
459 needed for the type storage in bytes.
461 XXX may need arch-dependent attention. */
464 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
466 const ctf_type_t
*tp
;
467 ctf_file_t
*ofp
= fp
;
470 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
471 return -1; /* errno is set for us. */
473 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
474 return -1; /* errno is set for us. */
476 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
481 return fp
->ctf_dmodel
->ctd_pointer
;
486 if (ctf_array_info (fp
, type
, &r
) < 0)
487 return -1; /* errno is set for us. */
488 return (ctf_type_align (fp
, r
.ctr_contents
));
497 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
499 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
500 ssize_t size
, increment
;
503 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
504 vmp
= (unsigned char *) tp
+ increment
;
506 if (kind
== CTF_K_STRUCT
)
507 n
= MIN (n
, 1); /* Only use first member for structs. */
509 if (size
< CTF_LSTRUCT_THRESH
)
511 const ctf_member_t
*mp
= vmp
;
512 for (; n
!= 0; n
--, mp
++)
514 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
515 align
= MAX (align
, (size_t) am
);
520 const ctf_lmember_t
*lmp
= vmp
;
521 for (; n
!= 0; n
--, lmp
++)
523 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
524 align
= MAX (align
, (size_t) am
);
532 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
533 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
535 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
536 align
= MAX (align
, (size_t) am
);
537 if (kind
== CTF_K_STRUCT
)
546 return fp
->ctf_dmodel
->ctd_int
;
548 default: /* including slices of enums, etc */
549 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
553 /* Return the kind (CTF_K_* constant) for the specified type ID. */
556 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
558 const ctf_type_t
*tp
;
560 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
561 return -1; /* errno is set for us. */
563 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
566 /* Return the kind (CTF_K_* constant) for the specified type ID.
567 Slices are considered to be of the same kind as the type sliced. */
570 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
574 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
577 if (kind
== CTF_K_SLICE
)
579 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
581 kind
= ctf_type_kind_unsliced (fp
, type
);
587 /* If the type is one that directly references another type (such as POINTER),
588 then return the ID of the type to which it refers. */
591 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
593 ctf_file_t
*ofp
= fp
;
594 const ctf_type_t
*tp
;
596 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
597 return CTF_ERR
; /* errno is set for us. */
599 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
607 /* Slices store their type in an unusual place. */
610 const ctf_slice_t
*sp
;
612 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
613 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
617 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
621 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
622 pointer to the given type, see if we can compute a pointer to the type
623 resulting from resolving the type down to its base type and use that
624 instead. This helps with cases where the CTF data includes "struct foo *"
625 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
627 XXX what about parent containers? */
630 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
632 ctf_file_t
*ofp
= fp
;
635 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
636 return CTF_ERR
; /* errno is set for us. */
638 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
639 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
641 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
642 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
644 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
645 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
647 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
648 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
650 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
653 /* Return the encoding for the specified INTEGER or FLOAT. */
656 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
658 ctf_file_t
*ofp
= fp
;
660 const ctf_type_t
*tp
;
664 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
665 return -1; /* errno is set for us. */
667 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
669 *ep
= dtd
->dtd_u
.dtu_enc
;
673 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
675 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
678 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
679 ep
->cte_format
= CTF_INT_ENCODING (data
);
680 ep
->cte_offset
= CTF_INT_OFFSET (data
);
681 ep
->cte_bits
= CTF_INT_BITS (data
);
684 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
685 ep
->cte_format
= CTF_FP_ENCODING (data
);
686 ep
->cte_offset
= CTF_FP_OFFSET (data
);
687 ep
->cte_bits
= CTF_FP_BITS (data
);
691 const ctf_slice_t
*slice
;
692 ctf_encoding_t underlying_en
;
694 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
695 data
= ctf_type_encoding (fp
, slice
->cts_type
, &underlying_en
);
697 ep
->cte_format
= underlying_en
.cte_format
;
698 ep
->cte_offset
= slice
->cts_offset
;
699 ep
->cte_bits
= slice
->cts_bits
;
703 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
710 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
717 else if (ltype
> rtype
)
725 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
726 lfp
= lfp
->ctf_parent
;
728 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
729 rfp
= rfp
->ctf_parent
;
740 /* Return a boolean value indicating if two types are compatible. This function
741 returns true if the two types are the same, or if they (or their ultimate
742 base type) have the same encoding properties, or (for structs / unions /
743 enums / forward declarations) if they have the same name and (for structs /
744 unions) member count. */
747 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
748 ctf_file_t
*rfp
, ctf_id_t rtype
)
750 const ctf_type_t
*ltp
, *rtp
;
751 ctf_encoding_t le
, re
;
753 uint32_t lkind
, rkind
;
756 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
759 ltype
= ctf_type_resolve (lfp
, ltype
);
760 lkind
= ctf_type_kind (lfp
, ltype
);
762 rtype
= ctf_type_resolve (rfp
, rtype
);
763 rkind
= ctf_type_kind (rfp
, rtype
);
765 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
766 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
768 if (ltp
!= NULL
&& rtp
!= NULL
)
769 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
770 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
772 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
773 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
783 memset (&le
, 0, sizeof (le
));
784 memset (&re
, 0, sizeof (re
));
785 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
786 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
787 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
789 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
790 rfp
, ctf_type_reference (rfp
, rtype
)));
792 return (ctf_array_info (lfp
, ltype
, &la
) == 0
793 && ctf_array_info (rfp
, rtype
, &ra
) == 0
794 && la
.ctr_nelems
== ra
.ctr_nelems
795 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
796 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
799 return (same_names
&& (ctf_type_size (lfp
, ltype
)
800 == ctf_type_size (rfp
, rtype
)));
803 int lencoded
, rencoded
;
804 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
805 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
807 if ((lencoded
!= rencoded
) ||
808 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
813 return same_names
; /* No other checks required for these type kinds. */
815 return 0; /* Should not get here since we did a resolve. */
819 /* Return the type and offset for a given member of a STRUCT or UNION. */
822 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
825 ctf_file_t
*ofp
= fp
;
826 const ctf_type_t
*tp
;
827 ssize_t size
, increment
;
830 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
831 return -1; /* errno is set for us. */
833 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
834 return -1; /* errno is set for us. */
836 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
837 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
839 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
840 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
842 if (size
< CTF_LSTRUCT_THRESH
)
844 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
847 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
849 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
851 mip
->ctm_type
= mp
->ctm_type
;
852 mip
->ctm_offset
= mp
->ctm_offset
;
859 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
862 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
864 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
866 mip
->ctm_type
= lmp
->ctlm_type
;
867 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
873 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
876 /* Return the array type, index, and size information for the specified ARRAY. */
879 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
881 ctf_file_t
*ofp
= fp
;
882 const ctf_type_t
*tp
;
883 const ctf_array_t
*ap
;
884 const ctf_dtdef_t
*dtd
;
887 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
888 return -1; /* errno is set for us. */
890 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
891 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
893 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
895 *arp
= dtd
->dtd_u
.dtu_arr
;
899 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
901 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
902 arp
->ctr_contents
= ap
->cta_contents
;
903 arp
->ctr_index
= ap
->cta_index
;
904 arp
->ctr_nelems
= ap
->cta_nelems
;
909 /* Convert the specified value to the corresponding enum tag name, if a
910 matching name can be found. Otherwise NULL is returned. */
913 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
915 ctf_file_t
*ofp
= fp
;
916 const ctf_type_t
*tp
;
917 const ctf_enum_t
*ep
;
921 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
922 return NULL
; /* errno is set for us. */
924 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
925 return NULL
; /* errno is set for us. */
927 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
929 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
933 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
935 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
937 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
939 if (ep
->cte_value
== value
)
940 return (ctf_strptr (fp
, ep
->cte_name
));
943 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
947 /* Convert the specified enum tag name to the corresponding value, if a
948 matching name can be found. Otherwise CTF_ERR is returned. */
951 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
953 ctf_file_t
*ofp
= fp
;
954 const ctf_type_t
*tp
;
955 const ctf_enum_t
*ep
;
959 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
960 return -1; /* errno is set for us. */
962 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
963 return -1; /* errno is set for us. */
965 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
967 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
971 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
973 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
975 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
977 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
980 *valp
= ep
->cte_value
;
985 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
989 /* Given a type ID relating to a function type, return info on return types and
990 arg counts for that function. */
993 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
995 const ctf_type_t
*tp
;
997 const uint32_t *args
;
998 ssize_t size
, increment
;
1000 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1001 return -1; /* errno is set for us. */
1003 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1004 return -1; /* errno is set for us. */
1006 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1007 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1009 if (kind
!= CTF_K_FUNCTION
)
1010 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1012 fip
->ctc_return
= tp
->ctt_type
;
1013 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1016 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1018 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1020 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1027 /* Given a type ID relating to a function type,, return the arguments for the
1031 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1033 const ctf_type_t
*tp
;
1034 const uint32_t *args
;
1035 ssize_t size
, increment
;
1038 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1039 return -1; /* errno is set for us. */
1041 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1042 return -1; /* errno is set for us. */
1044 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1045 return -1; /* errno is set for us. */
1047 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1049 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1051 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1057 /* Recursively visit the members of any type. This function is used as the
1058 engine for ctf_type_visit, below. We resolve the input type, recursively
1059 invoke ourself for each type member if the type is a struct or union, and
1060 then invoke the callback function on the current type. If any callback
1061 returns non-zero, we abort and percolate the error code back up to the top. */
1064 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1065 void *arg
, const char *name
, unsigned long offset
, int depth
)
1067 ctf_id_t otype
= type
;
1068 const ctf_type_t
*tp
;
1069 ssize_t size
, increment
;
1073 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1074 return -1; /* errno is set for us. */
1076 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1077 return -1; /* errno is set for us. */
1079 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1082 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1084 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1087 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1089 if (size
< CTF_LSTRUCT_THRESH
)
1091 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1094 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1096 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1097 func
, arg
, ctf_strptr (fp
, mp
->ctm_name
),
1098 offset
+ mp
->ctm_offset
,
1106 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1109 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1111 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1112 func
, arg
, ctf_strptr (fp
,
1114 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1123 /* Recursively visit the members of any type. We pass the name, member
1124 type, and offset of each member to the specified callback function. */
1126 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1128 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));