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_file_t
*fp
, ctf_id_t id
)
29 return (LCTF_TYPE_ISPARENT (fp
, id
));
33 ctf_type_ischild (ctf_file_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_file_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_file_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
113 const char **name
, ctf_id_t
*membtype
)
115 ctf_file_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_file_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
232 ctf_file_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_file_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
285 ctf_file_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 container.
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_file_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 container, 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_file_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 container, 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_file_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 container, in arbitrary order.
490 We pass the name of each variable to the specified callback function. */
493 ctf_variable_iter (ctf_file_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 container, 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_file_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_file_t
*fp
, ctf_id_t type
)
591 ctf_id_t prev
= type
, otype
= type
;
592 ctf_file_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_dprintf ("type %ld cycle detected\n", otype
);
610 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
619 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
622 return CTF_ERR
; /* errno is set for us. */
625 /* Like ctf_type_resolve(), but traverse down through slices to their contained
629 ctf_type_resolve_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
631 const ctf_type_t
*tp
;
633 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
636 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
637 return CTF_ERR
; /* errno is set for us. */
639 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
640 return ctf_type_reference (fp
, type
);
644 /* Look up a name in the given name table, in the appropriate hash given the
645 kind of the identifier. The name is a raw, undecorated identifier. */
647 ctf_id_t
ctf_lookup_by_rawname (ctf_file_t
*fp
, int kind
, const char *name
)
649 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
652 /* Look up a name in the given name table, in the appropriate hash given the
653 readability state of the dictionary. The name is a raw, undecorated
656 ctf_id_t
ctf_lookup_by_rawhash (ctf_file_t
*fp
, ctf_names_t
*np
, const char *name
)
660 if (fp
->ctf_flags
& LCTF_RDWR
)
661 id
= (ctf_id_t
) ctf_dynhash_lookup (np
->ctn_writable
, name
);
663 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
667 /* Lookup the given type ID and return its name as a new dynamically-allocated
671 ctf_type_aname (ctf_file_t
*fp
, ctf_id_t type
)
674 ctf_decl_node_t
*cdp
;
675 ctf_decl_prec_t prec
, lp
, rp
;
680 if (fp
== NULL
&& type
== CTF_ERR
)
681 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
684 ctf_decl_push (&cd
, fp
, type
);
689 ctf_set_errno (fp
, cd
.cd_err
);
693 /* If the type graph's order conflicts with lexical precedence order
694 for pointers or arrays, then we need to surround the declarations at
695 the corresponding lexical precedence with parentheses. This can
696 result in either a parenthesized pointer (*) as in int (*)() or
697 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
699 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
700 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
702 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
703 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
705 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
707 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
709 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
710 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
712 ctf_file_t
*rfp
= fp
;
713 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
714 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
716 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
717 ctf_decl_sprintf (&cd
, " ");
721 ctf_decl_sprintf (&cd
, "(");
725 switch (cdp
->cd_kind
)
730 /* Integers, floats, and typedefs must always be named types. */
734 ctf_set_errno (fp
, ECTF_CORRUPT
);
739 ctf_decl_sprintf (&cd
, "%s", name
);
742 ctf_decl_sprintf (&cd
, "*");
745 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
748 ctf_decl_sprintf (&cd
, "()");
752 ctf_decl_sprintf (&cd
, "struct %s", name
);
755 ctf_decl_sprintf (&cd
, "union %s", name
);
758 ctf_decl_sprintf (&cd
, "enum %s", name
);
761 ctf_decl_sprintf (&cd
, "volatile");
764 ctf_decl_sprintf (&cd
, "const");
767 ctf_decl_sprintf (&cd
, "restrict");
770 /* No representation: just changes encoding of contained type,
771 which is not in any case printed. Skip it. */
779 ctf_decl_sprintf (&cd
, ")");
783 (void) ctf_set_errno (fp
, ENOMEM
);
785 buf
= ctf_decl_buf (&cd
);
791 /* Lookup the given type ID and print a string name for it into buf. Return
792 the actual number of bytes (not including \0) needed to format the name. */
795 ctf_type_lname (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
797 char *str
= ctf_type_aname (fp
, type
);
801 return CTF_ERR
; /* errno is set for us. */
804 snprintf (buf
, len
, "%s", str
);
808 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
813 /* Lookup the given type ID and print a string name for it into buf. If buf
814 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
817 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
819 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
820 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
823 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
824 The name will live as long as its ctf_file_t does. */
827 ctf_type_name_raw (ctf_file_t
*fp
, ctf_id_t type
)
829 const ctf_type_t
*tp
;
831 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
832 return NULL
; /* errno is set for us. */
834 return ctf_strraw (fp
, tp
->ctt_name
);
837 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
838 new dynamically-allocated string. */
841 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
843 const char *name
= ctf_type_name_raw (fp
, type
);
846 return strdup (name
);
851 /* Resolve the type down to a base type node, and then return the size
852 of the type storage in bytes. */
855 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
857 const ctf_type_t
*tp
;
861 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
862 return -1; /* errno is set for us. */
864 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
865 return -1; /* errno is set for us. */
867 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
870 return fp
->ctf_dmodel
->ctd_pointer
;
873 return 0; /* Function size is only known by symtab. */
876 return fp
->ctf_dmodel
->ctd_int
;
879 /* ctf_add_array() does not directly encode the element size, but
880 requires the user to multiply to determine the element size.
882 If ctf_get_ctt_size() returns nonzero, then use the recorded
885 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
888 if (ctf_array_info (fp
, type
, &ar
) < 0
889 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
890 return -1; /* errno is set for us. */
892 return size
* ar
.ctr_nelems
;
894 default: /* including slices of enums, etc */
895 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
899 /* Resolve the type down to a base type node, and then return the alignment
900 needed for the type storage in bytes.
902 XXX may need arch-dependent attention. */
905 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
907 const ctf_type_t
*tp
;
908 ctf_file_t
*ofp
= fp
;
911 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
912 return -1; /* errno is set for us. */
914 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
915 return -1; /* errno is set for us. */
917 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
922 return fp
->ctf_dmodel
->ctd_pointer
;
927 if (ctf_array_info (fp
, type
, &r
) < 0)
928 return -1; /* errno is set for us. */
929 return (ctf_type_align (fp
, r
.ctr_contents
));
938 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
940 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
941 ssize_t size
, increment
;
944 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
945 vmp
= (unsigned char *) tp
+ increment
;
947 if (kind
== CTF_K_STRUCT
)
948 n
= MIN (n
, 1); /* Only use first member for structs. */
950 if (size
< CTF_LSTRUCT_THRESH
)
952 const ctf_member_t
*mp
= vmp
;
953 for (; n
!= 0; n
--, mp
++)
955 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
956 align
= MAX (align
, (size_t) am
);
961 const ctf_lmember_t
*lmp
= vmp
;
962 for (; n
!= 0; n
--, lmp
++)
964 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
965 align
= MAX (align
, (size_t) am
);
973 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
974 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
976 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
977 align
= MAX (align
, (size_t) am
);
978 if (kind
== CTF_K_STRUCT
)
987 return fp
->ctf_dmodel
->ctd_int
;
989 default: /* including slices of enums, etc */
990 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
994 /* Return the kind (CTF_K_* constant) for the specified type ID. */
997 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
999 const ctf_type_t
*tp
;
1001 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1002 return -1; /* errno is set for us. */
1004 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1007 /* Return the kind (CTF_K_* constant) for the specified type ID.
1008 Slices are considered to be of the same kind as the type sliced. */
1011 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
1015 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1018 if (kind
== CTF_K_SLICE
)
1020 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1022 kind
= ctf_type_kind_unsliced (fp
, type
);
1028 /* Return the kind of this type, except, for forwards, return the kind of thing
1029 this is a forward to. */
1031 ctf_type_kind_forwarded (ctf_file_t
*fp
, ctf_id_t type
)
1034 const ctf_type_t
*tp
;
1036 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1037 return -1; /* errno is set for us. */
1039 if (kind
!= CTF_K_FORWARD
)
1042 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1043 return -1; /* errno is set for us. */
1045 return tp
->ctt_type
;
1048 /* If the type is one that directly references another type (such as POINTER),
1049 then return the ID of the type to which it refers. */
1052 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
1054 ctf_file_t
*ofp
= fp
;
1055 const ctf_type_t
*tp
;
1057 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1058 return CTF_ERR
; /* errno is set for us. */
1060 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1064 case CTF_K_VOLATILE
:
1066 case CTF_K_RESTRICT
:
1067 return tp
->ctt_type
;
1068 /* Slices store their type in an unusual place. */
1072 const ctf_slice_t
*sp
;
1074 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1078 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1079 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1082 sp
= &dtd
->dtd_u
.dtu_slice
;
1084 return sp
->cts_type
;
1087 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1091 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1092 pointer to the given type, see if we can compute a pointer to the type
1093 resulting from resolving the type down to its base type and use that
1094 instead. This helps with cases where the CTF data includes "struct foo *"
1095 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1097 XXX what about parent containers? */
1100 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
1102 ctf_file_t
*ofp
= fp
;
1105 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1106 return CTF_ERR
; /* errno is set for us. */
1108 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1109 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1111 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1112 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1114 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1115 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1117 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1118 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1120 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1123 /* Return the encoding for the specified INTEGER or FLOAT. */
1126 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1128 ctf_file_t
*ofp
= fp
;
1130 const ctf_type_t
*tp
;
1134 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1135 return -1; /* errno is set for us. */
1137 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1139 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1143 *ep
= dtd
->dtd_u
.dtu_enc
;
1147 const ctf_slice_t
*slice
;
1148 ctf_encoding_t underlying_en
;
1149 ctf_id_t underlying
;
1151 slice
= &dtd
->dtd_u
.dtu_slice
;
1152 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1153 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1155 ep
->cte_format
= underlying_en
.cte_format
;
1156 ep
->cte_offset
= slice
->cts_offset
;
1157 ep
->cte_bits
= slice
->cts_bits
;
1161 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1166 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1168 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1171 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1172 ep
->cte_format
= CTF_INT_ENCODING (data
);
1173 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1174 ep
->cte_bits
= CTF_INT_BITS (data
);
1177 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1178 ep
->cte_format
= CTF_FP_ENCODING (data
);
1179 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1180 ep
->cte_bits
= CTF_FP_BITS (data
);
1184 const ctf_slice_t
*slice
;
1185 ctf_encoding_t underlying_en
;
1186 ctf_id_t underlying
;
1188 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1189 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1190 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1192 ep
->cte_format
= underlying_en
.cte_format
;
1193 ep
->cte_offset
= slice
->cts_offset
;
1194 ep
->cte_bits
= slice
->cts_bits
;
1198 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1205 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
1212 else if (ltype
> rtype
)
1220 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1221 lfp
= lfp
->ctf_parent
;
1223 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1224 rfp
= rfp
->ctf_parent
;
1235 /* Return a boolean value indicating if two types are compatible. This function
1236 returns true if the two types are the same, or if they (or their ultimate
1237 base type) have the same encoding properties, or (for structs / unions /
1238 enums / forward declarations) if they have the same name and (for structs /
1239 unions) member count. */
1242 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
1243 ctf_file_t
*rfp
, ctf_id_t rtype
)
1245 const ctf_type_t
*ltp
, *rtp
;
1246 ctf_encoding_t le
, re
;
1247 ctf_arinfo_t la
, ra
;
1248 uint32_t lkind
, rkind
;
1251 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1254 ltype
= ctf_type_resolve (lfp
, ltype
);
1255 lkind
= ctf_type_kind (lfp
, ltype
);
1257 rtype
= ctf_type_resolve (rfp
, rtype
);
1258 rkind
= ctf_type_kind (rfp
, rtype
);
1260 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1261 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1263 if (ltp
!= NULL
&& rtp
!= NULL
)
1264 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1265 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1267 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1268 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1278 memset (&le
, 0, sizeof (le
));
1279 memset (&re
, 0, sizeof (re
));
1280 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1281 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1282 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1284 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1285 rfp
, ctf_type_reference (rfp
, rtype
)));
1287 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1288 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1289 && la
.ctr_nelems
== ra
.ctr_nelems
1290 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1291 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1294 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1295 == ctf_type_size (rfp
, rtype
)));
1298 int lencoded
, rencoded
;
1299 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1300 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1302 if ((lencoded
!= rencoded
) ||
1303 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1308 return same_names
; /* No other checks required for these type kinds. */
1310 return 0; /* Should not get here since we did a resolve. */
1314 /* Return the number of members in a STRUCT or UNION, or the number of
1315 enumerators in an ENUM. */
1318 ctf_member_count (ctf_file_t
*fp
, ctf_id_t type
)
1320 ctf_file_t
*ofp
= fp
;
1321 const ctf_type_t
*tp
;
1324 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1325 return -1; /* errno is set for us. */
1327 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1328 return -1; /* errno is set for us. */
1330 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1332 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1333 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1335 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1338 /* Return the type and offset for a given member of a STRUCT or UNION. */
1341 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
1342 ctf_membinfo_t
*mip
)
1344 ctf_file_t
*ofp
= fp
;
1345 const ctf_type_t
*tp
;
1347 ssize_t size
, increment
;
1350 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1351 return -1; /* errno is set for us. */
1353 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1354 return -1; /* errno is set for us. */
1356 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1357 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1359 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1360 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1362 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1364 if (size
< CTF_LSTRUCT_THRESH
)
1366 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1369 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1371 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
1373 mip
->ctm_type
= mp
->ctm_type
;
1374 mip
->ctm_offset
= mp
->ctm_offset
;
1381 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1384 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1386 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
1388 mip
->ctm_type
= lmp
->ctlm_type
;
1389 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1399 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1400 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1402 if (strcmp (dmd
->dmd_name
, name
) == 0)
1404 mip
->ctm_type
= dmd
->dmd_type
;
1405 mip
->ctm_offset
= dmd
->dmd_offset
;
1411 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1414 /* Return the array type, index, and size information for the specified ARRAY. */
1417 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1419 ctf_file_t
*ofp
= fp
;
1420 const ctf_type_t
*tp
;
1421 const ctf_array_t
*ap
;
1422 const ctf_dtdef_t
*dtd
;
1425 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1426 return -1; /* errno is set for us. */
1428 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1429 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1431 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1433 *arp
= dtd
->dtd_u
.dtu_arr
;
1437 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1439 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1440 arp
->ctr_contents
= ap
->cta_contents
;
1441 arp
->ctr_index
= ap
->cta_index
;
1442 arp
->ctr_nelems
= ap
->cta_nelems
;
1447 /* Convert the specified value to the corresponding enum tag name, if a
1448 matching name can be found. Otherwise NULL is returned. */
1451 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
1453 ctf_file_t
*ofp
= fp
;
1454 const ctf_type_t
*tp
;
1455 const ctf_enum_t
*ep
;
1456 const ctf_dtdef_t
*dtd
;
1460 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1461 return NULL
; /* errno is set for us. */
1463 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1464 return NULL
; /* errno is set for us. */
1466 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1468 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1472 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1474 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1476 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1478 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1480 if (ep
->cte_value
== value
)
1481 return (ctf_strptr (fp
, ep
->cte_name
));
1488 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1489 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1491 if (dmd
->dmd_value
== value
)
1492 return dmd
->dmd_name
;
1496 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1500 /* Convert the specified enum tag name to the corresponding value, if a
1501 matching name can be found. Otherwise CTF_ERR is returned. */
1504 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1506 ctf_file_t
*ofp
= fp
;
1507 const ctf_type_t
*tp
;
1508 const ctf_enum_t
*ep
;
1509 const ctf_dtdef_t
*dtd
;
1513 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1514 return -1; /* errno is set for us. */
1516 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1517 return -1; /* errno is set for us. */
1519 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1521 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1525 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1527 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1529 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1531 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1533 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1536 *valp
= ep
->cte_value
;
1545 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1546 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1548 if (strcmp (dmd
->dmd_name
, name
) == 0)
1551 *valp
= dmd
->dmd_value
;
1557 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1561 /* Given a type ID relating to a function type, return info on return types and
1562 arg counts for that function. */
1565 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1567 const ctf_type_t
*tp
;
1569 const uint32_t *args
;
1570 const ctf_dtdef_t
*dtd
;
1571 ssize_t size
, increment
;
1573 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1574 return -1; /* errno is set for us. */
1576 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1577 return -1; /* errno is set for us. */
1579 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1580 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1582 if (kind
!= CTF_K_FUNCTION
)
1583 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1585 fip
->ctc_return
= tp
->ctt_type
;
1587 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1589 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1590 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1592 args
= dtd
->dtd_u
.dtu_argv
;
1594 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1596 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1603 /* Given a type ID relating to a function type, return the arguments for the
1607 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1609 const ctf_type_t
*tp
;
1610 const uint32_t *args
;
1611 const ctf_dtdef_t
*dtd
;
1612 ssize_t size
, increment
;
1615 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1616 return -1; /* errno is set for us. */
1618 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1619 return -1; /* errno is set for us. */
1621 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1622 return -1; /* errno is set for us. */
1624 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1626 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1627 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1629 args
= dtd
->dtd_u
.dtu_argv
;
1631 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1637 /* Recursively visit the members of any type. This function is used as the
1638 engine for ctf_type_visit, below. We resolve the input type, recursively
1639 invoke ourself for each type member if the type is a struct or union, and
1640 then invoke the callback function on the current type. If any callback
1641 returns non-zero, we abort and percolate the error code back up to the top. */
1644 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1645 void *arg
, const char *name
, unsigned long offset
, int depth
)
1647 ctf_id_t otype
= type
;
1648 const ctf_type_t
*tp
;
1649 const ctf_dtdef_t
*dtd
;
1650 ssize_t size
, increment
;
1654 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1655 return -1; /* errno is set for us. */
1657 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1658 return -1; /* errno is set for us. */
1660 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1663 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1665 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1668 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1670 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1672 if (size
< CTF_LSTRUCT_THRESH
)
1674 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1677 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1679 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1680 func
, arg
, ctf_strptr (fp
,
1682 offset
+ mp
->ctm_offset
,
1689 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1692 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1694 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1695 func
, arg
, ctf_strptr (fp
,
1697 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1707 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1708 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1710 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1711 dmd
->dmd_name
, dmd
->dmd_offset
,
1720 /* Recursively visit the members of any type. We pass the name, member
1721 type, and offset of each member to the specified callback function. */
1723 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1725 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));