1 /* Type handling functions.
2 Copyright (C) 2019-2020 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
);
444 return CTF_ERR
; /* errno is set for us. */
447 snprintf (buf
, len
, "%s", str
);
451 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
456 /* Lookup the given type ID and print a string name for it into buf. If buf
457 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
460 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
462 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
463 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
466 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
467 new dynamcally-allocated string. */
470 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
472 const ctf_type_t
*tp
;
474 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
475 return NULL
; /* errno is set for us. */
477 if (ctf_strraw (fp
, tp
->ctt_name
) != NULL
)
478 return strdup (ctf_strraw (fp
, tp
->ctt_name
));
483 /* Resolve the type down to a base type node, and then return the size
484 of the type storage in bytes. */
487 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
489 const ctf_type_t
*tp
;
493 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
494 return -1; /* errno is set for us. */
496 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
497 return -1; /* errno is set for us. */
499 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
502 return fp
->ctf_dmodel
->ctd_pointer
;
505 return 0; /* Function size is only known by symtab. */
508 return fp
->ctf_dmodel
->ctd_int
;
511 /* ctf_add_array() does not directly encode the element size, but
512 requires the user to multiply to determine the element size.
514 If ctf_get_ctt_size() returns nonzero, then use the recorded
517 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
520 if (ctf_array_info (fp
, type
, &ar
) < 0
521 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
522 return -1; /* errno is set for us. */
524 return size
* ar
.ctr_nelems
;
526 default: /* including slices of enums, etc */
527 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
531 /* Resolve the type down to a base type node, and then return the alignment
532 needed for the type storage in bytes.
534 XXX may need arch-dependent attention. */
537 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
539 const ctf_type_t
*tp
;
540 ctf_file_t
*ofp
= fp
;
543 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
544 return -1; /* errno is set for us. */
546 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
547 return -1; /* errno is set for us. */
549 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
554 return fp
->ctf_dmodel
->ctd_pointer
;
559 if (ctf_array_info (fp
, type
, &r
) < 0)
560 return -1; /* errno is set for us. */
561 return (ctf_type_align (fp
, r
.ctr_contents
));
570 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
572 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
573 ssize_t size
, increment
;
576 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
577 vmp
= (unsigned char *) tp
+ increment
;
579 if (kind
== CTF_K_STRUCT
)
580 n
= MIN (n
, 1); /* Only use first member for structs. */
582 if (size
< CTF_LSTRUCT_THRESH
)
584 const ctf_member_t
*mp
= vmp
;
585 for (; n
!= 0; n
--, mp
++)
587 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
588 align
= MAX (align
, (size_t) am
);
593 const ctf_lmember_t
*lmp
= vmp
;
594 for (; n
!= 0; n
--, lmp
++)
596 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
597 align
= MAX (align
, (size_t) am
);
605 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
606 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
608 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
609 align
= MAX (align
, (size_t) am
);
610 if (kind
== CTF_K_STRUCT
)
619 return fp
->ctf_dmodel
->ctd_int
;
621 default: /* including slices of enums, etc */
622 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
626 /* Return the kind (CTF_K_* constant) for the specified type ID. */
629 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
631 const ctf_type_t
*tp
;
633 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
634 return -1; /* errno is set for us. */
636 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
639 /* Return the kind (CTF_K_* constant) for the specified type ID.
640 Slices are considered to be of the same kind as the type sliced. */
643 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
647 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
650 if (kind
== CTF_K_SLICE
)
652 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
654 kind
= ctf_type_kind_unsliced (fp
, type
);
660 /* If the type is one that directly references another type (such as POINTER),
661 then return the ID of the type to which it refers. */
664 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
666 ctf_file_t
*ofp
= fp
;
667 const ctf_type_t
*tp
;
669 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
670 return CTF_ERR
; /* errno is set for us. */
672 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
680 /* Slices store their type in an unusual place. */
684 const ctf_slice_t
*sp
;
686 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
690 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
691 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
694 sp
= &dtd
->dtd_u
.dtu_slice
;
699 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
703 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
704 pointer to the given type, see if we can compute a pointer to the type
705 resulting from resolving the type down to its base type and use that
706 instead. This helps with cases where the CTF data includes "struct foo *"
707 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
709 XXX what about parent containers? */
712 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
714 ctf_file_t
*ofp
= fp
;
717 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
718 return CTF_ERR
; /* errno is set for us. */
720 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
721 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
723 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
724 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
726 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
727 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
729 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
730 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
732 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
735 /* Return the encoding for the specified INTEGER or FLOAT. */
738 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
740 ctf_file_t
*ofp
= fp
;
742 const ctf_type_t
*tp
;
746 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
747 return -1; /* errno is set for us. */
749 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
751 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
755 *ep
= dtd
->dtd_u
.dtu_enc
;
759 const ctf_slice_t
*slice
;
760 ctf_encoding_t underlying_en
;
763 slice
= &dtd
->dtd_u
.dtu_slice
;
764 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
765 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
767 ep
->cte_format
= underlying_en
.cte_format
;
768 ep
->cte_offset
= slice
->cts_offset
;
769 ep
->cte_bits
= slice
->cts_bits
;
773 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
778 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
780 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
783 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
784 ep
->cte_format
= CTF_INT_ENCODING (data
);
785 ep
->cte_offset
= CTF_INT_OFFSET (data
);
786 ep
->cte_bits
= CTF_INT_BITS (data
);
789 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
790 ep
->cte_format
= CTF_FP_ENCODING (data
);
791 ep
->cte_offset
= CTF_FP_OFFSET (data
);
792 ep
->cte_bits
= CTF_FP_BITS (data
);
796 const ctf_slice_t
*slice
;
797 ctf_encoding_t underlying_en
;
800 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
801 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
802 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
804 ep
->cte_format
= underlying_en
.cte_format
;
805 ep
->cte_offset
= slice
->cts_offset
;
806 ep
->cte_bits
= slice
->cts_bits
;
810 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
817 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
824 else if (ltype
> rtype
)
832 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
833 lfp
= lfp
->ctf_parent
;
835 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
836 rfp
= rfp
->ctf_parent
;
847 /* Return a boolean value indicating if two types are compatible. This function
848 returns true if the two types are the same, or if they (or their ultimate
849 base type) have the same encoding properties, or (for structs / unions /
850 enums / forward declarations) if they have the same name and (for structs /
851 unions) member count. */
854 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
855 ctf_file_t
*rfp
, ctf_id_t rtype
)
857 const ctf_type_t
*ltp
, *rtp
;
858 ctf_encoding_t le
, re
;
860 uint32_t lkind
, rkind
;
863 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
866 ltype
= ctf_type_resolve (lfp
, ltype
);
867 lkind
= ctf_type_kind (lfp
, ltype
);
869 rtype
= ctf_type_resolve (rfp
, rtype
);
870 rkind
= ctf_type_kind (rfp
, rtype
);
872 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
873 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
875 if (ltp
!= NULL
&& rtp
!= NULL
)
876 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
877 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
879 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
880 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
890 memset (&le
, 0, sizeof (le
));
891 memset (&re
, 0, sizeof (re
));
892 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
893 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
894 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
896 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
897 rfp
, ctf_type_reference (rfp
, rtype
)));
899 return (ctf_array_info (lfp
, ltype
, &la
) == 0
900 && ctf_array_info (rfp
, rtype
, &ra
) == 0
901 && la
.ctr_nelems
== ra
.ctr_nelems
902 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
903 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
906 return (same_names
&& (ctf_type_size (lfp
, ltype
)
907 == ctf_type_size (rfp
, rtype
)));
910 int lencoded
, rencoded
;
911 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
912 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
914 if ((lencoded
!= rencoded
) ||
915 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
920 return same_names
; /* No other checks required for these type kinds. */
922 return 0; /* Should not get here since we did a resolve. */
926 /* Return the type and offset for a given member of a STRUCT or UNION. */
929 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
932 ctf_file_t
*ofp
= fp
;
933 const ctf_type_t
*tp
;
935 ssize_t size
, increment
;
938 if ((type
= ctf_type_resolve (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 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
945 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
947 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
948 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
950 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
952 if (size
< CTF_LSTRUCT_THRESH
)
954 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
957 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
959 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
961 mip
->ctm_type
= mp
->ctm_type
;
962 mip
->ctm_offset
= mp
->ctm_offset
;
969 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
972 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
974 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
976 mip
->ctm_type
= lmp
->ctlm_type
;
977 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
987 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
988 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
990 if (strcmp (dmd
->dmd_name
, name
) == 0)
992 mip
->ctm_type
= dmd
->dmd_type
;
993 mip
->ctm_offset
= dmd
->dmd_offset
;
999 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1002 /* Return the array type, index, and size information for the specified ARRAY. */
1005 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1007 ctf_file_t
*ofp
= fp
;
1008 const ctf_type_t
*tp
;
1009 const ctf_array_t
*ap
;
1010 const ctf_dtdef_t
*dtd
;
1013 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1014 return -1; /* errno is set for us. */
1016 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1017 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1019 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1021 *arp
= dtd
->dtd_u
.dtu_arr
;
1025 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1027 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1028 arp
->ctr_contents
= ap
->cta_contents
;
1029 arp
->ctr_index
= ap
->cta_index
;
1030 arp
->ctr_nelems
= ap
->cta_nelems
;
1035 /* Convert the specified value to the corresponding enum tag name, if a
1036 matching name can be found. Otherwise NULL is returned. */
1039 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
1041 ctf_file_t
*ofp
= fp
;
1042 const ctf_type_t
*tp
;
1043 const ctf_enum_t
*ep
;
1044 const ctf_dtdef_t
*dtd
;
1048 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1049 return NULL
; /* errno is set for us. */
1051 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1052 return NULL
; /* errno is set for us. */
1054 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1056 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1060 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1062 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1064 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1066 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1068 if (ep
->cte_value
== value
)
1069 return (ctf_strptr (fp
, ep
->cte_name
));
1076 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1077 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1079 if (dmd
->dmd_value
== value
)
1080 return dmd
->dmd_name
;
1084 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1088 /* Convert the specified enum tag name to the corresponding value, if a
1089 matching name can be found. Otherwise CTF_ERR is returned. */
1092 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1094 ctf_file_t
*ofp
= fp
;
1095 const ctf_type_t
*tp
;
1096 const ctf_enum_t
*ep
;
1097 const ctf_dtdef_t
*dtd
;
1101 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1102 return -1; /* errno is set for us. */
1104 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1105 return -1; /* errno is set for us. */
1107 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1109 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1113 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1115 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1117 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1119 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1121 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1124 *valp
= ep
->cte_value
;
1133 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1134 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1136 if (strcmp (dmd
->dmd_name
, name
) == 0)
1139 *valp
= dmd
->dmd_value
;
1145 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1149 /* Given a type ID relating to a function type, return info on return types and
1150 arg counts for that function. */
1153 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1155 const ctf_type_t
*tp
;
1157 const uint32_t *args
;
1158 const ctf_dtdef_t
*dtd
;
1159 ssize_t size
, increment
;
1161 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1162 return -1; /* errno is set for us. */
1164 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1165 return -1; /* errno is set for us. */
1167 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1168 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1170 if (kind
!= CTF_K_FUNCTION
)
1171 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1173 fip
->ctc_return
= tp
->ctt_type
;
1175 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1177 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1178 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1180 args
= dtd
->dtd_u
.dtu_argv
;
1182 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1184 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1191 /* Given a type ID relating to a function type, return the arguments for the
1195 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1197 const ctf_type_t
*tp
;
1198 const uint32_t *args
;
1199 const ctf_dtdef_t
*dtd
;
1200 ssize_t size
, increment
;
1203 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1204 return -1; /* errno is set for us. */
1206 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1207 return -1; /* errno is set for us. */
1209 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1210 return -1; /* errno is set for us. */
1212 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1214 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1215 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1217 args
= dtd
->dtd_u
.dtu_argv
;
1219 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1225 /* Recursively visit the members of any type. This function is used as the
1226 engine for ctf_type_visit, below. We resolve the input type, recursively
1227 invoke ourself for each type member if the type is a struct or union, and
1228 then invoke the callback function on the current type. If any callback
1229 returns non-zero, we abort and percolate the error code back up to the top. */
1232 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1233 void *arg
, const char *name
, unsigned long offset
, int depth
)
1235 ctf_id_t otype
= type
;
1236 const ctf_type_t
*tp
;
1237 const ctf_dtdef_t
*dtd
;
1238 ssize_t size
, increment
;
1242 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1243 return -1; /* errno is set for us. */
1245 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1246 return -1; /* errno is set for us. */
1248 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1251 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1253 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1256 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1258 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1260 if (size
< CTF_LSTRUCT_THRESH
)
1262 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1265 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1267 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1268 func
, arg
, ctf_strptr (fp
,
1270 offset
+ mp
->ctm_offset
,
1277 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1280 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1282 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1283 func
, arg
, ctf_strptr (fp
,
1285 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1295 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1296 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1298 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1299 dmd
->dmd_name
, dmd
->dmd_offset
,
1308 /* Recursively visit the members of any type. We pass the name, member
1309 type, and offset of each member to the specified callback function. */
1311 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1313 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));