1 /* Type handling functions.
2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
4 This file is part of libctf.
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
24 /* Determine whether a type is a parent or a child. */
27 ctf_type_isparent (ctf_dict_t
*fp
, ctf_id_t id
)
29 return (LCTF_TYPE_ISPARENT (fp
, id
));
33 ctf_type_ischild (ctf_dict_t
* fp
, ctf_id_t id
)
35 return (LCTF_TYPE_ISCHILD (fp
, id
));
38 /* Iterate over the members of a STRUCT or UNION. We pass the name, member
39 type, and offset of each member to the specified callback function. */
42 ctf_member_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_member_f
*func
, void *arg
)
47 ssize_t size
, increment
;
51 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
52 return -1; /* errno is set for us. */
54 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
55 return -1; /* errno is set for us. */
57 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
58 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
60 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
61 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
63 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
65 if (size
< CTF_LSTRUCT_THRESH
)
67 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
70 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
72 const char *name
= ctf_strptr (fp
, mp
->ctm_name
);
73 if ((rc
= func (name
, mp
->ctm_type
, mp
->ctm_offset
, arg
)) != 0)
79 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
82 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
84 const char *name
= ctf_strptr (fp
, lmp
->ctlm_name
);
85 if ((rc
= func (name
, lmp
->ctlm_type
,
86 (unsigned long) CTF_LMEM_OFFSET (lmp
), arg
)) != 0)
95 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
96 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
98 if ((rc
= func (dmd
->dmd_name
, dmd
->dmd_type
,
99 dmd
->dmd_offset
, arg
)) != 0)
107 /* Iterate over the members of a STRUCT or UNION, returning each member's
108 offset and optionally name and member type in turn. On end-of-iteration,
112 ctf_member_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
113 const char **name
, ctf_id_t
*membtype
)
115 ctf_dict_t
*ofp
= fp
;
122 const ctf_type_t
*tp
;
125 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
126 return -1; /* errno is set for us. */
128 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
129 return -1; /* errno is set for us. */
131 if ((i
= ctf_next_create ()) == NULL
)
132 return ctf_set_errno (ofp
, ENOMEM
);
135 (void) ctf_get_ctt_size (fp
, tp
, &i
->ctn_size
,
137 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
139 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
141 ctf_next_destroy (i
);
142 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
145 dtd
= ctf_dynamic_type (fp
, type
);
146 i
->ctn_iter_fun
= (void (*) (void)) ctf_member_next
;
148 /* We depend below on the RDWR state indicating whether the DTD-related
149 fields or the DMD-related fields have been initialized. */
151 assert ((dtd
&& (fp
->ctf_flags
& LCTF_RDWR
))
152 || (!dtd
&& (!(fp
->ctf_flags
& LCTF_RDWR
))));
156 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
158 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
159 i
->u
.ctn_mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
162 i
->u
.ctn_lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
166 i
->u
.ctn_dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
171 if ((void (*) (void)) ctf_member_next
!= i
->ctn_iter_fun
)
172 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
));
174 if (ofp
!= i
->cu
.ctn_fp
)
175 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
));
177 /* Resolve to the native dict of this type. */
178 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
179 return (ctf_set_errno (ofp
, ECTF_NOPARENT
));
181 if (!(fp
->ctf_flags
& LCTF_RDWR
))
186 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
189 *name
= ctf_strptr (fp
, i
->u
.ctn_mp
->ctm_name
);
191 *membtype
= i
->u
.ctn_mp
->ctm_type
;
192 offset
= i
->u
.ctn_mp
->ctm_offset
;
198 *name
= ctf_strptr (fp
, i
->u
.ctn_lmp
->ctlm_name
);
200 *membtype
= i
->u
.ctn_lmp
->ctlm_type
;
201 offset
= (unsigned long) CTF_LMEM_OFFSET (i
->u
.ctn_lmp
);
208 if (i
->u
.ctn_dmd
== NULL
)
211 *name
= i
->u
.ctn_dmd
->dmd_name
;
213 *membtype
= i
->u
.ctn_dmd
->dmd_type
;
214 offset
= i
->u
.ctn_dmd
->dmd_offset
;
215 i
->u
.ctn_dmd
= ctf_list_next (i
->u
.ctn_dmd
);
221 ctf_next_destroy (i
);
223 return ctf_set_errno (ofp
, ECTF_NEXT_END
);
226 /* Iterate over the members of an ENUM. We pass the string name and associated
227 integer value of each enum element to the specified callback function. */
230 ctf_enum_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
232 ctf_dict_t
*ofp
= fp
;
233 const ctf_type_t
*tp
;
234 const ctf_enum_t
*ep
;
240 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
241 return -1; /* errno is set for us. */
243 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
244 return -1; /* errno is set for us. */
246 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
247 return (ctf_set_errno (ofp
, ECTF_NOTENUM
));
249 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
251 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
253 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
255 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
257 const char *name
= ctf_strptr (fp
, ep
->cte_name
);
258 if ((rc
= func (name
, ep
->cte_value
, arg
)) != 0)
266 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
267 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
269 if ((rc
= func (dmd
->dmd_name
, dmd
->dmd_value
, arg
)) != 0)
277 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
278 NULL at end of iteration or error, and optionally passing back the
279 enumerand's integer VALue. */
282 ctf_enum_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
285 ctf_dict_t
*ofp
= fp
;
292 const ctf_type_t
*tp
;
295 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
296 return NULL
; /* errno is set for us. */
298 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
299 return NULL
; /* errno is set for us. */
301 if ((i
= ctf_next_create ()) == NULL
)
303 ctf_set_errno (ofp
, ENOMEM
);
308 (void) ctf_get_ctt_size (fp
, tp
, NULL
,
310 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
312 if (kind
!= CTF_K_ENUM
)
314 ctf_next_destroy (i
);
315 ctf_set_errno (ofp
, ECTF_NOTENUM
);
319 dtd
= ctf_dynamic_type (fp
, type
);
320 i
->ctn_iter_fun
= (void (*) (void)) ctf_enum_next
;
322 /* We depend below on the RDWR state indicating whether the DTD-related
323 fields or the DMD-related fields have been initialized. */
325 assert ((dtd
&& (fp
->ctf_flags
& LCTF_RDWR
))
326 || (!dtd
&& (!(fp
->ctf_flags
& LCTF_RDWR
))));
330 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
332 i
->u
.ctn_en
= (const ctf_enum_t
*) ((uintptr_t) tp
+
336 i
->u
.ctn_dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
341 if ((void (*) (void)) ctf_enum_next
!= i
->ctn_iter_fun
)
343 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
);
347 if (ofp
!= i
->cu
.ctn_fp
)
349 ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
);
353 /* Resolve to the native dict of this type. */
354 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
356 ctf_set_errno (ofp
, ECTF_NOPARENT
);
360 if (!(fp
->ctf_flags
& LCTF_RDWR
))
365 name
= ctf_strptr (fp
, i
->u
.ctn_en
->cte_name
);
367 *val
= i
->u
.ctn_en
->cte_value
;
373 if (i
->u
.ctn_dmd
== NULL
)
376 name
= i
->u
.ctn_dmd
->dmd_name
;
378 *val
= i
->u
.ctn_dmd
->dmd_value
;
379 i
->u
.ctn_dmd
= ctf_list_next (i
->u
.ctn_dmd
);
385 ctf_next_destroy (i
);
387 ctf_set_errno (ofp
, ECTF_NEXT_END
);
391 /* Iterate over every root (user-visible) type in the given CTF dict.
392 We pass the type ID of each type to the specified callback function.
394 Does not traverse parent types: you have to do that explicitly. This is by
395 design, to avoid traversing them more than once if traversing many children
396 of a single parent. */
399 ctf_type_iter (ctf_dict_t
*fp
, ctf_type_f
*func
, void *arg
)
401 ctf_id_t id
, max
= fp
->ctf_typemax
;
402 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
404 for (id
= 1; id
<= max
; id
++)
406 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
407 if (LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)
408 && (rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
), arg
)) != 0)
415 /* Iterate over every type in the given CTF dict, user-visible or not.
416 We pass the type ID of each type to the specified callback function.
418 Does not traverse parent types: you have to do that explicitly. This is by
419 design, to avoid traversing them more than once if traversing many children
420 of a single parent. */
423 ctf_type_iter_all (ctf_dict_t
*fp
, ctf_type_all_f
*func
, void *arg
)
425 ctf_id_t id
, max
= fp
->ctf_typemax
;
426 int rc
, child
= (fp
->ctf_flags
& LCTF_CHILD
);
428 for (id
= 1; id
<= max
; id
++)
430 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, id
);
431 if ((rc
= func (LCTF_INDEX_TO_TYPE (fp
, id
, child
),
432 LCTF_INFO_ISROOT(fp
, tp
->ctt_info
)
433 ? CTF_ADD_ROOT
: CTF_ADD_NONROOT
, arg
) != 0))
440 /* Iterate over every type in the given CTF dict, optionally including
441 non-user-visible types, returning each type ID and hidden flag in turn.
442 Returns CTF_ERR on end of iteration or error.
444 Does not traverse parent types: you have to do that explicitly. This is by
445 design, to avoid traversing them more than once if traversing many children
446 of a single parent. */
449 ctf_type_next (ctf_dict_t
*fp
, ctf_next_t
**it
, int *flag
, int want_hidden
)
455 if ((i
= ctf_next_create ()) == NULL
)
456 return ctf_set_errno (fp
, ENOMEM
);
460 i
->ctn_iter_fun
= (void (*) (void)) ctf_type_next
;
464 if ((void (*) (void)) ctf_type_next
!= i
->ctn_iter_fun
)
465 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
467 if (fp
!= i
->cu
.ctn_fp
)
468 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
470 while (i
->ctn_type
<= fp
->ctf_typemax
)
472 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, i
->ctn_type
);
474 if ((!want_hidden
) && (!LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)))
481 *flag
= LCTF_INFO_ISROOT (fp
, tp
->ctt_info
);
482 return LCTF_INDEX_TO_TYPE (fp
, i
->ctn_type
++, fp
->ctf_flags
& LCTF_CHILD
);
484 ctf_next_destroy (i
);
486 return ctf_set_errno (fp
, ECTF_NEXT_END
);
489 /* Iterate over every variable in the given CTF dict, in arbitrary order.
490 We pass the name of each variable to the specified callback function. */
493 ctf_variable_iter (ctf_dict_t
*fp
, ctf_variable_f
*func
, void *arg
)
497 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
498 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
500 if (!(fp
->ctf_flags
& LCTF_RDWR
))
503 for (i
= 0; i
< fp
->ctf_nvars
; i
++)
504 if ((rc
= func (ctf_strptr (fp
, fp
->ctf_vars
[i
].ctv_name
),
505 fp
->ctf_vars
[i
].ctv_type
, arg
)) != 0)
512 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
;
513 dvd
= ctf_list_next (dvd
))
515 if ((rc
= func (dvd
->dvd_name
, dvd
->dvd_type
, arg
)) != 0)
523 /* Iterate over every variable in the given CTF dict, in arbitrary order,
524 returning the name and type of each variable in turn. The name argument is
525 not optional. Returns CTF_ERR on end of iteration or error. */
528 ctf_variable_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
)
532 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
533 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
537 if ((i
= ctf_next_create ()) == NULL
)
538 return ctf_set_errno (fp
, ENOMEM
);
541 i
->ctn_iter_fun
= (void (*) (void)) ctf_variable_next
;
542 if (fp
->ctf_flags
& LCTF_RDWR
)
543 i
->u
.ctn_dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
547 if ((void (*) (void)) ctf_variable_next
!= i
->ctn_iter_fun
)
548 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
550 if (fp
!= i
->cu
.ctn_fp
)
551 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
553 if (!(fp
->ctf_flags
& LCTF_RDWR
))
555 if (i
->ctn_n
>= fp
->ctf_nvars
)
558 *name
= ctf_strptr (fp
, fp
->ctf_vars
[i
->ctn_n
].ctv_name
);
559 return fp
->ctf_vars
[i
->ctn_n
++].ctv_type
;
565 if (i
->u
.ctn_dvd
== NULL
)
568 *name
= i
->u
.ctn_dvd
->dvd_name
;
569 id
= i
->u
.ctn_dvd
->dvd_type
;
570 i
->u
.ctn_dvd
= ctf_list_next (i
->u
.ctn_dvd
);
575 ctf_next_destroy (i
);
577 return ctf_set_errno (fp
, ECTF_NEXT_END
);
580 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
581 RESTRICT nodes until we reach a "base" type node. This is useful when
582 we want to follow a type ID to a node that has members or a size. To guard
583 against infinite loops, we implement simplified cycle detection and check
584 each link against itself, the previous node, and the topmost node.
586 Does not drill down through slices to their contained type.
588 Callers of this function must not presume that a type it returns must have a
589 valid ctt_size: forwards do not, and must be separately handled. */
592 ctf_type_resolve (ctf_dict_t
*fp
, ctf_id_t type
)
594 ctf_id_t prev
= type
, otype
= type
;
595 ctf_dict_t
*ofp
= fp
;
596 const ctf_type_t
*tp
;
599 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
601 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
603 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
609 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
610 || tp
->ctt_type
== prev
)
612 ctf_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
614 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
623 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
626 return CTF_ERR
; /* errno is set for us. */
629 /* Like ctf_type_resolve(), but traverse down through slices to their contained
633 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
635 const ctf_type_t
*tp
;
637 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
640 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
641 return CTF_ERR
; /* errno is set for us. */
643 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
644 return ctf_type_reference (fp
, type
);
648 /* Return the native dict of a given type: if called on a child and the
649 type is in the parent, return the parent. Needed if you plan to access
650 the type directly, without using the API. */
652 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
654 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
655 return fp
->ctf_parent
;
660 /* Look up a name in the given name table, in the appropriate hash given the
661 kind of the identifier. The name is a raw, undecorated identifier. */
663 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
665 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
668 /* Look up a name in the given name table, in the appropriate hash given the
669 readability state of the dictionary. The name is a raw, undecorated
672 ctf_id_t
ctf_lookup_by_rawhash (ctf_dict_t
*fp
, ctf_names_t
*np
, const char *name
)
676 if (fp
->ctf_flags
& LCTF_RDWR
)
677 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
679 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
683 /* Lookup the given type ID and return its name as a new dynamically-allocated
687 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
690 ctf_decl_node_t
*cdp
;
691 ctf_decl_prec_t prec
, lp
, rp
;
696 if (fp
== NULL
&& type
== CTF_ERR
)
697 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
700 ctf_decl_push (&cd
, fp
, type
);
705 ctf_set_errno (fp
, cd
.cd_err
);
709 /* If the type graph's order conflicts with lexical precedence order
710 for pointers or arrays, then we need to surround the declarations at
711 the corresponding lexical precedence with parentheses. This can
712 result in either a parenthesized pointer (*) as in int (*)() or
713 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
715 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
716 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
718 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
719 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
721 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
723 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
725 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
726 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
728 ctf_dict_t
*rfp
= fp
;
729 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
730 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
732 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
733 ctf_decl_sprintf (&cd
, " ");
737 ctf_decl_sprintf (&cd
, "(");
741 switch (cdp
->cd_kind
)
746 /* Integers, floats, and typedefs must always be named types. */
750 ctf_set_errno (fp
, ECTF_CORRUPT
);
755 ctf_decl_sprintf (&cd
, "%s", name
);
758 ctf_decl_sprintf (&cd
, "*");
761 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
767 ctf_id_t
*argv
= NULL
;
769 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
770 goto err
; /* errno is set for us. */
772 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
774 ctf_set_errno (rfp
, errno
);
778 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
779 fi
.ctc_argc
, argv
) < 0)
780 goto err
; /* errno is set for us. */
782 ctf_decl_sprintf (&cd
, "(*) (");
783 for (i
= 0; i
< fi
.ctc_argc
; i
++)
785 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
788 goto err
; /* errno is set for us. */
789 ctf_decl_sprintf (&cd
, "%s", arg
);
792 if ((i
< fi
.ctc_argc
- 1)
793 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
794 ctf_decl_sprintf (&cd
, ", ");
797 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
798 ctf_decl_sprintf (&cd
, "...");
799 ctf_decl_sprintf (&cd
, ")");
812 ctf_decl_sprintf (&cd
, "struct %s", name
);
815 ctf_decl_sprintf (&cd
, "union %s", name
);
818 ctf_decl_sprintf (&cd
, "enum %s", name
);
821 ctf_decl_sprintf (&cd
, "volatile");
824 ctf_decl_sprintf (&cd
, "const");
827 ctf_decl_sprintf (&cd
, "restrict");
830 /* No representation: just changes encoding of contained type,
831 which is not in any case printed. Skip it. */
839 ctf_decl_sprintf (&cd
, ")");
843 (void) ctf_set_errno (fp
, ENOMEM
);
845 buf
= ctf_decl_buf (&cd
);
851 /* Lookup the given type ID and print a string name for it into buf. Return
852 the actual number of bytes (not including \0) needed to format the name. */
855 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
857 char *str
= ctf_type_aname (fp
, type
);
861 return CTF_ERR
; /* errno is set for us. */
864 snprintf (buf
, len
, "%s", str
);
868 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
873 /* Lookup the given type ID and print a string name for it into buf. If buf
874 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
877 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
879 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
880 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
883 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
884 The name will live as long as its ctf_dict_t does. */
887 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
889 const ctf_type_t
*tp
;
891 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
892 return NULL
; /* errno is set for us. */
894 return ctf_strraw (fp
, tp
->ctt_name
);
897 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
898 new dynamically-allocated string. */
901 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
903 const char *name
= ctf_type_name_raw (fp
, type
);
906 return strdup (name
);
911 /* Resolve the type down to a base type node, and then return the size
912 of the type storage in bytes. */
915 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
917 ctf_dict_t
*ofp
= fp
;
918 const ctf_type_t
*tp
;
922 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
923 return -1; /* errno is set for us. */
925 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
926 return -1; /* errno is set for us. */
928 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
931 return fp
->ctf_dmodel
->ctd_pointer
;
934 return 0; /* Function size is only known by symtab. */
937 return fp
->ctf_dmodel
->ctd_int
;
940 /* ctf_add_array() does not directly encode the element size, but
941 requires the user to multiply to determine the element size.
943 If ctf_get_ctt_size() returns nonzero, then use the recorded
946 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
949 if (ctf_array_info (ofp
, type
, &ar
) < 0
950 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
951 return -1; /* errno is set for us. */
953 return size
* ar
.ctr_nelems
;
956 /* Forwards do not have a meaningful size. */
957 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
959 default: /* including slices of enums, etc */
960 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
964 /* Resolve the type down to a base type node, and then return the alignment
965 needed for the type storage in bytes.
967 XXX may need arch-dependent attention. */
970 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
972 const ctf_type_t
*tp
;
973 ctf_dict_t
*ofp
= fp
;
976 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
977 return -1; /* errno is set for us. */
979 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
980 return -1; /* errno is set for us. */
982 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
987 return fp
->ctf_dmodel
->ctd_pointer
;
992 if (ctf_array_info (ofp
, type
, &r
) < 0)
993 return -1; /* errno is set for us. */
994 return (ctf_type_align (ofp
, r
.ctr_contents
));
1003 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1005 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1006 ssize_t size
, increment
;
1009 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1010 vmp
= (unsigned char *) tp
+ increment
;
1012 if (kind
== CTF_K_STRUCT
)
1013 n
= MIN (n
, 1); /* Only use first member for structs. */
1015 if (size
< CTF_LSTRUCT_THRESH
)
1017 const ctf_member_t
*mp
= vmp
;
1018 for (; n
!= 0; n
--, mp
++)
1020 ssize_t am
= ctf_type_align (ofp
, mp
->ctm_type
);
1021 align
= MAX (align
, (size_t) am
);
1026 const ctf_lmember_t
*lmp
= vmp
;
1027 for (; n
!= 0; n
--, lmp
++)
1029 ssize_t am
= ctf_type_align (ofp
, lmp
->ctlm_type
);
1030 align
= MAX (align
, (size_t) am
);
1038 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1039 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1041 ssize_t am
= ctf_type_align (ofp
, dmd
->dmd_type
);
1042 align
= MAX (align
, (size_t) am
);
1043 if (kind
== CTF_K_STRUCT
)
1052 return fp
->ctf_dmodel
->ctd_int
;
1055 /* Forwards do not have a meaningful alignment. */
1056 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1058 default: /* including slices of enums, etc */
1059 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1063 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1066 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1068 const ctf_type_t
*tp
;
1070 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1071 return -1; /* errno is set for us. */
1073 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1076 /* Return the kind (CTF_K_* constant) for the specified type ID.
1077 Slices are considered to be of the same kind as the type sliced. */
1080 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1084 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1087 if (kind
== CTF_K_SLICE
)
1089 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1091 kind
= ctf_type_kind_unsliced (fp
, type
);
1097 /* Return the kind of this type, except, for forwards, return the kind of thing
1098 this is a forward to. */
1100 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1103 const ctf_type_t
*tp
;
1105 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1106 return -1; /* errno is set for us. */
1108 if (kind
!= CTF_K_FORWARD
)
1111 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1112 return -1; /* errno is set for us. */
1114 return tp
->ctt_type
;
1117 /* If the type is one that directly references another type (such as POINTER),
1118 then return the ID of the type to which it refers. */
1121 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1123 ctf_dict_t
*ofp
= fp
;
1124 const ctf_type_t
*tp
;
1126 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1127 return CTF_ERR
; /* errno is set for us. */
1129 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1133 case CTF_K_VOLATILE
:
1135 case CTF_K_RESTRICT
:
1136 return tp
->ctt_type
;
1137 /* Slices store their type in an unusual place. */
1141 const ctf_slice_t
*sp
;
1143 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1147 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1148 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1151 sp
= &dtd
->dtd_u
.dtu_slice
;
1153 return sp
->cts_type
;
1156 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1160 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1161 pointer to the given type, see if we can compute a pointer to the type
1162 resulting from resolving the type down to its base type and use that
1163 instead. This helps with cases where the CTF data includes "struct foo *"
1164 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1166 XXX what about parent dicts? */
1169 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1171 ctf_dict_t
*ofp
= fp
;
1174 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1175 return CTF_ERR
; /* errno is set for us. */
1177 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1178 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1180 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1181 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1183 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1184 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1186 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1187 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1189 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1192 /* Return the encoding for the specified INTEGER or FLOAT. */
1195 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1197 ctf_dict_t
*ofp
= fp
;
1199 const ctf_type_t
*tp
;
1203 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1204 return -1; /* errno is set for us. */
1206 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1208 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1212 *ep
= dtd
->dtd_u
.dtu_enc
;
1216 const ctf_slice_t
*slice
;
1217 ctf_encoding_t underlying_en
;
1218 ctf_id_t underlying
;
1220 slice
= &dtd
->dtd_u
.dtu_slice
;
1221 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1222 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1224 ep
->cte_format
= underlying_en
.cte_format
;
1225 ep
->cte_offset
= slice
->cts_offset
;
1226 ep
->cte_bits
= slice
->cts_bits
;
1230 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1235 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1237 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1240 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1241 ep
->cte_format
= CTF_INT_ENCODING (data
);
1242 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1243 ep
->cte_bits
= CTF_INT_BITS (data
);
1246 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1247 ep
->cte_format
= CTF_FP_ENCODING (data
);
1248 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1249 ep
->cte_bits
= CTF_FP_BITS (data
);
1253 const ctf_slice_t
*slice
;
1254 ctf_encoding_t underlying_en
;
1255 ctf_id_t underlying
;
1257 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1258 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1259 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1261 ep
->cte_format
= underlying_en
.cte_format
;
1262 ep
->cte_offset
= slice
->cts_offset
;
1263 ep
->cte_bits
= slice
->cts_bits
;
1267 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1274 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1281 else if (ltype
> rtype
)
1289 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1290 lfp
= lfp
->ctf_parent
;
1292 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1293 rfp
= rfp
->ctf_parent
;
1304 /* Return a boolean value indicating if two types are compatible. This function
1305 returns true if the two types are the same, or if they (or their ultimate
1306 base type) have the same encoding properties, or (for structs / unions /
1307 enums / forward declarations) if they have the same name and (for structs /
1308 unions) member count. */
1311 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1312 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1314 const ctf_type_t
*ltp
, *rtp
;
1315 ctf_encoding_t le
, re
;
1316 ctf_arinfo_t la
, ra
;
1317 uint32_t lkind
, rkind
;
1320 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1323 ltype
= ctf_type_resolve (lfp
, ltype
);
1324 lkind
= ctf_type_kind (lfp
, ltype
);
1326 rtype
= ctf_type_resolve (rfp
, rtype
);
1327 rkind
= ctf_type_kind (rfp
, rtype
);
1329 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1330 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1332 if (ltp
!= NULL
&& rtp
!= NULL
)
1333 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1334 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1336 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1337 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1347 memset (&le
, 0, sizeof (le
));
1348 memset (&re
, 0, sizeof (re
));
1349 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1350 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1351 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1353 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1354 rfp
, ctf_type_reference (rfp
, rtype
)));
1356 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1357 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1358 && la
.ctr_nelems
== ra
.ctr_nelems
1359 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1360 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1363 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1364 == ctf_type_size (rfp
, rtype
)));
1367 int lencoded
, rencoded
;
1368 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1369 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1371 if ((lencoded
!= rencoded
) ||
1372 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1377 return same_names
; /* No other checks required for these type kinds. */
1379 return 0; /* Should not get here since we did a resolve. */
1383 /* Return the number of members in a STRUCT or UNION, or the number of
1384 enumerators in an ENUM. */
1387 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1389 ctf_dict_t
*ofp
= fp
;
1390 const ctf_type_t
*tp
;
1393 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1394 return -1; /* errno is set for us. */
1396 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1397 return -1; /* errno is set for us. */
1399 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1401 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1402 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1404 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1407 /* Return the type and offset for a given member of a STRUCT or UNION. */
1410 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1411 ctf_membinfo_t
*mip
)
1413 ctf_dict_t
*ofp
= fp
;
1414 const ctf_type_t
*tp
;
1416 ssize_t size
, increment
;
1419 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1420 return -1; /* errno is set for us. */
1422 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1423 return -1; /* errno is set for us. */
1425 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1426 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1428 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1429 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1431 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1433 if (size
< CTF_LSTRUCT_THRESH
)
1435 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1438 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1440 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
1442 mip
->ctm_type
= mp
->ctm_type
;
1443 mip
->ctm_offset
= mp
->ctm_offset
;
1450 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1453 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1455 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
1457 mip
->ctm_type
= lmp
->ctlm_type
;
1458 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1468 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1469 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1471 if (strcmp (dmd
->dmd_name
, name
) == 0)
1473 mip
->ctm_type
= dmd
->dmd_type
;
1474 mip
->ctm_offset
= dmd
->dmd_offset
;
1480 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1483 /* Return the array type, index, and size information for the specified ARRAY. */
1486 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1488 ctf_dict_t
*ofp
= fp
;
1489 const ctf_type_t
*tp
;
1490 const ctf_array_t
*ap
;
1491 const ctf_dtdef_t
*dtd
;
1494 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1495 return -1; /* errno is set for us. */
1497 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1498 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1500 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1502 *arp
= dtd
->dtd_u
.dtu_arr
;
1506 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1508 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1509 arp
->ctr_contents
= ap
->cta_contents
;
1510 arp
->ctr_index
= ap
->cta_index
;
1511 arp
->ctr_nelems
= ap
->cta_nelems
;
1516 /* Convert the specified value to the corresponding enum tag name, if a
1517 matching name can be found. Otherwise NULL is returned. */
1520 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1522 ctf_dict_t
*ofp
= fp
;
1523 const ctf_type_t
*tp
;
1524 const ctf_enum_t
*ep
;
1525 const ctf_dtdef_t
*dtd
;
1529 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1530 return NULL
; /* errno is set for us. */
1532 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1533 return NULL
; /* errno is set for us. */
1535 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1537 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1541 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1543 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1545 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1547 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1549 if (ep
->cte_value
== value
)
1550 return (ctf_strptr (fp
, ep
->cte_name
));
1557 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1558 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1560 if (dmd
->dmd_value
== value
)
1561 return dmd
->dmd_name
;
1565 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1569 /* Convert the specified enum tag name to the corresponding value, if a
1570 matching name can be found. Otherwise CTF_ERR is returned. */
1573 ctf_enum_value (ctf_dict_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1575 ctf_dict_t
*ofp
= fp
;
1576 const ctf_type_t
*tp
;
1577 const ctf_enum_t
*ep
;
1578 const ctf_dtdef_t
*dtd
;
1582 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1583 return -1; /* errno is set for us. */
1585 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1586 return -1; /* errno is set for us. */
1588 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1590 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1594 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1596 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1598 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1600 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1602 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1605 *valp
= ep
->cte_value
;
1614 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1615 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1617 if (strcmp (dmd
->dmd_name
, name
) == 0)
1620 *valp
= dmd
->dmd_value
;
1626 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1630 /* Given a type ID relating to a function type, return info on return types and
1631 arg counts for that function. */
1634 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1636 const ctf_type_t
*tp
;
1638 const uint32_t *args
;
1639 const ctf_dtdef_t
*dtd
;
1640 ssize_t size
, increment
;
1642 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1643 return -1; /* errno is set for us. */
1645 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1646 return -1; /* errno is set for us. */
1648 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1649 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1651 if (kind
!= CTF_K_FUNCTION
)
1652 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1654 fip
->ctc_return
= tp
->ctt_type
;
1656 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1658 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1659 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1661 args
= dtd
->dtd_u
.dtu_argv
;
1663 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1665 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1672 /* Given a type ID relating to a function type, return the arguments for the
1676 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1678 const ctf_type_t
*tp
;
1679 const uint32_t *args
;
1680 const ctf_dtdef_t
*dtd
;
1681 ssize_t size
, increment
;
1684 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1685 return -1; /* errno is set for us. */
1687 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1688 return -1; /* errno is set for us. */
1690 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1691 return -1; /* errno is set for us. */
1693 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1695 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1696 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1698 args
= dtd
->dtd_u
.dtu_argv
;
1700 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1706 /* Recursively visit the members of any type. This function is used as the
1707 engine for ctf_type_visit, below. We resolve the input type, recursively
1708 invoke ourself for each type member if the type is a struct or union, and
1709 then invoke the callback function on the current type. If any callback
1710 returns non-zero, we abort and percolate the error code back up to the top. */
1713 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1714 void *arg
, const char *name
, unsigned long offset
, int depth
)
1716 ctf_id_t otype
= type
;
1717 const ctf_type_t
*tp
;
1718 const ctf_dtdef_t
*dtd
;
1719 ssize_t size
, increment
;
1723 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1724 return -1; /* errno is set for us. */
1726 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1727 return -1; /* errno is set for us. */
1729 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1732 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1734 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1737 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1739 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1741 if (size
< CTF_LSTRUCT_THRESH
)
1743 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1746 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1748 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1749 func
, arg
, ctf_strptr (fp
,
1751 offset
+ mp
->ctm_offset
,
1758 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1761 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1763 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1764 func
, arg
, ctf_strptr (fp
,
1766 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1776 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1777 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1779 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1780 dmd
->dmd_name
, dmd
->dmd_offset
,
1789 /* Recursively visit the members of any type. We pass the name, member
1790 type, and offset of each member to the specified callback function. */
1792 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1794 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));