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. */
928 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
930 const ctf_type_t
*tp
;
932 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
933 return NULL
; /* errno is set for us. */
935 return ctf_strraw (fp
, tp
->ctt_name
);
938 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
939 new dynamically-allocated string. */
942 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
944 const char *name
= ctf_type_name_raw (fp
, type
);
947 return strdup (name
);
952 /* Resolve the type down to a base type node, and then return the size
953 of the type storage in bytes. */
956 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
958 ctf_dict_t
*ofp
= fp
;
959 const ctf_type_t
*tp
;
963 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
964 return -1; /* errno is set for us. */
966 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
967 return -1; /* errno is set for us. */
969 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
972 return fp
->ctf_dmodel
->ctd_pointer
;
975 return 0; /* Function size is only known by symtab. */
978 return fp
->ctf_dmodel
->ctd_int
;
981 /* ctf_add_array() does not directly encode the element size, but
982 requires the user to multiply to determine the element size.
984 If ctf_get_ctt_size() returns nonzero, then use the recorded
987 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
990 if (ctf_array_info (ofp
, type
, &ar
) < 0
991 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
992 return -1; /* errno is set for us. */
994 return size
* ar
.ctr_nelems
;
997 /* Forwards do not have a meaningful size. */
998 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1000 default: /* including slices of enums, etc */
1001 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1005 /* Resolve the type down to a base type node, and then return the alignment
1006 needed for the type storage in bytes.
1008 XXX may need arch-dependent attention. */
1011 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
1013 const ctf_type_t
*tp
;
1014 ctf_dict_t
*ofp
= fp
;
1017 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1018 return -1; /* errno is set for us. */
1020 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1021 return -1; /* errno is set for us. */
1023 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1027 case CTF_K_FUNCTION
:
1028 return fp
->ctf_dmodel
->ctd_pointer
;
1033 if (ctf_array_info (ofp
, type
, &r
) < 0)
1034 return -1; /* errno is set for us. */
1035 return (ctf_type_align (ofp
, r
.ctr_contents
));
1044 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1046 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1047 ssize_t size
, increment
;
1050 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1051 vmp
= (unsigned char *) tp
+ increment
;
1053 if (kind
== CTF_K_STRUCT
)
1054 n
= MIN (n
, 1); /* Only use first member for structs. */
1056 if (size
< CTF_LSTRUCT_THRESH
)
1058 const ctf_member_t
*mp
= vmp
;
1059 for (; n
!= 0; n
--, mp
++)
1061 ssize_t am
= ctf_type_align (ofp
, mp
->ctm_type
);
1062 align
= MAX (align
, (size_t) am
);
1067 const ctf_lmember_t
*lmp
= vmp
;
1068 for (; n
!= 0; n
--, lmp
++)
1070 ssize_t am
= ctf_type_align (ofp
, lmp
->ctlm_type
);
1071 align
= MAX (align
, (size_t) am
);
1079 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1080 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1082 ssize_t am
= ctf_type_align (ofp
, dmd
->dmd_type
);
1083 align
= MAX (align
, (size_t) am
);
1084 if (kind
== CTF_K_STRUCT
)
1093 return fp
->ctf_dmodel
->ctd_int
;
1096 /* Forwards do not have a meaningful alignment. */
1097 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1099 default: /* including slices of enums, etc */
1100 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1104 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1107 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1109 const ctf_type_t
*tp
;
1111 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1112 return -1; /* errno is set for us. */
1114 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1117 /* Return the kind (CTF_K_* constant) for the specified type ID.
1118 Slices are considered to be of the same kind as the type sliced. */
1121 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1125 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1128 if (kind
== CTF_K_SLICE
)
1130 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1132 kind
= ctf_type_kind_unsliced (fp
, type
);
1138 /* Return the kind of this type, except, for forwards, return the kind of thing
1139 this is a forward to. */
1141 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1144 const ctf_type_t
*tp
;
1146 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1147 return -1; /* errno is set for us. */
1149 if (kind
!= CTF_K_FORWARD
)
1152 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1153 return -1; /* errno is set for us. */
1155 return tp
->ctt_type
;
1158 /* If the type is one that directly references another type (such as POINTER),
1159 then return the ID of the type to which it refers. */
1162 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1164 ctf_dict_t
*ofp
= fp
;
1165 const ctf_type_t
*tp
;
1167 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1168 return CTF_ERR
; /* errno is set for us. */
1170 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1174 case CTF_K_VOLATILE
:
1176 case CTF_K_RESTRICT
:
1177 return tp
->ctt_type
;
1178 /* Slices store their type in an unusual place. */
1182 const ctf_slice_t
*sp
;
1184 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1188 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1189 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1192 sp
= &dtd
->dtd_u
.dtu_slice
;
1194 return sp
->cts_type
;
1197 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1201 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1202 pointer to the given type, see if we can compute a pointer to the type
1203 resulting from resolving the type down to its base type and use that
1204 instead. This helps with cases where the CTF data includes "struct foo *"
1205 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1207 XXX what about parent dicts? */
1210 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1212 ctf_dict_t
*ofp
= fp
;
1215 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1216 return CTF_ERR
; /* errno is set for us. */
1218 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1219 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1221 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1222 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1224 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1225 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1227 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1228 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1230 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1233 /* Return the encoding for the specified INTEGER or FLOAT. */
1236 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1238 ctf_dict_t
*ofp
= fp
;
1240 const ctf_type_t
*tp
;
1244 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1245 return -1; /* errno is set for us. */
1247 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1249 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1253 *ep
= dtd
->dtd_u
.dtu_enc
;
1257 const ctf_slice_t
*slice
;
1258 ctf_encoding_t underlying_en
;
1259 ctf_id_t underlying
;
1261 slice
= &dtd
->dtd_u
.dtu_slice
;
1262 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1263 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1265 ep
->cte_format
= underlying_en
.cte_format
;
1266 ep
->cte_offset
= slice
->cts_offset
;
1267 ep
->cte_bits
= slice
->cts_bits
;
1271 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1276 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1278 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1281 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1282 ep
->cte_format
= CTF_INT_ENCODING (data
);
1283 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1284 ep
->cte_bits
= CTF_INT_BITS (data
);
1287 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1288 ep
->cte_format
= CTF_FP_ENCODING (data
);
1289 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1290 ep
->cte_bits
= CTF_FP_BITS (data
);
1294 const ctf_slice_t
*slice
;
1295 ctf_encoding_t underlying_en
;
1296 ctf_id_t underlying
;
1298 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1299 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1300 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1302 ep
->cte_format
= underlying_en
.cte_format
;
1303 ep
->cte_offset
= slice
->cts_offset
;
1304 ep
->cte_bits
= slice
->cts_bits
;
1308 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1315 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1322 else if (ltype
> rtype
)
1330 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1331 lfp
= lfp
->ctf_parent
;
1333 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1334 rfp
= rfp
->ctf_parent
;
1345 /* Return a boolean value indicating if two types are compatible. This function
1346 returns true if the two types are the same, or if they (or their ultimate
1347 base type) have the same encoding properties, or (for structs / unions /
1348 enums / forward declarations) if they have the same name and (for structs /
1349 unions) member count. */
1352 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1353 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1355 const ctf_type_t
*ltp
, *rtp
;
1356 ctf_encoding_t le
, re
;
1357 ctf_arinfo_t la
, ra
;
1358 uint32_t lkind
, rkind
;
1361 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1364 ltype
= ctf_type_resolve (lfp
, ltype
);
1365 lkind
= ctf_type_kind (lfp
, ltype
);
1367 rtype
= ctf_type_resolve (rfp
, rtype
);
1368 rkind
= ctf_type_kind (rfp
, rtype
);
1370 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1371 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1373 if (ltp
!= NULL
&& rtp
!= NULL
)
1374 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1375 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1377 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1378 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1388 memset (&le
, 0, sizeof (le
));
1389 memset (&re
, 0, sizeof (re
));
1390 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1391 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1392 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1394 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1395 rfp
, ctf_type_reference (rfp
, rtype
)));
1397 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1398 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1399 && la
.ctr_nelems
== ra
.ctr_nelems
1400 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1401 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1404 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1405 == ctf_type_size (rfp
, rtype
)));
1408 int lencoded
, rencoded
;
1409 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1410 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1412 if ((lencoded
!= rencoded
) ||
1413 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1418 return same_names
; /* No other checks required for these type kinds. */
1420 return 0; /* Should not get here since we did a resolve. */
1424 /* Return the number of members in a STRUCT or UNION, or the number of
1425 enumerators in an ENUM. The count does not include unnamed sub-members. */
1428 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1430 ctf_dict_t
*ofp
= fp
;
1431 const ctf_type_t
*tp
;
1434 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1435 return -1; /* errno is set for us. */
1437 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1438 return -1; /* errno is set for us. */
1440 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1442 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1443 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1445 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1448 /* Return the type and offset for a given member of a STRUCT or UNION. */
1451 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1452 ctf_membinfo_t
*mip
)
1454 ctf_dict_t
*ofp
= fp
;
1455 const ctf_type_t
*tp
;
1457 ssize_t size
, increment
;
1460 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1461 return -1; /* errno is set for us. */
1463 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1464 return -1; /* errno is set for us. */
1466 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1467 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1469 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1470 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1472 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1474 if (size
< CTF_LSTRUCT_THRESH
)
1476 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1479 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1481 const char *membname
= ctf_strptr (fp
, mp
->ctm_name
);
1483 if (membname
[0] == 0
1484 && (ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_STRUCT
1485 || ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_UNION
)
1486 && (ctf_member_info (fp
, mp
->ctm_type
, name
, mip
) == 0))
1489 if (strcmp (membname
, name
) == 0)
1491 mip
->ctm_type
= mp
->ctm_type
;
1492 mip
->ctm_offset
= mp
->ctm_offset
;
1499 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1502 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1504 const char *membname
= ctf_strptr (fp
, lmp
->ctlm_name
);
1506 if (membname
[0] == 0
1507 && (ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_STRUCT
1508 || ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_UNION
)
1509 && (ctf_member_info (fp
, lmp
->ctlm_type
, name
, mip
) == 0))
1512 if (strcmp (membname
, name
) == 0)
1514 mip
->ctm_type
= lmp
->ctlm_type
;
1515 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1525 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1526 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1528 if (dmd
->dmd_name
== NULL
1529 && (ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_STRUCT
1530 || ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_UNION
)
1531 && (ctf_member_info (fp
, dmd
->dmd_type
, name
, mip
) == 0))
1534 if (dmd
->dmd_name
!= NULL
1535 && strcmp (dmd
->dmd_name
, name
) == 0)
1537 mip
->ctm_type
= dmd
->dmd_type
;
1538 mip
->ctm_offset
= dmd
->dmd_offset
;
1544 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1547 /* Return the array type, index, and size information for the specified ARRAY. */
1550 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1552 ctf_dict_t
*ofp
= fp
;
1553 const ctf_type_t
*tp
;
1554 const ctf_array_t
*ap
;
1555 const ctf_dtdef_t
*dtd
;
1558 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1559 return -1; /* errno is set for us. */
1561 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1562 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1564 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1566 *arp
= dtd
->dtd_u
.dtu_arr
;
1570 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1572 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1573 arp
->ctr_contents
= ap
->cta_contents
;
1574 arp
->ctr_index
= ap
->cta_index
;
1575 arp
->ctr_nelems
= ap
->cta_nelems
;
1580 /* Convert the specified value to the corresponding enum tag name, if a
1581 matching name can be found. Otherwise NULL is returned. */
1584 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1586 ctf_dict_t
*ofp
= fp
;
1587 const ctf_type_t
*tp
;
1588 const ctf_enum_t
*ep
;
1589 const ctf_dtdef_t
*dtd
;
1593 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1594 return NULL
; /* errno is set for us. */
1596 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1597 return NULL
; /* errno is set for us. */
1599 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1601 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1605 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1607 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1609 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1611 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1613 if (ep
->cte_value
== value
)
1614 return (ctf_strptr (fp
, ep
->cte_name
));
1621 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1622 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1624 if (dmd
->dmd_value
== value
)
1625 return dmd
->dmd_name
;
1629 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1633 /* Convert the specified enum tag name to the corresponding value, if a
1634 matching name can be found. Otherwise CTF_ERR is returned. */
1637 ctf_enum_value (ctf_dict_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1639 ctf_dict_t
*ofp
= fp
;
1640 const ctf_type_t
*tp
;
1641 const ctf_enum_t
*ep
;
1642 const ctf_dtdef_t
*dtd
;
1646 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1647 return -1; /* errno is set for us. */
1649 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1650 return -1; /* errno is set for us. */
1652 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1654 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1658 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1660 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1662 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1664 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1666 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1669 *valp
= ep
->cte_value
;
1678 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1679 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1681 if (strcmp (dmd
->dmd_name
, name
) == 0)
1684 *valp
= dmd
->dmd_value
;
1690 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1694 /* Given a type ID relating to a function type, return info on return types and
1695 arg counts for that function. */
1698 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1700 const ctf_type_t
*tp
;
1702 const uint32_t *args
;
1703 const ctf_dtdef_t
*dtd
;
1704 ssize_t size
, increment
;
1706 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1707 return -1; /* errno is set for us. */
1709 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1710 return -1; /* errno is set for us. */
1712 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1713 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1715 if (kind
!= CTF_K_FUNCTION
)
1716 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1718 fip
->ctc_return
= tp
->ctt_type
;
1720 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1722 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1723 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1725 args
= dtd
->dtd_u
.dtu_argv
;
1727 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1729 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1736 /* Given a type ID relating to a function type, return the arguments for the
1740 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1742 const ctf_type_t
*tp
;
1743 const uint32_t *args
;
1744 const ctf_dtdef_t
*dtd
;
1745 ssize_t size
, increment
;
1748 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1749 return -1; /* errno is set for us. */
1751 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1752 return -1; /* errno is set for us. */
1754 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1755 return -1; /* errno is set for us. */
1757 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1759 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1760 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1762 args
= dtd
->dtd_u
.dtu_argv
;
1764 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1770 /* Recursively visit the members of any type. This function is used as the
1771 engine for ctf_type_visit, below. We resolve the input type, recursively
1772 invoke ourself for each type member if the type is a struct or union, and
1773 then invoke the callback function on the current type. If any callback
1774 returns non-zero, we abort and percolate the error code back up to the top. */
1777 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1778 void *arg
, const char *name
, unsigned long offset
, int depth
)
1780 ctf_id_t otype
= type
;
1781 const ctf_type_t
*tp
;
1782 const ctf_dtdef_t
*dtd
;
1783 ssize_t size
, increment
;
1787 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1788 return -1; /* errno is set for us. */
1790 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1791 return -1; /* errno is set for us. */
1793 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1796 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1798 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1801 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1803 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1805 if (size
< CTF_LSTRUCT_THRESH
)
1807 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1810 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1812 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1813 func
, arg
, ctf_strptr (fp
,
1815 offset
+ mp
->ctm_offset
,
1822 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1825 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1827 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1828 func
, arg
, ctf_strptr (fp
,
1830 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1840 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1841 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1843 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1844 dmd
->dmd_name
, dmd
->dmd_offset
,
1853 /* Recursively visit the members of any type. We pass the name, member
1854 type, and offset of each member to the specified callback function. */
1856 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1858 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));