1 /* Type handling functions.
2 Copyright (C) 2019-2024 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 /* Expand a structure element into the passed-in ctf_lmember_t. */
41 ctf_struct_member (ctf_dict_t
*fp
, ctf_lmember_t
*dst
, const ctf_type_t
*tp
,
42 unsigned char *vlen
, size_t vbytes
, size_t n
)
44 if (!ctf_assert (fp
, n
< LCTF_INFO_VLEN (fp
, tp
->ctt_info
)))
45 return -1; /* errno is set for us. */
48 if (tp
->ctt_size
== CTF_LSIZE_SENT
)
50 ctf_lmember_t
*lmp
= (ctf_lmember_t
*) vlen
;
52 if (!ctf_assert (fp
, (n
+ 1) * sizeof (ctf_lmember_t
) <= vbytes
))
53 return -1; /* errno is set for us. */
55 memcpy (dst
, &lmp
[n
], sizeof (ctf_lmember_t
));
59 ctf_member_t
*mp
= (ctf_member_t
*) vlen
;
60 dst
->ctlm_name
= mp
[n
].ctm_name
;
61 dst
->ctlm_type
= mp
[n
].ctm_type
;
62 dst
->ctlm_offsetlo
= mp
[n
].ctm_offset
;
63 dst
->ctlm_offsethi
= 0;
68 /* Iterate over the members of a STRUCT or UNION. We pass the name, member
69 type, and offset of each member to the specified callback function. */
72 ctf_member_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_member_f
*func
, void *arg
)
79 while ((offset
= ctf_member_next (fp
, type
, &i
, &name
, &membtype
, 0)) >= 0)
82 if ((rc
= func (name
, membtype
, offset
, arg
)) != 0)
88 if (ctf_errno (fp
) != ECTF_NEXT_END
)
89 return -1; /* errno is set for us. */
94 /* Iterate over the members of a STRUCT or UNION, returning each member's
95 offset and optionally name and member type in turn. On end-of-iteration,
96 returns -1. If FLAGS is CTF_MN_RECURSE, recurse into unnamed members. */
99 ctf_member_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
100 const char **name
, ctf_id_t
*membtype
, int flags
)
102 ctf_dict_t
*ofp
= fp
;
110 const ctf_type_t
*tp
;
115 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
116 return -1; /* errno is set for us. */
118 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
119 return -1; /* errno is set for us. */
121 if ((i
= ctf_next_create ()) == NULL
)
122 return ctf_set_errno (ofp
, ENOMEM
);
126 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
127 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
129 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
131 ctf_next_destroy (i
);
132 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
135 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
137 i
->u
.ctn_vlen
= dtd
->dtd_vlen
;
138 i
->ctn_size
= dtd
->dtd_vlen_alloc
;
142 unsigned long vlen
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
144 i
->u
.ctn_vlen
= (unsigned char *) tp
+ increment
;
145 i
->ctn_size
= LCTF_VBYTES (fp
, kind
, size
, vlen
);;
147 i
->ctn_iter_fun
= (void (*) (void)) ctf_member_next
;
152 if ((void (*) (void)) ctf_member_next
!= i
->ctn_iter_fun
)
153 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
));
155 if (ofp
!= i
->cu
.ctn_fp
)
156 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
));
158 /* Resolve to the native dict of this type. */
159 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
160 return (ctf_set_errno (ofp
, ECTF_NOPARENT
));
162 max_vlen
= LCTF_INFO_VLEN (fp
, i
->ctn_tp
->ctt_info
);
164 /* When we hit an unnamed struct/union member, we set ctn_type to indicate
165 that we are inside one, then return the unnamed member: on the next call,
166 we must skip over top-level member iteration in favour of iteration within
167 the sub-struct until it later turns out that that iteration has ended. */
173 const char *membname
;
175 if (i
->ctn_n
== max_vlen
)
178 if (ctf_struct_member (fp
, &memb
, i
->ctn_tp
, i
->u
.ctn_vlen
, i
->ctn_size
,
180 return (ctf_set_errno (ofp
, ctf_errno (fp
)));
182 membname
= ctf_strptr (fp
, memb
.ctlm_name
);
187 *membtype
= memb
.ctlm_type
;
188 offset
= (unsigned long) CTF_LMEM_OFFSET (&memb
);
191 && (ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_STRUCT
192 || ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_UNION
))
193 i
->ctn_type
= memb
.ctlm_type
;
196 /* The callers might want automatic recursive sub-struct traversal. */
197 if (!(flags
& CTF_MN_RECURSE
))
200 /* Sub-struct traversal starting? Take note of the offset of this member,
201 for later boosting of sub-struct members' offsets. */
203 i
->ctn_increment
= offset
;
205 /* Traversing a sub-struct? Just return it, with the offset adjusted. */
208 ssize_t ret
= ctf_member_next (fp
, i
->ctn_type
, &i
->ctn_next
, name
,
212 return ret
+ i
->ctn_increment
;
214 if (ctf_errno (fp
) != ECTF_NEXT_END
)
216 ctf_next_destroy (i
);
219 ctf_set_errno (ofp
, ctf_errno (fp
));
223 if (!ctf_assert (fp
, (i
->ctn_next
== NULL
)))
224 return (ctf_set_errno (ofp
, ctf_errno (fp
)));
227 /* This sub-struct has ended: on to the next real member. */
234 ctf_next_destroy (i
);
236 return ctf_set_errno (ofp
, ECTF_NEXT_END
);
239 /* Iterate over the members of an ENUM. We pass the string name and associated
240 integer value of each enum element to the specified callback function. */
243 ctf_enum_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
245 ctf_next_t
*i
= NULL
;
249 while ((name
= ctf_enum_next (fp
, type
, &i
, &val
)) != NULL
)
252 if ((rc
= func (name
, val
, arg
)) != 0)
254 ctf_next_destroy (i
);
258 if (ctf_errno (fp
) != ECTF_NEXT_END
)
259 return -1; /* errno is set for us. */
264 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
265 NULL at end of iteration or error, and optionally passing back the
266 enumerand's integer VALue. */
269 ctf_enum_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
272 ctf_dict_t
*ofp
= fp
;
279 const ctf_type_t
*tp
;
282 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
283 return NULL
; /* errno is set for us. */
285 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
286 return NULL
; /* errno is set for us. */
288 if ((i
= ctf_next_create ()) == NULL
)
290 ctf_set_errno (ofp
, ENOMEM
);
295 (void) ctf_get_ctt_size (fp
, tp
, NULL
,
297 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
299 if (kind
!= CTF_K_ENUM
)
301 ctf_next_destroy (i
);
302 ctf_set_errno (ofp
, ECTF_NOTENUM
);
306 dtd
= ctf_dynamic_type (fp
, type
);
307 i
->ctn_iter_fun
= (void (*) (void)) ctf_enum_next
;
308 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
311 i
->u
.ctn_en
= (const ctf_enum_t
*) ((uintptr_t) tp
+
314 i
->u
.ctn_en
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
319 if ((void (*) (void)) ctf_enum_next
!= i
->ctn_iter_fun
)
321 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
);
325 if (ofp
!= i
->cu
.ctn_fp
)
327 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
);
331 /* Resolve to the native dict of this type. */
332 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
334 ctf_set_errno (ofp
, ECTF_NOPARENT
);
341 name
= ctf_strptr (fp
, i
->u
.ctn_en
->cte_name
);
343 *val
= i
->u
.ctn_en
->cte_value
;
350 ctf_next_destroy (i
);
352 ctf_set_errno (ofp
, ECTF_NEXT_END
);
356 /* Iterate over every root (user-visible) type in the given CTF dict.
357 We pass the type ID of each type to the specified callback function.
359 Does not traverse parent types: you have to do that explicitly. This is by
360 design, to avoid traversing them more than once if traversing many children
361 of a single parent. */
364 ctf_type_iter (ctf_dict_t
*fp
, ctf_type_f
*func
, void *arg
)
366 ctf_next_t
*i
= NULL
;
369 while ((type
= ctf_type_next (fp
, &i
, NULL
, 0)) != CTF_ERR
)
372 if ((rc
= func (type
, arg
)) != 0)
374 ctf_next_destroy (i
);
378 if (ctf_errno (fp
) != ECTF_NEXT_END
)
379 return -1; /* errno is set for us. */
384 /* Iterate over every type in the given CTF dict, user-visible or not.
385 We pass the type ID of each type to the specified callback function.
387 Does not traverse parent types: you have to do that explicitly. This is by
388 design, to avoid traversing them more than once if traversing many children
389 of a single parent. */
392 ctf_type_iter_all (ctf_dict_t
*fp
, ctf_type_all_f
*func
, void *arg
)
394 ctf_next_t
*i
= NULL
;
398 while ((type
= ctf_type_next (fp
, &i
, &flag
, 1)) != CTF_ERR
)
401 if ((rc
= func (type
, flag
, arg
)) != 0)
403 ctf_next_destroy (i
);
407 if (ctf_errno (fp
) != ECTF_NEXT_END
)
408 return -1; /* errno is set for us. */
413 /* Iterate over every type in the given CTF dict, optionally including
414 non-user-visible types, returning each type ID and hidden flag in turn.
415 Returns CTF_ERR on end of iteration or error.
417 Does not traverse parent types: you have to do that explicitly. This is by
418 design, to avoid traversing them more than once if traversing many children
419 of a single parent. */
422 ctf_type_next (ctf_dict_t
*fp
, ctf_next_t
**it
, int *flag
, int want_hidden
)
428 if ((i
= ctf_next_create ()) == NULL
)
429 return ctf_set_typed_errno (fp
, ENOMEM
);
433 i
->ctn_iter_fun
= (void (*) (void)) ctf_type_next
;
437 if ((void (*) (void)) ctf_type_next
!= i
->ctn_iter_fun
)
438 return (ctf_set_typed_errno (fp
, ECTF_NEXT_WRONGFUN
));
440 if (fp
!= i
->cu
.ctn_fp
)
441 return (ctf_set_typed_errno (fp
, ECTF_NEXT_WRONGFP
));
443 while (i
->ctn_type
<= fp
->ctf_typemax
)
445 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, i
->ctn_type
);
447 if ((!want_hidden
) && (!LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)))
454 *flag
= LCTF_INFO_ISROOT (fp
, tp
->ctt_info
);
455 return LCTF_INDEX_TO_TYPE (fp
, i
->ctn_type
++, fp
->ctf_flags
& LCTF_CHILD
);
457 ctf_next_destroy (i
);
459 return ctf_set_typed_errno (fp
, ECTF_NEXT_END
);
462 /* Iterate over every variable in the given CTF dict, in arbitrary order.
463 We pass the name of each variable to the specified callback function. */
466 ctf_variable_iter (ctf_dict_t
*fp
, ctf_variable_f
*func
, void *arg
)
468 ctf_next_t
*i
= NULL
;
472 while ((type
= ctf_variable_next (fp
, &i
, &name
)) != CTF_ERR
)
475 if ((rc
= func (name
, type
, arg
)) != 0)
477 ctf_next_destroy (i
);
481 if (ctf_errno (fp
) != ECTF_NEXT_END
)
482 return -1; /* errno is set for us. */
487 /* Iterate over every variable in the given CTF dict, in arbitrary order,
488 returning the name and type of each variable in turn. The name argument is
489 not optional. Returns CTF_ERR on end of iteration or error. */
492 ctf_variable_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
)
497 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
498 return (ctf_set_typed_errno (fp
, ECTF_NOPARENT
));
502 if ((i
= ctf_next_create ()) == NULL
)
503 return ctf_set_typed_errno (fp
, ENOMEM
);
506 i
->ctn_iter_fun
= (void (*) (void)) ctf_variable_next
;
507 i
->u
.ctn_dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
511 if ((void (*) (void)) ctf_variable_next
!= i
->ctn_iter_fun
)
512 return (ctf_set_typed_errno (fp
, ECTF_NEXT_WRONGFUN
));
514 if (fp
!= i
->cu
.ctn_fp
)
515 return (ctf_set_typed_errno (fp
, ECTF_NEXT_WRONGFP
));
517 if (i
->ctn_n
< fp
->ctf_nvars
)
519 *name
= ctf_strptr (fp
, fp
->ctf_vars
[i
->ctn_n
].ctv_name
);
520 return fp
->ctf_vars
[i
->ctn_n
++].ctv_type
;
524 if (i
->u
.ctn_dvd
== NULL
)
527 *name
= i
->u
.ctn_dvd
->dvd_name
;
528 id
= i
->u
.ctn_dvd
->dvd_type
;
529 i
->u
.ctn_dvd
= ctf_list_next (i
->u
.ctn_dvd
);
533 ctf_next_destroy (i
);
535 return ctf_set_typed_errno (fp
, ECTF_NEXT_END
);
538 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
539 RESTRICT nodes until we reach a "base" type node. This is useful when
540 we want to follow a type ID to a node that has members or a size. To guard
541 against infinite loops, we implement simplified cycle detection and check
542 each link against itself, the previous node, and the topmost node.
544 Does not drill down through slices to their contained type.
546 Callers of this function must not presume that a type it returns must have a
547 valid ctt_size: forwards do not, and must be separately handled. */
550 ctf_type_resolve (ctf_dict_t
*fp
, ctf_id_t type
)
552 ctf_id_t prev
= type
, otype
= type
;
553 ctf_dict_t
*ofp
= fp
;
554 const ctf_type_t
*tp
;
557 return (ctf_set_typed_errno (ofp
, ECTF_NONREPRESENTABLE
));
559 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
561 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
567 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
568 || tp
->ctt_type
== prev
)
570 ctf_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
572 return (ctf_set_typed_errno (ofp
, ECTF_CORRUPT
));
578 return (ctf_set_typed_errno (ofp
, ECTF_NONREPRESENTABLE
));
583 return (ctf_set_typed_errno (ofp
, ECTF_NONREPRESENTABLE
));
586 return CTF_ERR
; /* errno is set for us. */
589 /* Like ctf_type_resolve(), but traverse down through slices to their contained
593 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
595 ctf_dict_t
*ofp
= fp
;
596 const ctf_type_t
*tp
;
598 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
601 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
602 return CTF_ERR
; /* errno is set for us. */
604 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
608 if ((ret
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
609 return (ctf_set_typed_errno (ofp
, ctf_errno (fp
)));
615 /* Return the native dict of a given type: if called on a child and the
616 type is in the parent, return the parent. Needed if you plan to access
617 the type directly, without using the API. */
619 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
621 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
622 return fp
->ctf_parent
;
627 /* Look up a name in the given name table, in the appropriate hash given the
628 kind of the identifier. The name is a raw, undecorated identifier. */
630 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
632 return (ctf_id_t
) (uintptr_t)
633 ctf_dynhash_lookup (ctf_name_table (fp
, kind
), name
);
636 /* Lookup the given type ID and return its name as a new dynamically-allocated
640 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
643 ctf_decl_node_t
*cdp
;
644 ctf_decl_prec_t prec
, lp
, rp
;
649 if (fp
== NULL
&& type
== CTF_ERR
)
650 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
653 ctf_decl_push (&cd
, fp
, type
);
658 ctf_set_errno (fp
, cd
.cd_err
);
662 /* If the type graph's order conflicts with lexical precedence order
663 for pointers or arrays, then we need to surround the declarations at
664 the corresponding lexical precedence with parentheses. This can
665 result in either a parenthesized pointer (*) as in int (*)() or
666 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
668 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
669 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
671 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
672 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
674 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
676 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
678 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
679 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
681 ctf_dict_t
*rfp
= fp
;
682 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
683 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
685 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
686 ctf_decl_sprintf (&cd
, " ");
690 ctf_decl_sprintf (&cd
, "(");
694 switch (cdp
->cd_kind
)
699 /* Integers, floats, and typedefs must always be named types. */
703 ctf_set_errno (fp
, ECTF_CORRUPT
);
708 ctf_decl_sprintf (&cd
, "%s", name
);
711 ctf_decl_sprintf (&cd
, "*");
714 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
720 ctf_id_t
*argv
= NULL
;
722 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
723 goto err
; /* errno is set for us. */
725 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
727 ctf_set_errno (rfp
, errno
);
731 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
732 fi
.ctc_argc
, argv
) < 0)
733 goto err
; /* errno is set for us. */
735 ctf_decl_sprintf (&cd
, "(*) (");
736 for (i
= 0; i
< fi
.ctc_argc
; i
++)
738 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
741 goto err
; /* errno is set for us. */
742 ctf_decl_sprintf (&cd
, "%s", arg
);
745 if ((i
< fi
.ctc_argc
- 1)
746 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
747 ctf_decl_sprintf (&cd
, ", ");
750 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
751 ctf_decl_sprintf (&cd
, "...");
752 ctf_decl_sprintf (&cd
, ")");
758 ctf_set_errno (fp
, ctf_errno (rfp
));
765 ctf_decl_sprintf (&cd
, "struct %s", name
);
768 ctf_decl_sprintf (&cd
, "union %s", name
);
771 ctf_decl_sprintf (&cd
, "enum %s", name
);
775 switch (ctf_type_kind_forwarded (fp
, cdp
->cd_type
))
778 ctf_decl_sprintf (&cd
, "struct %s", name
);
781 ctf_decl_sprintf (&cd
, "union %s", name
);
784 ctf_decl_sprintf (&cd
, "enum %s", name
);
787 ctf_set_errno (fp
, ECTF_CORRUPT
);
794 ctf_decl_sprintf (&cd
, "volatile");
797 ctf_decl_sprintf (&cd
, "const");
800 ctf_decl_sprintf (&cd
, "restrict");
804 ctf_decl_sprintf (&cd
, _("(nonrepresentable type)"));
806 ctf_decl_sprintf (&cd
, _("(nonrepresentable type %s)"),
815 ctf_decl_sprintf (&cd
, ")");
819 (void) ctf_set_errno (fp
, ENOMEM
);
821 buf
= ctf_decl_buf (&cd
);
827 /* Lookup the given type ID and print a string name for it into buf. Return
828 the actual number of bytes (not including \0) needed to format the name. */
831 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
833 char *str
= ctf_type_aname (fp
, type
);
837 return -1; /* errno is set for us. */
840 snprintf (buf
, len
, "%s", str
);
844 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
849 /* Lookup the given type ID and print a string name for it into buf. If buf
850 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
853 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
855 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
856 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
859 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
860 The name will live as long as its ctf_dict_t does.
862 The only decoration is that a NULL return always means an error: nameless
863 types return a null string. */
866 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
868 const ctf_type_t
*tp
;
870 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
871 return NULL
; /* errno is set for us. */
873 if (tp
->ctt_name
== 0)
876 return ctf_strraw (fp
, tp
->ctt_name
);
879 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
880 new dynamically-allocated string. */
883 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
885 const char *name
= ctf_type_name_raw (fp
, type
);
888 return strdup (name
);
893 /* Resolve the type down to a base type node, and then return the size
894 of the type storage in bytes. */
897 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
899 ctf_dict_t
*ofp
= fp
;
900 const ctf_type_t
*tp
;
904 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
905 return -1; /* errno is set for us. */
907 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
908 return -1; /* errno is set for us. */
910 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
913 return fp
->ctf_dmodel
->ctd_pointer
;
916 return 0; /* Function size is only known by symtab. */
919 return fp
->ctf_dmodel
->ctd_int
;
922 /* ctf_add_array() does not directly encode the element size, but
923 requires the user to multiply to determine the element size.
925 If ctf_get_ctt_size() returns nonzero, then use the recorded
928 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
931 if (ctf_array_info (ofp
, type
, &ar
) < 0
932 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
933 return -1; /* errno is set for us. */
935 return size
* ar
.ctr_nelems
;
938 /* Forwards do not have a meaningful size. */
939 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
941 default: /* including slices of enums, etc */
942 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
946 /* Resolve the type down to a base type node, and then return the alignment
947 needed for the type storage in bytes.
949 XXX may need arch-dependent attention. */
952 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
954 const ctf_type_t
*tp
;
955 ctf_dict_t
*ofp
= fp
;
958 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
959 return -1; /* errno is set for us. */
961 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
962 return -1; /* errno is set for us. */
964 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
969 return fp
->ctf_dmodel
->ctd_pointer
;
974 if (ctf_array_info (ofp
, type
, &r
) < 0)
975 return -1; /* errno is set for us. */
976 return (ctf_type_align (ofp
, r
.ctr_contents
));
985 uint32_t i
= 0, n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
986 ssize_t size
, increment
, vbytes
;
988 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
990 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
992 vlen
= dtd
->dtd_vlen
;
993 vbytes
= dtd
->dtd_vlen_alloc
;
997 vlen
= (unsigned char *) tp
+ increment
;
998 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1001 if (kind
== CTF_K_STRUCT
)
1002 n
= MIN (n
, 1); /* Only use first member for structs. */
1004 for (; n
!= 0; n
--, i
++)
1008 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1009 return -1; /* errno is set for us. */
1011 ssize_t am
= ctf_type_align (ofp
, memb
.ctlm_type
);
1012 align
= MAX (align
, (size_t) am
);
1018 return fp
->ctf_dmodel
->ctd_int
;
1021 /* Forwards do not have a meaningful alignment. */
1022 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1024 default: /* including slices of enums, etc */
1025 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1029 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1032 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1034 const ctf_type_t
*tp
;
1036 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1037 return -1; /* errno is set for us. */
1039 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1042 /* Return the kind (CTF_K_* constant) for the specified type ID.
1043 Slices are considered to be of the same kind as the type sliced. */
1046 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1050 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1053 if (kind
== CTF_K_SLICE
)
1055 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1057 kind
= ctf_type_kind_unsliced (fp
, type
);
1063 /* Return the kind of this type, except, for forwards, return the kind of thing
1064 this is a forward to. */
1066 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1069 const ctf_type_t
*tp
;
1071 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1072 return -1; /* errno is set for us. */
1074 if (kind
!= CTF_K_FORWARD
)
1077 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1078 return -1; /* errno is set for us. */
1080 return tp
->ctt_type
;
1083 /* If the type is one that directly references another type (such as POINTER),
1084 then return the ID of the type to which it refers. */
1087 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1089 ctf_dict_t
*ofp
= fp
;
1090 const ctf_type_t
*tp
;
1092 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1093 return CTF_ERR
; /* errno is set for us. */
1095 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1099 case CTF_K_VOLATILE
:
1101 case CTF_K_RESTRICT
:
1102 return tp
->ctt_type
;
1103 /* Slices store their type in an unusual place. */
1107 const ctf_slice_t
*sp
;
1109 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1113 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1114 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1117 sp
= (const ctf_slice_t
*) dtd
->dtd_vlen
;
1119 return sp
->cts_type
;
1122 return (ctf_set_typed_errno (ofp
, ECTF_NOTREF
));
1126 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1127 pointer to the given type, see if we can compute a pointer to the type
1128 resulting from resolving the type down to its base type and use that
1129 instead. This helps with cases where the CTF data includes "struct foo *"
1130 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1132 XXX what about parent dicts? */
1135 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1137 ctf_dict_t
*ofp
= fp
;
1140 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1141 return CTF_ERR
; /* errno is set for us. */
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 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1147 return (ctf_set_typed_errno (ofp
, ECTF_NOTYPE
));
1149 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1150 return (ctf_set_typed_errno (ofp
, ECTF_NOTYPE
));
1152 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1153 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1155 return (ctf_set_typed_errno (ofp
, ECTF_NOTYPE
));
1158 /* Return the encoding for the specified INTEGER, FLOAT, or ENUM. */
1161 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1163 ctf_dict_t
*ofp
= fp
;
1165 const ctf_type_t
*tp
;
1167 const unsigned char *vlen
;
1170 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1171 return -1; /* errno is set for us. */
1173 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1174 vlen
= dtd
->dtd_vlen
;
1177 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1178 vlen
= (const unsigned char *) ((uintptr_t) tp
+ increment
);
1181 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1184 data
= *(const uint32_t *) vlen
;
1185 ep
->cte_format
= CTF_INT_ENCODING (data
);
1186 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1187 ep
->cte_bits
= CTF_INT_BITS (data
);
1190 data
= *(const uint32_t *) vlen
;
1191 ep
->cte_format
= CTF_FP_ENCODING (data
);
1192 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1193 ep
->cte_bits
= CTF_FP_BITS (data
);
1196 /* v3 only: we must guess at the underlying integral format. */
1197 ep
->cte_format
= CTF_INT_SIGNED
;
1203 const ctf_slice_t
*slice
;
1204 ctf_encoding_t underlying_en
;
1205 ctf_id_t underlying
;
1207 slice
= (ctf_slice_t
*) vlen
;
1208 underlying
= ctf_type_resolve (ofp
, slice
->cts_type
);
1209 if (ctf_type_encoding (ofp
, underlying
, &underlying_en
) < 0)
1210 return -1; /* errno is set for us. */
1212 ep
->cte_format
= underlying_en
.cte_format
;
1213 ep
->cte_offset
= slice
->cts_offset
;
1214 ep
->cte_bits
= slice
->cts_bits
;
1218 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1225 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1232 else if (ltype
> rtype
)
1240 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1241 lfp
= lfp
->ctf_parent
;
1243 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1244 rfp
= rfp
->ctf_parent
;
1255 /* Return a boolean value indicating if two types are compatible. This function
1256 returns true if the two types are the same, or if they (or their ultimate
1257 base type) have the same encoding properties, or (for structs / unions /
1258 enums / forward declarations) if they have the same name and (for structs /
1259 unions) member count. */
1262 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1263 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1265 const ctf_type_t
*ltp
, *rtp
;
1266 ctf_encoding_t le
, re
;
1267 ctf_arinfo_t la
, ra
;
1268 uint32_t lkind
, rkind
;
1271 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1274 ltype
= ctf_type_resolve (lfp
, ltype
);
1275 lkind
= ctf_type_kind (lfp
, ltype
);
1277 rtype
= ctf_type_resolve (rfp
, rtype
);
1278 rkind
= ctf_type_kind (rfp
, rtype
);
1280 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1281 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1283 if (ltp
!= NULL
&& rtp
!= NULL
)
1284 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1285 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1287 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1288 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1298 memset (&le
, 0, sizeof (le
));
1299 memset (&re
, 0, sizeof (re
));
1300 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1301 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1302 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1304 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1305 rfp
, ctf_type_reference (rfp
, rtype
)));
1307 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1308 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1309 && la
.ctr_nelems
== ra
.ctr_nelems
1310 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1311 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1314 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1315 == ctf_type_size (rfp
, rtype
)));
1318 int lencoded
, rencoded
;
1319 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1320 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1322 if ((lencoded
!= rencoded
) ||
1323 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1328 return same_names
; /* No other checks required for these type kinds. */
1330 return 0; /* Should not get here since we did a resolve. */
1334 /* Return the number of members in a STRUCT or UNION, or the number of
1335 enumerators in an ENUM. The count does not include unnamed sub-members. */
1338 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1340 ctf_dict_t
*ofp
= fp
;
1341 const ctf_type_t
*tp
;
1344 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1345 return -1; /* errno is set for us. */
1347 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1348 return -1; /* errno is set for us. */
1350 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1352 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1353 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1355 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1358 /* Return the type and offset for a given member of a STRUCT or UNION. */
1361 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1362 ctf_membinfo_t
*mip
)
1364 ctf_dict_t
*ofp
= fp
;
1365 const ctf_type_t
*tp
;
1367 unsigned char *vlen
;
1368 ssize_t size
, increment
, vbytes
;
1369 uint32_t kind
, n
, i
= 0;
1371 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1372 return -1; /* errno is set for us. */
1374 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1375 return -1; /* errno is set for us. */
1377 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1378 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1380 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1381 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1383 n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1384 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1386 vlen
= dtd
->dtd_vlen
;
1387 vbytes
= dtd
->dtd_vlen_alloc
;
1391 vlen
= (unsigned char *) tp
+ increment
;
1392 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1395 for (; n
!= 0; n
--, i
++)
1398 const char *membname
;
1400 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1401 return (ctf_set_errno (ofp
, ctf_errno (fp
)));
1403 membname
= ctf_strptr (fp
, memb
.ctlm_name
);
1405 if (membname
[0] == 0
1406 && (ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_STRUCT
1407 || ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_UNION
)
1408 && (ctf_member_info (fp
, memb
.ctlm_type
, name
, mip
) == 0))
1410 mip
->ctm_offset
+= (unsigned long) CTF_LMEM_OFFSET (&memb
);
1414 if (strcmp (membname
, name
) == 0)
1416 mip
->ctm_type
= memb
.ctlm_type
;
1417 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (&memb
);
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
)
1518 return ctf_set_errno (ofp
, ECTF_NOTENUM
);
1520 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1522 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1523 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1525 ep
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
1527 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1529 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1532 *valp
= ep
->cte_value
;
1537 return ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1540 /* Given a type ID relating to a function type, return info on return types and
1541 arg counts for that function. */
1544 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1546 ctf_dict_t
*ofp
= fp
;
1547 const ctf_type_t
*tp
;
1549 const uint32_t *args
;
1550 const ctf_dtdef_t
*dtd
;
1551 ssize_t size
, increment
;
1553 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1554 return -1; /* errno is set for us. */
1556 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1557 return -1; /* errno is set for us. */
1559 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1560 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1562 if (kind
!= CTF_K_FUNCTION
)
1563 return (ctf_set_errno (ofp
, ECTF_NOTFUNC
));
1565 fip
->ctc_return
= tp
->ctt_type
;
1567 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1569 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1570 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1572 args
= (uint32_t *) dtd
->dtd_vlen
;
1574 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1576 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1583 /* Given a type ID relating to a function type, return the arguments for the
1587 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1589 const ctf_type_t
*tp
;
1590 const uint32_t *args
;
1591 const ctf_dtdef_t
*dtd
;
1592 ssize_t size
, increment
;
1595 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1596 return -1; /* errno is set for us. */
1598 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1599 return -1; /* errno is set for us. */
1601 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1602 return -1; /* errno is set for us. */
1604 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1606 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1607 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1609 args
= (uint32_t *) dtd
->dtd_vlen
;
1611 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1617 /* Recursively visit the members of any type. This function is used as the
1618 engine for ctf_type_visit, below. We resolve the input type, recursively
1619 invoke ourself for each type member if the type is a struct or union, and
1620 then invoke the callback function on the current type. If any callback
1621 returns non-zero, we abort and percolate the error code back up to the top. */
1624 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1625 void *arg
, const char *name
, unsigned long offset
, int depth
)
1627 ctf_dict_t
*ofp
= fp
;
1628 ctf_id_t otype
= type
;
1629 const ctf_type_t
*tp
= NULL
;
1630 const ctf_dtdef_t
*dtd
;
1631 unsigned char *vlen
;
1632 ssize_t size
, increment
, vbytes
;
1633 uint32_t kind
, n
, i
= 0;
1634 int nonrepresentable
= 0;
1637 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
) {
1638 if (ctf_errno (fp
) != ECTF_NONREPRESENTABLE
)
1639 return -1; /* errno is set for us. */
1641 nonrepresentable
= 1;
1644 if (!nonrepresentable
)
1645 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1646 return -1; /* errno is set for us. */
1648 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1651 if (!nonrepresentable
)
1652 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1654 if (nonrepresentable
|| (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
))
1657 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1659 n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1660 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1662 vlen
= dtd
->dtd_vlen
;
1663 vbytes
= dtd
->dtd_vlen_alloc
;
1667 vlen
= (unsigned char *) tp
+ increment
;
1668 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1671 for (; n
!= 0; n
--, i
++)
1675 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1676 return (ctf_set_errno (ofp
, ctf_errno (fp
)));
1678 if ((rc
= ctf_type_rvisit (fp
, memb
.ctlm_type
,
1679 func
, arg
, ctf_strptr (fp
, memb
.ctlm_name
),
1680 offset
+ (unsigned long) CTF_LMEM_OFFSET (&memb
),
1688 /* Recursively visit the members of any type. We pass the name, member
1689 type, and offset of each member to the specified callback function. */
1691 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1693 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));