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
)
49 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
;
104 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
108 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
109 i
->u
.ctn_mp
= (const ctf_member_t
*) ((uintptr_t) tp
+ increment
);
111 i
->u
.ctn_lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+ increment
);
114 i
->u
.ctn_lmp
= (const ctf_lmember_t
*) dtd
->dtd_vlen
;
119 if ((void (*) (void)) ctf_member_next
!= i
->ctn_iter_fun
)
120 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
));
122 if (ofp
!= i
->cu
.ctn_fp
)
123 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
));
125 /* Resolve to the native dict of this type. */
126 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
127 return (ctf_set_errno (ofp
, ECTF_NOPARENT
));
129 /* When we hit an unnamed struct/union member, we set ctn_type to indicate
130 that we are inside one, then return the unnamed member: on the next call,
131 we must skip over top-level member iteration in favour of iteration within
132 the sub-struct until it later turns out that that iteration has ended. */
140 /* Dynamic structures in read-write dicts always use lmembers. */
141 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
142 && !(fp
->ctf_flags
& LCTF_RDWR
))
144 const char *membname
= ctf_strptr (fp
, i
->u
.ctn_mp
->ctm_name
);
149 *membtype
= i
->u
.ctn_mp
->ctm_type
;
150 offset
= i
->u
.ctn_mp
->ctm_offset
;
153 && (ctf_type_kind (fp
, i
->u
.ctn_mp
->ctm_type
) == CTF_K_STRUCT
154 || ctf_type_kind (fp
, i
->u
.ctn_mp
->ctm_type
) == CTF_K_UNION
))
155 i
->ctn_type
= i
->u
.ctn_mp
->ctm_type
;
161 const char *membname
= ctf_strptr (fp
, i
->u
.ctn_lmp
->ctlm_name
);
166 *membtype
= i
->u
.ctn_lmp
->ctlm_type
;
167 offset
= (unsigned long) CTF_LMEM_OFFSET (i
->u
.ctn_lmp
);
170 && (ctf_type_kind (fp
, i
->u
.ctn_lmp
->ctlm_type
) == CTF_K_STRUCT
171 || ctf_type_kind (fp
, i
->u
.ctn_lmp
->ctlm_type
) == CTF_K_UNION
))
172 i
->ctn_type
= i
->u
.ctn_lmp
->ctlm_type
;
178 /* The callers might want automatic recursive sub-struct traversal. */
179 if (!(flags
& CTF_MN_RECURSE
))
182 /* Sub-struct traversal starting? Take note of the offset of this member,
183 for later boosting of sub-struct members' offsets. */
185 i
->ctn_increment
= offset
;
187 /* Traversing a sub-struct? Just return it, with the offset adjusted. */
190 ssize_t ret
= ctf_member_next (fp
, i
->ctn_type
, &i
->ctn_next
, name
,
194 return ret
+ i
->ctn_increment
;
196 if (ctf_errno (fp
) != ECTF_NEXT_END
)
198 ctf_next_destroy (i
);
201 return ret
; /* errno is set for us. */
204 if (!ctf_assert (fp
, (i
->ctn_next
== NULL
)))
205 return -1; /* errno is set for us. */
208 /* This sub-struct has ended: on to the next real member. */
215 ctf_next_destroy (i
);
217 return ctf_set_errno (ofp
, ECTF_NEXT_END
);
220 /* Iterate over the members of an ENUM. We pass the string name and associated
221 integer value of each enum element to the specified callback function. */
224 ctf_enum_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
226 ctf_next_t
*i
= NULL
;
230 while ((name
= ctf_enum_next (fp
, type
, &i
, &val
)) != NULL
)
233 if ((rc
= func (name
, val
, arg
)) != 0)
235 ctf_next_destroy (i
);
239 if (ctf_errno (fp
) != ECTF_NEXT_END
)
240 return -1; /* errno is set for us. */
245 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
246 NULL at end of iteration or error, and optionally passing back the
247 enumerand's integer VALue. */
250 ctf_enum_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
253 ctf_dict_t
*ofp
= fp
;
260 const ctf_type_t
*tp
;
263 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
264 return NULL
; /* errno is set for us. */
266 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
267 return NULL
; /* errno is set for us. */
269 if ((i
= ctf_next_create ()) == NULL
)
271 ctf_set_errno (ofp
, ENOMEM
);
276 (void) ctf_get_ctt_size (fp
, tp
, NULL
,
278 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
280 if (kind
!= CTF_K_ENUM
)
282 ctf_next_destroy (i
);
283 ctf_set_errno (ofp
, ECTF_NOTENUM
);
287 dtd
= ctf_dynamic_type (fp
, type
);
288 i
->ctn_iter_fun
= (void (*) (void)) ctf_enum_next
;
289 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
292 i
->u
.ctn_en
= (const ctf_enum_t
*) ((uintptr_t) tp
+
295 i
->u
.ctn_en
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
300 if ((void (*) (void)) ctf_enum_next
!= i
->ctn_iter_fun
)
302 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
);
306 if (ofp
!= i
->cu
.ctn_fp
)
308 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
);
312 /* Resolve to the native dict of this type. */
313 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
315 ctf_set_errno (ofp
, ECTF_NOPARENT
);
322 name
= ctf_strptr (fp
, i
->u
.ctn_en
->cte_name
);
324 *val
= i
->u
.ctn_en
->cte_value
;
331 ctf_next_destroy (i
);
333 ctf_set_errno (ofp
, ECTF_NEXT_END
);
337 /* Iterate over every root (user-visible) type in the given CTF dict.
338 We pass the type ID of each type to the specified callback function.
340 Does not traverse parent types: you have to do that explicitly. This is by
341 design, to avoid traversing them more than once if traversing many children
342 of a single parent. */
345 ctf_type_iter (ctf_dict_t
*fp
, ctf_type_f
*func
, void *arg
)
347 ctf_next_t
*i
= NULL
;
350 while ((type
= ctf_type_next (fp
, &i
, NULL
, 0)) != CTF_ERR
)
353 if ((rc
= func (type
, arg
)) != 0)
355 ctf_next_destroy (i
);
359 if (ctf_errno (fp
) != ECTF_NEXT_END
)
360 return -1; /* errno is set for us. */
365 /* Iterate over every type in the given CTF dict, user-visible or not.
366 We pass the type ID of each type to the specified callback function.
368 Does not traverse parent types: you have to do that explicitly. This is by
369 design, to avoid traversing them more than once if traversing many children
370 of a single parent. */
373 ctf_type_iter_all (ctf_dict_t
*fp
, ctf_type_all_f
*func
, void *arg
)
375 ctf_next_t
*i
= NULL
;
379 while ((type
= ctf_type_next (fp
, &i
, &flag
, 1)) != CTF_ERR
)
382 if ((rc
= func (type
, flag
, arg
)) != 0)
384 ctf_next_destroy (i
);
388 if (ctf_errno (fp
) != ECTF_NEXT_END
)
389 return -1; /* errno is set for us. */
394 /* Iterate over every type in the given CTF dict, optionally including
395 non-user-visible types, returning each type ID and hidden flag in turn.
396 Returns CTF_ERR on end of iteration or error.
398 Does not traverse parent types: you have to do that explicitly. This is by
399 design, to avoid traversing them more than once if traversing many children
400 of a single parent. */
403 ctf_type_next (ctf_dict_t
*fp
, ctf_next_t
**it
, int *flag
, int want_hidden
)
409 if ((i
= ctf_next_create ()) == NULL
)
410 return ctf_set_errno (fp
, ENOMEM
);
414 i
->ctn_iter_fun
= (void (*) (void)) ctf_type_next
;
418 if ((void (*) (void)) ctf_type_next
!= i
->ctn_iter_fun
)
419 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
421 if (fp
!= i
->cu
.ctn_fp
)
422 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
424 while (i
->ctn_type
<= fp
->ctf_typemax
)
426 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, i
->ctn_type
);
428 if ((!want_hidden
) && (!LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)))
435 *flag
= LCTF_INFO_ISROOT (fp
, tp
->ctt_info
);
436 return LCTF_INDEX_TO_TYPE (fp
, i
->ctn_type
++, fp
->ctf_flags
& LCTF_CHILD
);
438 ctf_next_destroy (i
);
440 return ctf_set_errno (fp
, ECTF_NEXT_END
);
443 /* Iterate over every variable in the given CTF dict, in arbitrary order.
444 We pass the name of each variable to the specified callback function. */
447 ctf_variable_iter (ctf_dict_t
*fp
, ctf_variable_f
*func
, void *arg
)
449 ctf_next_t
*i
= NULL
;
453 while ((type
= ctf_variable_next (fp
, &i
, &name
)) != CTF_ERR
)
456 if ((rc
= func (name
, type
, arg
)) != 0)
458 ctf_next_destroy (i
);
462 if (ctf_errno (fp
) != ECTF_NEXT_END
)
463 return -1; /* errno is set for us. */
468 /* Iterate over every variable in the given CTF dict, in arbitrary order,
469 returning the name and type of each variable in turn. The name argument is
470 not optional. Returns CTF_ERR on end of iteration or error. */
473 ctf_variable_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
)
477 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
478 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
482 if ((i
= ctf_next_create ()) == NULL
)
483 return ctf_set_errno (fp
, ENOMEM
);
486 i
->ctn_iter_fun
= (void (*) (void)) ctf_variable_next
;
487 if (fp
->ctf_flags
& LCTF_RDWR
)
488 i
->u
.ctn_dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
492 if ((void (*) (void)) ctf_variable_next
!= i
->ctn_iter_fun
)
493 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
495 if (fp
!= i
->cu
.ctn_fp
)
496 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
498 if (!(fp
->ctf_flags
& LCTF_RDWR
))
500 if (i
->ctn_n
>= fp
->ctf_nvars
)
503 *name
= ctf_strptr (fp
, fp
->ctf_vars
[i
->ctn_n
].ctv_name
);
504 return fp
->ctf_vars
[i
->ctn_n
++].ctv_type
;
510 if (i
->u
.ctn_dvd
== NULL
)
513 *name
= i
->u
.ctn_dvd
->dvd_name
;
514 id
= i
->u
.ctn_dvd
->dvd_type
;
515 i
->u
.ctn_dvd
= ctf_list_next (i
->u
.ctn_dvd
);
520 ctf_next_destroy (i
);
522 return ctf_set_errno (fp
, ECTF_NEXT_END
);
525 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
526 RESTRICT nodes until we reach a "base" type node. This is useful when
527 we want to follow a type ID to a node that has members or a size. To guard
528 against infinite loops, we implement simplified cycle detection and check
529 each link against itself, the previous node, and the topmost node.
531 Does not drill down through slices to their contained type.
533 Callers of this function must not presume that a type it returns must have a
534 valid ctt_size: forwards do not, and must be separately handled. */
537 ctf_type_resolve (ctf_dict_t
*fp
, ctf_id_t type
)
539 ctf_id_t prev
= type
, otype
= type
;
540 ctf_dict_t
*ofp
= fp
;
541 const ctf_type_t
*tp
;
544 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
546 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
548 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
554 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
555 || tp
->ctt_type
== prev
)
557 ctf_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
559 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
568 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
571 return CTF_ERR
; /* errno is set for us. */
574 /* Like ctf_type_resolve(), but traverse down through slices to their contained
578 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
580 const ctf_type_t
*tp
;
582 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
585 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
586 return CTF_ERR
; /* errno is set for us. */
588 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
589 return ctf_type_reference (fp
, type
);
593 /* Return the native dict of a given type: if called on a child and the
594 type is in the parent, return the parent. Needed if you plan to access
595 the type directly, without using the API. */
597 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
599 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
600 return fp
->ctf_parent
;
605 /* Look up a name in the given name table, in the appropriate hash given the
606 kind of the identifier. The name is a raw, undecorated identifier. */
608 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
610 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
613 /* Look up a name in the given name table, in the appropriate hash given the
614 readability state of the dictionary. The name is a raw, undecorated
617 ctf_id_t
ctf_lookup_by_rawhash (ctf_dict_t
*fp
, ctf_names_t
*np
, const char *name
)
621 if (fp
->ctf_flags
& LCTF_RDWR
)
622 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
624 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
628 /* Lookup the given type ID and return its name as a new dynamically-allocated
632 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
635 ctf_decl_node_t
*cdp
;
636 ctf_decl_prec_t prec
, lp
, rp
;
641 if (fp
== NULL
&& type
== CTF_ERR
)
642 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
645 ctf_decl_push (&cd
, fp
, type
);
650 ctf_set_errno (fp
, cd
.cd_err
);
654 /* If the type graph's order conflicts with lexical precedence order
655 for pointers or arrays, then we need to surround the declarations at
656 the corresponding lexical precedence with parentheses. This can
657 result in either a parenthesized pointer (*) as in int (*)() or
658 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
660 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
661 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
663 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
664 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
666 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
668 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
670 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
671 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
673 ctf_dict_t
*rfp
= fp
;
674 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
675 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
677 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
678 ctf_decl_sprintf (&cd
, " ");
682 ctf_decl_sprintf (&cd
, "(");
686 switch (cdp
->cd_kind
)
691 /* Integers, floats, and typedefs must always be named types. */
695 ctf_set_errno (fp
, ECTF_CORRUPT
);
700 ctf_decl_sprintf (&cd
, "%s", name
);
703 ctf_decl_sprintf (&cd
, "*");
706 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
712 ctf_id_t
*argv
= NULL
;
714 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
715 goto err
; /* errno is set for us. */
717 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
719 ctf_set_errno (rfp
, errno
);
723 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
724 fi
.ctc_argc
, argv
) < 0)
725 goto err
; /* errno is set for us. */
727 ctf_decl_sprintf (&cd
, "(*) (");
728 for (i
= 0; i
< fi
.ctc_argc
; i
++)
730 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
733 goto err
; /* errno is set for us. */
734 ctf_decl_sprintf (&cd
, "%s", arg
);
737 if ((i
< fi
.ctc_argc
- 1)
738 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
739 ctf_decl_sprintf (&cd
, ", ");
742 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
743 ctf_decl_sprintf (&cd
, "...");
744 ctf_decl_sprintf (&cd
, ")");
756 ctf_decl_sprintf (&cd
, "struct %s", name
);
759 ctf_decl_sprintf (&cd
, "union %s", name
);
762 ctf_decl_sprintf (&cd
, "enum %s", name
);
766 switch (ctf_type_kind_forwarded (fp
, cdp
->cd_type
))
769 ctf_decl_sprintf (&cd
, "struct %s", name
);
772 ctf_decl_sprintf (&cd
, "union %s", name
);
775 ctf_decl_sprintf (&cd
, "enum %s", name
);
778 ctf_set_errno (fp
, ECTF_CORRUPT
);
785 ctf_decl_sprintf (&cd
, "volatile");
788 ctf_decl_sprintf (&cd
, "const");
791 ctf_decl_sprintf (&cd
, "restrict");
799 ctf_decl_sprintf (&cd
, ")");
803 (void) ctf_set_errno (fp
, ENOMEM
);
805 buf
= ctf_decl_buf (&cd
);
811 /* Lookup the given type ID and print a string name for it into buf. Return
812 the actual number of bytes (not including \0) needed to format the name. */
815 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
817 char *str
= ctf_type_aname (fp
, type
);
821 return CTF_ERR
; /* errno is set for us. */
824 snprintf (buf
, len
, "%s", str
);
828 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
833 /* Lookup the given type ID and print a string name for it into buf. If buf
834 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
837 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
839 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
840 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
843 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
844 The name will live as long as its ctf_dict_t does.
846 The only decoration is that a NULL return always means an error: nameless
847 types return a null string. */
850 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
852 const ctf_type_t
*tp
;
854 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
855 return NULL
; /* errno is set for us. */
857 if (tp
->ctt_name
== 0)
860 return ctf_strraw (fp
, tp
->ctt_name
);
863 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
864 new dynamically-allocated string. */
867 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
869 const char *name
= ctf_type_name_raw (fp
, type
);
872 return strdup (name
);
877 /* Resolve the type down to a base type node, and then return the size
878 of the type storage in bytes. */
881 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
883 ctf_dict_t
*ofp
= fp
;
884 const ctf_type_t
*tp
;
888 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
889 return -1; /* errno is set for us. */
891 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
892 return -1; /* errno is set for us. */
894 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
897 return fp
->ctf_dmodel
->ctd_pointer
;
900 return 0; /* Function size is only known by symtab. */
903 return fp
->ctf_dmodel
->ctd_int
;
906 /* ctf_add_array() does not directly encode the element size, but
907 requires the user to multiply to determine the element size.
909 If ctf_get_ctt_size() returns nonzero, then use the recorded
912 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
915 if (ctf_array_info (ofp
, type
, &ar
) < 0
916 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
917 return -1; /* errno is set for us. */
919 return size
* ar
.ctr_nelems
;
922 /* Forwards do not have a meaningful size. */
923 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
925 default: /* including slices of enums, etc */
926 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
930 /* Resolve the type down to a base type node, and then return the alignment
931 needed for the type storage in bytes.
933 XXX may need arch-dependent attention. */
936 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
938 const ctf_type_t
*tp
;
939 ctf_dict_t
*ofp
= fp
;
942 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
943 return -1; /* errno is set for us. */
945 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
946 return -1; /* errno is set for us. */
948 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
953 return fp
->ctf_dmodel
->ctd_pointer
;
958 if (ctf_array_info (ofp
, type
, &r
) < 0)
959 return -1; /* errno is set for us. */
960 return (ctf_type_align (ofp
, r
.ctr_contents
));
970 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
973 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
974 ssize_t size
, increment
;
977 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
980 vmp
= (unsigned char *) tp
+ increment
;
984 if (kind
== CTF_K_STRUCT
)
985 n
= MIN (n
, 1); /* Only use first member for structs. */
987 if (size
< CTF_LSTRUCT_THRESH
&& !dynamic
)
989 const ctf_member_t
*mp
= vmp
;
990 for (; n
!= 0; n
--, mp
++)
992 ssize_t am
= ctf_type_align (ofp
, mp
->ctm_type
);
993 align
= MAX (align
, (size_t) am
);
998 const ctf_lmember_t
*lmp
= vmp
;
999 for (; n
!= 0; n
--, lmp
++)
1001 ssize_t am
= ctf_type_align (ofp
, lmp
->ctlm_type
);
1002 align
= MAX (align
, (size_t) am
);
1009 return fp
->ctf_dmodel
->ctd_int
;
1012 /* Forwards do not have a meaningful alignment. */
1013 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1015 default: /* including slices of enums, etc */
1016 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1020 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1023 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1025 const ctf_type_t
*tp
;
1027 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1028 return -1; /* errno is set for us. */
1030 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1033 /* Return the kind (CTF_K_* constant) for the specified type ID.
1034 Slices are considered to be of the same kind as the type sliced. */
1037 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1041 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1044 if (kind
== CTF_K_SLICE
)
1046 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1048 kind
= ctf_type_kind_unsliced (fp
, type
);
1054 /* Return the kind of this type, except, for forwards, return the kind of thing
1055 this is a forward to. */
1057 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1060 const ctf_type_t
*tp
;
1062 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1063 return -1; /* errno is set for us. */
1065 if (kind
!= CTF_K_FORWARD
)
1068 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1069 return -1; /* errno is set for us. */
1071 return tp
->ctt_type
;
1074 /* If the type is one that directly references another type (such as POINTER),
1075 then return the ID of the type to which it refers. */
1078 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1080 ctf_dict_t
*ofp
= fp
;
1081 const ctf_type_t
*tp
;
1083 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1084 return CTF_ERR
; /* errno is set for us. */
1086 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1090 case CTF_K_VOLATILE
:
1092 case CTF_K_RESTRICT
:
1093 return tp
->ctt_type
;
1094 /* Slices store their type in an unusual place. */
1098 const ctf_slice_t
*sp
;
1100 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1104 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1105 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1108 sp
= (const ctf_slice_t
*) dtd
->dtd_vlen
;
1110 return sp
->cts_type
;
1113 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1117 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1118 pointer to the given type, see if we can compute a pointer to the type
1119 resulting from resolving the type down to its base type and use that
1120 instead. This helps with cases where the CTF data includes "struct foo *"
1121 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1123 XXX what about parent dicts? */
1126 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1128 ctf_dict_t
*ofp
= fp
;
1131 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1132 return CTF_ERR
; /* errno is set for us. */
1134 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1135 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1137 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1138 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1140 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1141 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1143 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1144 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1146 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1149 /* Return the encoding for the specified INTEGER or FLOAT. */
1152 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1154 ctf_dict_t
*ofp
= fp
;
1156 const ctf_type_t
*tp
;
1158 const unsigned char *vlen
;
1161 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1162 return -1; /* errno is set for us. */
1164 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1165 vlen
= dtd
->dtd_vlen
;
1168 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1169 vlen
= (const unsigned char *) ((uintptr_t) tp
+ increment
);
1172 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1175 data
= *(const uint32_t *) vlen
;
1176 ep
->cte_format
= CTF_INT_ENCODING (data
);
1177 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1178 ep
->cte_bits
= CTF_INT_BITS (data
);
1181 data
= *(const uint32_t *) vlen
;
1182 ep
->cte_format
= CTF_FP_ENCODING (data
);
1183 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1184 ep
->cte_bits
= CTF_FP_BITS (data
);
1188 const ctf_slice_t
*slice
;
1189 ctf_encoding_t underlying_en
;
1190 ctf_id_t underlying
;
1192 slice
= (ctf_slice_t
*) vlen
;
1193 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1194 if (ctf_type_encoding (fp
, underlying
, &underlying_en
) < 0)
1195 return -1; /* errno is set for us. */
1197 ep
->cte_format
= underlying_en
.cte_format
;
1198 ep
->cte_offset
= slice
->cts_offset
;
1199 ep
->cte_bits
= slice
->cts_bits
;
1203 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1210 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1217 else if (ltype
> rtype
)
1225 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1226 lfp
= lfp
->ctf_parent
;
1228 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1229 rfp
= rfp
->ctf_parent
;
1240 /* Return a boolean value indicating if two types are compatible. This function
1241 returns true if the two types are the same, or if they (or their ultimate
1242 base type) have the same encoding properties, or (for structs / unions /
1243 enums / forward declarations) if they have the same name and (for structs /
1244 unions) member count. */
1247 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1248 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1250 const ctf_type_t
*ltp
, *rtp
;
1251 ctf_encoding_t le
, re
;
1252 ctf_arinfo_t la
, ra
;
1253 uint32_t lkind
, rkind
;
1256 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1259 ltype
= ctf_type_resolve (lfp
, ltype
);
1260 lkind
= ctf_type_kind (lfp
, ltype
);
1262 rtype
= ctf_type_resolve (rfp
, rtype
);
1263 rkind
= ctf_type_kind (rfp
, rtype
);
1265 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1266 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1268 if (ltp
!= NULL
&& rtp
!= NULL
)
1269 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1270 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1272 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1273 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1283 memset (&le
, 0, sizeof (le
));
1284 memset (&re
, 0, sizeof (re
));
1285 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1286 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1287 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1289 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1290 rfp
, ctf_type_reference (rfp
, rtype
)));
1292 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1293 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1294 && la
.ctr_nelems
== ra
.ctr_nelems
1295 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1296 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1299 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1300 == ctf_type_size (rfp
, rtype
)));
1303 int lencoded
, rencoded
;
1304 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1305 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1307 if ((lencoded
!= rencoded
) ||
1308 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1313 return same_names
; /* No other checks required for these type kinds. */
1315 return 0; /* Should not get here since we did a resolve. */
1319 /* Return the number of members in a STRUCT or UNION, or the number of
1320 enumerators in an ENUM. The count does not include unnamed sub-members. */
1323 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1325 ctf_dict_t
*ofp
= fp
;
1326 const ctf_type_t
*tp
;
1329 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1330 return -1; /* errno is set for us. */
1332 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1333 return -1; /* errno is set for us. */
1335 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1337 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1338 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1340 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1343 /* Return the type and offset for a given member of a STRUCT or UNION. */
1346 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1347 ctf_membinfo_t
*mip
)
1349 ctf_dict_t
*ofp
= fp
;
1350 const ctf_type_t
*tp
;
1353 ssize_t size
, increment
;
1357 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1358 return -1; /* errno is set for us. */
1360 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1361 return -1; /* errno is set for us. */
1363 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1364 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1366 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1367 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1369 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1373 vmp
= (unsigned char *) tp
+ increment
;
1375 vmp
= dtd
->dtd_vlen
;
1377 if (size
< CTF_LSTRUCT_THRESH
&& !dynamic
)
1379 const ctf_member_t
*mp
= vmp
;
1381 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1383 const char *membname
= ctf_strptr (fp
, mp
->ctm_name
);
1385 if (membname
[0] == 0
1386 && (ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_STRUCT
1387 || ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_UNION
)
1388 && (ctf_member_info (fp
, mp
->ctm_type
, name
, mip
) == 0))
1391 if (strcmp (membname
, name
) == 0)
1393 mip
->ctm_type
= mp
->ctm_type
;
1394 mip
->ctm_offset
= mp
->ctm_offset
;
1401 const ctf_lmember_t
*lmp
= vmp
;
1403 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1405 const char *membname
= ctf_strptr (fp
, lmp
->ctlm_name
);
1407 if (membname
[0] == 0
1408 && (ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_STRUCT
1409 || ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_UNION
)
1410 && (ctf_member_info (fp
, lmp
->ctlm_type
, name
, mip
) == 0))
1413 if (strcmp (membname
, name
) == 0)
1415 mip
->ctm_type
= lmp
->ctlm_type
;
1416 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1422 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1425 /* Return the array type, index, and size information for the specified ARRAY. */
1428 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1430 ctf_dict_t
*ofp
= fp
;
1431 const ctf_type_t
*tp
;
1432 const ctf_array_t
*ap
;
1433 const ctf_dtdef_t
*dtd
;
1436 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1437 return -1; /* errno is set for us. */
1439 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1440 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1442 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1443 ap
= (const ctf_array_t
*) dtd
->dtd_vlen
;
1446 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1447 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1449 arp
->ctr_contents
= ap
->cta_contents
;
1450 arp
->ctr_index
= ap
->cta_index
;
1451 arp
->ctr_nelems
= ap
->cta_nelems
;
1456 /* Convert the specified value to the corresponding enum tag name, if a
1457 matching name can be found. Otherwise NULL is returned. */
1460 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1462 ctf_dict_t
*ofp
= fp
;
1463 const ctf_type_t
*tp
;
1464 const ctf_enum_t
*ep
;
1465 const ctf_dtdef_t
*dtd
;
1469 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1470 return NULL
; /* errno is set for us. */
1472 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1473 return NULL
; /* errno is set for us. */
1475 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1477 ctf_set_errno (ofp
, ECTF_NOTENUM
);
1481 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1483 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1484 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1486 ep
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
1488 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1490 if (ep
->cte_value
== value
)
1491 return (ctf_strptr (fp
, ep
->cte_name
));
1494 ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1498 /* Convert the specified enum tag name to the corresponding value, if a
1499 matching name can be found. Otherwise CTF_ERR is returned. */
1502 ctf_enum_value (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
, int *valp
)
1504 ctf_dict_t
*ofp
= fp
;
1505 const ctf_type_t
*tp
;
1506 const ctf_enum_t
*ep
;
1507 const ctf_dtdef_t
*dtd
;
1511 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1512 return -1; /* errno is set for us. */
1514 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1515 return -1; /* errno is set for us. */
1517 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1519 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1523 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1525 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1526 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1528 ep
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
1530 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1532 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1535 *valp
= ep
->cte_value
;
1540 ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1544 /* Given a type ID relating to a function type, return info on return types and
1545 arg counts for that function. */
1548 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1550 const ctf_type_t
*tp
;
1552 const uint32_t *args
;
1553 const ctf_dtdef_t
*dtd
;
1554 ssize_t size
, increment
;
1556 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1557 return -1; /* errno is set for us. */
1559 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1560 return -1; /* errno is set for us. */
1562 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1563 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1565 if (kind
!= CTF_K_FUNCTION
)
1566 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1568 fip
->ctc_return
= tp
->ctt_type
;
1570 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1572 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1573 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1575 args
= (uint32_t *) dtd
->dtd_vlen
;
1577 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1579 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1586 /* Given a type ID relating to a function type, return the arguments for the
1590 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1592 const ctf_type_t
*tp
;
1593 const uint32_t *args
;
1594 const ctf_dtdef_t
*dtd
;
1595 ssize_t size
, increment
;
1598 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1599 return -1; /* errno is set for us. */
1601 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1602 return -1; /* errno is set for us. */
1604 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1605 return -1; /* errno is set for us. */
1607 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1609 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1610 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1612 args
= (uint32_t *) dtd
->dtd_vlen
;
1614 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1620 /* Recursively visit the members of any type. This function is used as the
1621 engine for ctf_type_visit, below. We resolve the input type, recursively
1622 invoke ourself for each type member if the type is a struct or union, and
1623 then invoke the callback function on the current type. If any callback
1624 returns non-zero, we abort and percolate the error code back up to the top. */
1627 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1628 void *arg
, const char *name
, unsigned long offset
, int depth
)
1630 ctf_id_t otype
= type
;
1631 const ctf_type_t
*tp
;
1632 const ctf_dtdef_t
*dtd
;
1634 ssize_t size
, increment
;
1639 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1640 return -1; /* errno is set for us. */
1642 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1643 return -1; /* errno is set for us. */
1645 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1648 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1650 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1653 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1655 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1659 vmp
= (unsigned char *) tp
+ increment
;
1661 vmp
= dtd
->dtd_vlen
;
1663 if (size
< CTF_LSTRUCT_THRESH
&& !dynamic
)
1665 const ctf_member_t
*mp
= vmp
;
1667 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1669 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1670 func
, arg
, ctf_strptr (fp
,
1672 offset
+ mp
->ctm_offset
,
1679 const ctf_lmember_t
*lmp
= vmp
;
1681 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1683 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1684 func
, arg
, ctf_strptr (fp
,
1686 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1695 /* Recursively visit the members of any type. We pass the name, member
1696 type, and offset of each member to the specified callback function. */
1698 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1700 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));