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.
476 The name will live as long as its ctf_file_t does. */
479 ctf_type_name_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 return ctf_strraw (fp
, tp
->ctt_name
);
489 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
490 new dynamically-allocated string. */
493 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
495 const char *name
= ctf_type_name_raw (fp
, type
);
498 return strdup (name
);
503 /* Resolve the type down to a base type node, and then return the size
504 of the type storage in bytes. */
507 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
509 const ctf_type_t
*tp
;
513 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
514 return -1; /* errno is set for us. */
516 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
517 return -1; /* errno is set for us. */
519 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
522 return fp
->ctf_dmodel
->ctd_pointer
;
525 return 0; /* Function size is only known by symtab. */
528 return fp
->ctf_dmodel
->ctd_int
;
531 /* ctf_add_array() does not directly encode the element size, but
532 requires the user to multiply to determine the element size.
534 If ctf_get_ctt_size() returns nonzero, then use the recorded
537 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
540 if (ctf_array_info (fp
, type
, &ar
) < 0
541 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
542 return -1; /* errno is set for us. */
544 return size
* ar
.ctr_nelems
;
546 default: /* including slices of enums, etc */
547 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
551 /* Resolve the type down to a base type node, and then return the alignment
552 needed for the type storage in bytes.
554 XXX may need arch-dependent attention. */
557 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
559 const ctf_type_t
*tp
;
560 ctf_file_t
*ofp
= fp
;
563 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
564 return -1; /* errno is set for us. */
566 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
567 return -1; /* errno is set for us. */
569 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
574 return fp
->ctf_dmodel
->ctd_pointer
;
579 if (ctf_array_info (fp
, type
, &r
) < 0)
580 return -1; /* errno is set for us. */
581 return (ctf_type_align (fp
, r
.ctr_contents
));
590 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
592 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
593 ssize_t size
, increment
;
596 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
597 vmp
= (unsigned char *) tp
+ increment
;
599 if (kind
== CTF_K_STRUCT
)
600 n
= MIN (n
, 1); /* Only use first member for structs. */
602 if (size
< CTF_LSTRUCT_THRESH
)
604 const ctf_member_t
*mp
= vmp
;
605 for (; n
!= 0; n
--, mp
++)
607 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
608 align
= MAX (align
, (size_t) am
);
613 const ctf_lmember_t
*lmp
= vmp
;
614 for (; n
!= 0; n
--, lmp
++)
616 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
617 align
= MAX (align
, (size_t) am
);
625 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
626 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
628 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
629 align
= MAX (align
, (size_t) am
);
630 if (kind
== CTF_K_STRUCT
)
639 return fp
->ctf_dmodel
->ctd_int
;
641 default: /* including slices of enums, etc */
642 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
646 /* Return the kind (CTF_K_* constant) for the specified type ID. */
649 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
651 const ctf_type_t
*tp
;
653 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
654 return -1; /* errno is set for us. */
656 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
659 /* Return the kind (CTF_K_* constant) for the specified type ID.
660 Slices are considered to be of the same kind as the type sliced. */
663 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
667 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
670 if (kind
== CTF_K_SLICE
)
672 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
674 kind
= ctf_type_kind_unsliced (fp
, type
);
680 /* Return the kind of this type, except, for forwards, return the kind of thing
681 this is a forward to. */
683 ctf_type_kind_forwarded (ctf_file_t
*fp
, ctf_id_t type
)
686 const ctf_type_t
*tp
;
688 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
689 return -1; /* errno is set for us. */
691 if (kind
!= CTF_K_FORWARD
)
694 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
695 return -1; /* errno is set for us. */
700 /* If the type is one that directly references another type (such as POINTER),
701 then return the ID of the type to which it refers. */
704 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
706 ctf_file_t
*ofp
= fp
;
707 const ctf_type_t
*tp
;
709 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
710 return CTF_ERR
; /* errno is set for us. */
712 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
720 /* Slices store their type in an unusual place. */
724 const ctf_slice_t
*sp
;
726 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
730 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
731 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
734 sp
= &dtd
->dtd_u
.dtu_slice
;
739 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
743 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
744 pointer to the given type, see if we can compute a pointer to the type
745 resulting from resolving the type down to its base type and use that
746 instead. This helps with cases where the CTF data includes "struct foo *"
747 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
749 XXX what about parent containers? */
752 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
754 ctf_file_t
*ofp
= fp
;
757 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
758 return CTF_ERR
; /* errno is set for us. */
760 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
761 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
763 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
764 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
766 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
767 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
769 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
770 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
772 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
775 /* Return the encoding for the specified INTEGER or FLOAT. */
778 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
780 ctf_file_t
*ofp
= fp
;
782 const ctf_type_t
*tp
;
786 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
787 return -1; /* errno is set for us. */
789 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
791 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
795 *ep
= dtd
->dtd_u
.dtu_enc
;
799 const ctf_slice_t
*slice
;
800 ctf_encoding_t underlying_en
;
803 slice
= &dtd
->dtd_u
.dtu_slice
;
804 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
805 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
807 ep
->cte_format
= underlying_en
.cte_format
;
808 ep
->cte_offset
= slice
->cts_offset
;
809 ep
->cte_bits
= slice
->cts_bits
;
813 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
818 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
820 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
823 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
824 ep
->cte_format
= CTF_INT_ENCODING (data
);
825 ep
->cte_offset
= CTF_INT_OFFSET (data
);
826 ep
->cte_bits
= CTF_INT_BITS (data
);
829 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
830 ep
->cte_format
= CTF_FP_ENCODING (data
);
831 ep
->cte_offset
= CTF_FP_OFFSET (data
);
832 ep
->cte_bits
= CTF_FP_BITS (data
);
836 const ctf_slice_t
*slice
;
837 ctf_encoding_t underlying_en
;
840 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
841 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
842 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
844 ep
->cte_format
= underlying_en
.cte_format
;
845 ep
->cte_offset
= slice
->cts_offset
;
846 ep
->cte_bits
= slice
->cts_bits
;
850 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
857 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
864 else if (ltype
> rtype
)
872 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
873 lfp
= lfp
->ctf_parent
;
875 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
876 rfp
= rfp
->ctf_parent
;
887 /* Return a boolean value indicating if two types are compatible. This function
888 returns true if the two types are the same, or if they (or their ultimate
889 base type) have the same encoding properties, or (for structs / unions /
890 enums / forward declarations) if they have the same name and (for structs /
891 unions) member count. */
894 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
895 ctf_file_t
*rfp
, ctf_id_t rtype
)
897 const ctf_type_t
*ltp
, *rtp
;
898 ctf_encoding_t le
, re
;
900 uint32_t lkind
, rkind
;
903 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
906 ltype
= ctf_type_resolve (lfp
, ltype
);
907 lkind
= ctf_type_kind (lfp
, ltype
);
909 rtype
= ctf_type_resolve (rfp
, rtype
);
910 rkind
= ctf_type_kind (rfp
, rtype
);
912 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
913 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
915 if (ltp
!= NULL
&& rtp
!= NULL
)
916 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
917 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
919 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
920 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
930 memset (&le
, 0, sizeof (le
));
931 memset (&re
, 0, sizeof (re
));
932 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
933 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
934 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
936 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
937 rfp
, ctf_type_reference (rfp
, rtype
)));
939 return (ctf_array_info (lfp
, ltype
, &la
) == 0
940 && ctf_array_info (rfp
, rtype
, &ra
) == 0
941 && la
.ctr_nelems
== ra
.ctr_nelems
942 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
943 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
946 return (same_names
&& (ctf_type_size (lfp
, ltype
)
947 == ctf_type_size (rfp
, rtype
)));
950 int lencoded
, rencoded
;
951 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
952 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
954 if ((lencoded
!= rencoded
) ||
955 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
960 return same_names
; /* No other checks required for these type kinds. */
962 return 0; /* Should not get here since we did a resolve. */
966 /* Return the number of members in a STRUCT or UNION, or the number of
967 enumerators in an ENUM. */
970 ctf_member_count (ctf_file_t
*fp
, ctf_id_t type
)
972 ctf_file_t
*ofp
= fp
;
973 const ctf_type_t
*tp
;
976 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
977 return -1; /* errno is set for us. */
979 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
980 return -1; /* errno is set for us. */
982 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
984 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
985 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
987 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
990 /* Return the type and offset for a given member of a STRUCT or UNION. */
993 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
996 ctf_file_t
*ofp
= fp
;
997 const ctf_type_t
*tp
;
999 ssize_t size
, increment
;
1002 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1003 return -1; /* errno is set for us. */
1005 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1006 return -1; /* errno is set for us. */
1008 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1009 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1011 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1012 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1014 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1016 if (size
< CTF_LSTRUCT_THRESH
)
1018 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1021 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1023 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
1025 mip
->ctm_type
= mp
->ctm_type
;
1026 mip
->ctm_offset
= mp
->ctm_offset
;
1033 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1036 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1038 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
1040 mip
->ctm_type
= lmp
->ctlm_type
;
1041 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1051 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1052 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1054 if (strcmp (dmd
->dmd_name
, name
) == 0)
1056 mip
->ctm_type
= dmd
->dmd_type
;
1057 mip
->ctm_offset
= dmd
->dmd_offset
;
1063 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1066 /* Return the array type, index, and size information for the specified ARRAY. */
1069 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1071 ctf_file_t
*ofp
= fp
;
1072 const ctf_type_t
*tp
;
1073 const ctf_array_t
*ap
;
1074 const ctf_dtdef_t
*dtd
;
1077 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1078 return -1; /* errno is set for us. */
1080 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1081 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1083 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1085 *arp
= dtd
->dtd_u
.dtu_arr
;
1089 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1091 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1092 arp
->ctr_contents
= ap
->cta_contents
;
1093 arp
->ctr_index
= ap
->cta_index
;
1094 arp
->ctr_nelems
= ap
->cta_nelems
;
1099 /* Convert the specified value to the corresponding enum tag name, if a
1100 matching name can be found. Otherwise NULL is returned. */
1103 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
1105 ctf_file_t
*ofp
= fp
;
1106 const ctf_type_t
*tp
;
1107 const ctf_enum_t
*ep
;
1108 const ctf_dtdef_t
*dtd
;
1112 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1113 return NULL
; /* errno is set for us. */
1115 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1116 return NULL
; /* errno is set for us. */
1118 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1120 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1124 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1126 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1128 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1130 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1132 if (ep
->cte_value
== value
)
1133 return (ctf_strptr (fp
, ep
->cte_name
));
1140 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1141 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1143 if (dmd
->dmd_value
== value
)
1144 return dmd
->dmd_name
;
1148 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1152 /* Convert the specified enum tag name to the corresponding value, if a
1153 matching name can be found. Otherwise CTF_ERR is returned. */
1156 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1158 ctf_file_t
*ofp
= fp
;
1159 const ctf_type_t
*tp
;
1160 const ctf_enum_t
*ep
;
1161 const ctf_dtdef_t
*dtd
;
1165 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1166 return -1; /* errno is set for us. */
1168 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1169 return -1; /* errno is set for us. */
1171 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1173 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1177 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1179 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1181 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1183 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1185 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1188 *valp
= ep
->cte_value
;
1197 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1198 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1200 if (strcmp (dmd
->dmd_name
, name
) == 0)
1203 *valp
= dmd
->dmd_value
;
1209 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1213 /* Given a type ID relating to a function type, return info on return types and
1214 arg counts for that function. */
1217 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1219 const ctf_type_t
*tp
;
1221 const uint32_t *args
;
1222 const ctf_dtdef_t
*dtd
;
1223 ssize_t size
, increment
;
1225 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1226 return -1; /* errno is set for us. */
1228 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1229 return -1; /* errno is set for us. */
1231 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1232 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1234 if (kind
!= CTF_K_FUNCTION
)
1235 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1237 fip
->ctc_return
= tp
->ctt_type
;
1239 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1241 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1242 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1244 args
= dtd
->dtd_u
.dtu_argv
;
1246 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1248 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1255 /* Given a type ID relating to a function type, return the arguments for the
1259 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1261 const ctf_type_t
*tp
;
1262 const uint32_t *args
;
1263 const ctf_dtdef_t
*dtd
;
1264 ssize_t size
, increment
;
1267 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1268 return -1; /* errno is set for us. */
1270 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1271 return -1; /* errno is set for us. */
1273 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1274 return -1; /* errno is set for us. */
1276 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1278 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1279 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1281 args
= dtd
->dtd_u
.dtu_argv
;
1283 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1289 /* Recursively visit the members of any type. This function is used as the
1290 engine for ctf_type_visit, below. We resolve the input type, recursively
1291 invoke ourself for each type member if the type is a struct or union, and
1292 then invoke the callback function on the current type. If any callback
1293 returns non-zero, we abort and percolate the error code back up to the top. */
1296 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1297 void *arg
, const char *name
, unsigned long offset
, int depth
)
1299 ctf_id_t otype
= type
;
1300 const ctf_type_t
*tp
;
1301 const ctf_dtdef_t
*dtd
;
1302 ssize_t size
, increment
;
1306 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1307 return -1; /* errno is set for us. */
1309 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1310 return -1; /* errno is set for us. */
1312 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1315 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1317 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1320 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1322 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1324 if (size
< CTF_LSTRUCT_THRESH
)
1326 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1329 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1331 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1332 func
, arg
, ctf_strptr (fp
,
1334 offset
+ mp
->ctm_offset
,
1341 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1344 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1346 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1347 func
, arg
, ctf_strptr (fp
,
1349 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1359 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1360 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1362 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1363 dmd
->dmd_name
, dmd
->dmd_offset
,
1372 /* Recursively visit the members of any type. We pass the name, member
1373 type, and offset of each member to the specified callback function. */
1375 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1377 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));