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
, ")");
837 ctf_decl_sprintf (&cd
, "struct %s", name
);
840 ctf_decl_sprintf (&cd
, "union %s", name
);
843 ctf_decl_sprintf (&cd
, "enum %s", name
);
847 switch (ctf_type_kind_forwarded (fp
, cdp
->cd_type
))
850 ctf_decl_sprintf (&cd
, "struct %s", name
);
853 ctf_decl_sprintf (&cd
, "union %s", name
);
856 ctf_decl_sprintf (&cd
, "enum %s", name
);
859 ctf_set_errno (fp
, ECTF_CORRUPT
);
866 ctf_decl_sprintf (&cd
, "volatile");
869 ctf_decl_sprintf (&cd
, "const");
872 ctf_decl_sprintf (&cd
, "restrict");
880 ctf_decl_sprintf (&cd
, ")");
884 (void) ctf_set_errno (fp
, ENOMEM
);
886 buf
= ctf_decl_buf (&cd
);
892 /* Lookup the given type ID and print a string name for it into buf. Return
893 the actual number of bytes (not including \0) needed to format the name. */
896 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
898 char *str
= ctf_type_aname (fp
, type
);
902 return CTF_ERR
; /* errno is set for us. */
905 snprintf (buf
, len
, "%s", str
);
909 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
914 /* Lookup the given type ID and print a string name for it into buf. If buf
915 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
918 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
920 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
921 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
924 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
925 The name will live as long as its ctf_dict_t does.
927 The only decoration is that a NULL return always means an error: nameless
928 types return a null string. */
931 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
933 const ctf_type_t
*tp
;
935 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
936 return NULL
; /* errno is set for us. */
938 if (tp
->ctt_name
== 0)
941 return ctf_strraw (fp
, tp
->ctt_name
);
944 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
945 new dynamically-allocated string. */
948 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
950 const char *name
= ctf_type_name_raw (fp
, type
);
953 return strdup (name
);
958 /* Resolve the type down to a base type node, and then return the size
959 of the type storage in bytes. */
962 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
964 ctf_dict_t
*ofp
= fp
;
965 const ctf_type_t
*tp
;
969 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
970 return -1; /* errno is set for us. */
972 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
973 return -1; /* errno is set for us. */
975 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
978 return fp
->ctf_dmodel
->ctd_pointer
;
981 return 0; /* Function size is only known by symtab. */
984 return fp
->ctf_dmodel
->ctd_int
;
987 /* ctf_add_array() does not directly encode the element size, but
988 requires the user to multiply to determine the element size.
990 If ctf_get_ctt_size() returns nonzero, then use the recorded
993 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
996 if (ctf_array_info (ofp
, type
, &ar
) < 0
997 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
998 return -1; /* errno is set for us. */
1000 return size
* ar
.ctr_nelems
;
1003 /* Forwards do not have a meaningful size. */
1004 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1006 default: /* including slices of enums, etc */
1007 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1011 /* Resolve the type down to a base type node, and then return the alignment
1012 needed for the type storage in bytes.
1014 XXX may need arch-dependent attention. */
1017 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
1019 const ctf_type_t
*tp
;
1020 ctf_dict_t
*ofp
= fp
;
1023 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1024 return -1; /* errno is set for us. */
1026 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1027 return -1; /* errno is set for us. */
1029 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1033 case CTF_K_FUNCTION
:
1034 return fp
->ctf_dmodel
->ctd_pointer
;
1039 if (ctf_array_info (ofp
, type
, &r
) < 0)
1040 return -1; /* errno is set for us. */
1041 return (ctf_type_align (ofp
, r
.ctr_contents
));
1050 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1052 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1053 ssize_t size
, increment
;
1056 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1057 vmp
= (unsigned char *) tp
+ increment
;
1059 if (kind
== CTF_K_STRUCT
)
1060 n
= MIN (n
, 1); /* Only use first member for structs. */
1062 if (size
< CTF_LSTRUCT_THRESH
)
1064 const ctf_member_t
*mp
= vmp
;
1065 for (; n
!= 0; n
--, mp
++)
1067 ssize_t am
= ctf_type_align (ofp
, mp
->ctm_type
);
1068 align
= MAX (align
, (size_t) am
);
1073 const ctf_lmember_t
*lmp
= vmp
;
1074 for (; n
!= 0; n
--, lmp
++)
1076 ssize_t am
= ctf_type_align (ofp
, lmp
->ctlm_type
);
1077 align
= MAX (align
, (size_t) am
);
1085 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1086 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1088 ssize_t am
= ctf_type_align (ofp
, dmd
->dmd_type
);
1089 align
= MAX (align
, (size_t) am
);
1090 if (kind
== CTF_K_STRUCT
)
1099 return fp
->ctf_dmodel
->ctd_int
;
1102 /* Forwards do not have a meaningful alignment. */
1103 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1105 default: /* including slices of enums, etc */
1106 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1110 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1113 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1115 const ctf_type_t
*tp
;
1117 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1118 return -1; /* errno is set for us. */
1120 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1123 /* Return the kind (CTF_K_* constant) for the specified type ID.
1124 Slices are considered to be of the same kind as the type sliced. */
1127 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1131 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1134 if (kind
== CTF_K_SLICE
)
1136 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1138 kind
= ctf_type_kind_unsliced (fp
, type
);
1144 /* Return the kind of this type, except, for forwards, return the kind of thing
1145 this is a forward to. */
1147 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1150 const ctf_type_t
*tp
;
1152 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1153 return -1; /* errno is set for us. */
1155 if (kind
!= CTF_K_FORWARD
)
1158 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1159 return -1; /* errno is set for us. */
1161 return tp
->ctt_type
;
1164 /* If the type is one that directly references another type (such as POINTER),
1165 then return the ID of the type to which it refers. */
1168 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1170 ctf_dict_t
*ofp
= fp
;
1171 const ctf_type_t
*tp
;
1173 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1174 return CTF_ERR
; /* errno is set for us. */
1176 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1180 case CTF_K_VOLATILE
:
1182 case CTF_K_RESTRICT
:
1183 return tp
->ctt_type
;
1184 /* Slices store their type in an unusual place. */
1188 const ctf_slice_t
*sp
;
1190 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1194 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1195 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1198 sp
= &dtd
->dtd_u
.dtu_slice
;
1200 return sp
->cts_type
;
1203 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1207 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1208 pointer to the given type, see if we can compute a pointer to the type
1209 resulting from resolving the type down to its base type and use that
1210 instead. This helps with cases where the CTF data includes "struct foo *"
1211 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1213 XXX what about parent dicts? */
1216 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1218 ctf_dict_t
*ofp
= fp
;
1221 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1222 return CTF_ERR
; /* errno is set for us. */
1224 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1225 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1227 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1228 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1230 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1231 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1233 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1234 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1236 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1239 /* Return the encoding for the specified INTEGER or FLOAT. */
1242 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1244 ctf_dict_t
*ofp
= fp
;
1246 const ctf_type_t
*tp
;
1250 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1251 return -1; /* errno is set for us. */
1253 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1255 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1259 *ep
= dtd
->dtd_u
.dtu_enc
;
1263 const ctf_slice_t
*slice
;
1264 ctf_encoding_t underlying_en
;
1265 ctf_id_t underlying
;
1267 slice
= &dtd
->dtd_u
.dtu_slice
;
1268 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1269 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1271 ep
->cte_format
= underlying_en
.cte_format
;
1272 ep
->cte_offset
= slice
->cts_offset
;
1273 ep
->cte_bits
= slice
->cts_bits
;
1277 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1282 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1284 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1287 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1288 ep
->cte_format
= CTF_INT_ENCODING (data
);
1289 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1290 ep
->cte_bits
= CTF_INT_BITS (data
);
1293 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1294 ep
->cte_format
= CTF_FP_ENCODING (data
);
1295 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1296 ep
->cte_bits
= CTF_FP_BITS (data
);
1300 const ctf_slice_t
*slice
;
1301 ctf_encoding_t underlying_en
;
1302 ctf_id_t underlying
;
1304 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1305 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1306 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1308 ep
->cte_format
= underlying_en
.cte_format
;
1309 ep
->cte_offset
= slice
->cts_offset
;
1310 ep
->cte_bits
= slice
->cts_bits
;
1314 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1321 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1328 else if (ltype
> rtype
)
1336 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1337 lfp
= lfp
->ctf_parent
;
1339 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1340 rfp
= rfp
->ctf_parent
;
1351 /* Return a boolean value indicating if two types are compatible. This function
1352 returns true if the two types are the same, or if they (or their ultimate
1353 base type) have the same encoding properties, or (for structs / unions /
1354 enums / forward declarations) if they have the same name and (for structs /
1355 unions) member count. */
1358 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1359 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1361 const ctf_type_t
*ltp
, *rtp
;
1362 ctf_encoding_t le
, re
;
1363 ctf_arinfo_t la
, ra
;
1364 uint32_t lkind
, rkind
;
1367 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1370 ltype
= ctf_type_resolve (lfp
, ltype
);
1371 lkind
= ctf_type_kind (lfp
, ltype
);
1373 rtype
= ctf_type_resolve (rfp
, rtype
);
1374 rkind
= ctf_type_kind (rfp
, rtype
);
1376 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1377 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1379 if (ltp
!= NULL
&& rtp
!= NULL
)
1380 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1381 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1383 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1384 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1394 memset (&le
, 0, sizeof (le
));
1395 memset (&re
, 0, sizeof (re
));
1396 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1397 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1398 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1400 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1401 rfp
, ctf_type_reference (rfp
, rtype
)));
1403 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1404 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1405 && la
.ctr_nelems
== ra
.ctr_nelems
1406 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1407 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1410 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1411 == ctf_type_size (rfp
, rtype
)));
1414 int lencoded
, rencoded
;
1415 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1416 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1418 if ((lencoded
!= rencoded
) ||
1419 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1424 return same_names
; /* No other checks required for these type kinds. */
1426 return 0; /* Should not get here since we did a resolve. */
1430 /* Return the number of members in a STRUCT or UNION, or the number of
1431 enumerators in an ENUM. The count does not include unnamed sub-members. */
1434 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1436 ctf_dict_t
*ofp
= fp
;
1437 const ctf_type_t
*tp
;
1440 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1441 return -1; /* errno is set for us. */
1443 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1444 return -1; /* errno is set for us. */
1446 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1448 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1449 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1451 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1454 /* Return the type and offset for a given member of a STRUCT or UNION. */
1457 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1458 ctf_membinfo_t
*mip
)
1460 ctf_dict_t
*ofp
= fp
;
1461 const ctf_type_t
*tp
;
1463 ssize_t size
, increment
;
1466 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1467 return -1; /* errno is set for us. */
1469 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1470 return -1; /* errno is set for us. */
1472 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1473 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1475 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1476 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1478 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1480 if (size
< CTF_LSTRUCT_THRESH
)
1482 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1485 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1487 const char *membname
= ctf_strptr (fp
, mp
->ctm_name
);
1489 if (membname
[0] == 0
1490 && (ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_STRUCT
1491 || ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_UNION
)
1492 && (ctf_member_info (fp
, mp
->ctm_type
, name
, mip
) == 0))
1495 if (strcmp (membname
, name
) == 0)
1497 mip
->ctm_type
= mp
->ctm_type
;
1498 mip
->ctm_offset
= mp
->ctm_offset
;
1505 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1508 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1510 const char *membname
= ctf_strptr (fp
, lmp
->ctlm_name
);
1512 if (membname
[0] == 0
1513 && (ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_STRUCT
1514 || ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_UNION
)
1515 && (ctf_member_info (fp
, lmp
->ctlm_type
, name
, mip
) == 0))
1518 if (strcmp (membname
, name
) == 0)
1520 mip
->ctm_type
= lmp
->ctlm_type
;
1521 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1531 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1532 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1534 if (dmd
->dmd_name
== NULL
1535 && (ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_STRUCT
1536 || ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_UNION
)
1537 && (ctf_member_info (fp
, dmd
->dmd_type
, name
, mip
) == 0))
1540 if (dmd
->dmd_name
!= NULL
1541 && strcmp (dmd
->dmd_name
, name
) == 0)
1543 mip
->ctm_type
= dmd
->dmd_type
;
1544 mip
->ctm_offset
= dmd
->dmd_offset
;
1550 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1553 /* Return the array type, index, and size information for the specified ARRAY. */
1556 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1558 ctf_dict_t
*ofp
= fp
;
1559 const ctf_type_t
*tp
;
1560 const ctf_array_t
*ap
;
1561 const ctf_dtdef_t
*dtd
;
1564 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1565 return -1; /* errno is set for us. */
1567 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1568 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1570 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1572 *arp
= dtd
->dtd_u
.dtu_arr
;
1576 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1578 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1579 arp
->ctr_contents
= ap
->cta_contents
;
1580 arp
->ctr_index
= ap
->cta_index
;
1581 arp
->ctr_nelems
= ap
->cta_nelems
;
1586 /* Convert the specified value to the corresponding enum tag name, if a
1587 matching name can be found. Otherwise NULL is returned. */
1590 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1592 ctf_dict_t
*ofp
= fp
;
1593 const ctf_type_t
*tp
;
1594 const ctf_enum_t
*ep
;
1595 const ctf_dtdef_t
*dtd
;
1599 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1600 return NULL
; /* errno is set for us. */
1602 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1603 return NULL
; /* errno is set for us. */
1605 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1607 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1611 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1613 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1615 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1617 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1619 if (ep
->cte_value
== value
)
1620 return (ctf_strptr (fp
, ep
->cte_name
));
1627 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1628 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1630 if (dmd
->dmd_value
== value
)
1631 return dmd
->dmd_name
;
1635 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1639 /* Convert the specified enum tag name to the corresponding value, if a
1640 matching name can be found. Otherwise CTF_ERR is returned. */
1643 ctf_enum_value (ctf_dict_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1645 ctf_dict_t
*ofp
= fp
;
1646 const ctf_type_t
*tp
;
1647 const ctf_enum_t
*ep
;
1648 const ctf_dtdef_t
*dtd
;
1652 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1653 return -1; /* errno is set for us. */
1655 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1656 return -1; /* errno is set for us. */
1658 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1660 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1664 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1666 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1668 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1670 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1672 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1675 *valp
= ep
->cte_value
;
1684 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1685 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1687 if (strcmp (dmd
->dmd_name
, name
) == 0)
1690 *valp
= dmd
->dmd_value
;
1696 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1700 /* Given a type ID relating to a function type, return info on return types and
1701 arg counts for that function. */
1704 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1706 const ctf_type_t
*tp
;
1708 const uint32_t *args
;
1709 const ctf_dtdef_t
*dtd
;
1710 ssize_t size
, increment
;
1712 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1713 return -1; /* errno is set for us. */
1715 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1716 return -1; /* errno is set for us. */
1718 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1719 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1721 if (kind
!= CTF_K_FUNCTION
)
1722 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1724 fip
->ctc_return
= tp
->ctt_type
;
1726 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1728 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1729 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1731 args
= dtd
->dtd_u
.dtu_argv
;
1733 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1735 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1742 /* Given a type ID relating to a function type, return the arguments for the
1746 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1748 const ctf_type_t
*tp
;
1749 const uint32_t *args
;
1750 const ctf_dtdef_t
*dtd
;
1751 ssize_t size
, increment
;
1754 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1755 return -1; /* errno is set for us. */
1757 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1758 return -1; /* errno is set for us. */
1760 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1761 return -1; /* errno is set for us. */
1763 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1765 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1766 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1768 args
= dtd
->dtd_u
.dtu_argv
;
1770 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1776 /* Recursively visit the members of any type. This function is used as the
1777 engine for ctf_type_visit, below. We resolve the input type, recursively
1778 invoke ourself for each type member if the type is a struct or union, and
1779 then invoke the callback function on the current type. If any callback
1780 returns non-zero, we abort and percolate the error code back up to the top. */
1783 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1784 void *arg
, const char *name
, unsigned long offset
, int depth
)
1786 ctf_id_t otype
= type
;
1787 const ctf_type_t
*tp
;
1788 const ctf_dtdef_t
*dtd
;
1789 ssize_t size
, increment
;
1793 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1794 return -1; /* errno is set for us. */
1796 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1797 return -1; /* errno is set for us. */
1799 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1802 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1804 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1807 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1809 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1811 if (size
< CTF_LSTRUCT_THRESH
)
1813 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1816 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1818 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1819 func
, arg
, ctf_strptr (fp
,
1821 offset
+ mp
->ctm_offset
,
1828 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1831 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1833 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1834 func
, arg
, ctf_strptr (fp
,
1836 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1846 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1847 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1849 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1850 dmd
->dmd_name
, dmd
->dmd_offset
,
1859 /* Recursively visit the members of any type. We pass the name, member
1860 type, and offset of each member to the specified callback function. */
1862 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1864 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));