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
)
46 ssize_t size
, increment
;
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
+
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)
78 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
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)
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)
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
;
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)
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)
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)
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))
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
)
206 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
207 return ECTF_NOPARENT
;
209 if (!(fp
->ctf_flags
& LCTF_RDWR
))
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)
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)
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. */
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
;
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
))
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
));
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
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
)
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
);
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
308 ctf_id_t
ctf_lookup_by_rawhash (ctf_file_t
*fp
, ctf_names_t
*np
, const char *name
)
312 if (fp
->ctf_flags
& LCTF_RDWR
)
313 id
= (ctf_id_t
) ctf_dynhash_lookup (np
->ctn_writable
, name
);
315 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
319 /* Lookup the given type ID and return its name as a new dynamcally-allocated
323 ctf_type_aname (ctf_file_t
*fp
, ctf_id_t type
)
326 ctf_decl_node_t
*cdp
;
327 ctf_decl_prec_t prec
, lp
, rp
;
332 if (fp
== NULL
&& type
== CTF_ERR
)
333 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
336 ctf_decl_push (&cd
, fp
, type
);
341 ctf_set_errno (fp
, cd
.cd_err
);
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
, " ");
373 ctf_decl_sprintf (&cd
, "(");
377 switch (cdp
->cd_kind
)
382 ctf_decl_sprintf (&cd
, "%s", name
);
385 ctf_decl_sprintf (&cd
, "*");
388 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
391 ctf_decl_sprintf (&cd
, "()");
395 ctf_decl_sprintf (&cd
, "struct %s", name
);
398 ctf_decl_sprintf (&cd
, "union %s", name
);
401 ctf_decl_sprintf (&cd
, "enum %s", name
);
404 ctf_decl_sprintf (&cd
, "volatile");
407 ctf_decl_sprintf (&cd
, "const");
410 ctf_decl_sprintf (&cd
, "restrict");
413 /* No representation: just changes encoding of contained type,
414 which is not in any case printed. Skip it. */
422 ctf_decl_sprintf (&cd
, ")");
426 (void) ctf_set_errno (fp
, ENOMEM
);
428 buf
= ctf_decl_buf (&cd
);
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. */
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
= strlen (str
);
444 return CTF_ERR
; /* errno is set for us */
446 snprintf (buf
, len
, "%s", str
);
450 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
455 /* Lookup the given type ID and print a string name for it into buf. If buf
456 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
459 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
461 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
462 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
465 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
466 new dynamcally-allocated string. */
469 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
471 const ctf_type_t
*tp
;
473 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
474 return NULL
; /* errno is set for us. */
476 if (ctf_strraw (fp
, tp
->ctt_name
) != NULL
)
477 return strdup (ctf_strraw (fp
, tp
->ctt_name
));
482 /* Resolve the type down to a base type node, and then return the size
483 of the type storage in bytes. */
486 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
488 const ctf_type_t
*tp
;
492 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
493 return -1; /* errno is set for us. */
495 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
496 return -1; /* errno is set for us. */
498 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
501 return fp
->ctf_dmodel
->ctd_pointer
;
504 return 0; /* Function size is only known by symtab. */
507 return fp
->ctf_dmodel
->ctd_int
;
510 /* ctf_add_array() does not directly encode the element size, but
511 requires the user to multiply to determine the element size.
513 If ctf_get_ctt_size() returns nonzero, then use the recorded
516 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
519 if (ctf_array_info (fp
, type
, &ar
) < 0
520 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
521 return -1; /* errno is set for us. */
523 return size
* ar
.ctr_nelems
;
525 default: /* including slices of enums, etc */
526 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
530 /* Resolve the type down to a base type node, and then return the alignment
531 needed for the type storage in bytes.
533 XXX may need arch-dependent attention. */
536 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
538 const ctf_type_t
*tp
;
539 ctf_file_t
*ofp
= fp
;
542 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
543 return -1; /* errno is set for us. */
545 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
546 return -1; /* errno is set for us. */
548 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
553 return fp
->ctf_dmodel
->ctd_pointer
;
558 if (ctf_array_info (fp
, type
, &r
) < 0)
559 return -1; /* errno is set for us. */
560 return (ctf_type_align (fp
, r
.ctr_contents
));
569 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
571 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
572 ssize_t size
, increment
;
575 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
576 vmp
= (unsigned char *) tp
+ increment
;
578 if (kind
== CTF_K_STRUCT
)
579 n
= MIN (n
, 1); /* Only use first member for structs. */
581 if (size
< CTF_LSTRUCT_THRESH
)
583 const ctf_member_t
*mp
= vmp
;
584 for (; n
!= 0; n
--, mp
++)
586 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
587 align
= MAX (align
, (size_t) am
);
592 const ctf_lmember_t
*lmp
= vmp
;
593 for (; n
!= 0; n
--, lmp
++)
595 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
596 align
= MAX (align
, (size_t) am
);
604 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
605 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
607 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
608 align
= MAX (align
, (size_t) am
);
609 if (kind
== CTF_K_STRUCT
)
618 return fp
->ctf_dmodel
->ctd_int
;
620 default: /* including slices of enums, etc */
621 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
625 /* Return the kind (CTF_K_* constant) for the specified type ID. */
628 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
630 const ctf_type_t
*tp
;
632 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
633 return -1; /* errno is set for us. */
635 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
638 /* Return the kind (CTF_K_* constant) for the specified type ID.
639 Slices are considered to be of the same kind as the type sliced. */
642 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
646 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
649 if (kind
== CTF_K_SLICE
)
651 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
653 kind
= ctf_type_kind_unsliced (fp
, type
);
659 /* If the type is one that directly references another type (such as POINTER),
660 then return the ID of the type to which it refers. */
663 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
665 ctf_file_t
*ofp
= fp
;
666 const ctf_type_t
*tp
;
668 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
669 return CTF_ERR
; /* errno is set for us. */
671 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
679 /* Slices store their type in an unusual place. */
682 const ctf_slice_t
*sp
;
684 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
685 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
689 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
693 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
694 pointer to the given type, see if we can compute a pointer to the type
695 resulting from resolving the type down to its base type and use that
696 instead. This helps with cases where the CTF data includes "struct foo *"
697 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
699 XXX what about parent containers? */
702 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
704 ctf_file_t
*ofp
= fp
;
707 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
708 return CTF_ERR
; /* errno is set for us. */
710 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
711 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
713 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
714 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
716 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
717 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
719 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
720 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
722 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
725 /* Return the encoding for the specified INTEGER or FLOAT. */
728 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
730 ctf_file_t
*ofp
= fp
;
732 const ctf_type_t
*tp
;
736 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
737 return -1; /* errno is set for us. */
739 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
741 *ep
= dtd
->dtd_u
.dtu_enc
;
745 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
747 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
750 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
751 ep
->cte_format
= CTF_INT_ENCODING (data
);
752 ep
->cte_offset
= CTF_INT_OFFSET (data
);
753 ep
->cte_bits
= CTF_INT_BITS (data
);
756 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
757 ep
->cte_format
= CTF_FP_ENCODING (data
);
758 ep
->cte_offset
= CTF_FP_OFFSET (data
);
759 ep
->cte_bits
= CTF_FP_BITS (data
);
763 const ctf_slice_t
*slice
;
764 ctf_encoding_t underlying_en
;
766 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
767 data
= ctf_type_encoding (fp
, slice
->cts_type
, &underlying_en
);
769 ep
->cte_format
= underlying_en
.cte_format
;
770 ep
->cte_offset
= slice
->cts_offset
;
771 ep
->cte_bits
= slice
->cts_bits
;
775 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
782 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
789 else if (ltype
> rtype
)
797 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
798 lfp
= lfp
->ctf_parent
;
800 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
801 rfp
= rfp
->ctf_parent
;
812 /* Return a boolean value indicating if two types are compatible. This function
813 returns true if the two types are the same, or if they (or their ultimate
814 base type) have the same encoding properties, or (for structs / unions /
815 enums / forward declarations) if they have the same name and (for structs /
816 unions) member count. */
819 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
820 ctf_file_t
*rfp
, ctf_id_t rtype
)
822 const ctf_type_t
*ltp
, *rtp
;
823 ctf_encoding_t le
, re
;
825 uint32_t lkind
, rkind
;
828 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
831 ltype
= ctf_type_resolve (lfp
, ltype
);
832 lkind
= ctf_type_kind (lfp
, ltype
);
834 rtype
= ctf_type_resolve (rfp
, rtype
);
835 rkind
= ctf_type_kind (rfp
, rtype
);
837 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
838 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
840 if (ltp
!= NULL
&& rtp
!= NULL
)
841 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
842 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
844 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
845 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
855 memset (&le
, 0, sizeof (le
));
856 memset (&re
, 0, sizeof (re
));
857 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
858 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
859 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
861 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
862 rfp
, ctf_type_reference (rfp
, rtype
)));
864 return (ctf_array_info (lfp
, ltype
, &la
) == 0
865 && ctf_array_info (rfp
, rtype
, &ra
) == 0
866 && la
.ctr_nelems
== ra
.ctr_nelems
867 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
868 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
871 return (same_names
&& (ctf_type_size (lfp
, ltype
)
872 == ctf_type_size (rfp
, rtype
)));
875 int lencoded
, rencoded
;
876 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
877 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
879 if ((lencoded
!= rencoded
) ||
880 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
885 return same_names
; /* No other checks required for these type kinds. */
887 return 0; /* Should not get here since we did a resolve. */
891 /* Return the type and offset for a given member of a STRUCT or UNION. */
894 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
897 ctf_file_t
*ofp
= fp
;
898 const ctf_type_t
*tp
;
900 ssize_t size
, increment
;
903 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
904 return -1; /* errno is set for us. */
906 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
907 return -1; /* errno is set for us. */
909 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
910 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
912 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
913 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
915 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
917 if (size
< CTF_LSTRUCT_THRESH
)
919 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
922 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
924 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
926 mip
->ctm_type
= mp
->ctm_type
;
927 mip
->ctm_offset
= mp
->ctm_offset
;
934 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
937 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
939 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
941 mip
->ctm_type
= lmp
->ctlm_type
;
942 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
952 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
953 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
955 if (strcmp (dmd
->dmd_name
, name
) == 0)
957 mip
->ctm_type
= dmd
->dmd_type
;
958 mip
->ctm_offset
= dmd
->dmd_offset
;
964 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
967 /* Return the array type, index, and size information for the specified ARRAY. */
970 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
972 ctf_file_t
*ofp
= fp
;
973 const ctf_type_t
*tp
;
974 const ctf_array_t
*ap
;
975 const ctf_dtdef_t
*dtd
;
978 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
979 return -1; /* errno is set for us. */
981 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
982 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
984 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
986 *arp
= dtd
->dtd_u
.dtu_arr
;
990 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
992 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
993 arp
->ctr_contents
= ap
->cta_contents
;
994 arp
->ctr_index
= ap
->cta_index
;
995 arp
->ctr_nelems
= ap
->cta_nelems
;
1000 /* Convert the specified value to the corresponding enum tag name, if a
1001 matching name can be found. Otherwise NULL is returned. */
1004 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
1006 ctf_file_t
*ofp
= fp
;
1007 const ctf_type_t
*tp
;
1008 const ctf_enum_t
*ep
;
1009 const ctf_dtdef_t
*dtd
;
1013 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1014 return NULL
; /* errno is set for us. */
1016 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1017 return NULL
; /* errno is set for us. */
1019 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1021 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1025 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1027 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1029 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1031 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1033 if (ep
->cte_value
== value
)
1034 return (ctf_strptr (fp
, ep
->cte_name
));
1041 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1042 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1044 if (dmd
->dmd_value
== value
)
1045 return dmd
->dmd_name
;
1049 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1053 /* Convert the specified enum tag name to the corresponding value, if a
1054 matching name can be found. Otherwise CTF_ERR is returned. */
1057 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1059 ctf_file_t
*ofp
= fp
;
1060 const ctf_type_t
*tp
;
1061 const ctf_enum_t
*ep
;
1062 const ctf_dtdef_t
*dtd
;
1066 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1067 return -1; /* errno is set for us. */
1069 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1070 return -1; /* errno is set for us. */
1072 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1074 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1078 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1080 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1082 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1084 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1086 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1089 *valp
= ep
->cte_value
;
1098 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1099 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1101 if (strcmp (dmd
->dmd_name
, name
) == 0)
1104 *valp
= dmd
->dmd_value
;
1110 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1114 /* Given a type ID relating to a function type, return info on return types and
1115 arg counts for that function. */
1118 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1120 const ctf_type_t
*tp
;
1122 const uint32_t *args
;
1123 const ctf_dtdef_t
*dtd
;
1124 ssize_t size
, increment
;
1126 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1127 return -1; /* errno is set for us. */
1129 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1130 return -1; /* errno is set for us. */
1132 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1133 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1135 if (kind
!= CTF_K_FUNCTION
)
1136 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1138 fip
->ctc_return
= tp
->ctt_type
;
1140 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1142 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1143 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1145 args
= (uint32_t *) dtd
->dtd_u
.dtu_argv
;
1147 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1149 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1156 /* Given a type ID relating to a function type,, return the arguments for the
1160 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1162 const ctf_type_t
*tp
;
1163 const uint32_t *args
;
1164 const ctf_dtdef_t
*dtd
;
1165 ssize_t size
, increment
;
1168 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1169 return -1; /* errno is set for us. */
1171 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1172 return -1; /* errno is set for us. */
1174 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1175 return -1; /* errno is set for us. */
1177 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1179 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1180 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1182 args
= (uint32_t *) dtd
->dtd_u
.dtu_argv
;
1184 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1190 /* Recursively visit the members of any type. This function is used as the
1191 engine for ctf_type_visit, below. We resolve the input type, recursively
1192 invoke ourself for each type member if the type is a struct or union, and
1193 then invoke the callback function on the current type. If any callback
1194 returns non-zero, we abort and percolate the error code back up to the top. */
1197 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1198 void *arg
, const char *name
, unsigned long offset
, int depth
)
1200 ctf_id_t otype
= type
;
1201 const ctf_type_t
*tp
;
1202 const ctf_dtdef_t
*dtd
;
1203 ssize_t size
, increment
;
1207 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1208 return -1; /* errno is set for us. */
1210 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1211 return -1; /* errno is set for us. */
1213 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1216 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1218 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1221 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1223 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1225 if (size
< CTF_LSTRUCT_THRESH
)
1227 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1230 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1232 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1233 func
, arg
, ctf_strptr (fp
,
1235 offset
+ mp
->ctm_offset
,
1242 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1245 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1247 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1248 func
, arg
, ctf_strptr (fp
,
1250 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1260 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1261 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1263 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1264 dmd
->dmd_name
, dmd
->dmd_offset
,
1273 /* Recursively visit the members of any type. We pass the name, member
1274 type, and offset of each member to the specified callback function. */
1276 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1278 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));