1 /* Type handling functions.
2 Copyright (C) 2019-2021 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
)
50 while ((offset
= ctf_member_next (fp
, type
, &i
, &name
, &membtype
, 0)) >= 0)
52 if ((rc
= func (name
, membtype
, offset
, arg
)) != 0)
58 if (ctf_errno (fp
) != ECTF_NEXT_END
)
59 return -1; /* errno is set for us. */
64 /* Iterate over the members of a STRUCT or UNION, returning each member's
65 offset and optionally name and member type in turn. On end-of-iteration,
66 returns -1. If FLAGS is CTF_MN_RECURSE, recurse into unnamed members. */
69 ctf_member_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
70 const char **name
, ctf_id_t
*membtype
, int flags
)
83 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
84 return -1; /* errno is set for us. */
86 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
87 return -1; /* errno is set for us. */
89 if ((i
= ctf_next_create ()) == NULL
)
90 return ctf_set_errno (ofp
, ENOMEM
);
93 (void) ctf_get_ctt_size (fp
, tp
, &i
->ctn_size
, &increment
);
94 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
96 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
99 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
102 dtd
= ctf_dynamic_type (fp
, type
);
103 i
->ctn_iter_fun
= (void (*) (void)) ctf_member_next
;
105 /* We depend below on the RDWR state indicating whether the DTD-related
106 fields or the DMD-related fields have been initialized. */
108 assert ((dtd
&& (fp
->ctf_flags
& LCTF_RDWR
))
109 || (!dtd
&& (!(fp
->ctf_flags
& LCTF_RDWR
))));
113 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
115 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
116 i
->u
.ctn_mp
= (const ctf_member_t
*) ((uintptr_t) tp
+ increment
);
118 i
->u
.ctn_lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+ increment
);
121 i
->u
.ctn_dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
126 if ((void (*) (void)) ctf_member_next
!= i
->ctn_iter_fun
)
127 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
));
129 if (ofp
!= i
->cu
.ctn_fp
)
130 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
));
132 /* Resolve to the native dict of this type. */
133 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
134 return (ctf_set_errno (ofp
, ECTF_NOPARENT
));
136 /* When we hit an unnamed struct/union member, we set ctn_type to indicate
137 that we are inside one, then return the unnamed member: on the next call,
138 we must skip over top-level member iteration in favour of iteration within
139 the sub-struct until it later turns out that that iteration has ended. */
144 if (!(fp
->ctf_flags
& LCTF_RDWR
))
149 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
151 const char *membname
= ctf_strptr (fp
, i
->u
.ctn_mp
->ctm_name
);
156 *membtype
= i
->u
.ctn_mp
->ctm_type
;
157 offset
= i
->u
.ctn_mp
->ctm_offset
;
160 && (ctf_type_kind (fp
, i
->u
.ctn_mp
->ctm_type
) == CTF_K_STRUCT
161 || ctf_type_kind (fp
, i
->u
.ctn_mp
->ctm_type
) == CTF_K_UNION
))
162 i
->ctn_type
= i
->u
.ctn_mp
->ctm_type
;
168 const char *membname
= ctf_strptr (fp
, i
->u
.ctn_lmp
->ctlm_name
);
173 *membtype
= i
->u
.ctn_lmp
->ctlm_type
;
174 offset
= (unsigned long) CTF_LMEM_OFFSET (i
->u
.ctn_lmp
);
177 && (ctf_type_kind (fp
, i
->u
.ctn_lmp
->ctlm_type
) == CTF_K_STRUCT
178 || ctf_type_kind (fp
, i
->u
.ctn_lmp
->ctlm_type
) == CTF_K_UNION
))
179 i
->ctn_type
= i
->u
.ctn_lmp
->ctlm_type
;
187 if (i
->u
.ctn_dmd
== NULL
)
189 /* The dmd contains a NULL for unnamed dynamic members. Don't inflict
190 this on our callers. */
193 if (i
->u
.ctn_dmd
->dmd_name
)
194 *name
= i
->u
.ctn_dmd
->dmd_name
;
199 *membtype
= i
->u
.ctn_dmd
->dmd_type
;
200 offset
= i
->u
.ctn_dmd
->dmd_offset
;
202 if (i
->u
.ctn_dmd
->dmd_name
== NULL
203 && (ctf_type_kind (fp
, i
->u
.ctn_dmd
->dmd_type
) == CTF_K_STRUCT
204 || ctf_type_kind (fp
, i
->u
.ctn_dmd
->dmd_type
) == CTF_K_UNION
))
205 i
->ctn_type
= i
->u
.ctn_dmd
->dmd_type
;
207 i
->u
.ctn_dmd
= ctf_list_next (i
->u
.ctn_dmd
);
210 /* The callers might want automatic recursive sub-struct traversal. */
211 if (!(flags
& CTF_MN_RECURSE
))
214 /* Sub-struct traversal starting? Take note of the offset of this member,
215 for later boosting of sub-struct members' offsets. */
217 i
->ctn_increment
= offset
;
219 /* Traversing a sub-struct? Just return it, with the offset adjusted. */
222 ssize_t ret
= ctf_member_next (fp
, i
->ctn_type
, &i
->ctn_next
, name
,
226 return ret
+ i
->ctn_increment
;
228 if (ctf_errno (fp
) != ECTF_NEXT_END
)
230 ctf_next_destroy (i
);
233 return ret
; /* errno is set for us. */
236 if (!ctf_assert (fp
, (i
->ctn_next
== NULL
)))
237 return -1; /* errno is set for us. */
240 /* This sub-struct has ended: on to the next real member. */
247 ctf_next_destroy (i
);
249 return ctf_set_errno (ofp
, ECTF_NEXT_END
);
252 /* Iterate over the members of an ENUM. We pass the string name and associated
253 integer value of each enum element to the specified callback function. */
256 ctf_enum_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
258 ctf_dict_t
*ofp
= fp
;
259 const ctf_type_t
*tp
;
260 const ctf_enum_t
*ep
;
266 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
267 return -1; /* errno is set for us. */
269 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
270 return -1; /* errno is set for us. */
272 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
273 return (ctf_set_errno (ofp
, ECTF_NOTENUM
));
275 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
277 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
279 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
281 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
283 const char *name
= ctf_strptr (fp
, ep
->cte_name
);
284 if ((rc
= func (name
, ep
->cte_value
, arg
)) != 0)
292 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
293 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
295 if ((rc
= func (dmd
->dmd_name
, dmd
->dmd_value
, arg
)) != 0)
303 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
304 NULL at end of iteration or error, and optionally passing back the
305 enumerand's integer VALue. */
308 ctf_enum_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
311 ctf_dict_t
*ofp
= fp
;
318 const ctf_type_t
*tp
;
321 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
322 return NULL
; /* errno is set for us. */
324 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
325 return NULL
; /* errno is set for us. */
327 if ((i
= ctf_next_create ()) == NULL
)
329 ctf_set_errno (ofp
, ENOMEM
);
334 (void) ctf_get_ctt_size (fp
, tp
, NULL
,
336 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
338 if (kind
!= CTF_K_ENUM
)
340 ctf_next_destroy (i
);
341 ctf_set_errno (ofp
, ECTF_NOTENUM
);
345 dtd
= ctf_dynamic_type (fp
, type
);
346 i
->ctn_iter_fun
= (void (*) (void)) ctf_enum_next
;
348 /* We depend below on the RDWR state indicating whether the DTD-related
349 fields or the DMD-related fields have been initialized. */
351 assert ((dtd
&& (fp
->ctf_flags
& LCTF_RDWR
))
352 || (!dtd
&& (!(fp
->ctf_flags
& LCTF_RDWR
))));
356 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
358 i
->u
.ctn_en
= (const ctf_enum_t
*) ((uintptr_t) tp
+
362 i
->u
.ctn_dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
367 if ((void (*) (void)) ctf_enum_next
!= i
->ctn_iter_fun
)
369 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
);
373 if (ofp
!= i
->cu
.ctn_fp
)
375 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
);
379 /* Resolve to the native dict of this type. */
380 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
382 ctf_set_errno (ofp
, ECTF_NOPARENT
);
386 if (!(fp
->ctf_flags
& LCTF_RDWR
))
391 name
= ctf_strptr (fp
, i
->u
.ctn_en
->cte_name
);
393 *val
= i
->u
.ctn_en
->cte_value
;
399 if (i
->u
.ctn_dmd
== NULL
)
402 name
= i
->u
.ctn_dmd
->dmd_name
;
404 *val
= i
->u
.ctn_dmd
->dmd_value
;
405 i
->u
.ctn_dmd
= ctf_list_next (i
->u
.ctn_dmd
);
411 ctf_next_destroy (i
);
413 ctf_set_errno (ofp
, ECTF_NEXT_END
);
417 /* Iterate over every root (user-visible) type in the given CTF dict.
418 We pass the type ID of each type to the specified callback function.
420 Does not traverse parent types: you have to do that explicitly. This is by
421 design, to avoid traversing them more than once if traversing many children
422 of a single parent. */
425 ctf_type_iter (ctf_dict_t
*fp
, ctf_type_f
*func
, void *arg
)
427 ctf_id_t id
, max
= fp
->ctf_typemax
;
428 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
430 for (id
= 1; id
<= max
; id
++)
432 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
433 if (LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)
434 && (rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
), arg
)) != 0)
441 /* Iterate over every type in the given CTF dict, user-visible or not.
442 We pass the type ID of each type to the specified callback function.
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_iter_all (ctf_dict_t
*fp
, ctf_type_all_f
*func
, void *arg
)
451 ctf_id_t id
, max
= fp
->ctf_typemax
;
452 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
454 for (id
= 1; id
<= max
; id
++)
456 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
457 if ((rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
),
458 LCTF_INFO_ISROOT(fp
, tp
->ctt_info
)
459 ? CTF_ADD_ROOT
: CTF_ADD_NONROOT
, arg
) != 0))
466 /* Iterate over every type in the given CTF dict, optionally including
467 non-user-visible types, returning each type ID and hidden flag in turn.
468 Returns CTF_ERR on end of iteration or error.
470 Does not traverse parent types: you have to do that explicitly. This is by
471 design, to avoid traversing them more than once if traversing many children
472 of a single parent. */
475 ctf_type_next (ctf_dict_t
*fp
, ctf_next_t
**it
, int *flag
, int want_hidden
)
481 if ((i
= ctf_next_create ()) == NULL
)
482 return ctf_set_errno (fp
, ENOMEM
);
486 i
->ctn_iter_fun
= (void (*) (void)) ctf_type_next
;
490 if ((void (*) (void)) ctf_type_next
!= i
->ctn_iter_fun
)
491 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
493 if (fp
!= i
->cu
.ctn_fp
)
494 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
496 while (i
->ctn_type
<= fp
->ctf_typemax
)
498 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, i
->ctn_type
);
500 if ((!want_hidden
) && (!LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)))
507 *flag
= LCTF_INFO_ISROOT (fp
, tp
->ctt_info
);
508 return LCTF_INDEX_TO_TYPE (fp
, i
->ctn_type
++, fp
->ctf_flags
& LCTF_CHILD
);
510 ctf_next_destroy (i
);
512 return ctf_set_errno (fp
, ECTF_NEXT_END
);
515 /* Iterate over every variable in the given CTF dict, in arbitrary order.
516 We pass the name of each variable to the specified callback function. */
519 ctf_variable_iter (ctf_dict_t
*fp
, ctf_variable_f
*func
, void *arg
)
523 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
524 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
526 if (!(fp
->ctf_flags
& LCTF_RDWR
))
529 for (i
= 0; i
< fp
->ctf_nvars
; i
++)
530 if ((rc
= func (ctf_strptr (fp
, fp
->ctf_vars
[i
].ctv_name
),
531 fp
->ctf_vars
[i
].ctv_type
, arg
)) != 0)
538 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
;
539 dvd
= ctf_list_next (dvd
))
541 if ((rc
= func (dvd
->dvd_name
, dvd
->dvd_type
, arg
)) != 0)
549 /* Iterate over every variable in the given CTF dict, in arbitrary order,
550 returning the name and type of each variable in turn. The name argument is
551 not optional. Returns CTF_ERR on end of iteration or error. */
554 ctf_variable_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
)
558 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
559 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
563 if ((i
= ctf_next_create ()) == NULL
)
564 return ctf_set_errno (fp
, ENOMEM
);
567 i
->ctn_iter_fun
= (void (*) (void)) ctf_variable_next
;
568 if (fp
->ctf_flags
& LCTF_RDWR
)
569 i
->u
.ctn_dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
573 if ((void (*) (void)) ctf_variable_next
!= i
->ctn_iter_fun
)
574 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
576 if (fp
!= i
->cu
.ctn_fp
)
577 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
579 if (!(fp
->ctf_flags
& LCTF_RDWR
))
581 if (i
->ctn_n
>= fp
->ctf_nvars
)
584 *name
= ctf_strptr (fp
, fp
->ctf_vars
[i
->ctn_n
].ctv_name
);
585 return fp
->ctf_vars
[i
->ctn_n
++].ctv_type
;
591 if (i
->u
.ctn_dvd
== NULL
)
594 *name
= i
->u
.ctn_dvd
->dvd_name
;
595 id
= i
->u
.ctn_dvd
->dvd_type
;
596 i
->u
.ctn_dvd
= ctf_list_next (i
->u
.ctn_dvd
);
601 ctf_next_destroy (i
);
603 return ctf_set_errno (fp
, ECTF_NEXT_END
);
606 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
607 RESTRICT nodes until we reach a "base" type node. This is useful when
608 we want to follow a type ID to a node that has members or a size. To guard
609 against infinite loops, we implement simplified cycle detection and check
610 each link against itself, the previous node, and the topmost node.
612 Does not drill down through slices to their contained type.
614 Callers of this function must not presume that a type it returns must have a
615 valid ctt_size: forwards do not, and must be separately handled. */
618 ctf_type_resolve (ctf_dict_t
*fp
, ctf_id_t type
)
620 ctf_id_t prev
= type
, otype
= type
;
621 ctf_dict_t
*ofp
= fp
;
622 const ctf_type_t
*tp
;
625 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
627 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
629 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
635 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
636 || tp
->ctt_type
== prev
)
638 ctf_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
640 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
649 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
652 return CTF_ERR
; /* errno is set for us. */
655 /* Like ctf_type_resolve(), but traverse down through slices to their contained
659 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
661 const ctf_type_t
*tp
;
663 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
666 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
667 return CTF_ERR
; /* errno is set for us. */
669 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
670 return ctf_type_reference (fp
, type
);
674 /* Return the native dict of a given type: if called on a child and the
675 type is in the parent, return the parent. Needed if you plan to access
676 the type directly, without using the API. */
678 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
680 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
681 return fp
->ctf_parent
;
686 /* Look up a name in the given name table, in the appropriate hash given the
687 kind of the identifier. The name is a raw, undecorated identifier. */
689 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
691 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
694 /* Look up a name in the given name table, in the appropriate hash given the
695 readability state of the dictionary. The name is a raw, undecorated
698 ctf_id_t
ctf_lookup_by_rawhash (ctf_dict_t
*fp
, ctf_names_t
*np
, const char *name
)
702 if (fp
->ctf_flags
& LCTF_RDWR
)
703 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
705 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
709 /* Lookup the given type ID and return its name as a new dynamically-allocated
713 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
716 ctf_decl_node_t
*cdp
;
717 ctf_decl_prec_t prec
, lp
, rp
;
722 if (fp
== NULL
&& type
== CTF_ERR
)
723 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
726 ctf_decl_push (&cd
, fp
, type
);
731 ctf_set_errno (fp
, cd
.cd_err
);
735 /* If the type graph's order conflicts with lexical precedence order
736 for pointers or arrays, then we need to surround the declarations at
737 the corresponding lexical precedence with parentheses. This can
738 result in either a parenthesized pointer (*) as in int (*)() or
739 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
741 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
742 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
744 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
745 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
747 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
749 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
751 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
752 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
754 ctf_dict_t
*rfp
= fp
;
755 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
756 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
758 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
759 ctf_decl_sprintf (&cd
, " ");
763 ctf_decl_sprintf (&cd
, "(");
767 switch (cdp
->cd_kind
)
772 /* Integers, floats, and typedefs must always be named types. */
776 ctf_set_errno (fp
, ECTF_CORRUPT
);
781 ctf_decl_sprintf (&cd
, "%s", name
);
784 ctf_decl_sprintf (&cd
, "*");
787 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
793 ctf_id_t
*argv
= NULL
;
795 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
796 goto err
; /* errno is set for us. */
798 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
800 ctf_set_errno (rfp
, errno
);
804 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
805 fi
.ctc_argc
, argv
) < 0)
806 goto err
; /* errno is set for us. */
808 ctf_decl_sprintf (&cd
, "(*) (");
809 for (i
= 0; i
< fi
.ctc_argc
; i
++)
811 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
814 goto err
; /* errno is set for us. */
815 ctf_decl_sprintf (&cd
, "%s", arg
);
818 if ((i
< fi
.ctc_argc
- 1)
819 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
820 ctf_decl_sprintf (&cd
, ", ");
823 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
824 ctf_decl_sprintf (&cd
, "...");
825 ctf_decl_sprintf (&cd
, ")");
838 ctf_decl_sprintf (&cd
, "struct %s", name
);
841 ctf_decl_sprintf (&cd
, "union %s", name
);
844 ctf_decl_sprintf (&cd
, "enum %s", name
);
847 ctf_decl_sprintf (&cd
, "volatile");
850 ctf_decl_sprintf (&cd
, "const");
853 ctf_decl_sprintf (&cd
, "restrict");
861 ctf_decl_sprintf (&cd
, ")");
865 (void) ctf_set_errno (fp
, ENOMEM
);
867 buf
= ctf_decl_buf (&cd
);
873 /* Lookup the given type ID and print a string name for it into buf. Return
874 the actual number of bytes (not including \0) needed to format the name. */
877 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
879 char *str
= ctf_type_aname (fp
, type
);
883 return CTF_ERR
; /* errno is set for us. */
886 snprintf (buf
, len
, "%s", str
);
890 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
895 /* Lookup the given type ID and print a string name for it into buf. If buf
896 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
899 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
901 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
902 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
905 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
906 The name will live as long as its ctf_dict_t does. */
909 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
911 const ctf_type_t
*tp
;
913 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
914 return NULL
; /* errno is set for us. */
916 return ctf_strraw (fp
, tp
->ctt_name
);
919 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
920 new dynamically-allocated string. */
923 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
925 const char *name
= ctf_type_name_raw (fp
, type
);
928 return strdup (name
);
933 /* Resolve the type down to a base type node, and then return the size
934 of the type storage in bytes. */
937 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
939 ctf_dict_t
*ofp
= fp
;
940 const ctf_type_t
*tp
;
944 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
945 return -1; /* errno is set for us. */
947 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
948 return -1; /* errno is set for us. */
950 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
953 return fp
->ctf_dmodel
->ctd_pointer
;
956 return 0; /* Function size is only known by symtab. */
959 return fp
->ctf_dmodel
->ctd_int
;
962 /* ctf_add_array() does not directly encode the element size, but
963 requires the user to multiply to determine the element size.
965 If ctf_get_ctt_size() returns nonzero, then use the recorded
968 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
971 if (ctf_array_info (ofp
, type
, &ar
) < 0
972 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
973 return -1; /* errno is set for us. */
975 return size
* ar
.ctr_nelems
;
978 /* Forwards do not have a meaningful size. */
979 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
981 default: /* including slices of enums, etc */
982 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
986 /* Resolve the type down to a base type node, and then return the alignment
987 needed for the type storage in bytes.
989 XXX may need arch-dependent attention. */
992 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
994 const ctf_type_t
*tp
;
995 ctf_dict_t
*ofp
= fp
;
998 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
999 return -1; /* errno is set for us. */
1001 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1002 return -1; /* errno is set for us. */
1004 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1008 case CTF_K_FUNCTION
:
1009 return fp
->ctf_dmodel
->ctd_pointer
;
1014 if (ctf_array_info (ofp
, type
, &r
) < 0)
1015 return -1; /* errno is set for us. */
1016 return (ctf_type_align (ofp
, r
.ctr_contents
));
1025 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1027 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1028 ssize_t size
, increment
;
1031 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1032 vmp
= (unsigned char *) tp
+ increment
;
1034 if (kind
== CTF_K_STRUCT
)
1035 n
= MIN (n
, 1); /* Only use first member for structs. */
1037 if (size
< CTF_LSTRUCT_THRESH
)
1039 const ctf_member_t
*mp
= vmp
;
1040 for (; n
!= 0; n
--, mp
++)
1042 ssize_t am
= ctf_type_align (ofp
, mp
->ctm_type
);
1043 align
= MAX (align
, (size_t) am
);
1048 const ctf_lmember_t
*lmp
= vmp
;
1049 for (; n
!= 0; n
--, lmp
++)
1051 ssize_t am
= ctf_type_align (ofp
, lmp
->ctlm_type
);
1052 align
= MAX (align
, (size_t) am
);
1060 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1061 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1063 ssize_t am
= ctf_type_align (ofp
, dmd
->dmd_type
);
1064 align
= MAX (align
, (size_t) am
);
1065 if (kind
== CTF_K_STRUCT
)
1074 return fp
->ctf_dmodel
->ctd_int
;
1077 /* Forwards do not have a meaningful alignment. */
1078 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1080 default: /* including slices of enums, etc */
1081 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1085 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1088 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1090 const ctf_type_t
*tp
;
1092 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1093 return -1; /* errno is set for us. */
1095 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1098 /* Return the kind (CTF_K_* constant) for the specified type ID.
1099 Slices are considered to be of the same kind as the type sliced. */
1102 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1106 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1109 if (kind
== CTF_K_SLICE
)
1111 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1113 kind
= ctf_type_kind_unsliced (fp
, type
);
1119 /* Return the kind of this type, except, for forwards, return the kind of thing
1120 this is a forward to. */
1122 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1125 const ctf_type_t
*tp
;
1127 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1128 return -1; /* errno is set for us. */
1130 if (kind
!= CTF_K_FORWARD
)
1133 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1134 return -1; /* errno is set for us. */
1136 return tp
->ctt_type
;
1139 /* If the type is one that directly references another type (such as POINTER),
1140 then return the ID of the type to which it refers. */
1143 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1145 ctf_dict_t
*ofp
= fp
;
1146 const ctf_type_t
*tp
;
1148 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1149 return CTF_ERR
; /* errno is set for us. */
1151 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1155 case CTF_K_VOLATILE
:
1157 case CTF_K_RESTRICT
:
1158 return tp
->ctt_type
;
1159 /* Slices store their type in an unusual place. */
1163 const ctf_slice_t
*sp
;
1165 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1169 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1170 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1173 sp
= &dtd
->dtd_u
.dtu_slice
;
1175 return sp
->cts_type
;
1178 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1182 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1183 pointer to the given type, see if we can compute a pointer to the type
1184 resulting from resolving the type down to its base type and use that
1185 instead. This helps with cases where the CTF data includes "struct foo *"
1186 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1188 XXX what about parent dicts? */
1191 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1193 ctf_dict_t
*ofp
= fp
;
1196 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1197 return CTF_ERR
; /* errno is set for us. */
1199 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1200 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1202 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1203 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1205 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1206 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1208 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1209 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1211 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1214 /* Return the encoding for the specified INTEGER or FLOAT. */
1217 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1219 ctf_dict_t
*ofp
= fp
;
1221 const ctf_type_t
*tp
;
1225 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1226 return -1; /* errno is set for us. */
1228 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1230 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1234 *ep
= dtd
->dtd_u
.dtu_enc
;
1238 const ctf_slice_t
*slice
;
1239 ctf_encoding_t underlying_en
;
1240 ctf_id_t underlying
;
1242 slice
= &dtd
->dtd_u
.dtu_slice
;
1243 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1244 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1246 ep
->cte_format
= underlying_en
.cte_format
;
1247 ep
->cte_offset
= slice
->cts_offset
;
1248 ep
->cte_bits
= slice
->cts_bits
;
1252 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1257 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1259 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1262 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1263 ep
->cte_format
= CTF_INT_ENCODING (data
);
1264 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1265 ep
->cte_bits
= CTF_INT_BITS (data
);
1268 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1269 ep
->cte_format
= CTF_FP_ENCODING (data
);
1270 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1271 ep
->cte_bits
= CTF_FP_BITS (data
);
1275 const ctf_slice_t
*slice
;
1276 ctf_encoding_t underlying_en
;
1277 ctf_id_t underlying
;
1279 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1280 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1281 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1283 ep
->cte_format
= underlying_en
.cte_format
;
1284 ep
->cte_offset
= slice
->cts_offset
;
1285 ep
->cte_bits
= slice
->cts_bits
;
1289 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1296 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1303 else if (ltype
> rtype
)
1311 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1312 lfp
= lfp
->ctf_parent
;
1314 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1315 rfp
= rfp
->ctf_parent
;
1326 /* Return a boolean value indicating if two types are compatible. This function
1327 returns true if the two types are the same, or if they (or their ultimate
1328 base type) have the same encoding properties, or (for structs / unions /
1329 enums / forward declarations) if they have the same name and (for structs /
1330 unions) member count. */
1333 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1334 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1336 const ctf_type_t
*ltp
, *rtp
;
1337 ctf_encoding_t le
, re
;
1338 ctf_arinfo_t la
, ra
;
1339 uint32_t lkind
, rkind
;
1342 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1345 ltype
= ctf_type_resolve (lfp
, ltype
);
1346 lkind
= ctf_type_kind (lfp
, ltype
);
1348 rtype
= ctf_type_resolve (rfp
, rtype
);
1349 rkind
= ctf_type_kind (rfp
, rtype
);
1351 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1352 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1354 if (ltp
!= NULL
&& rtp
!= NULL
)
1355 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1356 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1358 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1359 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1369 memset (&le
, 0, sizeof (le
));
1370 memset (&re
, 0, sizeof (re
));
1371 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1372 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1373 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1375 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1376 rfp
, ctf_type_reference (rfp
, rtype
)));
1378 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1379 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1380 && la
.ctr_nelems
== ra
.ctr_nelems
1381 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1382 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1385 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1386 == ctf_type_size (rfp
, rtype
)));
1389 int lencoded
, rencoded
;
1390 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1391 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1393 if ((lencoded
!= rencoded
) ||
1394 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1399 return same_names
; /* No other checks required for these type kinds. */
1401 return 0; /* Should not get here since we did a resolve. */
1405 /* Return the number of members in a STRUCT or UNION, or the number of
1406 enumerators in an ENUM. The count does not include unnamed sub-members. */
1409 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1411 ctf_dict_t
*ofp
= fp
;
1412 const ctf_type_t
*tp
;
1415 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1416 return -1; /* errno is set for us. */
1418 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1419 return -1; /* errno is set for us. */
1421 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1423 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1424 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1426 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1429 /* Return the type and offset for a given member of a STRUCT or UNION. */
1432 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1433 ctf_membinfo_t
*mip
)
1435 ctf_dict_t
*ofp
= fp
;
1436 const ctf_type_t
*tp
;
1438 ssize_t size
, increment
;
1441 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1442 return -1; /* errno is set for us. */
1444 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1445 return -1; /* errno is set for us. */
1447 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1448 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1450 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1451 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1453 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1455 if (size
< CTF_LSTRUCT_THRESH
)
1457 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1460 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1462 const char *membname
= ctf_strptr (fp
, mp
->ctm_name
);
1464 if (membname
[0] == 0
1465 && (ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_STRUCT
1466 || ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_UNION
)
1467 && (ctf_member_info (fp
, mp
->ctm_type
, name
, mip
) == 0))
1470 if (strcmp (membname
, name
) == 0)
1472 mip
->ctm_type
= mp
->ctm_type
;
1473 mip
->ctm_offset
= mp
->ctm_offset
;
1480 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1483 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1485 const char *membname
= ctf_strptr (fp
, lmp
->ctlm_name
);
1487 if (membname
[0] == 0
1488 && (ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_STRUCT
1489 || ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_UNION
)
1490 && (ctf_member_info (fp
, lmp
->ctlm_type
, name
, mip
) == 0))
1493 if (strcmp (membname
, name
) == 0)
1495 mip
->ctm_type
= lmp
->ctlm_type
;
1496 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1506 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1507 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1509 if (dmd
->dmd_name
== NULL
1510 && (ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_STRUCT
1511 || ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_UNION
)
1512 && (ctf_member_info (fp
, dmd
->dmd_type
, name
, mip
) == 0))
1515 if (dmd
->dmd_name
!= NULL
1516 && strcmp (dmd
->dmd_name
, name
) == 0)
1518 mip
->ctm_type
= dmd
->dmd_type
;
1519 mip
->ctm_offset
= dmd
->dmd_offset
;
1525 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1528 /* Return the array type, index, and size information for the specified ARRAY. */
1531 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1533 ctf_dict_t
*ofp
= fp
;
1534 const ctf_type_t
*tp
;
1535 const ctf_array_t
*ap
;
1536 const ctf_dtdef_t
*dtd
;
1539 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1540 return -1; /* errno is set for us. */
1542 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1543 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1545 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1547 *arp
= dtd
->dtd_u
.dtu_arr
;
1551 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1553 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1554 arp
->ctr_contents
= ap
->cta_contents
;
1555 arp
->ctr_index
= ap
->cta_index
;
1556 arp
->ctr_nelems
= ap
->cta_nelems
;
1561 /* Convert the specified value to the corresponding enum tag name, if a
1562 matching name can be found. Otherwise NULL is returned. */
1565 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1567 ctf_dict_t
*ofp
= fp
;
1568 const ctf_type_t
*tp
;
1569 const ctf_enum_t
*ep
;
1570 const ctf_dtdef_t
*dtd
;
1574 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1575 return NULL
; /* errno is set for us. */
1577 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1578 return NULL
; /* errno is set for us. */
1580 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1582 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1586 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1588 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1590 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1592 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1594 if (ep
->cte_value
== value
)
1595 return (ctf_strptr (fp
, ep
->cte_name
));
1602 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1603 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1605 if (dmd
->dmd_value
== value
)
1606 return dmd
->dmd_name
;
1610 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1614 /* Convert the specified enum tag name to the corresponding value, if a
1615 matching name can be found. Otherwise CTF_ERR is returned. */
1618 ctf_enum_value (ctf_dict_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1620 ctf_dict_t
*ofp
= fp
;
1621 const ctf_type_t
*tp
;
1622 const ctf_enum_t
*ep
;
1623 const ctf_dtdef_t
*dtd
;
1627 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1628 return -1; /* errno is set for us. */
1630 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1631 return -1; /* errno is set for us. */
1633 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1635 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1639 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1641 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1643 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1645 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1647 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1650 *valp
= ep
->cte_value
;
1659 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1660 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1662 if (strcmp (dmd
->dmd_name
, name
) == 0)
1665 *valp
= dmd
->dmd_value
;
1671 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1675 /* Given a type ID relating to a function type, return info on return types and
1676 arg counts for that function. */
1679 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1681 const ctf_type_t
*tp
;
1683 const uint32_t *args
;
1684 const ctf_dtdef_t
*dtd
;
1685 ssize_t size
, increment
;
1687 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1688 return -1; /* errno is set for us. */
1690 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1691 return -1; /* errno is set for us. */
1693 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1694 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1696 if (kind
!= CTF_K_FUNCTION
)
1697 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1699 fip
->ctc_return
= tp
->ctt_type
;
1701 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1703 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1704 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1706 args
= dtd
->dtd_u
.dtu_argv
;
1708 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1710 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1717 /* Given a type ID relating to a function type, return the arguments for the
1721 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1723 const ctf_type_t
*tp
;
1724 const uint32_t *args
;
1725 const ctf_dtdef_t
*dtd
;
1726 ssize_t size
, increment
;
1729 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1730 return -1; /* errno is set for us. */
1732 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1733 return -1; /* errno is set for us. */
1735 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1736 return -1; /* errno is set for us. */
1738 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1740 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1741 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1743 args
= dtd
->dtd_u
.dtu_argv
;
1745 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1751 /* Recursively visit the members of any type. This function is used as the
1752 engine for ctf_type_visit, below. We resolve the input type, recursively
1753 invoke ourself for each type member if the type is a struct or union, and
1754 then invoke the callback function on the current type. If any callback
1755 returns non-zero, we abort and percolate the error code back up to the top. */
1758 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1759 void *arg
, const char *name
, unsigned long offset
, int depth
)
1761 ctf_id_t otype
= type
;
1762 const ctf_type_t
*tp
;
1763 const ctf_dtdef_t
*dtd
;
1764 ssize_t size
, increment
;
1768 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1769 return -1; /* errno is set for us. */
1771 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1772 return -1; /* errno is set for us. */
1774 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1777 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1779 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1782 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1784 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1786 if (size
< CTF_LSTRUCT_THRESH
)
1788 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1791 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1793 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1794 func
, arg
, ctf_strptr (fp
,
1796 offset
+ mp
->ctm_offset
,
1803 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1806 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1808 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1809 func
, arg
, ctf_strptr (fp
,
1811 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1821 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1822 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1824 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1825 dmd
->dmd_name
, dmd
->dmd_offset
,
1834 /* Recursively visit the members of any type. We pass the name, member
1835 type, and offset of each member to the specified callback function. */
1837 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1839 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));