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 dynamically-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 /* Integers, floats, and typedefs must always be named types. */
386 ctf_set_errno (fp
, ECTF_CORRUPT
);
391 ctf_decl_sprintf (&cd
, "%s", name
);
394 ctf_decl_sprintf (&cd
, "*");
397 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
400 ctf_decl_sprintf (&cd
, "()");
404 ctf_decl_sprintf (&cd
, "struct %s", name
);
407 ctf_decl_sprintf (&cd
, "union %s", name
);
410 ctf_decl_sprintf (&cd
, "enum %s", name
);
413 ctf_decl_sprintf (&cd
, "volatile");
416 ctf_decl_sprintf (&cd
, "const");
419 ctf_decl_sprintf (&cd
, "restrict");
422 /* No representation: just changes encoding of contained type,
423 which is not in any case printed. Skip it. */
431 ctf_decl_sprintf (&cd
, ")");
435 (void) ctf_set_errno (fp
, ENOMEM
);
437 buf
= ctf_decl_buf (&cd
);
443 /* Lookup the given type ID and print a string name for it into buf. Return
444 the actual number of bytes (not including \0) needed to format the name. */
447 ctf_type_lname (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
449 char *str
= ctf_type_aname (fp
, type
);
453 return CTF_ERR
; /* errno is set for us. */
456 snprintf (buf
, len
, "%s", str
);
460 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
465 /* Lookup the given type ID and print a string name for it into buf. If buf
466 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
469 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
471 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
472 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
475 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
476 new dynamcally-allocated string. */
479 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
481 const ctf_type_t
*tp
;
483 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
484 return NULL
; /* errno is set for us. */
486 if (ctf_strraw (fp
, tp
->ctt_name
) != NULL
)
487 return strdup (ctf_strraw (fp
, tp
->ctt_name
));
492 /* Resolve the type down to a base type node, and then return the size
493 of the type storage in bytes. */
496 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
498 const ctf_type_t
*tp
;
502 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
503 return -1; /* errno is set for us. */
505 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
506 return -1; /* errno is set for us. */
508 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
511 return fp
->ctf_dmodel
->ctd_pointer
;
514 return 0; /* Function size is only known by symtab. */
517 return fp
->ctf_dmodel
->ctd_int
;
520 /* ctf_add_array() does not directly encode the element size, but
521 requires the user to multiply to determine the element size.
523 If ctf_get_ctt_size() returns nonzero, then use the recorded
526 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
529 if (ctf_array_info (fp
, type
, &ar
) < 0
530 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
531 return -1; /* errno is set for us. */
533 return size
* ar
.ctr_nelems
;
535 default: /* including slices of enums, etc */
536 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
540 /* Resolve the type down to a base type node, and then return the alignment
541 needed for the type storage in bytes.
543 XXX may need arch-dependent attention. */
546 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
548 const ctf_type_t
*tp
;
549 ctf_file_t
*ofp
= fp
;
552 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
553 return -1; /* errno is set for us. */
555 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
556 return -1; /* errno is set for us. */
558 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
563 return fp
->ctf_dmodel
->ctd_pointer
;
568 if (ctf_array_info (fp
, type
, &r
) < 0)
569 return -1; /* errno is set for us. */
570 return (ctf_type_align (fp
, r
.ctr_contents
));
579 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
581 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
582 ssize_t size
, increment
;
585 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
586 vmp
= (unsigned char *) tp
+ increment
;
588 if (kind
== CTF_K_STRUCT
)
589 n
= MIN (n
, 1); /* Only use first member for structs. */
591 if (size
< CTF_LSTRUCT_THRESH
)
593 const ctf_member_t
*mp
= vmp
;
594 for (; n
!= 0; n
--, mp
++)
596 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
597 align
= MAX (align
, (size_t) am
);
602 const ctf_lmember_t
*lmp
= vmp
;
603 for (; n
!= 0; n
--, lmp
++)
605 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
606 align
= MAX (align
, (size_t) am
);
614 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
615 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
617 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
618 align
= MAX (align
, (size_t) am
);
619 if (kind
== CTF_K_STRUCT
)
628 return fp
->ctf_dmodel
->ctd_int
;
630 default: /* including slices of enums, etc */
631 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
635 /* Return the kind (CTF_K_* constant) for the specified type ID. */
638 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
640 const ctf_type_t
*tp
;
642 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
643 return -1; /* errno is set for us. */
645 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
648 /* Return the kind (CTF_K_* constant) for the specified type ID.
649 Slices are considered to be of the same kind as the type sliced. */
652 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
656 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
659 if (kind
== CTF_K_SLICE
)
661 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
663 kind
= ctf_type_kind_unsliced (fp
, type
);
669 /* If the type is one that directly references another type (such as POINTER),
670 then return the ID of the type to which it refers. */
673 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
675 ctf_file_t
*ofp
= fp
;
676 const ctf_type_t
*tp
;
678 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
679 return CTF_ERR
; /* errno is set for us. */
681 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
689 /* Slices store their type in an unusual place. */
693 const ctf_slice_t
*sp
;
695 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
699 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
700 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
703 sp
= &dtd
->dtd_u
.dtu_slice
;
708 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
712 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
713 pointer to the given type, see if we can compute a pointer to the type
714 resulting from resolving the type down to its base type and use that
715 instead. This helps with cases where the CTF data includes "struct foo *"
716 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
718 XXX what about parent containers? */
721 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
723 ctf_file_t
*ofp
= fp
;
726 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
727 return CTF_ERR
; /* errno is set for us. */
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 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
733 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
735 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
736 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
738 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
739 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
741 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
744 /* Return the encoding for the specified INTEGER or FLOAT. */
747 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
749 ctf_file_t
*ofp
= fp
;
751 const ctf_type_t
*tp
;
755 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
756 return -1; /* errno is set for us. */
758 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
760 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
764 *ep
= dtd
->dtd_u
.dtu_enc
;
768 const ctf_slice_t
*slice
;
769 ctf_encoding_t underlying_en
;
772 slice
= &dtd
->dtd_u
.dtu_slice
;
773 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
774 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
776 ep
->cte_format
= underlying_en
.cte_format
;
777 ep
->cte_offset
= slice
->cts_offset
;
778 ep
->cte_bits
= slice
->cts_bits
;
782 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
787 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
789 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
792 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
793 ep
->cte_format
= CTF_INT_ENCODING (data
);
794 ep
->cte_offset
= CTF_INT_OFFSET (data
);
795 ep
->cte_bits
= CTF_INT_BITS (data
);
798 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
799 ep
->cte_format
= CTF_FP_ENCODING (data
);
800 ep
->cte_offset
= CTF_FP_OFFSET (data
);
801 ep
->cte_bits
= CTF_FP_BITS (data
);
805 const ctf_slice_t
*slice
;
806 ctf_encoding_t underlying_en
;
809 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
810 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
811 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
813 ep
->cte_format
= underlying_en
.cte_format
;
814 ep
->cte_offset
= slice
->cts_offset
;
815 ep
->cte_bits
= slice
->cts_bits
;
819 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
826 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
833 else if (ltype
> rtype
)
841 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
842 lfp
= lfp
->ctf_parent
;
844 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
845 rfp
= rfp
->ctf_parent
;
856 /* Return a boolean value indicating if two types are compatible. This function
857 returns true if the two types are the same, or if they (or their ultimate
858 base type) have the same encoding properties, or (for structs / unions /
859 enums / forward declarations) if they have the same name and (for structs /
860 unions) member count. */
863 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
864 ctf_file_t
*rfp
, ctf_id_t rtype
)
866 const ctf_type_t
*ltp
, *rtp
;
867 ctf_encoding_t le
, re
;
869 uint32_t lkind
, rkind
;
872 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
875 ltype
= ctf_type_resolve (lfp
, ltype
);
876 lkind
= ctf_type_kind (lfp
, ltype
);
878 rtype
= ctf_type_resolve (rfp
, rtype
);
879 rkind
= ctf_type_kind (rfp
, rtype
);
881 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
882 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
884 if (ltp
!= NULL
&& rtp
!= NULL
)
885 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
886 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
888 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
889 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
899 memset (&le
, 0, sizeof (le
));
900 memset (&re
, 0, sizeof (re
));
901 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
902 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
903 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
905 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
906 rfp
, ctf_type_reference (rfp
, rtype
)));
908 return (ctf_array_info (lfp
, ltype
, &la
) == 0
909 && ctf_array_info (rfp
, rtype
, &ra
) == 0
910 && la
.ctr_nelems
== ra
.ctr_nelems
911 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
912 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
915 return (same_names
&& (ctf_type_size (lfp
, ltype
)
916 == ctf_type_size (rfp
, rtype
)));
919 int lencoded
, rencoded
;
920 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
921 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
923 if ((lencoded
!= rencoded
) ||
924 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
929 return same_names
; /* No other checks required for these type kinds. */
931 return 0; /* Should not get here since we did a resolve. */
935 /* Return the type and offset for a given member of a STRUCT or UNION. */
938 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
941 ctf_file_t
*ofp
= fp
;
942 const ctf_type_t
*tp
;
944 ssize_t size
, increment
;
947 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
948 return -1; /* errno is set for us. */
950 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
951 return -1; /* errno is set for us. */
953 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
954 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
956 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
957 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
959 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
961 if (size
< CTF_LSTRUCT_THRESH
)
963 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
966 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
968 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
970 mip
->ctm_type
= mp
->ctm_type
;
971 mip
->ctm_offset
= mp
->ctm_offset
;
978 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
981 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
983 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
985 mip
->ctm_type
= lmp
->ctlm_type
;
986 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
996 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
997 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
999 if (strcmp (dmd
->dmd_name
, name
) == 0)
1001 mip
->ctm_type
= dmd
->dmd_type
;
1002 mip
->ctm_offset
= dmd
->dmd_offset
;
1008 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1011 /* Return the array type, index, and size information for the specified ARRAY. */
1014 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1016 ctf_file_t
*ofp
= fp
;
1017 const ctf_type_t
*tp
;
1018 const ctf_array_t
*ap
;
1019 const ctf_dtdef_t
*dtd
;
1022 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1023 return -1; /* errno is set for us. */
1025 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1026 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1028 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1030 *arp
= dtd
->dtd_u
.dtu_arr
;
1034 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1036 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1037 arp
->ctr_contents
= ap
->cta_contents
;
1038 arp
->ctr_index
= ap
->cta_index
;
1039 arp
->ctr_nelems
= ap
->cta_nelems
;
1044 /* Convert the specified value to the corresponding enum tag name, if a
1045 matching name can be found. Otherwise NULL is returned. */
1048 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
1050 ctf_file_t
*ofp
= fp
;
1051 const ctf_type_t
*tp
;
1052 const ctf_enum_t
*ep
;
1053 const ctf_dtdef_t
*dtd
;
1057 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1058 return NULL
; /* errno is set for us. */
1060 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1061 return NULL
; /* errno is set for us. */
1063 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1065 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1069 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1071 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1073 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1075 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1077 if (ep
->cte_value
== value
)
1078 return (ctf_strptr (fp
, ep
->cte_name
));
1085 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1086 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1088 if (dmd
->dmd_value
== value
)
1089 return dmd
->dmd_name
;
1093 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1097 /* Convert the specified enum tag name to the corresponding value, if a
1098 matching name can be found. Otherwise CTF_ERR is returned. */
1101 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1103 ctf_file_t
*ofp
= fp
;
1104 const ctf_type_t
*tp
;
1105 const ctf_enum_t
*ep
;
1106 const ctf_dtdef_t
*dtd
;
1110 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1111 return -1; /* errno is set for us. */
1113 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1114 return -1; /* errno is set for us. */
1116 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1118 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1122 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1124 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1126 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1128 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1130 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1133 *valp
= ep
->cte_value
;
1142 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1143 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1145 if (strcmp (dmd
->dmd_name
, name
) == 0)
1148 *valp
= dmd
->dmd_value
;
1154 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1158 /* Given a type ID relating to a function type, return info on return types and
1159 arg counts for that function. */
1162 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1164 const ctf_type_t
*tp
;
1166 const uint32_t *args
;
1167 const ctf_dtdef_t
*dtd
;
1168 ssize_t size
, increment
;
1170 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1171 return -1; /* errno is set for us. */
1173 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1174 return -1; /* errno is set for us. */
1176 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1177 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1179 if (kind
!= CTF_K_FUNCTION
)
1180 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1182 fip
->ctc_return
= tp
->ctt_type
;
1184 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1186 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1187 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1189 args
= dtd
->dtd_u
.dtu_argv
;
1191 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1193 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1200 /* Given a type ID relating to a function type, return the arguments for the
1204 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1206 const ctf_type_t
*tp
;
1207 const uint32_t *args
;
1208 const ctf_dtdef_t
*dtd
;
1209 ssize_t size
, increment
;
1212 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1213 return -1; /* errno is set for us. */
1215 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1216 return -1; /* errno is set for us. */
1218 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1219 return -1; /* errno is set for us. */
1221 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1223 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1224 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1226 args
= dtd
->dtd_u
.dtu_argv
;
1228 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1234 /* Recursively visit the members of any type. This function is used as the
1235 engine for ctf_type_visit, below. We resolve the input type, recursively
1236 invoke ourself for each type member if the type is a struct or union, and
1237 then invoke the callback function on the current type. If any callback
1238 returns non-zero, we abort and percolate the error code back up to the top. */
1241 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1242 void *arg
, const char *name
, unsigned long offset
, int depth
)
1244 ctf_id_t otype
= type
;
1245 const ctf_type_t
*tp
;
1246 const ctf_dtdef_t
*dtd
;
1247 ssize_t size
, increment
;
1251 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1252 return -1; /* errno is set for us. */
1254 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1255 return -1; /* errno is set for us. */
1257 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1260 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1262 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1265 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1267 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1269 if (size
< CTF_LSTRUCT_THRESH
)
1271 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1274 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1276 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1277 func
, arg
, ctf_strptr (fp
,
1279 offset
+ mp
->ctm_offset
,
1286 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1289 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1291 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1292 func
, arg
, ctf_strptr (fp
,
1294 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1304 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1305 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1307 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1308 dmd
->dmd_name
, dmd
->dmd_offset
,
1317 /* Recursively visit the members of any type. We pass the name, member
1318 type, and offset of each member to the specified callback function. */
1320 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1322 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));