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/>. */
24 /* Determine whether a type is a parent or a child. */
27 ctf_type_isparent (ctf_dict_t
*fp
, ctf_id_t id
)
29 return (LCTF_TYPE_ISPARENT (fp
, id
));
33 ctf_type_ischild (ctf_dict_t
* fp
, ctf_id_t id
)
35 return (LCTF_TYPE_ISCHILD (fp
, id
));
38 /* Iterate over the members of a STRUCT or UNION. We pass the name, member
39 type, and offset of each member to the specified callback function. */
42 ctf_member_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_member_f
*func
, void *arg
)
47 ssize_t size
, increment
;
51 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
52 return -1; /* errno is set for us. */
54 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
55 return -1; /* errno is set for us. */
57 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
58 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
60 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
61 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
63 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
65 if (size
< CTF_LSTRUCT_THRESH
)
67 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
70 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
72 const char *name
= ctf_strptr (fp
, mp
->ctm_name
);
73 if ((rc
= func (name
, mp
->ctm_type
, mp
->ctm_offset
, arg
)) != 0)
79 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
82 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
84 const char *name
= ctf_strptr (fp
, lmp
->ctlm_name
);
85 if ((rc
= func (name
, lmp
->ctlm_type
,
86 (unsigned long) CTF_LMEM_OFFSET (lmp
), arg
)) != 0)
95 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
96 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
98 if ((rc
= func (dmd
->dmd_name
, dmd
->dmd_type
,
99 dmd
->dmd_offset
, arg
)) != 0)
107 /* Iterate over the members of a STRUCT or UNION, returning each member's
108 offset and optionally name and member type in turn. On end-of-iteration,
112 ctf_member_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
113 const char **name
, ctf_id_t
*membtype
)
115 ctf_dict_t
*ofp
= fp
;
122 const ctf_type_t
*tp
;
125 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
126 return -1; /* errno is set for us. */
128 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
129 return -1; /* errno is set for us. */
131 if ((i
= ctf_next_create ()) == NULL
)
132 return ctf_set_errno (ofp
, ENOMEM
);
135 (void) ctf_get_ctt_size (fp
, tp
, &i
->ctn_size
,
137 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
139 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
141 ctf_next_destroy (i
);
142 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
145 dtd
= ctf_dynamic_type (fp
, type
);
146 i
->ctn_iter_fun
= (void (*) (void)) ctf_member_next
;
148 /* We depend below on the RDWR state indicating whether the DTD-related
149 fields or the DMD-related fields have been initialized. */
151 assert ((dtd
&& (fp
->ctf_flags
& LCTF_RDWR
))
152 || (!dtd
&& (!(fp
->ctf_flags
& LCTF_RDWR
))));
156 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
158 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
159 i
->u
.ctn_mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
162 i
->u
.ctn_lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
166 i
->u
.ctn_dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
171 if ((void (*) (void)) ctf_member_next
!= i
->ctn_iter_fun
)
172 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
));
174 if (ofp
!= i
->cu
.ctn_fp
)
175 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
));
177 /* Resolve to the native dict of this type. */
178 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
179 return (ctf_set_errno (ofp
, ECTF_NOPARENT
));
181 if (!(fp
->ctf_flags
& LCTF_RDWR
))
186 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
189 *name
= ctf_strptr (fp
, i
->u
.ctn_mp
->ctm_name
);
191 *membtype
= i
->u
.ctn_mp
->ctm_type
;
192 offset
= i
->u
.ctn_mp
->ctm_offset
;
198 *name
= ctf_strptr (fp
, i
->u
.ctn_lmp
->ctlm_name
);
200 *membtype
= i
->u
.ctn_lmp
->ctlm_type
;
201 offset
= (unsigned long) CTF_LMEM_OFFSET (i
->u
.ctn_lmp
);
208 if (i
->u
.ctn_dmd
== NULL
)
211 *name
= i
->u
.ctn_dmd
->dmd_name
;
213 *membtype
= i
->u
.ctn_dmd
->dmd_type
;
214 offset
= i
->u
.ctn_dmd
->dmd_offset
;
215 i
->u
.ctn_dmd
= ctf_list_next (i
->u
.ctn_dmd
);
221 ctf_next_destroy (i
);
223 return ctf_set_errno (ofp
, ECTF_NEXT_END
);
226 /* Iterate over the members of an ENUM. We pass the string name and associated
227 integer value of each enum element to the specified callback function. */
230 ctf_enum_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
232 ctf_dict_t
*ofp
= fp
;
233 const ctf_type_t
*tp
;
234 const ctf_enum_t
*ep
;
240 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
241 return -1; /* errno is set for us. */
243 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
244 return -1; /* errno is set for us. */
246 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
247 return (ctf_set_errno (ofp
, ECTF_NOTENUM
));
249 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
251 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
253 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
255 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
257 const char *name
= ctf_strptr (fp
, ep
->cte_name
);
258 if ((rc
= func (name
, ep
->cte_value
, arg
)) != 0)
266 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
267 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
269 if ((rc
= func (dmd
->dmd_name
, dmd
->dmd_value
, arg
)) != 0)
277 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
278 NULL at end of iteration or error, and optionally passing back the
279 enumerand's integer VALue. */
282 ctf_enum_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
285 ctf_dict_t
*ofp
= fp
;
292 const ctf_type_t
*tp
;
295 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
296 return NULL
; /* errno is set for us. */
298 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
299 return NULL
; /* errno is set for us. */
301 if ((i
= ctf_next_create ()) == NULL
)
303 ctf_set_errno (ofp
, ENOMEM
);
308 (void) ctf_get_ctt_size (fp
, tp
, NULL
,
310 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
312 if (kind
!= CTF_K_ENUM
)
314 ctf_next_destroy (i
);
315 ctf_set_errno (ofp
, ECTF_NOTENUM
);
319 dtd
= ctf_dynamic_type (fp
, type
);
320 i
->ctn_iter_fun
= (void (*) (void)) ctf_enum_next
;
322 /* We depend below on the RDWR state indicating whether the DTD-related
323 fields or the DMD-related fields have been initialized. */
325 assert ((dtd
&& (fp
->ctf_flags
& LCTF_RDWR
))
326 || (!dtd
&& (!(fp
->ctf_flags
& LCTF_RDWR
))));
330 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
332 i
->u
.ctn_en
= (const ctf_enum_t
*) ((uintptr_t) tp
+
336 i
->u
.ctn_dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
341 if ((void (*) (void)) ctf_enum_next
!= i
->ctn_iter_fun
)
343 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
);
347 if (ofp
!= i
->cu
.ctn_fp
)
349 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
);
353 /* Resolve to the native dict of this type. */
354 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
356 ctf_set_errno (ofp
, ECTF_NOPARENT
);
360 if (!(fp
->ctf_flags
& LCTF_RDWR
))
365 name
= ctf_strptr (fp
, i
->u
.ctn_en
->cte_name
);
367 *val
= i
->u
.ctn_en
->cte_value
;
373 if (i
->u
.ctn_dmd
== NULL
)
376 name
= i
->u
.ctn_dmd
->dmd_name
;
378 *val
= i
->u
.ctn_dmd
->dmd_value
;
379 i
->u
.ctn_dmd
= ctf_list_next (i
->u
.ctn_dmd
);
385 ctf_next_destroy (i
);
387 ctf_set_errno (ofp
, ECTF_NEXT_END
);
391 /* Iterate over every root (user-visible) type in the given CTF dict.
392 We pass the type ID of each type to the specified callback function.
394 Does not traverse parent types: you have to do that explicitly. This is by
395 design, to avoid traversing them more than once if traversing many children
396 of a single parent. */
399 ctf_type_iter (ctf_dict_t
*fp
, ctf_type_f
*func
, void *arg
)
401 ctf_id_t id
, max
= fp
->ctf_typemax
;
402 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
404 for (id
= 1; id
<= max
; id
++)
406 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
407 if (LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)
408 && (rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
), arg
)) != 0)
415 /* Iterate over every type in the given CTF dict, user-visible or not.
416 We pass the type ID of each type to the specified callback function.
418 Does not traverse parent types: you have to do that explicitly. This is by
419 design, to avoid traversing them more than once if traversing many children
420 of a single parent. */
423 ctf_type_iter_all (ctf_dict_t
*fp
, ctf_type_all_f
*func
, void *arg
)
425 ctf_id_t id
, max
= fp
->ctf_typemax
;
426 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
428 for (id
= 1; id
<= max
; id
++)
430 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
431 if ((rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
),
432 LCTF_INFO_ISROOT(fp
, tp
->ctt_info
)
433 ? CTF_ADD_ROOT
: CTF_ADD_NONROOT
, arg
) != 0))
440 /* Iterate over every type in the given CTF dict, optionally including
441 non-user-visible types, returning each type ID and hidden flag in turn.
442 Returns CTF_ERR on end of iteration or error.
444 Does not traverse parent types: you have to do that explicitly. This is by
445 design, to avoid traversing them more than once if traversing many children
446 of a single parent. */
449 ctf_type_next (ctf_dict_t
*fp
, ctf_next_t
**it
, int *flag
, int want_hidden
)
455 if ((i
= ctf_next_create ()) == NULL
)
456 return ctf_set_errno (fp
, ENOMEM
);
460 i
->ctn_iter_fun
= (void (*) (void)) ctf_type_next
;
464 if ((void (*) (void)) ctf_type_next
!= i
->ctn_iter_fun
)
465 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
467 if (fp
!= i
->cu
.ctn_fp
)
468 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
470 while (i
->ctn_type
<= fp
->ctf_typemax
)
472 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, i
->ctn_type
);
474 if ((!want_hidden
) && (!LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)))
481 *flag
= LCTF_INFO_ISROOT (fp
, tp
->ctt_info
);
482 return LCTF_INDEX_TO_TYPE (fp
, i
->ctn_type
++, fp
->ctf_flags
& LCTF_CHILD
);
484 ctf_next_destroy (i
);
486 return ctf_set_errno (fp
, ECTF_NEXT_END
);
489 /* Iterate over every variable in the given CTF dict, in arbitrary order.
490 We pass the name of each variable to the specified callback function. */
493 ctf_variable_iter (ctf_dict_t
*fp
, ctf_variable_f
*func
, void *arg
)
497 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
498 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
500 if (!(fp
->ctf_flags
& LCTF_RDWR
))
503 for (i
= 0; i
< fp
->ctf_nvars
; i
++)
504 if ((rc
= func (ctf_strptr (fp
, fp
->ctf_vars
[i
].ctv_name
),
505 fp
->ctf_vars
[i
].ctv_type
, arg
)) != 0)
512 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
;
513 dvd
= ctf_list_next (dvd
))
515 if ((rc
= func (dvd
->dvd_name
, dvd
->dvd_type
, arg
)) != 0)
523 /* Iterate over every variable in the given CTF dict, in arbitrary order,
524 returning the name and type of each variable in turn. The name argument is
525 not optional. Returns CTF_ERR on end of iteration or error. */
528 ctf_variable_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
)
532 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
533 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
537 if ((i
= ctf_next_create ()) == NULL
)
538 return ctf_set_errno (fp
, ENOMEM
);
541 i
->ctn_iter_fun
= (void (*) (void)) ctf_variable_next
;
542 if (fp
->ctf_flags
& LCTF_RDWR
)
543 i
->u
.ctn_dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
547 if ((void (*) (void)) ctf_variable_next
!= i
->ctn_iter_fun
)
548 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
550 if (fp
!= i
->cu
.ctn_fp
)
551 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
553 if (!(fp
->ctf_flags
& LCTF_RDWR
))
555 if (i
->ctn_n
>= fp
->ctf_nvars
)
558 *name
= ctf_strptr (fp
, fp
->ctf_vars
[i
->ctn_n
].ctv_name
);
559 return fp
->ctf_vars
[i
->ctn_n
++].ctv_type
;
565 if (i
->u
.ctn_dvd
== NULL
)
568 *name
= i
->u
.ctn_dvd
->dvd_name
;
569 id
= i
->u
.ctn_dvd
->dvd_type
;
570 i
->u
.ctn_dvd
= ctf_list_next (i
->u
.ctn_dvd
);
575 ctf_next_destroy (i
);
577 return ctf_set_errno (fp
, ECTF_NEXT_END
);
580 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
581 RESTRICT nodes until we reach a "base" type node. This is useful when
582 we want to follow a type ID to a node that has members or a size. To guard
583 against infinite loops, we implement simplified cycle detection and check
584 each link against itself, the previous node, and the topmost node.
586 Does not drill down through slices to their contained type. */
589 ctf_type_resolve (ctf_dict_t
*fp
, ctf_id_t type
)
591 ctf_id_t prev
= type
, otype
= type
;
592 ctf_dict_t
*ofp
= fp
;
593 const ctf_type_t
*tp
;
596 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
598 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
600 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
606 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
607 || tp
->ctt_type
== prev
)
609 ctf_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
611 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
620 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
623 return CTF_ERR
; /* errno is set for us. */
626 /* Like ctf_type_resolve(), but traverse down through slices to their contained
630 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
632 const ctf_type_t
*tp
;
634 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
637 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
638 return CTF_ERR
; /* errno is set for us. */
640 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
641 return ctf_type_reference (fp
, type
);
645 /* Return the native dict of a given type: if called on a child and the
646 type is in the parent, return the parent. Needed if you plan to access
647 the type directly, without using the API. */
649 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
651 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
652 return fp
->ctf_parent
;
657 /* Look up a name in the given name table, in the appropriate hash given the
658 kind of the identifier. The name is a raw, undecorated identifier. */
660 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
662 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
665 /* Look up a name in the given name table, in the appropriate hash given the
666 readability state of the dictionary. The name is a raw, undecorated
669 ctf_id_t
ctf_lookup_by_rawhash (ctf_dict_t
*fp
, ctf_names_t
*np
, const char *name
)
673 if (fp
->ctf_flags
& LCTF_RDWR
)
674 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
676 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
680 /* Lookup the given type ID and return its name as a new dynamically-allocated
684 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
687 ctf_decl_node_t
*cdp
;
688 ctf_decl_prec_t prec
, lp
, rp
;
693 if (fp
== NULL
&& type
== CTF_ERR
)
694 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
697 ctf_decl_push (&cd
, fp
, type
);
702 ctf_set_errno (fp
, cd
.cd_err
);
706 /* If the type graph's order conflicts with lexical precedence order
707 for pointers or arrays, then we need to surround the declarations at
708 the corresponding lexical precedence with parentheses. This can
709 result in either a parenthesized pointer (*) as in int (*)() or
710 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
712 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
713 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
715 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
716 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
718 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
720 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
722 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
723 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
725 ctf_dict_t
*rfp
= fp
;
726 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
727 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
729 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
730 ctf_decl_sprintf (&cd
, " ");
734 ctf_decl_sprintf (&cd
, "(");
738 switch (cdp
->cd_kind
)
743 /* Integers, floats, and typedefs must always be named types. */
747 ctf_set_errno (fp
, ECTF_CORRUPT
);
752 ctf_decl_sprintf (&cd
, "%s", name
);
755 ctf_decl_sprintf (&cd
, "*");
758 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
764 ctf_id_t
*argv
= NULL
;
766 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
767 goto err
; /* errno is set for us. */
769 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
771 ctf_set_errno (rfp
, errno
);
775 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
776 fi
.ctc_argc
, argv
) < 0)
777 goto err
; /* errno is set for us. */
779 ctf_decl_sprintf (&cd
, "(*) (");
780 for (i
= 0; i
< fi
.ctc_argc
; i
++)
782 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
785 goto err
; /* errno is set for us. */
786 ctf_decl_sprintf (&cd
, "%s", arg
);
789 if ((i
< fi
.ctc_argc
- 1)
790 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
791 ctf_decl_sprintf (&cd
, ", ");
794 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
795 ctf_decl_sprintf (&cd
, "...");
796 ctf_decl_sprintf (&cd
, ")");
809 ctf_decl_sprintf (&cd
, "struct %s", name
);
812 ctf_decl_sprintf (&cd
, "union %s", name
);
815 ctf_decl_sprintf (&cd
, "enum %s", name
);
818 ctf_decl_sprintf (&cd
, "volatile");
821 ctf_decl_sprintf (&cd
, "const");
824 ctf_decl_sprintf (&cd
, "restrict");
827 /* No representation: just changes encoding of contained type,
828 which is not in any case printed. Skip it. */
836 ctf_decl_sprintf (&cd
, ")");
840 (void) ctf_set_errno (fp
, ENOMEM
);
842 buf
= ctf_decl_buf (&cd
);
848 /* Lookup the given type ID and print a string name for it into buf. Return
849 the actual number of bytes (not including \0) needed to format the name. */
852 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
854 char *str
= ctf_type_aname (fp
, type
);
858 return CTF_ERR
; /* errno is set for us. */
861 snprintf (buf
, len
, "%s", str
);
865 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
870 /* Lookup the given type ID and print a string name for it into buf. If buf
871 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
874 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
876 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
877 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
880 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
881 The name will live as long as its ctf_dict_t does. */
884 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
886 const ctf_type_t
*tp
;
888 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
889 return NULL
; /* errno is set for us. */
891 return ctf_strraw (fp
, tp
->ctt_name
);
894 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
895 new dynamically-allocated string. */
898 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
900 const char *name
= ctf_type_name_raw (fp
, type
);
903 return strdup (name
);
908 /* Resolve the type down to a base type node, and then return the size
909 of the type storage in bytes. */
912 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
914 const ctf_type_t
*tp
;
918 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
919 return -1; /* errno is set for us. */
921 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
922 return -1; /* errno is set for us. */
924 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
927 return fp
->ctf_dmodel
->ctd_pointer
;
930 return 0; /* Function size is only known by symtab. */
933 return fp
->ctf_dmodel
->ctd_int
;
936 /* ctf_add_array() does not directly encode the element size, but
937 requires the user to multiply to determine the element size.
939 If ctf_get_ctt_size() returns nonzero, then use the recorded
942 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
945 if (ctf_array_info (fp
, type
, &ar
) < 0
946 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
947 return -1; /* errno is set for us. */
949 return size
* ar
.ctr_nelems
;
951 default: /* including slices of enums, etc */
952 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
956 /* Resolve the type down to a base type node, and then return the alignment
957 needed for the type storage in bytes.
959 XXX may need arch-dependent attention. */
962 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
964 const ctf_type_t
*tp
;
965 ctf_dict_t
*ofp
= fp
;
968 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
969 return -1; /* errno is set for us. */
971 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
972 return -1; /* errno is set for us. */
974 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
979 return fp
->ctf_dmodel
->ctd_pointer
;
984 if (ctf_array_info (fp
, type
, &r
) < 0)
985 return -1; /* errno is set for us. */
986 return (ctf_type_align (fp
, r
.ctr_contents
));
995 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
997 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
998 ssize_t size
, increment
;
1001 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1002 vmp
= (unsigned char *) tp
+ increment
;
1004 if (kind
== CTF_K_STRUCT
)
1005 n
= MIN (n
, 1); /* Only use first member for structs. */
1007 if (size
< CTF_LSTRUCT_THRESH
)
1009 const ctf_member_t
*mp
= vmp
;
1010 for (; n
!= 0; n
--, mp
++)
1012 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
1013 align
= MAX (align
, (size_t) am
);
1018 const ctf_lmember_t
*lmp
= vmp
;
1019 for (; n
!= 0; n
--, lmp
++)
1021 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
1022 align
= MAX (align
, (size_t) am
);
1030 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1031 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1033 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
1034 align
= MAX (align
, (size_t) am
);
1035 if (kind
== CTF_K_STRUCT
)
1044 return fp
->ctf_dmodel
->ctd_int
;
1046 default: /* including slices of enums, etc */
1047 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1051 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1054 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1056 const ctf_type_t
*tp
;
1058 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1059 return -1; /* errno is set for us. */
1061 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1064 /* Return the kind (CTF_K_* constant) for the specified type ID.
1065 Slices are considered to be of the same kind as the type sliced. */
1068 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1072 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1075 if (kind
== CTF_K_SLICE
)
1077 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1079 kind
= ctf_type_kind_unsliced (fp
, type
);
1085 /* Return the kind of this type, except, for forwards, return the kind of thing
1086 this is a forward to. */
1088 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1091 const ctf_type_t
*tp
;
1093 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1094 return -1; /* errno is set for us. */
1096 if (kind
!= CTF_K_FORWARD
)
1099 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1100 return -1; /* errno is set for us. */
1102 return tp
->ctt_type
;
1105 /* If the type is one that directly references another type (such as POINTER),
1106 then return the ID of the type to which it refers. */
1109 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1111 ctf_dict_t
*ofp
= fp
;
1112 const ctf_type_t
*tp
;
1114 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1115 return CTF_ERR
; /* errno is set for us. */
1117 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1121 case CTF_K_VOLATILE
:
1123 case CTF_K_RESTRICT
:
1124 return tp
->ctt_type
;
1125 /* Slices store their type in an unusual place. */
1129 const ctf_slice_t
*sp
;
1131 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1135 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1136 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1139 sp
= &dtd
->dtd_u
.dtu_slice
;
1141 return sp
->cts_type
;
1144 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1148 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1149 pointer to the given type, see if we can compute a pointer to the type
1150 resulting from resolving the type down to its base type and use that
1151 instead. This helps with cases where the CTF data includes "struct foo *"
1152 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1154 XXX what about parent dicts? */
1157 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1159 ctf_dict_t
*ofp
= fp
;
1162 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1163 return CTF_ERR
; /* errno is set for us. */
1165 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1166 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1168 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1169 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1171 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1172 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1174 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1175 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1177 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1180 /* Return the encoding for the specified INTEGER or FLOAT. */
1183 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1185 ctf_dict_t
*ofp
= fp
;
1187 const ctf_type_t
*tp
;
1191 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1192 return -1; /* errno is set for us. */
1194 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1196 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1200 *ep
= dtd
->dtd_u
.dtu_enc
;
1204 const ctf_slice_t
*slice
;
1205 ctf_encoding_t underlying_en
;
1206 ctf_id_t underlying
;
1208 slice
= &dtd
->dtd_u
.dtu_slice
;
1209 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1210 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1212 ep
->cte_format
= underlying_en
.cte_format
;
1213 ep
->cte_offset
= slice
->cts_offset
;
1214 ep
->cte_bits
= slice
->cts_bits
;
1218 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1223 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1225 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1228 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1229 ep
->cte_format
= CTF_INT_ENCODING (data
);
1230 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1231 ep
->cte_bits
= CTF_INT_BITS (data
);
1234 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1235 ep
->cte_format
= CTF_FP_ENCODING (data
);
1236 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1237 ep
->cte_bits
= CTF_FP_BITS (data
);
1241 const ctf_slice_t
*slice
;
1242 ctf_encoding_t underlying_en
;
1243 ctf_id_t underlying
;
1245 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1246 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1247 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1249 ep
->cte_format
= underlying_en
.cte_format
;
1250 ep
->cte_offset
= slice
->cts_offset
;
1251 ep
->cte_bits
= slice
->cts_bits
;
1255 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1262 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1269 else if (ltype
> rtype
)
1277 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1278 lfp
= lfp
->ctf_parent
;
1280 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1281 rfp
= rfp
->ctf_parent
;
1292 /* Return a boolean value indicating if two types are compatible. This function
1293 returns true if the two types are the same, or if they (or their ultimate
1294 base type) have the same encoding properties, or (for structs / unions /
1295 enums / forward declarations) if they have the same name and (for structs /
1296 unions) member count. */
1299 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1300 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1302 const ctf_type_t
*ltp
, *rtp
;
1303 ctf_encoding_t le
, re
;
1304 ctf_arinfo_t la
, ra
;
1305 uint32_t lkind
, rkind
;
1308 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1311 ltype
= ctf_type_resolve (lfp
, ltype
);
1312 lkind
= ctf_type_kind (lfp
, ltype
);
1314 rtype
= ctf_type_resolve (rfp
, rtype
);
1315 rkind
= ctf_type_kind (rfp
, rtype
);
1317 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1318 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1320 if (ltp
!= NULL
&& rtp
!= NULL
)
1321 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1322 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1324 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1325 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1335 memset (&le
, 0, sizeof (le
));
1336 memset (&re
, 0, sizeof (re
));
1337 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1338 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1339 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1341 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1342 rfp
, ctf_type_reference (rfp
, rtype
)));
1344 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1345 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1346 && la
.ctr_nelems
== ra
.ctr_nelems
1347 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1348 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1351 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1352 == ctf_type_size (rfp
, rtype
)));
1355 int lencoded
, rencoded
;
1356 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1357 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1359 if ((lencoded
!= rencoded
) ||
1360 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1365 return same_names
; /* No other checks required for these type kinds. */
1367 return 0; /* Should not get here since we did a resolve. */
1371 /* Return the number of members in a STRUCT or UNION, or the number of
1372 enumerators in an ENUM. */
1375 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1377 ctf_dict_t
*ofp
= fp
;
1378 const ctf_type_t
*tp
;
1381 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1382 return -1; /* errno is set for us. */
1384 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1385 return -1; /* errno is set for us. */
1387 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1389 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1390 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1392 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1395 /* Return the type and offset for a given member of a STRUCT or UNION. */
1398 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1399 ctf_membinfo_t
*mip
)
1401 ctf_dict_t
*ofp
= fp
;
1402 const ctf_type_t
*tp
;
1404 ssize_t size
, increment
;
1407 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1408 return -1; /* errno is set for us. */
1410 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1411 return -1; /* errno is set for us. */
1413 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1414 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1416 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1417 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1419 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1421 if (size
< CTF_LSTRUCT_THRESH
)
1423 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1426 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1428 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
1430 mip
->ctm_type
= mp
->ctm_type
;
1431 mip
->ctm_offset
= mp
->ctm_offset
;
1438 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1441 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1443 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
1445 mip
->ctm_type
= lmp
->ctlm_type
;
1446 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1456 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1457 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1459 if (strcmp (dmd
->dmd_name
, name
) == 0)
1461 mip
->ctm_type
= dmd
->dmd_type
;
1462 mip
->ctm_offset
= dmd
->dmd_offset
;
1468 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1471 /* Return the array type, index, and size information for the specified ARRAY. */
1474 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1476 ctf_dict_t
*ofp
= fp
;
1477 const ctf_type_t
*tp
;
1478 const ctf_array_t
*ap
;
1479 const ctf_dtdef_t
*dtd
;
1482 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1483 return -1; /* errno is set for us. */
1485 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1486 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1488 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1490 *arp
= dtd
->dtd_u
.dtu_arr
;
1494 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1496 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1497 arp
->ctr_contents
= ap
->cta_contents
;
1498 arp
->ctr_index
= ap
->cta_index
;
1499 arp
->ctr_nelems
= ap
->cta_nelems
;
1504 /* Convert the specified value to the corresponding enum tag name, if a
1505 matching name can be found. Otherwise NULL is returned. */
1508 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1510 ctf_dict_t
*ofp
= fp
;
1511 const ctf_type_t
*tp
;
1512 const ctf_enum_t
*ep
;
1513 const ctf_dtdef_t
*dtd
;
1517 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1518 return NULL
; /* errno is set for us. */
1520 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1521 return NULL
; /* errno is set for us. */
1523 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1525 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1529 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1531 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1533 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1535 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1537 if (ep
->cte_value
== value
)
1538 return (ctf_strptr (fp
, ep
->cte_name
));
1545 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1546 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1548 if (dmd
->dmd_value
== value
)
1549 return dmd
->dmd_name
;
1553 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1557 /* Convert the specified enum tag name to the corresponding value, if a
1558 matching name can be found. Otherwise CTF_ERR is returned. */
1561 ctf_enum_value (ctf_dict_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1563 ctf_dict_t
*ofp
= fp
;
1564 const ctf_type_t
*tp
;
1565 const ctf_enum_t
*ep
;
1566 const ctf_dtdef_t
*dtd
;
1570 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1571 return -1; /* errno is set for us. */
1573 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1574 return -1; /* errno is set for us. */
1576 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1578 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1582 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1584 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1586 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1588 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1590 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1593 *valp
= ep
->cte_value
;
1602 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1603 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1605 if (strcmp (dmd
->dmd_name
, name
) == 0)
1608 *valp
= dmd
->dmd_value
;
1614 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1618 /* Given a type ID relating to a function type, return info on return types and
1619 arg counts for that function. */
1622 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1624 const ctf_type_t
*tp
;
1626 const uint32_t *args
;
1627 const ctf_dtdef_t
*dtd
;
1628 ssize_t size
, increment
;
1630 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1631 return -1; /* errno is set for us. */
1633 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1634 return -1; /* errno is set for us. */
1636 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1637 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1639 if (kind
!= CTF_K_FUNCTION
)
1640 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1642 fip
->ctc_return
= tp
->ctt_type
;
1644 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1646 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1647 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1649 args
= dtd
->dtd_u
.dtu_argv
;
1651 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1653 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1660 /* Given a type ID relating to a function type, return the arguments for the
1664 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1666 const ctf_type_t
*tp
;
1667 const uint32_t *args
;
1668 const ctf_dtdef_t
*dtd
;
1669 ssize_t size
, increment
;
1672 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1673 return -1; /* errno is set for us. */
1675 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1676 return -1; /* errno is set for us. */
1678 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1679 return -1; /* errno is set for us. */
1681 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1683 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1684 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1686 args
= dtd
->dtd_u
.dtu_argv
;
1688 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1694 /* Recursively visit the members of any type. This function is used as the
1695 engine for ctf_type_visit, below. We resolve the input type, recursively
1696 invoke ourself for each type member if the type is a struct or union, and
1697 then invoke the callback function on the current type. If any callback
1698 returns non-zero, we abort and percolate the error code back up to the top. */
1701 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1702 void *arg
, const char *name
, unsigned long offset
, int depth
)
1704 ctf_id_t otype
= type
;
1705 const ctf_type_t
*tp
;
1706 const ctf_dtdef_t
*dtd
;
1707 ssize_t size
, increment
;
1711 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1712 return -1; /* errno is set for us. */
1714 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1715 return -1; /* errno is set for us. */
1717 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1720 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1722 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1725 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1727 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1729 if (size
< CTF_LSTRUCT_THRESH
)
1731 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1734 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1736 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1737 func
, arg
, ctf_strptr (fp
,
1739 offset
+ mp
->ctm_offset
,
1746 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1749 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1751 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1752 func
, arg
, ctf_strptr (fp
,
1754 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1764 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1765 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1767 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1768 dmd
->dmd_name
, dmd
->dmd_offset
,
1777 /* Recursively visit the members of any type. We pass the name, member
1778 type, and offset of each member to the specified callback function. */
1780 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1782 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));