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 /* 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 -1; /* errno is set for us. */
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 return ret
; /* errno is set for us. */
222 if (!ctf_assert (fp
, (i
->ctn_next
== NULL
)))
223 return -1; /* errno is set for us. */
226 /* This sub-struct has ended: on to the next real member. */
233 ctf_next_destroy (i
);
235 return ctf_set_errno (ofp
, ECTF_NEXT_END
);
238 /* Iterate over the members of an ENUM. We pass the string name and associated
239 integer value of each enum element to the specified callback function. */
242 ctf_enum_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
244 ctf_next_t
*i
= NULL
;
248 while ((name
= ctf_enum_next (fp
, type
, &i
, &val
)) != NULL
)
251 if ((rc
= func (name
, val
, arg
)) != 0)
253 ctf_next_destroy (i
);
257 if (ctf_errno (fp
) != ECTF_NEXT_END
)
258 return -1; /* errno is set for us. */
263 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
264 NULL at end of iteration or error, and optionally passing back the
265 enumerand's integer VALue. */
268 ctf_enum_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
271 ctf_dict_t
*ofp
= fp
;
278 const ctf_type_t
*tp
;
281 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
282 return NULL
; /* errno is set for us. */
284 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
285 return NULL
; /* errno is set for us. */
287 if ((i
= ctf_next_create ()) == NULL
)
289 ctf_set_errno (ofp
, ENOMEM
);
294 (void) ctf_get_ctt_size (fp
, tp
, NULL
,
296 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
298 if (kind
!= CTF_K_ENUM
)
300 ctf_next_destroy (i
);
301 ctf_set_errno (ofp
, ECTF_NOTENUM
);
305 dtd
= ctf_dynamic_type (fp
, type
);
306 i
->ctn_iter_fun
= (void (*) (void)) ctf_enum_next
;
307 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
310 i
->u
.ctn_en
= (const ctf_enum_t
*) ((uintptr_t) tp
+
313 i
->u
.ctn_en
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
318 if ((void (*) (void)) ctf_enum_next
!= i
->ctn_iter_fun
)
320 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
);
324 if (ofp
!= i
->cu
.ctn_fp
)
326 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
);
330 /* Resolve to the native dict of this type. */
331 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
333 ctf_set_errno (ofp
, ECTF_NOPARENT
);
340 name
= ctf_strptr (fp
, i
->u
.ctn_en
->cte_name
);
342 *val
= i
->u
.ctn_en
->cte_value
;
349 ctf_next_destroy (i
);
351 ctf_set_errno (ofp
, ECTF_NEXT_END
);
355 /* Iterate over every root (user-visible) type in the given CTF dict.
356 We pass the type ID of each type to the specified callback function.
358 Does not traverse parent types: you have to do that explicitly. This is by
359 design, to avoid traversing them more than once if traversing many children
360 of a single parent. */
363 ctf_type_iter (ctf_dict_t
*fp
, ctf_type_f
*func
, void *arg
)
365 ctf_next_t
*i
= NULL
;
368 while ((type
= ctf_type_next (fp
, &i
, NULL
, 0)) != CTF_ERR
)
371 if ((rc
= func (type
, arg
)) != 0)
373 ctf_next_destroy (i
);
377 if (ctf_errno (fp
) != ECTF_NEXT_END
)
378 return -1; /* errno is set for us. */
383 /* Iterate over every type in the given CTF dict, user-visible or not.
384 We pass the type ID of each type to the specified callback function.
386 Does not traverse parent types: you have to do that explicitly. This is by
387 design, to avoid traversing them more than once if traversing many children
388 of a single parent. */
391 ctf_type_iter_all (ctf_dict_t
*fp
, ctf_type_all_f
*func
, void *arg
)
393 ctf_next_t
*i
= NULL
;
397 while ((type
= ctf_type_next (fp
, &i
, &flag
, 1)) != CTF_ERR
)
400 if ((rc
= func (type
, flag
, arg
)) != 0)
402 ctf_next_destroy (i
);
406 if (ctf_errno (fp
) != ECTF_NEXT_END
)
407 return -1; /* errno is set for us. */
412 /* Iterate over every type in the given CTF dict, optionally including
413 non-user-visible types, returning each type ID and hidden flag in turn.
414 Returns CTF_ERR on end of iteration or error.
416 Does not traverse parent types: you have to do that explicitly. This is by
417 design, to avoid traversing them more than once if traversing many children
418 of a single parent. */
421 ctf_type_next (ctf_dict_t
*fp
, ctf_next_t
**it
, int *flag
, int want_hidden
)
427 if ((i
= ctf_next_create ()) == NULL
)
428 return ctf_set_errno (fp
, ENOMEM
);
432 i
->ctn_iter_fun
= (void (*) (void)) ctf_type_next
;
436 if ((void (*) (void)) ctf_type_next
!= i
->ctn_iter_fun
)
437 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
439 if (fp
!= i
->cu
.ctn_fp
)
440 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
442 while (i
->ctn_type
<= fp
->ctf_typemax
)
444 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, i
->ctn_type
);
446 if ((!want_hidden
) && (!LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)))
453 *flag
= LCTF_INFO_ISROOT (fp
, tp
->ctt_info
);
454 return LCTF_INDEX_TO_TYPE (fp
, i
->ctn_type
++, fp
->ctf_flags
& LCTF_CHILD
);
456 ctf_next_destroy (i
);
458 return ctf_set_errno (fp
, ECTF_NEXT_END
);
461 /* Iterate over every variable in the given CTF dict, in arbitrary order.
462 We pass the name of each variable to the specified callback function. */
465 ctf_variable_iter (ctf_dict_t
*fp
, ctf_variable_f
*func
, void *arg
)
467 ctf_next_t
*i
= NULL
;
471 while ((type
= ctf_variable_next (fp
, &i
, &name
)) != CTF_ERR
)
474 if ((rc
= func (name
, type
, arg
)) != 0)
476 ctf_next_destroy (i
);
480 if (ctf_errno (fp
) != ECTF_NEXT_END
)
481 return -1; /* errno is set for us. */
486 /* Iterate over every variable in the given CTF dict, in arbitrary order,
487 returning the name and type of each variable in turn. The name argument is
488 not optional. Returns CTF_ERR on end of iteration or error. */
491 ctf_variable_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
)
495 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
496 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
500 if ((i
= ctf_next_create ()) == NULL
)
501 return ctf_set_errno (fp
, ENOMEM
);
504 i
->ctn_iter_fun
= (void (*) (void)) ctf_variable_next
;
505 if (fp
->ctf_flags
& LCTF_RDWR
)
506 i
->u
.ctn_dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
510 if ((void (*) (void)) ctf_variable_next
!= i
->ctn_iter_fun
)
511 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
513 if (fp
!= i
->cu
.ctn_fp
)
514 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
516 if (!(fp
->ctf_flags
& LCTF_RDWR
))
518 if (i
->ctn_n
>= fp
->ctf_nvars
)
521 *name
= ctf_strptr (fp
, fp
->ctf_vars
[i
->ctn_n
].ctv_name
);
522 return fp
->ctf_vars
[i
->ctn_n
++].ctv_type
;
528 if (i
->u
.ctn_dvd
== NULL
)
531 *name
= i
->u
.ctn_dvd
->dvd_name
;
532 id
= i
->u
.ctn_dvd
->dvd_type
;
533 i
->u
.ctn_dvd
= ctf_list_next (i
->u
.ctn_dvd
);
538 ctf_next_destroy (i
);
540 return ctf_set_errno (fp
, ECTF_NEXT_END
);
543 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
544 RESTRICT nodes until we reach a "base" type node. This is useful when
545 we want to follow a type ID to a node that has members or a size. To guard
546 against infinite loops, we implement simplified cycle detection and check
547 each link against itself, the previous node, and the topmost node.
549 Does not drill down through slices to their contained type.
551 Callers of this function must not presume that a type it returns must have a
552 valid ctt_size: forwards do not, and must be separately handled. */
555 ctf_type_resolve (ctf_dict_t
*fp
, ctf_id_t type
)
557 ctf_id_t prev
= type
, otype
= type
;
558 ctf_dict_t
*ofp
= fp
;
559 const ctf_type_t
*tp
;
562 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
564 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
566 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
572 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
573 || tp
->ctt_type
== prev
)
575 ctf_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
577 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
586 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
589 return CTF_ERR
; /* errno is set for us. */
592 /* Like ctf_type_resolve(), but traverse down through slices to their contained
596 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
598 const ctf_type_t
*tp
;
600 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
603 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
604 return CTF_ERR
; /* errno is set for us. */
606 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
607 return ctf_type_reference (fp
, type
);
611 /* Return the native dict of a given type: if called on a child and the
612 type is in the parent, return the parent. Needed if you plan to access
613 the type directly, without using the API. */
615 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
617 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
618 return fp
->ctf_parent
;
623 /* Look up a name in the given name table, in the appropriate hash given the
624 kind of the identifier. The name is a raw, undecorated identifier. */
626 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
628 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
631 /* Look up a name in the given name table, in the appropriate hash given the
632 readability state of the dictionary. The name is a raw, undecorated
635 ctf_id_t
ctf_lookup_by_rawhash (ctf_dict_t
*fp
, ctf_names_t
*np
, const char *name
)
639 if (fp
->ctf_flags
& LCTF_RDWR
)
640 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
642 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
646 /* Lookup the given type ID and return its name as a new dynamically-allocated
650 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
653 ctf_decl_node_t
*cdp
;
654 ctf_decl_prec_t prec
, lp
, rp
;
659 if (fp
== NULL
&& type
== CTF_ERR
)
660 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
663 ctf_decl_push (&cd
, fp
, type
);
668 ctf_set_errno (fp
, cd
.cd_err
);
672 /* If the type graph's order conflicts with lexical precedence order
673 for pointers or arrays, then we need to surround the declarations at
674 the corresponding lexical precedence with parentheses. This can
675 result in either a parenthesized pointer (*) as in int (*)() or
676 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
678 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
679 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
681 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
682 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
684 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
686 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
688 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
689 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
691 ctf_dict_t
*rfp
= fp
;
692 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
693 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
695 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
696 ctf_decl_sprintf (&cd
, " ");
700 ctf_decl_sprintf (&cd
, "(");
704 switch (cdp
->cd_kind
)
709 /* Integers, floats, and typedefs must always be named types. */
713 ctf_set_errno (fp
, ECTF_CORRUPT
);
718 ctf_decl_sprintf (&cd
, "%s", name
);
721 ctf_decl_sprintf (&cd
, "*");
724 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
730 ctf_id_t
*argv
= NULL
;
732 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
733 goto err
; /* errno is set for us. */
735 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
737 ctf_set_errno (rfp
, errno
);
741 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
742 fi
.ctc_argc
, argv
) < 0)
743 goto err
; /* errno is set for us. */
745 ctf_decl_sprintf (&cd
, "(*) (");
746 for (i
= 0; i
< fi
.ctc_argc
; i
++)
748 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
751 goto err
; /* errno is set for us. */
752 ctf_decl_sprintf (&cd
, "%s", arg
);
755 if ((i
< fi
.ctc_argc
- 1)
756 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
757 ctf_decl_sprintf (&cd
, ", ");
760 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
761 ctf_decl_sprintf (&cd
, "...");
762 ctf_decl_sprintf (&cd
, ")");
774 ctf_decl_sprintf (&cd
, "struct %s", name
);
777 ctf_decl_sprintf (&cd
, "union %s", name
);
780 ctf_decl_sprintf (&cd
, "enum %s", name
);
784 switch (ctf_type_kind_forwarded (fp
, cdp
->cd_type
))
787 ctf_decl_sprintf (&cd
, "struct %s", name
);
790 ctf_decl_sprintf (&cd
, "union %s", name
);
793 ctf_decl_sprintf (&cd
, "enum %s", name
);
796 ctf_set_errno (fp
, ECTF_CORRUPT
);
803 ctf_decl_sprintf (&cd
, "volatile");
806 ctf_decl_sprintf (&cd
, "const");
809 ctf_decl_sprintf (&cd
, "restrict");
817 ctf_decl_sprintf (&cd
, ")");
821 (void) ctf_set_errno (fp
, ENOMEM
);
823 buf
= ctf_decl_buf (&cd
);
829 /* Lookup the given type ID and print a string name for it into buf. Return
830 the actual number of bytes (not including \0) needed to format the name. */
833 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
835 char *str
= ctf_type_aname (fp
, type
);
839 return CTF_ERR
; /* errno is set for us. */
842 snprintf (buf
, len
, "%s", str
);
846 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
851 /* Lookup the given type ID and print a string name for it into buf. If buf
852 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
855 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
857 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
858 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
861 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
862 The name will live as long as its ctf_dict_t does.
864 The only decoration is that a NULL return always means an error: nameless
865 types return a null string. */
868 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
870 const ctf_type_t
*tp
;
872 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
873 return NULL
; /* errno is set for us. */
875 if (tp
->ctt_name
== 0)
878 return ctf_strraw (fp
, tp
->ctt_name
);
881 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
882 new dynamically-allocated string. */
885 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
887 const char *name
= ctf_type_name_raw (fp
, type
);
890 return strdup (name
);
895 /* Resolve the type down to a base type node, and then return the size
896 of the type storage in bytes. */
899 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
901 ctf_dict_t
*ofp
= fp
;
902 const ctf_type_t
*tp
;
906 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
907 return -1; /* errno is set for us. */
909 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
910 return -1; /* errno is set for us. */
912 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
915 return fp
->ctf_dmodel
->ctd_pointer
;
918 return 0; /* Function size is only known by symtab. */
921 return fp
->ctf_dmodel
->ctd_int
;
924 /* ctf_add_array() does not directly encode the element size, but
925 requires the user to multiply to determine the element size.
927 If ctf_get_ctt_size() returns nonzero, then use the recorded
930 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
933 if (ctf_array_info (ofp
, type
, &ar
) < 0
934 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
935 return -1; /* errno is set for us. */
937 return size
* ar
.ctr_nelems
;
940 /* Forwards do not have a meaningful size. */
941 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
943 default: /* including slices of enums, etc */
944 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
948 /* Resolve the type down to a base type node, and then return the alignment
949 needed for the type storage in bytes.
951 XXX may need arch-dependent attention. */
954 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
956 const ctf_type_t
*tp
;
957 ctf_dict_t
*ofp
= fp
;
960 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
961 return -1; /* errno is set for us. */
963 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
964 return -1; /* errno is set for us. */
966 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
971 return fp
->ctf_dmodel
->ctd_pointer
;
976 if (ctf_array_info (ofp
, type
, &r
) < 0)
977 return -1; /* errno is set for us. */
978 return (ctf_type_align (ofp
, r
.ctr_contents
));
987 uint32_t i
= 0, n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
988 ssize_t size
, increment
, vbytes
;
990 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
992 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
994 vlen
= dtd
->dtd_vlen
;
995 vbytes
= dtd
->dtd_vlen_alloc
;
999 vlen
= (unsigned char *) tp
+ increment
;
1000 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1003 if (kind
== CTF_K_STRUCT
)
1004 n
= MIN (n
, 1); /* Only use first member for structs. */
1006 for (; n
!= 0; n
--, i
++)
1010 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1011 return -1; /* errno is set for us. */
1013 ssize_t am
= ctf_type_align (ofp
, memb
.ctlm_type
);
1014 align
= MAX (align
, (size_t) am
);
1020 return fp
->ctf_dmodel
->ctd_int
;
1023 /* Forwards do not have a meaningful alignment. */
1024 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1026 default: /* including slices of enums, etc */
1027 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1031 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1034 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1036 const ctf_type_t
*tp
;
1038 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1039 return -1; /* errno is set for us. */
1041 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1044 /* Return the kind (CTF_K_* constant) for the specified type ID.
1045 Slices are considered to be of the same kind as the type sliced. */
1048 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1052 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1055 if (kind
== CTF_K_SLICE
)
1057 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1059 kind
= ctf_type_kind_unsliced (fp
, type
);
1065 /* Return the kind of this type, except, for forwards, return the kind of thing
1066 this is a forward to. */
1068 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1071 const ctf_type_t
*tp
;
1073 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1074 return -1; /* errno is set for us. */
1076 if (kind
!= CTF_K_FORWARD
)
1079 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1080 return -1; /* errno is set for us. */
1082 return tp
->ctt_type
;
1085 /* If the type is one that directly references another type (such as POINTER),
1086 then return the ID of the type to which it refers. */
1089 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1091 ctf_dict_t
*ofp
= fp
;
1092 const ctf_type_t
*tp
;
1094 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1095 return CTF_ERR
; /* errno is set for us. */
1097 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1101 case CTF_K_VOLATILE
:
1103 case CTF_K_RESTRICT
:
1104 return tp
->ctt_type
;
1105 /* Slices store their type in an unusual place. */
1109 const ctf_slice_t
*sp
;
1111 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1115 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1116 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1119 sp
= (const ctf_slice_t
*) dtd
->dtd_vlen
;
1121 return sp
->cts_type
;
1124 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1128 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1129 pointer to the given type, see if we can compute a pointer to the type
1130 resulting from resolving the type down to its base type and use that
1131 instead. This helps with cases where the CTF data includes "struct foo *"
1132 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1134 XXX what about parent dicts? */
1137 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1139 ctf_dict_t
*ofp
= fp
;
1142 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1143 return CTF_ERR
; /* errno is set for us. */
1145 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1146 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1148 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1149 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1151 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1152 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1154 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1155 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1157 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1160 /* Return the encoding for the specified INTEGER, FLOAT, or ENUM. */
1163 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1165 ctf_dict_t
*ofp
= fp
;
1167 const ctf_type_t
*tp
;
1169 const unsigned char *vlen
;
1172 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1173 return -1; /* errno is set for us. */
1175 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1176 vlen
= dtd
->dtd_vlen
;
1179 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1180 vlen
= (const unsigned char *) ((uintptr_t) tp
+ increment
);
1183 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1186 data
= *(const uint32_t *) vlen
;
1187 ep
->cte_format
= CTF_INT_ENCODING (data
);
1188 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1189 ep
->cte_bits
= CTF_INT_BITS (data
);
1192 data
= *(const uint32_t *) vlen
;
1193 ep
->cte_format
= CTF_FP_ENCODING (data
);
1194 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1195 ep
->cte_bits
= CTF_FP_BITS (data
);
1198 /* v3 only: we must guess at the underlying integral format. */
1199 ep
->cte_format
= CTF_INT_SIGNED
;
1205 const ctf_slice_t
*slice
;
1206 ctf_encoding_t underlying_en
;
1207 ctf_id_t underlying
;
1209 slice
= (ctf_slice_t
*) vlen
;
1210 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1211 if (ctf_type_encoding (fp
, underlying
, &underlying_en
) < 0)
1212 return -1; /* errno is set for us. */
1214 ep
->cte_format
= underlying_en
.cte_format
;
1215 ep
->cte_offset
= slice
->cts_offset
;
1216 ep
->cte_bits
= slice
->cts_bits
;
1220 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1227 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1234 else if (ltype
> rtype
)
1242 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1243 lfp
= lfp
->ctf_parent
;
1245 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1246 rfp
= rfp
->ctf_parent
;
1257 /* Return a boolean value indicating if two types are compatible. This function
1258 returns true if the two types are the same, or if they (or their ultimate
1259 base type) have the same encoding properties, or (for structs / unions /
1260 enums / forward declarations) if they have the same name and (for structs /
1261 unions) member count. */
1264 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1265 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1267 const ctf_type_t
*ltp
, *rtp
;
1268 ctf_encoding_t le
, re
;
1269 ctf_arinfo_t la
, ra
;
1270 uint32_t lkind
, rkind
;
1273 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1276 ltype
= ctf_type_resolve (lfp
, ltype
);
1277 lkind
= ctf_type_kind (lfp
, ltype
);
1279 rtype
= ctf_type_resolve (rfp
, rtype
);
1280 rkind
= ctf_type_kind (rfp
, rtype
);
1282 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1283 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1285 if (ltp
!= NULL
&& rtp
!= NULL
)
1286 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1287 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1289 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1290 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1300 memset (&le
, 0, sizeof (le
));
1301 memset (&re
, 0, sizeof (re
));
1302 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1303 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1304 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1306 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1307 rfp
, ctf_type_reference (rfp
, rtype
)));
1309 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1310 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1311 && la
.ctr_nelems
== ra
.ctr_nelems
1312 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1313 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1316 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1317 == ctf_type_size (rfp
, rtype
)));
1320 int lencoded
, rencoded
;
1321 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1322 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1324 if ((lencoded
!= rencoded
) ||
1325 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1330 return same_names
; /* No other checks required for these type kinds. */
1332 return 0; /* Should not get here since we did a resolve. */
1336 /* Return the number of members in a STRUCT or UNION, or the number of
1337 enumerators in an ENUM. The count does not include unnamed sub-members. */
1340 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1342 ctf_dict_t
*ofp
= fp
;
1343 const ctf_type_t
*tp
;
1346 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1347 return -1; /* errno is set for us. */
1349 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1350 return -1; /* errno is set for us. */
1352 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1354 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1355 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1357 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1360 /* Return the type and offset for a given member of a STRUCT or UNION. */
1363 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1364 ctf_membinfo_t
*mip
)
1366 ctf_dict_t
*ofp
= fp
;
1367 const ctf_type_t
*tp
;
1369 unsigned char *vlen
;
1370 ssize_t size
, increment
, vbytes
;
1371 uint32_t kind
, n
, i
= 0;
1373 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1374 return -1; /* errno is set for us. */
1376 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1377 return -1; /* errno is set for us. */
1379 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1380 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1382 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1383 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1385 n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1386 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1388 vlen
= dtd
->dtd_vlen
;
1389 vbytes
= dtd
->dtd_vlen_alloc
;
1393 vlen
= (unsigned char *) tp
+ increment
;
1394 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1397 for (; n
!= 0; n
--, i
++)
1400 const char *membname
;
1402 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1403 return -1; /* errno is set for us. */
1405 membname
= ctf_strptr (fp
, memb
.ctlm_name
);
1407 if (membname
[0] == 0
1408 && (ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_STRUCT
1409 || ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_UNION
)
1410 && (ctf_member_info (fp
, memb
.ctlm_type
, name
, mip
) == 0))
1413 if (strcmp (membname
, name
) == 0)
1415 mip
->ctm_type
= memb
.ctlm_type
;
1416 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (&memb
);
1421 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1424 /* Return the array type, index, and size information for the specified ARRAY. */
1427 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1429 ctf_dict_t
*ofp
= fp
;
1430 const ctf_type_t
*tp
;
1431 const ctf_array_t
*ap
;
1432 const ctf_dtdef_t
*dtd
;
1435 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1436 return -1; /* errno is set for us. */
1438 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1439 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1441 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1442 ap
= (const ctf_array_t
*) dtd
->dtd_vlen
;
1445 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1446 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1448 arp
->ctr_contents
= ap
->cta_contents
;
1449 arp
->ctr_index
= ap
->cta_index
;
1450 arp
->ctr_nelems
= ap
->cta_nelems
;
1455 /* Convert the specified value to the corresponding enum tag name, if a
1456 matching name can be found. Otherwise NULL is returned. */
1459 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1461 ctf_dict_t
*ofp
= fp
;
1462 const ctf_type_t
*tp
;
1463 const ctf_enum_t
*ep
;
1464 const ctf_dtdef_t
*dtd
;
1468 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1469 return NULL
; /* errno is set for us. */
1471 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1472 return NULL
; /* errno is set for us. */
1474 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1476 ctf_set_errno (ofp
, ECTF_NOTENUM
);
1480 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1482 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1483 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1485 ep
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
1487 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1489 if (ep
->cte_value
== value
)
1490 return (ctf_strptr (fp
, ep
->cte_name
));
1493 ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1497 /* Convert the specified enum tag name to the corresponding value, if a
1498 matching name can be found. Otherwise CTF_ERR is returned. */
1501 ctf_enum_value (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
, int *valp
)
1503 ctf_dict_t
*ofp
= fp
;
1504 const ctf_type_t
*tp
;
1505 const ctf_enum_t
*ep
;
1506 const ctf_dtdef_t
*dtd
;
1510 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1511 return -1; /* errno is set for us. */
1513 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1514 return -1; /* errno is set for us. */
1516 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1518 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1522 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1524 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1525 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1527 ep
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
1529 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1531 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1534 *valp
= ep
->cte_value
;
1539 ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1543 /* Given a type ID relating to a function type, return info on return types and
1544 arg counts for that function. */
1547 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1549 const ctf_type_t
*tp
;
1551 const uint32_t *args
;
1552 const ctf_dtdef_t
*dtd
;
1553 ssize_t size
, increment
;
1555 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1556 return -1; /* errno is set for us. */
1558 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1559 return -1; /* errno is set for us. */
1561 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1562 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1564 if (kind
!= CTF_K_FUNCTION
)
1565 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1567 fip
->ctc_return
= tp
->ctt_type
;
1569 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1571 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1572 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1574 args
= (uint32_t *) dtd
->dtd_vlen
;
1576 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1578 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1585 /* Given a type ID relating to a function type, return the arguments for the
1589 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1591 const ctf_type_t
*tp
;
1592 const uint32_t *args
;
1593 const ctf_dtdef_t
*dtd
;
1594 ssize_t size
, increment
;
1597 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1598 return -1; /* errno is set for us. */
1600 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1601 return -1; /* errno is set for us. */
1603 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1604 return -1; /* errno is set for us. */
1606 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1608 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1609 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1611 args
= (uint32_t *) dtd
->dtd_vlen
;
1613 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1619 /* Recursively visit the members of any type. This function is used as the
1620 engine for ctf_type_visit, below. We resolve the input type, recursively
1621 invoke ourself for each type member if the type is a struct or union, and
1622 then invoke the callback function on the current type. If any callback
1623 returns non-zero, we abort and percolate the error code back up to the top. */
1626 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1627 void *arg
, const char *name
, unsigned long offset
, int depth
)
1629 ctf_id_t otype
= type
;
1630 const ctf_type_t
*tp
;
1631 const ctf_dtdef_t
*dtd
;
1632 unsigned char *vlen
;
1633 ssize_t size
, increment
, vbytes
;
1634 uint32_t kind
, n
, i
= 0;
1637 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1638 return -1; /* errno is set for us. */
1640 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1641 return -1; /* errno is set for us. */
1643 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1646 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1648 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1651 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1653 n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1654 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1656 vlen
= dtd
->dtd_vlen
;
1657 vbytes
= dtd
->dtd_vlen_alloc
;
1661 vlen
= (unsigned char *) tp
+ increment
;
1662 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1665 for (; n
!= 0; n
--, i
++)
1669 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1670 return -1; /* errno is set for us. */
1672 if ((rc
= ctf_type_rvisit (fp
, memb
.ctlm_type
,
1673 func
, arg
, ctf_strptr (fp
, memb
.ctlm_name
),
1674 offset
+ (unsigned long) CTF_LMEM_OFFSET (&memb
),
1682 /* Recursively visit the members of any type. We pass the name, member
1683 type, and offset of each member to the specified callback function. */
1685 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1687 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));