1 /* Type handling functions.
2 Copyright (C) 2019-2023 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
));
583 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
588 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
591 return CTF_ERR
; /* errno is set for us. */
594 /* Like ctf_type_resolve(), but traverse down through slices to their contained
598 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
600 const ctf_type_t
*tp
;
602 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
605 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
606 return CTF_ERR
; /* errno is set for us. */
608 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
609 return ctf_type_reference (fp
, type
);
613 /* Return the native dict of a given type: if called on a child and the
614 type is in the parent, return the parent. Needed if you plan to access
615 the type directly, without using the API. */
617 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
619 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
620 return fp
->ctf_parent
;
625 /* Look up a name in the given name table, in the appropriate hash given the
626 kind of the identifier. The name is a raw, undecorated identifier. */
628 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
630 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
633 /* Look up a name in the given name table, in the appropriate hash given the
634 readability state of the dictionary. The name is a raw, undecorated
637 ctf_id_t
ctf_lookup_by_rawhash (ctf_dict_t
*fp
, ctf_names_t
*np
, const char *name
)
641 if (fp
->ctf_flags
& LCTF_RDWR
)
642 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
644 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
648 /* Lookup the given type ID and return its name as a new dynamically-allocated
652 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
655 ctf_decl_node_t
*cdp
;
656 ctf_decl_prec_t prec
, lp
, rp
;
661 if (fp
== NULL
&& type
== CTF_ERR
)
662 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
665 ctf_decl_push (&cd
, fp
, type
);
670 ctf_set_errno (fp
, cd
.cd_err
);
674 /* If the type graph's order conflicts with lexical precedence order
675 for pointers or arrays, then we need to surround the declarations at
676 the corresponding lexical precedence with parentheses. This can
677 result in either a parenthesized pointer (*) as in int (*)() or
678 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
680 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
681 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
683 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
684 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
686 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
688 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
690 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
691 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
693 ctf_dict_t
*rfp
= fp
;
694 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
695 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
697 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
698 ctf_decl_sprintf (&cd
, " ");
702 ctf_decl_sprintf (&cd
, "(");
706 switch (cdp
->cd_kind
)
711 /* Integers, floats, and typedefs must always be named types. */
715 ctf_set_errno (fp
, ECTF_CORRUPT
);
720 ctf_decl_sprintf (&cd
, "%s", name
);
723 ctf_decl_sprintf (&cd
, "*");
726 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
732 ctf_id_t
*argv
= NULL
;
734 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
735 goto err
; /* errno is set for us. */
737 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
739 ctf_set_errno (rfp
, errno
);
743 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
744 fi
.ctc_argc
, argv
) < 0)
745 goto err
; /* errno is set for us. */
747 ctf_decl_sprintf (&cd
, "(*) (");
748 for (i
= 0; i
< fi
.ctc_argc
; i
++)
750 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
753 goto err
; /* errno is set for us. */
754 ctf_decl_sprintf (&cd
, "%s", arg
);
757 if ((i
< fi
.ctc_argc
- 1)
758 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
759 ctf_decl_sprintf (&cd
, ", ");
762 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
763 ctf_decl_sprintf (&cd
, "...");
764 ctf_decl_sprintf (&cd
, ")");
776 ctf_decl_sprintf (&cd
, "struct %s", name
);
779 ctf_decl_sprintf (&cd
, "union %s", name
);
782 ctf_decl_sprintf (&cd
, "enum %s", name
);
786 switch (ctf_type_kind_forwarded (fp
, cdp
->cd_type
))
789 ctf_decl_sprintf (&cd
, "struct %s", name
);
792 ctf_decl_sprintf (&cd
, "union %s", name
);
795 ctf_decl_sprintf (&cd
, "enum %s", name
);
798 ctf_set_errno (fp
, ECTF_CORRUPT
);
805 ctf_decl_sprintf (&cd
, "volatile");
808 ctf_decl_sprintf (&cd
, "const");
811 ctf_decl_sprintf (&cd
, "restrict");
815 ctf_decl_sprintf (&cd
, _("(nonrepresentable type)"));
817 ctf_decl_sprintf (&cd
, _("(nonrepresentable type %s)"),
826 ctf_decl_sprintf (&cd
, ")");
830 (void) ctf_set_errno (fp
, ENOMEM
);
832 buf
= ctf_decl_buf (&cd
);
838 /* Lookup the given type ID and print a string name for it into buf. Return
839 the actual number of bytes (not including \0) needed to format the name. */
842 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
844 char *str
= ctf_type_aname (fp
, type
);
848 return CTF_ERR
; /* errno is set for us. */
851 snprintf (buf
, len
, "%s", str
);
855 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
860 /* Lookup the given type ID and print a string name for it into buf. If buf
861 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
864 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
866 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
867 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
870 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
871 The name will live as long as its ctf_dict_t does.
873 The only decoration is that a NULL return always means an error: nameless
874 types return a null string. */
877 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
879 const ctf_type_t
*tp
;
881 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
882 return NULL
; /* errno is set for us. */
884 if (tp
->ctt_name
== 0)
887 return ctf_strraw (fp
, tp
->ctt_name
);
890 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
891 new dynamically-allocated string. */
894 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
896 const char *name
= ctf_type_name_raw (fp
, type
);
899 return strdup (name
);
904 /* Resolve the type down to a base type node, and then return the size
905 of the type storage in bytes. */
908 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
910 ctf_dict_t
*ofp
= fp
;
911 const ctf_type_t
*tp
;
915 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
916 return -1; /* errno is set for us. */
918 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
919 return -1; /* errno is set for us. */
921 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
924 return fp
->ctf_dmodel
->ctd_pointer
;
927 return 0; /* Function size is only known by symtab. */
930 return fp
->ctf_dmodel
->ctd_int
;
933 /* ctf_add_array() does not directly encode the element size, but
934 requires the user to multiply to determine the element size.
936 If ctf_get_ctt_size() returns nonzero, then use the recorded
939 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
942 if (ctf_array_info (ofp
, type
, &ar
) < 0
943 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
944 return -1; /* errno is set for us. */
946 return size
* ar
.ctr_nelems
;
949 /* Forwards do not have a meaningful size. */
950 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
952 default: /* including slices of enums, etc */
953 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
957 /* Resolve the type down to a base type node, and then return the alignment
958 needed for the type storage in bytes.
960 XXX may need arch-dependent attention. */
963 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
965 const ctf_type_t
*tp
;
966 ctf_dict_t
*ofp
= fp
;
969 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
970 return -1; /* errno is set for us. */
972 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
973 return -1; /* errno is set for us. */
975 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
980 return fp
->ctf_dmodel
->ctd_pointer
;
985 if (ctf_array_info (ofp
, type
, &r
) < 0)
986 return -1; /* errno is set for us. */
987 return (ctf_type_align (ofp
, r
.ctr_contents
));
996 uint32_t i
= 0, n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
997 ssize_t size
, increment
, vbytes
;
999 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1001 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1003 vlen
= dtd
->dtd_vlen
;
1004 vbytes
= dtd
->dtd_vlen_alloc
;
1008 vlen
= (unsigned char *) tp
+ increment
;
1009 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1012 if (kind
== CTF_K_STRUCT
)
1013 n
= MIN (n
, 1); /* Only use first member for structs. */
1015 for (; n
!= 0; n
--, i
++)
1019 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1020 return -1; /* errno is set for us. */
1022 ssize_t am
= ctf_type_align (ofp
, memb
.ctlm_type
);
1023 align
= MAX (align
, (size_t) am
);
1029 return fp
->ctf_dmodel
->ctd_int
;
1032 /* Forwards do not have a meaningful alignment. */
1033 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1035 default: /* including slices of enums, etc */
1036 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1040 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1043 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1045 const ctf_type_t
*tp
;
1047 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1048 return -1; /* errno is set for us. */
1050 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1053 /* Return the kind (CTF_K_* constant) for the specified type ID.
1054 Slices are considered to be of the same kind as the type sliced. */
1057 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1061 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1064 if (kind
== CTF_K_SLICE
)
1066 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1068 kind
= ctf_type_kind_unsliced (fp
, type
);
1074 /* Return the kind of this type, except, for forwards, return the kind of thing
1075 this is a forward to. */
1077 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1080 const ctf_type_t
*tp
;
1082 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1083 return -1; /* errno is set for us. */
1085 if (kind
!= CTF_K_FORWARD
)
1088 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1089 return -1; /* errno is set for us. */
1091 return tp
->ctt_type
;
1094 /* If the type is one that directly references another type (such as POINTER),
1095 then return the ID of the type to which it refers. */
1098 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1100 ctf_dict_t
*ofp
= fp
;
1101 const ctf_type_t
*tp
;
1103 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1104 return CTF_ERR
; /* errno is set for us. */
1106 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1110 case CTF_K_VOLATILE
:
1112 case CTF_K_RESTRICT
:
1113 return tp
->ctt_type
;
1114 /* Slices store their type in an unusual place. */
1118 const ctf_slice_t
*sp
;
1120 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1124 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1125 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1128 sp
= (const ctf_slice_t
*) dtd
->dtd_vlen
;
1130 return sp
->cts_type
;
1133 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1137 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1138 pointer to the given type, see if we can compute a pointer to the type
1139 resulting from resolving the type down to its base type and use that
1140 instead. This helps with cases where the CTF data includes "struct foo *"
1141 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1143 XXX what about parent dicts? */
1146 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1148 ctf_dict_t
*ofp
= fp
;
1151 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1152 return CTF_ERR
; /* errno is set for us. */
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 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1158 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1160 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1161 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1163 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1164 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1166 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1169 /* Return the encoding for the specified INTEGER, FLOAT, or ENUM. */
1172 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1174 ctf_dict_t
*ofp
= fp
;
1176 const ctf_type_t
*tp
;
1178 const unsigned char *vlen
;
1181 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1182 return -1; /* errno is set for us. */
1184 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1185 vlen
= dtd
->dtd_vlen
;
1188 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1189 vlen
= (const unsigned char *) ((uintptr_t) tp
+ increment
);
1192 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1195 data
= *(const uint32_t *) vlen
;
1196 ep
->cte_format
= CTF_INT_ENCODING (data
);
1197 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1198 ep
->cte_bits
= CTF_INT_BITS (data
);
1201 data
= *(const uint32_t *) vlen
;
1202 ep
->cte_format
= CTF_FP_ENCODING (data
);
1203 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1204 ep
->cte_bits
= CTF_FP_BITS (data
);
1207 /* v3 only: we must guess at the underlying integral format. */
1208 ep
->cte_format
= CTF_INT_SIGNED
;
1214 const ctf_slice_t
*slice
;
1215 ctf_encoding_t underlying_en
;
1216 ctf_id_t underlying
;
1218 slice
= (ctf_slice_t
*) vlen
;
1219 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1220 if (ctf_type_encoding (fp
, underlying
, &underlying_en
) < 0)
1221 return -1; /* errno is set for us. */
1223 ep
->cte_format
= underlying_en
.cte_format
;
1224 ep
->cte_offset
= slice
->cts_offset
;
1225 ep
->cte_bits
= slice
->cts_bits
;
1229 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1236 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1243 else if (ltype
> rtype
)
1251 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1252 lfp
= lfp
->ctf_parent
;
1254 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1255 rfp
= rfp
->ctf_parent
;
1266 /* Return a boolean value indicating if two types are compatible. This function
1267 returns true if the two types are the same, or if they (or their ultimate
1268 base type) have the same encoding properties, or (for structs / unions /
1269 enums / forward declarations) if they have the same name and (for structs /
1270 unions) member count. */
1273 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1274 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1276 const ctf_type_t
*ltp
, *rtp
;
1277 ctf_encoding_t le
, re
;
1278 ctf_arinfo_t la
, ra
;
1279 uint32_t lkind
, rkind
;
1282 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1285 ltype
= ctf_type_resolve (lfp
, ltype
);
1286 lkind
= ctf_type_kind (lfp
, ltype
);
1288 rtype
= ctf_type_resolve (rfp
, rtype
);
1289 rkind
= ctf_type_kind (rfp
, rtype
);
1291 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1292 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1294 if (ltp
!= NULL
&& rtp
!= NULL
)
1295 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1296 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1298 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1299 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1309 memset (&le
, 0, sizeof (le
));
1310 memset (&re
, 0, sizeof (re
));
1311 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1312 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1313 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1315 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1316 rfp
, ctf_type_reference (rfp
, rtype
)));
1318 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1319 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1320 && la
.ctr_nelems
== ra
.ctr_nelems
1321 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1322 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1325 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1326 == ctf_type_size (rfp
, rtype
)));
1329 int lencoded
, rencoded
;
1330 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1331 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1333 if ((lencoded
!= rencoded
) ||
1334 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1339 return same_names
; /* No other checks required for these type kinds. */
1341 return 0; /* Should not get here since we did a resolve. */
1345 /* Return the number of members in a STRUCT or UNION, or the number of
1346 enumerators in an ENUM. The count does not include unnamed sub-members. */
1349 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1351 ctf_dict_t
*ofp
= fp
;
1352 const ctf_type_t
*tp
;
1355 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1356 return -1; /* errno is set for us. */
1358 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1359 return -1; /* errno is set for us. */
1361 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1363 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1364 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1366 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1369 /* Return the type and offset for a given member of a STRUCT or UNION. */
1372 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1373 ctf_membinfo_t
*mip
)
1375 ctf_dict_t
*ofp
= fp
;
1376 const ctf_type_t
*tp
;
1378 unsigned char *vlen
;
1379 ssize_t size
, increment
, vbytes
;
1380 uint32_t kind
, n
, i
= 0;
1382 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1383 return -1; /* errno is set for us. */
1385 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1386 return -1; /* errno is set for us. */
1388 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1389 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1391 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1392 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1394 n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1395 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1397 vlen
= dtd
->dtd_vlen
;
1398 vbytes
= dtd
->dtd_vlen_alloc
;
1402 vlen
= (unsigned char *) tp
+ increment
;
1403 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1406 for (; n
!= 0; n
--, i
++)
1409 const char *membname
;
1411 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1412 return -1; /* errno is set for us. */
1414 membname
= ctf_strptr (fp
, memb
.ctlm_name
);
1416 if (membname
[0] == 0
1417 && (ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_STRUCT
1418 || ctf_type_kind (fp
, memb
.ctlm_type
) == CTF_K_UNION
)
1419 && (ctf_member_info (fp
, memb
.ctlm_type
, name
, mip
) == 0))
1422 if (strcmp (membname
, name
) == 0)
1424 mip
->ctm_type
= memb
.ctlm_type
;
1425 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (&memb
);
1430 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1433 /* Return the array type, index, and size information for the specified ARRAY. */
1436 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1438 ctf_dict_t
*ofp
= fp
;
1439 const ctf_type_t
*tp
;
1440 const ctf_array_t
*ap
;
1441 const ctf_dtdef_t
*dtd
;
1444 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1445 return -1; /* errno is set for us. */
1447 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1448 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1450 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1451 ap
= (const ctf_array_t
*) dtd
->dtd_vlen
;
1454 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1455 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1457 arp
->ctr_contents
= ap
->cta_contents
;
1458 arp
->ctr_index
= ap
->cta_index
;
1459 arp
->ctr_nelems
= ap
->cta_nelems
;
1464 /* Convert the specified value to the corresponding enum tag name, if a
1465 matching name can be found. Otherwise NULL is returned. */
1468 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1470 ctf_dict_t
*ofp
= fp
;
1471 const ctf_type_t
*tp
;
1472 const ctf_enum_t
*ep
;
1473 const ctf_dtdef_t
*dtd
;
1477 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1478 return NULL
; /* errno is set for us. */
1480 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1481 return NULL
; /* errno is set for us. */
1483 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1485 ctf_set_errno (ofp
, ECTF_NOTENUM
);
1489 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1491 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1492 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1494 ep
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
1496 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1498 if (ep
->cte_value
== value
)
1499 return (ctf_strptr (fp
, ep
->cte_name
));
1502 ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1506 /* Convert the specified enum tag name to the corresponding value, if a
1507 matching name can be found. Otherwise CTF_ERR is returned. */
1510 ctf_enum_value (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
, int *valp
)
1512 ctf_dict_t
*ofp
= fp
;
1513 const ctf_type_t
*tp
;
1514 const ctf_enum_t
*ep
;
1515 const ctf_dtdef_t
*dtd
;
1519 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1520 return -1; /* errno is set for us. */
1522 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1523 return -1; /* errno is set for us. */
1525 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1527 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1531 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1533 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1534 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1536 ep
= (const ctf_enum_t
*) dtd
->dtd_vlen
;
1538 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1540 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1543 *valp
= ep
->cte_value
;
1548 ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1552 /* Given a type ID relating to a function type, return info on return types and
1553 arg counts for that function. */
1556 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1558 const ctf_type_t
*tp
;
1560 const uint32_t *args
;
1561 const ctf_dtdef_t
*dtd
;
1562 ssize_t size
, increment
;
1564 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1565 return -1; /* errno is set for us. */
1567 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1568 return -1; /* errno is set for us. */
1570 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1571 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1573 if (kind
!= CTF_K_FUNCTION
)
1574 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1576 fip
->ctc_return
= tp
->ctt_type
;
1578 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1580 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1581 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1583 args
= (uint32_t *) dtd
->dtd_vlen
;
1585 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1587 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1594 /* Given a type ID relating to a function type, return the arguments for the
1598 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1600 const ctf_type_t
*tp
;
1601 const uint32_t *args
;
1602 const ctf_dtdef_t
*dtd
;
1603 ssize_t size
, increment
;
1606 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1607 return -1; /* errno is set for us. */
1609 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1610 return -1; /* errno is set for us. */
1612 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1613 return -1; /* errno is set for us. */
1615 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1617 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1618 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1620 args
= (uint32_t *) dtd
->dtd_vlen
;
1622 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1628 /* Recursively visit the members of any type. This function is used as the
1629 engine for ctf_type_visit, below. We resolve the input type, recursively
1630 invoke ourself for each type member if the type is a struct or union, and
1631 then invoke the callback function on the current type. If any callback
1632 returns non-zero, we abort and percolate the error code back up to the top. */
1635 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1636 void *arg
, const char *name
, unsigned long offset
, int depth
)
1638 ctf_id_t otype
= type
;
1639 const ctf_type_t
*tp
;
1640 const ctf_dtdef_t
*dtd
;
1641 unsigned char *vlen
;
1642 ssize_t size
, increment
, vbytes
;
1643 uint32_t kind
, n
, i
= 0;
1644 int nonrepresentable
= 0;
1647 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
) {
1648 if (ctf_errno (fp
) != ECTF_NONREPRESENTABLE
)
1649 return -1; /* errno is set for us. */
1651 nonrepresentable
= 1;
1654 if (!nonrepresentable
)
1655 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1656 return -1; /* errno is set for us. */
1658 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1661 if (!nonrepresentable
)
1662 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1664 if (nonrepresentable
|| (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
))
1667 ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1669 n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1670 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
1672 vlen
= dtd
->dtd_vlen
;
1673 vbytes
= dtd
->dtd_vlen_alloc
;
1677 vlen
= (unsigned char *) tp
+ increment
;
1678 vbytes
= LCTF_VBYTES (fp
, kind
, size
, n
);
1681 for (; n
!= 0; n
--, i
++)
1685 if (ctf_struct_member (fp
, &memb
, tp
, vlen
, vbytes
, i
) < 0)
1686 return -1; /* errno is set for us. */
1688 if ((rc
= ctf_type_rvisit (fp
, memb
.ctlm_type
,
1689 func
, arg
, ctf_strptr (fp
, memb
.ctlm_name
),
1690 offset
+ (unsigned long) CTF_LMEM_OFFSET (&memb
),
1698 /* Recursively visit the members of any type. We pass the name, member
1699 type, and offset of each member to the specified callback function. */
1701 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1703 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));